From 2fb9714dac14c7278c6c0a9383c2d7fb5329f967 Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Sun, 12 Jul 2015 21:35:45 +0000 Subject: [PATCH 001/314] Introduce Annapurna Labs HAL for Alpine PoC This commit adds HAL (Hardware Abstraction Layer) code for Alpine Platform on Chip from Annapurna Labs. Only published files are included. HAL version: 2.7 Obtained from: Semihalf Sponsored by: Annapurna Labs --- al_hal_common.h | 70 + al_hal_iofic.h | 222 +++ al_hal_iofic_regs.h | 127 ++ al_hal_nb_regs.h | 1823 +++++++++++++++++++++++ al_hal_pbs_regs.h | 2751 +++++++++++++++++++++++++++++++++++ al_hal_pcie.c | 2788 ++++++++++++++++++++++++++++++++++++ al_hal_pcie.h | 1157 +++++++++++++++ al_hal_pcie_axi_reg.h | 1501 +++++++++++++++++++ al_hal_pcie_interrupts.h | 271 ++++ al_hal_pcie_regs.h | 594 ++++++++ al_hal_pcie_w_reg.h | 1505 +++++++++++++++++++ al_hal_plat_services.h | 419 ++++++ al_hal_plat_types.h | 94 ++ al_hal_reg_utils.h | 188 +++ al_hal_types.h | 117 ++ al_hal_unit_adapter_regs.h | 314 ++++ 16 files changed, 13941 insertions(+) create mode 100644 al_hal_common.h create mode 100644 al_hal_iofic.h create mode 100644 al_hal_iofic_regs.h create mode 100644 al_hal_nb_regs.h create mode 100644 al_hal_pbs_regs.h create mode 100644 al_hal_pcie.c create mode 100644 al_hal_pcie.h create mode 100644 al_hal_pcie_axi_reg.h create mode 100644 al_hal_pcie_interrupts.h create mode 100644 al_hal_pcie_regs.h create mode 100644 al_hal_pcie_w_reg.h create mode 100644 al_hal_plat_services.h create mode 100644 al_hal_plat_types.h create mode 100644 al_hal_reg_utils.h create mode 100644 al_hal_types.h create mode 100644 al_hal_unit_adapter_regs.h diff --git a/al_hal_common.h b/al_hal_common.h new file mode 100644 index 000000000000..6e27e1795cb1 --- /dev/null +++ b/al_hal_common.h @@ -0,0 +1,70 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @defgroup group_common HAL Common Layer + * Includes all common header files used by HAL + * @{ + * @file al_hal_common.h + * + */ + +#ifndef __AL_HAL_COMMON_H__ +#define __AL_HAL_COMMON_H__ + +#include "al_hal_plat_types.h" +#include "al_hal_plat_services.h" + +#include "al_hal_types.h" +#include "al_hal_reg_utils.h" + +/* Get the maximal value out of two typed values */ +#define al_max_t(type, x, y) ({ \ + type __max1 = (x); \ + type __max2 = (y); \ + __max1 > __max2 ? __max1 : __max2; }) + +/* Get the minimal value out of two typed values */ +#define al_min_t(type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + __min1 < __min2 ? __min1 : __min2; }) + +/* Get the number of elements in an array */ +#define AL_ARR_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +/** @} end of Common group */ +#endif /* __AL_HAL_COMMON_H__ */ diff --git a/al_hal_iofic.h b/al_hal_iofic.h new file mode 100644 index 000000000000..5c19e0a12606 --- /dev/null +++ b/al_hal_iofic.h @@ -0,0 +1,222 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @defgroup group_interrupts Common I/O Fabric Interrupt Controller + * This HAL provides the API for programming the Common I/O Fabric Interrupt + * Controller (IOFIC) found in most of the units attached to the I/O Fabric of + * Alpine platform + * @{ + * @file al_hal_iofic.h + * + * @brief Header file for the interrupt controller that's embedded in various units + * + */ + +#ifndef __AL_HAL_IOFIC_H__ +#define __AL_HAL_IOFIC_H__ + +#include + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +#define AL_IOFIC_MAX_GROUPS 4 + +/* + * Configurations + */ + +/** + * Configure the interrupt controller registers, actual interrupts are still + * masked at this stage. + * + * @param regs_base regs pointer to interrupt controller registers + * @param group the interrupt group. + * @param flags flags of Interrupt Control Register + * + * @return 0 on success. -EINVAL otherwise. + */ +int al_iofic_config(void __iomem *regs_base, int group, + uint32_t flags); + +/** + * configure the moderation timer resolution for a given group + * Applies for both msix and legacy mode. + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + * @param resolution resolution of the timer interval, the resolution determines the rate + * of decrementing the interval timer, setting value N means that the interval + * timer will be decremented each (N+1) * (0.68) micro seconds. + * + * @return 0 on success. -EINVAL otherwise. + */ +int al_iofic_moder_res_config(void __iomem *regs_base, int group, + uint8_t resolution); + +/** + * configure the moderation timer interval for a given legacy interrupt group + * + * @param regs_base regs pointer to unit registers + * @param group the interrupt group + * @param interval between interrupts in resolution units. 0 disable + * + * @return 0 on success. -EINVAL otherwise. + */ +int al_iofic_legacy_moder_interval_config(void __iomem *regs_base, int group, + uint8_t interval); + +/** + * configure the moderation timer interval for a given msix vector + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + * @param vector vector index + * @param interval interval between interrupts, 0 disable + * + * @return 0 on success. -EINVAL otherwise. + */ +int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group, + uint8_t vector, uint8_t interval); + +/** +* configure the vmid attributes for a given msix vector. +* +* @param group the interrupt group +* @param vector index +* @param vmid the vmid value +* @param vmid_en take vmid from the intc +* +* @return 0 on success. -EINVAL otherwise. +*/ +int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group, + uint8_t vector, uint32_t vmid, uint8_t vmid_en); + +/** + * return the offset of the unmask register for a given group. + * this function can be used when the upper layer wants to directly + * access the unmask regiter and bypass the al_iofic_unmask() API. + * + * @param regs_base regs pointer to unit registers + * @param group the interrupt group + * @return the offset of the unmask register. + */ +uint32_t __iomem * al_iofic_unmask_offset_get(void __iomem *regs_base, int group); + +/** + * unmask specific interrupts for a given group + * this functions guarantees atomic operations, it is performance optimized as + * it will not require read-modify-write. The unmask done using the interrupt + * mask clear register, so it's safe to call it while the mask is changed by + * the HW (auto mask) or another core. + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + * @param mask bitwise of interrupts to unmask, set bits will be unmasked. + */ +void al_iofic_unmask(void __iomem *regs_base, int group, uint32_t mask); + +/** + * mask specific interrupts for a given group + * this functions modifies interrupt mask register, the callee must make sure + * the mask is not changed by another cpu. + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + * @param mask bitwise of interrupts to mask, set bits will be masked. + */ +void al_iofic_mask(void __iomem *regs_base, int group, uint32_t mask); + +/** + * read the mask register for a given group + * this functions return the interrupt mask register + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + */ +uint32_t al_iofic_read_mask(void __iomem *regs_base, int group); + +/** + * read interrupt cause register for a given group + * this will clear the set bits if the Clear on Read mode enabled. + * @param regs_base pointer to unit registers + * @param group the interrupt group + */ +uint32_t al_iofic_read_cause(void __iomem *regs_base, int group); + +/** + * clear bits in the interrupt cause register for a given group + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + * @param mask bitwise of bits to be cleared, set bits will be cleared. + */ +void al_iofic_clear_cause(void __iomem *regs_base, int group, uint32_t mask); + +/** + * set the cause register for a given group + * this function set the cause register. It will generate an interrupt (if + * the the interrupt isn't masked ) + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + * @param mask bitwise of bits to be set. + */ +void al_iofic_set_cause(void __iomem *regs_base, int group, uint32_t mask); + +/** + * unmask specific interrupts from aborting the udma a given group + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + * @param mask bitwise of interrupts to mask + */ +void al_iofic_abort_mask(void __iomem *regs_base, int group, uint32_t mask); + +/** + * trigger all interrupts that are waiting for moderation timers to expire + * + * @param regs_base pointer to unit registers + * @param group the interrupt group + */ +void al_iofic_interrupt_moderation_reset(void __iomem *regs_base, int group); + +#endif +/** @} end of interrupt controller group */ diff --git a/al_hal_iofic_regs.h b/al_hal_iofic_regs.h new file mode 100644 index 000000000000..81ba20fc9676 --- /dev/null +++ b/al_hal_iofic_regs.h @@ -0,0 +1,127 @@ +/*_ +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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 __AL_HAL_IOFIC_REG_H +#define __AL_HAL_IOFIC_REG_H + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + +struct al_iofic_grp_ctrl { + uint32_t int_cause_grp; /* Interrupt Cause RegisterSet by hardware */ + uint32_t rsrvd1; + uint32_t int_cause_set_grp; /* Interrupt Cause Set RegisterWriting 1 to a bit in t ... */ + uint32_t rsrvd2; + uint32_t int_mask_grp; /* Interrupt Mask RegisterIf Auto-mask control bit =TR ... */ + uint32_t rsrvd3; + uint32_t int_mask_clear_grp; /* Interrupt Mask Clear RegisterUsed when auto-mask co ... */ + uint32_t rsrvd4; + uint32_t int_status_grp; /* Interrupt status RegisterThis register latch the st ... */ + uint32_t rsrvd5; + uint32_t int_control_grp; /* Interrupt Control Register */ + uint32_t rsrvd6; + uint32_t int_abort_msk_grp; /* Interrupt Mask RegisterEach bit in this register ma ... */ + uint32_t rsrvd7; + uint32_t int_log_msk_grp; /* Interrupt Log RegisterEach bit in this register mas ... */ + uint32_t rsrvd8; +}; + +struct al_iofic_grp_mod { + uint32_t grp_int_mod_reg; /* Interrupt moderation registerDedicated moderation in ... */ + uint32_t grp_int_vmid_reg; +}; + +struct al_iofic_regs { + struct al_iofic_grp_ctrl ctrl[0]; + uint32_t rsrvd1[0x400 >> 2]; + struct al_iofic_grp_mod grp_int_mod[0][32]; +}; + + +/* +* Registers Fields +*/ + + +/**** int_control_grp register ****/ +/* When Clear_on_Read =1, All bits of Cause register ... */ +#define INT_CONTROL_GRP_CLEAR_ON_READ (1 << 0) +/* (must be set only when MSIX is enabled)When Auto-Ma ... */ +#define INT_CONTROL_GRP_AUTO_MASK (1 << 1) +/* Auto_Clear (RW)When Auto-Clear =1, the bits in the ... */ +#define INT_CONTROL_GRP_AUTO_CLEAR (1 << 2) +/* When Set_on_Posedge =1, the bits in the interrupt c ... */ +#define INT_CONTROL_GRP_SET_ON_POSEDGE (1 << 3) +/* When Moderation_Reset =1, all Moderation timers ass ... */ +#define INT_CONTROL_GRP_MOD_RST (1 << 4) +/* When mask_msi_x =1, No MSI-X from this group is sen ... */ +#define INT_CONTROL_GRP_MASK_MSI_X (1 << 5) +/* MSI-X AWID value, same ID for all cause bits */ +#define INT_CONTROL_GRP_AWID_MASK 0x00000F00 +#define INT_CONTROL_GRP_AWID_SHIFT 8 +/* This value determines the interval between interrup ... */ +#define INT_CONTROL_GRP_MOD_INTV_MASK 0x00FF0000 +#define INT_CONTROL_GRP_MOD_INTV_SHIFT 16 +/* This value determines the Moderation_Timer_Clock sp ... */ +#define INT_CONTROL_GRP_MOD_RES_MASK 0x0F000000 +#define INT_CONTROL_GRP_MOD_RES_SHIFT 24 + +/**** grp_int_mod_reg register ****/ +/* Interrupt Moderation Interval registerDedicated reg ... */ +#define INT_MOD_INTV_MASK 0x000000FF +#define INT_MOD_INTV_SHIFT 0 + +/**** grp_int_vmid_reg register ****/ +/* Interrupt vmid value registerDedicated reg ... */ +#define INT_MSIX_VMID_MASK 0x0000FFFF +#define INT_MSIX_VMID_SHIFT 0 +/* Interrupt vmid_en value registerDedicated reg ... */ +#define INT_MSIX_VMID_EN_SHIFT 31 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_IOFIC_REG_H */ + + + + diff --git a/al_hal_nb_regs.h b/al_hal_nb_regs.h new file mode 100644 index 000000000000..9de3bd246865 --- /dev/null +++ b/al_hal_nb_regs.h @@ -0,0 +1,1823 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_nb_regs.h + * + * @brief North Bridge service registers + * + */ + +#ifndef __AL_HAL_NB_REGS_H__ +#define __AL_HAL_NB_REGS_H__ + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct al_nb_global { + /* [0x0] */ + uint32_t cpus_config; + /* [0x4] */ + uint32_t cpus_secure; + /* [0x8] Force init reset. */ + uint32_t cpus_init_control; + /* [0xc] Force init reset per DECEI mode. */ + uint32_t cpus_init_status; + /* [0x10] */ + uint32_t nb_int_cause; + /* [0x14] */ + uint32_t sev_int_cause; + /* [0x18] */ + uint32_t pmus_int_cause; + /* [0x1c] */ + uint32_t sev_mask; + /* [0x20] */ + uint32_t cpus_hold_reset; + /* [0x24] */ + uint32_t cpus_software_reset; + /* [0x28] */ + uint32_t wd_timer0_reset; + /* [0x2c] */ + uint32_t wd_timer1_reset; + /* [0x30] */ + uint32_t wd_timer2_reset; + /* [0x34] */ + uint32_t wd_timer3_reset; + /* [0x38] */ + uint32_t ddrc_hold_reset; + /* [0x3c] */ + uint32_t fabric_software_reset; + /* [0x40] */ + uint32_t cpus_power_ctrl; + uint32_t rsrvd_0[7]; + /* [0x60] */ + uint32_t acf_base_high; + /* [0x64] */ + uint32_t acf_base_low; + /* [0x68] */ + uint32_t acf_control_override; + /* [0x6c] Read-only that reflects CPU Cluster Local GIC base high address */ + uint32_t lgic_base_high; + /* [0x70] Read-only that reflects CPU Cluster Local GIC base low address */ + uint32_t lgic_base_low; + /* [0x74] Read-only that reflects the device's IOGIC base high address. */ + uint32_t iogic_base_high; + /* [0x78] Read-only that reflects IOGIC base low address */ + uint32_t iogic_base_low; + /* [0x7c] */ + uint32_t io_wr_split_control; + /* [0x80] */ + uint32_t io_rd_rob_control; + /* [0x84] */ + uint32_t sb_pos_error_log_1; + /* [0x88] */ + uint32_t sb_pos_error_log_0; + /* [0x8c] */ + uint32_t c2swb_config; + /* [0x90] */ + uint32_t msix_error_log; + /* [0x94] */ + uint32_t error_cause; + /* [0x98] */ + uint32_t error_mask; + uint32_t rsrvd_1; + /* [0xa0] */ + uint32_t qos_peak_control; + /* [0xa4] */ + uint32_t qos_set_control; + /* [0xa8] */ + uint32_t ddr_qos; + uint32_t rsrvd_2[9]; + /* [0xd0] */ + uint32_t acf_misc; + /* [0xd4] */ + uint32_t config_bus_control; + uint32_t rsrvd_3[2]; + /* [0xe0] */ + uint32_t pos_id_match; + uint32_t rsrvd_4[3]; + /* [0xf0] */ + uint32_t sb_sel_override_awuser; + /* [0xf4] */ + uint32_t sb_override_awuser; + /* [0xf8] */ + uint32_t sb_sel_override_aruser; + /* [0xfc] */ + uint32_t sb_override_aruser; + /* [0x100] */ + uint32_t cpu_max_pd_timer; + /* [0x104] */ + uint32_t cpu_max_pu_timer; + uint32_t rsrvd_5[2]; + /* [0x110] */ + uint32_t auto_ddr_self_refresh_counter; + uint32_t rsrvd_6[3]; + /* [0x120] */ + uint32_t coresight_pd; + /* [0x124] */ + uint32_t coresight_internal_0; + /* [0x128] */ + uint32_t coresight_dbgromaddr; + /* [0x12c] */ + uint32_t coresight_dbgselfaddr; + /* [0x130] */ + uint32_t coresght_targetid; + /* [0x134] */ + uint32_t coresght_targetid0; + uint32_t rsrvd_7[10]; + /* [0x160] */ + uint32_t sb_force_same_id_cfg_0; + /* [0x164] */ + uint32_t sb_mstr_force_same_id_sel_0; + /* [0x168] */ + uint32_t sb_force_same_id_cfg_1; + /* [0x16c] */ + uint32_t sb_mstr_force_same_id_sel_1; + uint32_t rsrvd[932]; +}; +struct al_nb_system_counter { + /* [0x0] */ + uint32_t cnt_control; + /* [0x4] */ + uint32_t cnt_base_freq; + /* [0x8] */ + uint32_t cnt_low; + /* [0xc] */ + uint32_t cnt_high; + /* [0x10] */ + uint32_t cnt_init_low; + /* [0x14] */ + uint32_t cnt_init_high; + uint32_t rsrvd[58]; +}; +struct al_nb_rams_control_misc { + /* [0x0] */ + uint32_t ca15_rf_misc; + uint32_t rsrvd_0; + /* [0x8] */ + uint32_t nb_rf_misc; + uint32_t rsrvd[61]; +}; +struct al_nb_ca15_rams_control { + /* [0x0] */ + uint32_t rf_0; + /* [0x4] */ + uint32_t rf_1; + /* [0x8] */ + uint32_t rf_2; + uint32_t rsrvd; +}; +struct al_nb_semaphores { + /* [0x0] This configuration is only sampled during reset of the processor */ + uint32_t lockn; +}; +struct al_nb_debug { + /* [0x0] */ + uint32_t ca15_outputs_1; + /* [0x4] */ + uint32_t ca15_outputs_2; + uint32_t rsrvd_0[2]; + /* [0x10] */ + uint32_t cpu_msg[4]; + /* [0x20] */ + uint32_t rsv0_config; + /* [0x24] */ + uint32_t rsv1_config; + uint32_t rsrvd_1[2]; + /* [0x30] */ + uint32_t rsv0_status; + /* [0x34] */ + uint32_t rsv1_status; + uint32_t rsrvd_2[2]; + /* [0x40] */ + uint32_t ddrc; + /* [0x44] */ + uint32_t ddrc_phy_smode_control; + /* [0x48] */ + uint32_t ddrc_phy_smode_status; + uint32_t rsrvd_3[5]; + /* [0x60] */ + uint32_t pmc; + uint32_t rsrvd_4[3]; + /* [0x70] */ + uint32_t cpus_general; + /* [0x74] */ + uint32_t cpus_general_1; + uint32_t rsrvd_5[2]; + /* [0x80] */ + uint32_t cpus_int_out; + uint32_t rsrvd_6[3]; + /* [0x90] */ + uint32_t latch_pc_req; + uint32_t rsrvd_7; + /* [0x98] */ + uint32_t latch_pc_low; + /* [0x9c] */ + uint32_t latch_pc_high; + uint32_t rsrvd_8[24]; + /* [0x100] */ + uint32_t track_dump_ctrl; + /* [0x104] */ + uint32_t track_dump_rdata_0; + /* [0x108] */ + uint32_t track_dump_rdata_1; + uint32_t rsrvd_9[5]; + /* [0x120] */ + uint32_t track_events; + uint32_t rsrvd_10[3]; + /* [0x130] */ + uint32_t pos_track_dump_ctrl; + /* [0x134] */ + uint32_t pos_track_dump_rdata_0; + /* [0x138] */ + uint32_t pos_track_dump_rdata_1; + uint32_t rsrvd_11; + /* [0x140] */ + uint32_t c2swb_track_dump_ctrl; + /* [0x144] */ + uint32_t c2swb_track_dump_rdata_0; + /* [0x148] */ + uint32_t c2swb_track_dump_rdata_1; + uint32_t rsrvd_12; + /* [0x150] */ + uint32_t cpus_track_dump_ctrl; + /* [0x154] */ + uint32_t cpus_track_dump_rdata_0; + /* [0x158] */ + uint32_t cpus_track_dump_rdata_1; + uint32_t rsrvd_13; + /* [0x160] */ + uint32_t c2swb_bar_ovrd_high; + /* [0x164] */ + uint32_t c2swb_bar_ovrd_low; + uint32_t rsrvd[38]; +}; +struct al_nb_cpun_config_status { + /* [0x0] This configuration is only sampled during reset of the processor. */ + uint32_t config; + /* [0x4] This configuration is only sampled during reset of the processor. */ + uint32_t config_aarch64; + /* [0x8] */ + uint32_t local_cause_mask; + uint32_t rsrvd_0; + /* [0x10] */ + uint32_t pmus_cause_mask; + /* [0x14] */ + uint32_t sei_cause_mask; + uint32_t rsrvd_1[2]; + /* [0x20] Specifies the state of the CPU with reference to power modes. */ + uint32_t power_ctrl; + /* [0x24] */ + uint32_t power_status; + /* [0x28] */ + uint32_t resume_addr_l; + /* [0x2c] */ + uint32_t resume_addr_h; + uint32_t rsrvd_2[4]; + /* [0x40] */ + uint32_t warm_rst_ctl; + uint32_t rsrvd_3; + /* [0x48] */ + uint32_t rvbar_low; + /* [0x4c] */ + uint32_t rvbar_high; + /* [0x50] */ + uint32_t pmu_snapshot; + uint32_t rsrvd_4[3]; + /* [0x60] */ + uint32_t cpu_msg_in; + uint32_t rsrvd[39]; +}; +struct al_nb_mc_pmu { + /* [0x0] PMU Global Control Register */ + uint32_t pmu_control; + /* [0x4] PMU Global Control Register */ + uint32_t overflow; + uint32_t rsrvd[62]; +}; +struct al_nb_mc_pmu_counters { + /* [0x0] Counter Configuration Register */ + uint32_t cfg; + /* [0x4] Counter Control Register */ + uint32_t cntl; + /* [0x8] Counter Control Register */ + uint32_t low; + /* [0xc] Counter Control Register */ + uint32_t high; + uint32_t rsrvd[4]; +}; +struct al_nb_nb_version { + /* [0x0] Northbridge Revision */ + uint32_t version; + uint32_t rsrvd; +}; +struct al_nb_sriov { + /* [0x0] */ + uint32_t cpu_vmid[4]; + uint32_t rsrvd[4]; +}; +struct al_nb_dram_channels { + /* [0x0] */ + uint32_t dram_0_control; + uint32_t rsrvd_0; + /* [0x8] */ + uint32_t dram_0_status; + uint32_t rsrvd_1; + /* [0x10] */ + uint32_t ddr_int_cause; + uint32_t rsrvd_2; + /* [0x18] */ + uint32_t ddr_cause_mask; + uint32_t rsrvd_3; + /* [0x20] */ + uint32_t address_map; + uint32_t rsrvd_4[3]; + /* [0x30] */ + uint32_t reorder_id_mask_0; + /* [0x34] */ + uint32_t reorder_id_value_0; + /* [0x38] */ + uint32_t reorder_id_mask_1; + /* [0x3c] */ + uint32_t reorder_id_value_1; + /* [0x40] */ + uint32_t reorder_id_mask_2; + /* [0x44] */ + uint32_t reorder_id_value_2; + /* [0x48] */ + uint32_t reorder_id_mask_3; + /* [0x4c] */ + uint32_t reorder_id_value_3; + /* [0x50] */ + uint32_t mrr_control_status; + uint32_t rsrvd[43]; +}; +struct al_nb_ddr_0_mrr { + /* [0x0] Counter Configuration Register */ + uint32_t val; +}; +struct al_nb_push_packet { + /* [0x0] */ + uint32_t pp_config; + uint32_t rsrvd_0[3]; + /* [0x10] */ + uint32_t pp_ext_awuser; + uint32_t rsrvd_1[3]; + /* [0x20] */ + uint32_t pp_base_low; + /* [0x24] */ + uint32_t pp_base_high; + uint32_t rsrvd_2[2]; + /* [0x30] */ + uint32_t pp_sel_awuser; + uint32_t rsrvd[51]; +}; + +struct al_nb_regs { + struct al_nb_global global; /* [0x0] */ + struct al_nb_system_counter system_counter; /* [0x1000] */ + struct al_nb_rams_control_misc rams_control_misc; /* [0x1100] */ + struct al_nb_ca15_rams_control ca15_rams_control[5]; /* [0x1200] */ + uint32_t rsrvd_0[108]; + struct al_nb_semaphores semaphores[64]; /* [0x1400] */ + uint32_t rsrvd_1[320]; + struct al_nb_debug debug; /* [0x1a00] */ + uint32_t rsrvd_2[256]; + struct al_nb_cpun_config_status cpun_config_status[4]; /* [0x2000] */ + uint32_t rsrvd_3[1792]; + struct al_nb_mc_pmu mc_pmu; /* [0x4000] */ + struct al_nb_mc_pmu_counters mc_pmu_counters[4]; /* [0x4100] */ + uint32_t rsrvd_4[160]; + struct al_nb_nb_version nb_version; /* [0x4400] */ + uint32_t rsrvd_5[126]; + struct al_nb_sriov sriov; /* [0x4600] */ + uint32_t rsrvd_6[120]; + struct al_nb_dram_channels dram_channels; /* [0x4800] */ + struct al_nb_ddr_0_mrr ddr_0_mrr[9]; /* [0x4900] */ + uint32_t rsrvd_7[439]; + uint32_t rsrvd_8[1024]; /* [0x5000] */ + struct al_nb_push_packet push_packet; /* [0x6000] */ +}; + + +/* +* Registers Fields +*/ + + +/**** CPUs_Config register ****/ +/* Disable broadcast of barrier onto system bus. +Connect to Processor Cluster SYSBARDISABLE. */ +#define NB_GLOBAL_CPUS_CONFIG_SYSBARDISABLE (1 << 0) +/* Enable broadcast of inner shareable transactions from CPUs. +Connect to Processor Cluster BROADCASTINNER. */ +#define NB_GLOBAL_CPUS_CONFIG_BROADCASTINNER (1 << 1) +/* Disable broadcast of cache maintenance system bus. +Connect to Processor Cluster BROADCASTCACHEMAIN */ +#define NB_GLOBAL_CPUS_CONFIG_BROADCASTCACHEMAINT (1 << 2) +/* Enable broadcast of outer shareable transactions from CPUs. +Connect to Processor Cluster BROADCASTOUTER. */ +#define NB_GLOBAL_CPUS_CONFIG_BROADCASTOUTER (1 << 3) +/* Defines the internal CPU GIC operating frequency ratio with the main CPU clock. +0x0: 1:1 +0x1: 1:2 +0x2: 1:3 +0x3: 1:4 + +Note: This is not in used with CA57 */ +#define NB_GLOBAL_CPUS_CONFIG_PERIPHCLKEN_MASK 0x00000030 +#define NB_GLOBAL_CPUS_CONFIG_PERIPHCLKEN_SHIFT 4 +/* Disables the GIC CPU interface logic and routes the legacy nIRQ, nFIQ, nVIRQ, and nVFIQ +signals directly to the processor: +0 Enable the GIC CPU interface logic. +1 Disable the GIC CPU interface logic. +The processor only samples this signal as it exits reset. */ +#define NB_GLOBAL_CPUS_CONFIG_GIC_DISABLE (1 << 6) +/* Disable L1 data cache and L2 snoop tag RAMs automatic invalidate on reset functionality */ +#define NB_GLOBAL_CPUS_CONFIG_DBG_L1_RESET_DISABLE (1 << 7) +/* Value read in the Cluster ID Affinity Level-1 field, bits[15:8], of the Multiprocessor Affinity +Register (MPIDR). +This signal is only sampled during reset of the processor. */ +#define NB_GLOBAL_CPUS_CONFIG_CLUSTERIDAFF1_MASK 0x00FF0000 +#define NB_GLOBAL_CPUS_CONFIG_CLUSTERIDAFF1_SHIFT 16 +/* Value read in the Cluster ID Affinity Level-2 field, bits[23:16], of the Multiprocessor Affinity +Register (MPIDR). +This signal is only sampled during reset of the processor.. */ +#define NB_GLOBAL_CPUS_CONFIG_CLUSTERIDAFF2_MASK 0xFF000000 +#define NB_GLOBAL_CPUS_CONFIG_CLUSTERIDAFF2_SHIFT 24 + +/**** CPUs_Secure register ****/ +/* DBGEN + */ +#define NB_GLOBAL_CPUS_SECURE_DBGEN (1 << 0) +/* NIDEN + */ +#define NB_GLOBAL_CPUS_SECURE_NIDEN (1 << 1) +/* SPIDEN + */ +#define NB_GLOBAL_CPUS_SECURE_SPIDEN (1 << 2) +/* SPNIDEN + */ +#define NB_GLOBAL_CPUS_SECURE_SPNIDEN (1 << 3) +/* Disable write access to some secure GIC registers */ +#define NB_GLOBAL_CPUS_SECURE_CFGSDISABLE (1 << 4) +/* Disable write access to some secure IOGIC registers */ +#define NB_GLOBAL_CPUS_SECURE_IOGIC_CFGSDISABLE (1 << 5) + +/**** CPUs_Init_Control register ****/ +/* CPU Init Done +Specifies which CPUs' inits are done and can exit poreset. +By default, CPU0 only exits poreset when the CPUs cluster exits power-on-reset and then kicks other CPUs. +If this bit is cleared for a specific CPU, setting it by primary CPU as part of the initialization process will initiate power-on-reset to this specific CPU. */ +#define NB_GLOBAL_CPUS_INIT_CONTROL_CPUS_INITDONE_MASK 0x0000000F +#define NB_GLOBAL_CPUS_INIT_CONTROL_CPUS_INITDONE_SHIFT 0 +/* DBGPWRDNREQ Mask +When CPU does not exist, its DBGPWRDNREQ must be asserted. +If corresponding mask bit is set, the DBGPWDNREQ is deasserted. */ +#define NB_GLOBAL_CPUS_INIT_CONTROL_DBGPWRDNREQ_MASK_MASK 0x000000F0 +#define NB_GLOBAL_CPUS_INIT_CONTROL_DBGPWRDNREQ_MASK_SHIFT 4 +/* Force CPU init power-on-reset exit. +For debug purposes only. */ +#define NB_GLOBAL_CPUS_INIT_CONTROL_FORCE_CPUPOR_MASK 0x00000F00 +#define NB_GLOBAL_CPUS_INIT_CONTROL_FORCE_CPUPOR_SHIFT 8 +/* Force dbgpwrdup signal high +If dbgpwrdup is clear on the processor interface it indicates that the process debug resources are not available for APB access. */ +#define NB_GLOBAL_CPUS_INIT_CONTROL_FORCE_DBGPWRDUP_MASK 0x0000F000 +#define NB_GLOBAL_CPUS_INIT_CONTROL_FORCE_DBGPWRDUP_SHIFT 12 + +/**** CPUs_Init_Status register ****/ +/* Specifies which CPUs are enabled in the device configuration. +sample at rst_cpus_exist[3:0] reset strap. */ +#define NB_GLOBAL_CPUS_INIT_STATUS_CPUS_EXIST_MASK 0x0000000F +#define NB_GLOBAL_CPUS_INIT_STATUS_CPUS_EXIST_SHIFT 0 + +/**** NB_Int_Cause register ****/ +/* + * Each bit corresponds to an IRQ. + * value is 1 for level irq, 0 for trigger irq + * Level IRQ indices: 12-13, 23, 24, 26-29 + */ +#define NB_GLOBAL_NB_INT_CAUSE_LEVEL_IRQ_MASK 0x3D803000 +/* Cross trigger interrupt */ +#define NB_GLOBAL_NB_INT_CAUSE_NCTIIRQ_MASK 0x0000000F +#define NB_GLOBAL_NB_INT_CAUSE_NCTIIRQ_SHIFT 0 +/* Communications channel receive. Receive portion of Data Transfer Register full flag */ +#define NB_GLOBAL_NB_INT_CAUSE_COMMRX_MASK 0x000000F0 +#define NB_GLOBAL_NB_INT_CAUSE_COMMRX_SHIFT 4 +/* Communication channel transmit. Transmit portion of Data Transfer Register empty flag. */ +#define NB_GLOBAL_NB_INT_CAUSE_COMMTX_MASK 0x00000F00 +#define NB_GLOBAL_NB_INT_CAUSE_COMMTX_SHIFT 8 +/* Reserved, read undefined must write as zeros. */ +#define NB_GLOBAL_NB_INT_CAUSE_RESERVED_15_15 (1 << 15) +/* Error indicator for AXI write transactions with a BRESP error condition. Writing 0 to bit[29] of the L2ECTLR clears the error indicator connected to CA15 nAXIERRIRQ. */ +#define NB_GLOBAL_NB_INT_CAUSE_CPU_AXIERRIRQ (1 << 16) +/* Error indicator for: L2 RAM double-bit ECC error, illegal writes to the GIC memory-map region. */ +#define NB_GLOBAL_NB_INT_CAUSE_CPU_INTERRIRQ (1 << 17) +/* Coherent fabric error summary interrupt */ +#define NB_GLOBAL_NB_INT_CAUSE_ACF_ERRORIRQ (1 << 18) +/* DDR Controller ECC Correctable error summary interrupt */ +#define NB_GLOBAL_NB_INT_CAUSE_MCTL_ECC_CORR_ERR (1 << 19) +/* DDR Controller ECC Uncorrectable error summary interrupt */ +#define NB_GLOBAL_NB_INT_CAUSE_MCTL_ECC_UNCORR_ERR (1 << 20) +/* DRAM parity error interrupt */ +#define NB_GLOBAL_NB_INT_CAUSE_MCTL_PARITY_ERR (1 << 21) +/* Reserved, not functional */ +#define NB_GLOBAL_NB_INT_CAUSE_MCTL_WDATARAM_PAR (1 << 22) +/* Error cause summary interrupt */ +#define NB_GLOBAL_NB_INT_CAUSE_ERR_CAUSE_SUM_A0 (1 << 23) +/* SB PoS error */ +#define NB_GLOBAL_NB_INT_CAUSE_SB_POS_ERR (1 << 24) +/* Received msix is not mapped to local GIC or IO-GIC spin */ +#define NB_GLOBAL_NB_INT_CAUSE_MSIX_ERR_INT_M0 (1 << 25) +/* Coresight timestamp overflow */ +#define NB_GLOBAL_NB_INT_CAUSE_CORESIGHT_TS_OVERFLOW_M0 (1 << 26) + +/**** SEV_Int_Cause register ****/ +/* SMMU 0/1 global non-secure fault interrupt */ +#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_GBL_FLT_IRPT_NS_MASK 0x00000003 +#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_GBL_FLT_IRPT_NS_SHIFT 0 +/* SMMU 0/1 non-secure context interrupt */ +#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_CXT_IRPT_NS_MASK 0x0000000C +#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_CXT_IRPT_NS_SHIFT 2 +/* SMMU0/1 Non-secure configuration access fault interrupt */ +#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_CFG_FLT_IRPT_S_MASK 0x00000030 +#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_CFG_FLT_IRPT_S_SHIFT 4 +/* Reserved. Read undefined; must write as zeros. */ +#define NB_GLOBAL_SEV_INT_CAUSE_RESERVED_11_6_MASK 0x00000FC0 +#define NB_GLOBAL_SEV_INT_CAUSE_RESERVED_11_6_SHIFT 6 +/* Reserved. Read undefined; must write as zeros. */ +#define NB_GLOBAL_SEV_INT_CAUSE_RESERVED_31_20_MASK 0xFFF00000 +#define NB_GLOBAL_SEV_INT_CAUSE_RESERVED_31_20_SHIFT 20 + +/**** PMUs_Int_Cause register ****/ +/* CPUs PMU Overflow interrupt */ +#define NB_GLOBAL_PMUS_INT_CAUSE_CPUS_OVFL_MASK 0x0000000F +#define NB_GLOBAL_PMUS_INT_CAUSE_CPUS_OVFL_SHIFT 0 +/* Northbridge PMU overflow */ +#define NB_GLOBAL_PMUS_INT_CAUSE_NB_OVFL (1 << 4) +/* Memory Controller PMU overflow */ +#define NB_GLOBAL_PMUS_INT_CAUSE_MCTL_OVFL (1 << 5) +/* Coherency Interconnect PMU overflow */ +#define NB_GLOBAL_PMUS_INT_CAUSE_CCI_OVFL_MASK 0x000007C0 +#define NB_GLOBAL_PMUS_INT_CAUSE_CCI_OVFL_SHIFT 6 +/* Coherency Interconnect PMU overflow */ +#define NB_GLOBAL_PMUS_INT_CAUSE_SMMU_OVFL_MASK 0x00001800 +#define NB_GLOBAL_PMUS_INT_CAUSE_SMMU_OVFL_SHIFT 11 +/* Reserved. Read undefined; must write as zeros. */ +#define NB_GLOBAL_PMUS_INT_CAUSE_RESERVED_23_13_MASK 0x00FFE000 +#define NB_GLOBAL_PMUS_INT_CAUSE_RESERVED_23_13_SHIFT 13 +/* Southbridge PMUs overflow */ +#define NB_GLOBAL_PMUS_INT_CAUSE_SB_PMUS_OVFL_MASK 0xFF000000 +#define NB_GLOBAL_PMUS_INT_CAUSE_SB_PMUS_OVFL_SHIFT 24 + +/**** CPUs_Hold_Reset register ****/ +/* Shared L2 memory system, interrupt controller and timer logic reset. +Reset is applied only when all processors are in STNDBYWFI state. */ +#define NB_GLOBAL_CPUS_HOLD_RESET_L2RESET (1 << 0) +/* Shared debug domain reset */ +#define NB_GLOBAL_CPUS_HOLD_RESET_PRESETDBG (1 << 1) +/* Individual CPU debug, PTM, watchpoint and breakpoint logic reset */ +#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_DBGRESET_MASK 0x000000F0 +#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_DBGRESET_SHIFT 4 +/* Individual CPU core and VFP/NEON logic reset. +Reset is applied only when specific CPU is in STNDBYWFI state. */ +#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_CORERESET_MASK 0x00000F00 +#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_CORERESET_SHIFT 8 +/* Individual CPU por-on-reset. +Reset is applied only when specific CPU is in STNDBYWFI state. */ +#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_PORESET_MASK 0x0000F000 +#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_PORESET_SHIFT 12 +/* Wait for interrupt mask. +If set, reset is applied without waiting for the specified CPU's STNDBYWFI state. */ +#define NB_GLOBAL_CPUS_HOLD_RESET_WFI_MASK_MASK 0x000F0000 +#define NB_GLOBAL_CPUS_HOLD_RESET_WFI_MASK_SHIFT 16 + +/**** CPUs_Software_Reset register ****/ +/* Write 1. Apply the software reset. */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_SWRESET_REQ (1 << 0) +/* Defines the level of software reset. +0x0 - cpu_core: Individual CPU core reset. +0x1 - cpu_poreset: Individual CPU power-on-reset. +0x2 - cpu_dbg: Individual CPU debug reset. +0x3 - cluster_no_dbg: A Cluster reset puts each core into core reset (no dbg) and also resets the interrupt controller and L2 logic. +0x4 - cluster: A Cluster reset puts each core into power-on-reset and also resets the interrupt controller and L2 logic. Debug is active. +0x5 - cluster_poreset: A Cluster power-on-reset puts each core into power-on-reset and also resets the interrupt controller and L2 logic. This include the cluster debug logic. */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_MASK 0x0000000E +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT 1 +/* Individual CPU core reset. */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CPU_CORE \ + (0x0 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) +/* Individual CPU power-on-reset. */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CPU_PORESET \ + (0x1 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) +/* Individual CPU debug reset. */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CPU_DBG \ + (0x2 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) +/* A Cluster reset puts each core into core reset (no dbg) and a ... */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CLUSTER_NO_DBG \ + (0x3 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) +/* A Cluster reset puts each core into power-on-reset and also r ... */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CLUSTER \ + (0x4 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) +/* A Cluster power-on-reset puts each core into power-on-reset a ... */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CLUSTER_PORESET \ + (0x5 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) +/* Defines which cores to reset when no cluster_poreset is requested. */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_CORES_MASK 0x000000F0 +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_CORES_SHIFT 4 +/* CPUn wait for interrupt enable. +Defines which CPU WFI indication to wait for before applying the software reset. */ +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_WFI_MASK_MASK 0x000F0000 +#define NB_GLOBAL_CPUS_SOFTWARE_RESET_WFI_MASK_SHIFT 16 + +/**** WD_Timer0_Reset register ****/ +/* Shared L2 memory system, interrupt controller and timer logic reset */ +#define NB_GLOBAL_WD_TIMER0_RESET_L2RESET (1 << 0) +/* Shared debug domain reset */ +#define NB_GLOBAL_WD_TIMER0_RESET_PRESETDBG (1 << 1) +/* Individual CPU debug PTM, watchpoint and breakpoint logic reset */ +#define NB_GLOBAL_WD_TIMER0_RESET_CPU_DBGRESET_MASK 0x000000F0 +#define NB_GLOBAL_WD_TIMER0_RESET_CPU_DBGRESET_SHIFT 4 +/* Individual CPU core and VFP/NEON logic reset */ +#define NB_GLOBAL_WD_TIMER0_RESET_CPU_CORERESET_MASK 0x00000F00 +#define NB_GLOBAL_WD_TIMER0_RESET_CPU_CORERESET_SHIFT 8 +/* Individual CPU por-on-reset */ +#define NB_GLOBAL_WD_TIMER0_RESET_CPU_PORESET_MASK 0x0000F000 +#define NB_GLOBAL_WD_TIMER0_RESET_CPU_PORESET_SHIFT 12 + +/**** WD_Timer1_Reset register ****/ +/* Shared L2 memory system, interrupt controller and timer logic reset */ +#define NB_GLOBAL_WD_TIMER1_RESET_L2RESET (1 << 0) +/* Shared debug domain reset */ +#define NB_GLOBAL_WD_TIMER1_RESET_PRESETDBG (1 << 1) +/* Individual CPU debug PTM, watchpoint and breakpoint logic reset */ +#define NB_GLOBAL_WD_TIMER1_RESET_CPU_DBGRESET_MASK 0x000000F0 +#define NB_GLOBAL_WD_TIMER1_RESET_CPU_DBGRESET_SHIFT 4 +/* Individual CPU core and VFP/NEON logic reset */ +#define NB_GLOBAL_WD_TIMER1_RESET_CPU_CORERESET_MASK 0x00000F00 +#define NB_GLOBAL_WD_TIMER1_RESET_CPU_CORERESET_SHIFT 8 +/* Individual CPU por-on-reset */ +#define NB_GLOBAL_WD_TIMER1_RESET_CPU_PORESET_MASK 0x0000F000 +#define NB_GLOBAL_WD_TIMER1_RESET_CPU_PORESET_SHIFT 12 + +/**** WD_Timer2_Reset register ****/ +/* Shared L2 memory system, interrupt controller and timer logic reset */ +#define NB_GLOBAL_WD_TIMER2_RESET_L2RESET (1 << 0) +/* Shared debug domain reset */ +#define NB_GLOBAL_WD_TIMER2_RESET_PRESETDBG (1 << 1) +/* Individual CPU debug, PTM, watchpoint and breakpoint logic reset */ +#define NB_GLOBAL_WD_TIMER2_RESET_CPU_DBGRESET_MASK 0x000000F0 +#define NB_GLOBAL_WD_TIMER2_RESET_CPU_DBGRESET_SHIFT 4 +/* Individual CPU core and VFP/NEON logic reset */ +#define NB_GLOBAL_WD_TIMER2_RESET_CPU_CORERESET_MASK 0x00000F00 +#define NB_GLOBAL_WD_TIMER2_RESET_CPU_CORERESET_SHIFT 8 +/* Individual CPU por-on-reset */ +#define NB_GLOBAL_WD_TIMER2_RESET_CPU_PORESET_MASK 0x0000F000 +#define NB_GLOBAL_WD_TIMER2_RESET_CPU_PORESET_SHIFT 12 + +/**** WD_Timer3_Reset register ****/ +/* Shared L2 memory system, interrupt controller and timer logic reset */ +#define NB_GLOBAL_WD_TIMER3_RESET_L2RESET (1 << 0) +/* Shared debug domain reset */ +#define NB_GLOBAL_WD_TIMER3_RESET_PRESETDBG (1 << 1) +/* Individual CPU debug, PTM, watchpoint and breakpoint logic reset */ +#define NB_GLOBAL_WD_TIMER3_RESET_CPU_DBGRESET_MASK 0x000000F0 +#define NB_GLOBAL_WD_TIMER3_RESET_CPU_DBGRESET_SHIFT 4 +/* Individual CPU core and VFP/NEON logic reset */ +#define NB_GLOBAL_WD_TIMER3_RESET_CPU_CORERESET_MASK 0x00000F00 +#define NB_GLOBAL_WD_TIMER3_RESET_CPU_CORERESET_SHIFT 8 +/* Individual CPU por-on-reset */ +#define NB_GLOBAL_WD_TIMER3_RESET_CPU_PORESET_MASK 0x0000F000 +#define NB_GLOBAL_WD_TIMER3_RESET_CPU_PORESET_SHIFT 12 + +/**** DDRC_Hold_Reset register ****/ +/* DDR Control and PHY memory mapped registers reset control +0 - Reset is deasserted. +1 - Reset is asserted (active). */ +#define NB_GLOBAL_DDRC_HOLD_RESET_APB_SYNC_RESET (1 << 0) +/* DDR Control Core reset control +0 - Reset is deasserted. +1 - Reset is asserted. +This field must be set to 0 to start the initialization process after configuring the DDR Controller registers. */ +#define NB_GLOBAL_DDRC_HOLD_RESET_CORE_SYNC_RESET (1 << 1) +/* DDR Control AXI Interface reset control +0 - Reset is deasserted. +1 - Reset is asserted. +This field must not be set to 0 while core_sync_reset is set to 1. */ +#define NB_GLOBAL_DDRC_HOLD_RESET_AXI_SYNC_RESET (1 << 2) +/* DDR PUB Controller reset control +0 - Reset is deasserted. +1 - Reset is asserted. +This field must be set to 0 to start the initialization process after configuring the PUB Controller registers. */ +#define NB_GLOBAL_DDRC_HOLD_RESET_PUB_CTL_SYNC_RESET (1 << 3) +/* DDR PUB SDR Controller reset control +0 - Reset is deasserted. +1 - Reset is asserted. +This field must be set to 0 to start the initialization process after configuring the PUB Controller registers. */ +#define NB_GLOBAL_DDRC_HOLD_RESET_PUB_SDR_SYNC_RESET (1 << 4) +/* DDR PHY reset control +0 - Reset is deasserted. +1 - Reset is asserted. */ +#define NB_GLOBAL_DDRC_HOLD_RESET_PHY_SYNC_RESET (1 << 5) +/* Memory initialization input to DDR SRAM for parity check support */ +#define NB_GLOBAL_DDRC_HOLD_RESET_DDR_UNIT_MEM_INIT (1 << 6) + +/**** Fabric_Software_Reset register ****/ +/* Write 1 apply the software reset. */ +#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_SWRESET_REQ (1 << 0) +/* Defines the level of software reset: +0x0 - fabric: Fabric reset +0x1 - gic: GIC reset +0x2 - smmu: SMMU reset */ +#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_MASK 0x0000000E +#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SHIFT 1 +/* Fabric reset */ +#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_FABRIC \ + (0x0 << NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SHIFT) +/* GIC reset */ +#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_GIC \ + (0x1 << NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SHIFT) +/* SMMU reset */ +#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SMMU \ + (0x2 << NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SHIFT) +/* CPUn waiting for interrupt enable. +Defines which CPU WFI indication to wait before applying the software reset. */ +#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_WFI_MASK_MASK 0x000F0000 +#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_WFI_MASK_SHIFT 16 + +/**** CPUs_Power_Ctrl register ****/ +/* L2 WFI enable +When all the processors are in WFI mode or powered-down, the shared L2 memory system Power Management controller resumes clock on any interrupt. +Power management controller resumes clock on snoop request. +NOT IMPLEMENTED */ +#define NB_GLOBAL_CPUS_POWER_CTRL_L2WFI_EN (1 << 0) +/* L2 WFI status */ +#define NB_GLOBAL_CPUS_POWER_CTRL_L2WFI_STATUS (1 << 1) +/* L2 RAMs Power Down +Power down the L2 RAMs. L2 caches must be flushed prior to entering this state. */ +#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_EN (1 << 2) +/* L2 RAMs power down status */ +#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_STATUS (1 << 3) +/* CPU state condition to enable L2 RAM power down +0 - Power down +1 - WFI +NOT IMPLEMENTED */ +#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_CPUS_STATE_MASK 0x000000F0 +#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_CPUS_STATE_SHIFT 4 +/* Enable external debugger over power-down. +Provides support for external debug over power down. If any or all of the processors are powered down, the SoC can still use the debug facilities if the debug PCLKDBG domain is powered up. */ +#define NB_GLOBAL_CPUS_POWER_CTRL_EXT_DEBUGGER_OVER_PD_EN (1 << 8) +/* L2 hardware flush request. This signal indicates: +0 L2 hardware flush request is not asserted. flush is performed by SW +1 L2 hardware flush request is asserted by power management block as part of cluster rams power down flow. HW starts L2 flush flow when all CPUs are in WFI */ +#define NB_GLOBAL_CPUS_POWER_CTRL_L2FLUSH_EN (1 << 9) +/* Force wakeup the CPU in L2RAM power down +INTERNAL DEBUG PURPOSE ONLY */ +#define NB_GLOBAL_CPUS_POWER_CTRL_FORCE_CPUS_OK_PWRUP (1 << 27) +/* L2 RAMs power down SM status */ +#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_SM_STATUS_MASK 0xF0000000 +#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_SM_STATUS_SHIFT 28 + +/**** ACF_Base_High register ****/ +/* Coherency Fabric registers base [39:32]. */ +#define NB_GLOBAL_ACF_BASE_HIGH_BASE_39_32_MASK 0x000000FF +#define NB_GLOBAL_ACF_BASE_HIGH_BASE_39_32_SHIFT 0 +/* Coherency Fabric registers base [31:15] */ +#define NB_GLOBAL_ACF_BASE_LOW_BASED_31_15_MASK 0xFFFF8000 +#define NB_GLOBAL_ACF_BASE_LOW_BASED_31_15_SHIFT 15 + +/**** ACF_Control_Override register ****/ +/* Override the AWCACHE[0] and ARCACHE[0] outputs to be +non-bufferable. One bit exists for each master interface. +Connected to BUFFERABLEOVERRIDE[2:0] */ +#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_BUFFOVRD_MASK 0x00000007 +#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_BUFFOVRD_SHIFT 0 +/* Overrides the ARQOS and AWQOS input signals. One bit exists for each slave +interface. +Connected to QOSOVERRIDE[4:0] */ +#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_QOSOVRD_MASK 0x000000F8 +#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_QOSOVRD_SHIFT 3 +/* If LOW, then AC requests are never issued on the corresponding slave +interface. One bit exists for each slave interface. +Connected to ACCHANNELEN[4:0]. */ +#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_ACE_CH_EN_MASK 0x00001F00 +#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_ACE_CH_EN_SHIFT 8 +/* Internal register: +Enables 4k hazard of post-barrier vs pre-barrier transactions. Otherwise, 64B hazard granularity is applied. */ +#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_DMB_4K_HAZARD_EN (1 << 13) + +/**** LGIC_Base_High register ****/ +/* GIC registers base [39:32]. +This value is sampled into the CP15 Configuration Base Address Register (CBAR) at reset. */ +#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_39_32_MASK 0x000000FF +#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_39_32_SHIFT 0 +#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_MASK_PKR 0x00000FFF +#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_SHIFT_PKR 0 +/* GIC registers base [31:15]. +This value is sampled into the CP15 Configuration Base Address Register (CBAR) at reset */ +#define NB_GLOBAL_LGIC_BASE_LOW_BASED_31_15_MASK 0xFFFF8000 +#define NB_GLOBAL_LGIC_BASE_LOW_BASED_31_15_SHIFT 15 + +/**** IOGIC_Base_High register ****/ +/* IOGIC registers base [39:32] */ +#define NB_GLOBAL_IOGIC_BASE_HIGH_BASE_39_32_MASK 0x000000FF +#define NB_GLOBAL_IOGIC_BASE_HIGH_BASE_39_32_SHIFT 0 +/* IOGIC registers base [31:15] */ +#define NB_GLOBAL_IOGIC_BASE_LOW_BASED_31_15_MASK 0xFFFF8000 +#define NB_GLOBAL_IOGIC_BASE_LOW_BASED_31_15_SHIFT 15 + +/**** IO_Wr_Split_Control register ****/ +/* Write splitters bypass. +[0] Splitter 0 bypass enable +[1] Splitter 1 bypass enable */ +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_BYPASS_MASK 0x00000003 +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_BYPASS_SHIFT 0 +/* Write splitters store and forward. +If store and forward is disabled, splitter does not check non-active BE in the middle of a transaction. */ +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_ST_FW_MASK 0x0000000C +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_ST_FW_SHIFT 2 +/* Write splitters unmodify snoop type. +Disables modifying snoop type from Clean & Invalidate to Invalidate when conditions enable it. Only split operation to 64B is applied. */ +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_UNMODIFY_SNP_MASK 0x00000030 +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_UNMODIFY_SNP_SHIFT 4 +/* Write splitters unsplit non-coherent access. +Disables splitting of non-coherent access to cache-line chunks. */ +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_UNSPLIT_NOSNP_MASK 0x000000C0 +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_UNSPLIT_NOSNP_SHIFT 6 +/* Write splitter rate limit. */ +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR0_SPLT_RATE_LIMIT_MASK 0x00001F00 +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR0_SPLT_RATE_LIMIT_SHIFT 8 +/* Write splitter rate limit */ +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR1_SPLT_RATE_LIMIT_MASK 0x0003E000 +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR1_SPLT_RATE_LIMIT_SHIFT 13 +/* Write splitters 64bit remap enable +Enables remapping of 64bit transactions */ +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_REMAP_64BIT_EN_MASK 0x000C0000 +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_REMAP_64BIT_EN_SHIFT 18 +/* Clear is not supported. This bit was changed to wr_pack_disable. +In default mode, AWADDR waits for WDATA. */ +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_CLEAR_MASK 0xC0000000 +#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_CLEAR_SHIFT 30 + +/**** IO_Rd_ROB_Control register ****/ +/* Read ROB Bypass +[0] Rd ROB 0 bypass enable. +[1] Rd ROB 1 bypass enable. */ +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_BYPASS_MASK 0x00000003 +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_BYPASS_SHIFT 0 +/* Read ROB in order. +Return data in the order of request acceptance. */ +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_INORDER_MASK 0x0000000C +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_INORDER_SHIFT 2 +/* Read ROB response rate +When enabled drops one cycle from back to back read responses */ +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_RSP_RATE_MASK 0x00000030 +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_RSP_RATE_SHIFT 4 +/* Read splitter rate limit */ +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD0_ROB_RATE_LIMIT_MASK 0x00001F00 +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD0_ROB_RATE_LIMIT_SHIFT 8 +/* Read splitter rate limit */ +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD1_ROB_RATE_LIMIT_MASK 0x0003E000 +#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD1_ROB_RATE_LIMIT_SHIFT 13 + +/**** SB_PoS_Error_Log_1 register ****/ +/* Error Log 1 +[7:0] address_high +[16:8] request id +[18:17] bresp */ +#define NB_GLOBAL_SB_POS_ERROR_LOG_1_ERR_LOG_MASK 0x7FFFFFFF +#define NB_GLOBAL_SB_POS_ERROR_LOG_1_ERR_LOG_SHIFT 0 +/* Valid logged error +Set on SB PoS error occurrence on capturing the error information. Subsequent errors will not be captured until the valid bit is cleared. +The SB PoS reports on write errors. +When valid, an interrupt is set in the NB Cause Register. */ +#define NB_GLOBAL_SB_POS_ERROR_LOG_1_VALID (1 << 31) + +/**** MSIx_Error_Log register ****/ +/* Error Log +Corresponds to MSIx address message [30:0]. */ +#define NB_GLOBAL_MSIX_ERROR_LOG_ERR_LOG_MASK 0x7FFFFFFF +#define NB_GLOBAL_MSIX_ERROR_LOG_ERR_LOG_SHIFT 0 +/* Valid logged error */ +#define NB_GLOBAL_MSIX_ERROR_LOG_VALID (1 << 31) + +/**** Error_Cause register ****/ +/* Received msix is not mapped to local GIC or IO-GIC spin */ +#define NB_GLOBAL_ERROR_CAUSE_MSIX_ERR_INT (1 << 2) +/* Coresight timestamp overflow */ +#define NB_GLOBAL_ERROR_CAUSE_CORESIGHT_TS_OVERFLOW (1 << 3) +/* Write data parity error from SB channel 0. */ +#define NB_GLOBAL_ERROR_CAUSE_SB0_WRDATA_PERR (1 << 4) +/* Write data parity error from SB channel 1. */ +#define NB_GLOBAL_ERROR_CAUSE_SB1_WRDATA_PERR (1 << 5) +/* Read data parity error from SB slaves. */ +#define NB_GLOBAL_ERROR_CAUSE_SB_SLV_RDATA_PERR (1 << 6) +/* Local GIC uncorrectable ECC error */ +#define NB_GLOBAL_ERROR_CAUSE_LOCAL_GIC_ECC_FATAL (1 << 7) +/* SB PoS error */ +#define NB_GLOBAL_ERROR_CAUSE_SB_POS_ERR (1 << 8) +/* Coherent fabric error summary interrupt */ +#define NB_GLOBAL_ERROR_CAUSE_ACF_ERRORIRQ (1 << 9) +/* Error indicator for AXI write transactions with a BRESP error condition. Writing 0 to bit[29] of the L2ECTLR clears the error indicator connected to CA15 nAXIERRIRQ. */ +#define NB_GLOBAL_ERROR_CAUSE_CPU_AXIERRIRQ (1 << 10) +/* Error indicator for: L2 RAM double-bit ECC error, illegal writes to the GIC memory-map region. */ +#define NB_GLOBAL_ERROR_CAUSE_CPU_INTERRIRQ (1 << 12) +/* DDR cause summery interrupt */ +#define NB_GLOBAL_ERROR_CAUSE_DDR_CAUSE_SUM (1 << 14) + +/**** QoS_Peak_Control register ****/ +/* Peak Read Low Threshold +When the number of outstanding read transactions from SB masters is below this value, the CPU is assigned high-priority QoS. */ +#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_RD_L_THRESHOLD_MASK 0x0000007F +#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_RD_L_THRESHOLD_SHIFT 0 +/* Peak Read High Threshold +When the number of outstanding read transactions from SB masters exceeds this value, the CPU is assigned high-priority QoS. */ +#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_RD_H_THRESHOLD_MASK 0x00007F00 +#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_RD_H_THRESHOLD_SHIFT 8 +/* Peak Write Low Threshold +When the number of outstanding write transactions from SB masters is below this value, the CPU is assigned high-priority QoS */ +#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_WR_L_THRESHOLD_MASK 0x007F0000 +#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_WR_L_THRESHOLD_SHIFT 16 +/* Peak Write High Threshold +When the number of outstanding write transactions from SB masters exceeds this value, the CPU is assigned high-priority QoS. */ +#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_WR_H_THRESHOLD_MASK 0x7F000000 +#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_WR_H_THRESHOLD_SHIFT 24 + +/**** QoS_Set_Control register ****/ +/* CPU Low priority Read QoS */ +#define NB_GLOBAL_QOS_SET_CONTROL_CPU_LP_ARQOS_MASK 0x0000000F +#define NB_GLOBAL_QOS_SET_CONTROL_CPU_LP_ARQOS_SHIFT 0 +/* CPU High priority Read QoS */ +#define NB_GLOBAL_QOS_SET_CONTROL_CPU_HP_ARQOS_MASK 0x000000F0 +#define NB_GLOBAL_QOS_SET_CONTROL_CPU_HP_ARQOS_SHIFT 4 +/* CPU Low priority Write QoS */ +#define NB_GLOBAL_QOS_SET_CONTROL_CPU_LP_AWQOS_MASK 0x00000F00 +#define NB_GLOBAL_QOS_SET_CONTROL_CPU_LP_AWQOS_SHIFT 8 +/* CPU High priority Write QoS */ +#define NB_GLOBAL_QOS_SET_CONTROL_CPU_HP_AWQOS_MASK 0x0000F000 +#define NB_GLOBAL_QOS_SET_CONTROL_CPU_HP_AWQOS_SHIFT 12 +/* SB Low priority Read QoS */ +#define NB_GLOBAL_QOS_SET_CONTROL_SB_LP_ARQOS_MASK 0x000F0000 +#define NB_GLOBAL_QOS_SET_CONTROL_SB_LP_ARQOS_SHIFT 16 +/* SB Low-priority Write QoS */ +#define NB_GLOBAL_QOS_SET_CONTROL_SB_LP_AWQOS_MASK 0x00F00000 +#define NB_GLOBAL_QOS_SET_CONTROL_SB_LP_AWQOS_SHIFT 20 + +/**** DDR_QoS register ****/ +/* High Priority Read Threshold +Limits the number of outstanding high priority reads in the system through the memory controller. +This parameter is programmed in conjunction with number of outstanding high priority reads supported by the DDR controller. */ +#define NB_GLOBAL_DDR_QOS_HIGH_PRIO_THRESHOLD_MASK 0x0000007F +#define NB_GLOBAL_DDR_QOS_HIGH_PRIO_THRESHOLD_SHIFT 0 +/* DDR Low Priority QoS +Fabric priority below this value is mapped to DDR low priority queue. */ +#define NB_GLOBAL_DDR_QOS_LP_QOS_MASK 0x00000F00 +#define NB_GLOBAL_DDR_QOS_LP_QOS_SHIFT 8 + +/**** ACF_Misc register ****/ +/* Disable DDR Write Chop +Performance optimization feature to chop non-active data beats to the DDR. */ +#define NB_GLOBAL_ACF_MISC_DDR_WR_CHOP_DIS (1 << 0) +/* Disable SB-2-SB path through NB fabric. */ +#define NB_GLOBAL_ACF_MISC_SB2SB_PATH_DIS (1 << 1) +/* Disable ETR tracing to non-DDR. */ +#define NB_GLOBAL_ACF_MISC_ETR2SB_PATH_DIS (1 << 2) +/* Disable ETR tracing to non-DDR. */ +#define NB_GLOBAL_ACF_MISC_CPU2MSIX_DIS (1 << 3) +/* Disable CPU generation of MSIx +By default, the CPU can set any MSIx message results by setting any SPIn bit in the local and IO-GIC. */ +#define NB_GLOBAL_ACF_MISC_MSIX_TERMINATE_DIS (1 << 4) +/* Disable snoop override for MSIx +By default, an MSIx transaction is downgraded to non-coherent. */ +#define NB_GLOBAL_ACF_MISC_MSIX_SNOOPOVRD_DIS (1 << 5) +/* POS bypass */ +#define NB_GLOBAL_ACF_MISC_POS_BYPASS (1 << 6) +/* PoS ReadStronglyOrdered enable +SO read forces flushing of all prior writes */ +#define NB_GLOBAL_ACF_MISC_POS_RSO_EN (1 << 7) +/* WRAP to INC transfer enable */ +#define NB_GLOBAL_ACF_MISC_POS_WRAP2INC (1 << 8) +/* PoS DSB flush Disable +On DSB from CPU, PoS blocks the progress of post-barrier reads and writes until all pre-barrier writes have been completed. */ +#define NB_GLOBAL_ACF_MISC_POS_DSB_FLUSH_DIS (1 << 9) +/* PoS DMB Flush Disable +On DMB from CPU, the PoS blocks the progress of post-barrier non-buffereable reads or writes when there are outstanding non-bufferable writes that have not yet been completed. +Other access types are hazard check against the pre-barrier requests. */ +#define NB_GLOBAL_ACF_MISC_POS_DMB_FLUSH_DIS (1 << 10) +/* change DMB functionality to DSB (block and drain) */ +#define NB_GLOBAL_ACF_MISC_POS_DMB_TO_DSB_EN (1 << 11) +/* Disable write after read stall when accessing IO fabric slaves. */ +#define NB_GLOBAL_ACF_MISC_M0_WAR_STALL_DIS (1 << 12) +/* Disable write after read stall when accessing DDR */ +#define NB_GLOBAL_ACF_MISC_M1_WAR_STALL_DIS (1 << 13) +/* Disable counter (wait 1000 NB cycles) before applying PoS enable/disable configuration */ +#define NB_GLOBAL_ACF_MISC_POS_CONFIG_CNT_DIS (1 << 14) +/* Disable wr spliter A0 bug fixes */ +#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_M0_MODE (1 << 16) +/* Disable wr spliter PKR bug fixes */ +#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_A0_MODE (1 << 17) +/* Override the address parity calucation for write transactions going to IO-fabric */ +#define NB_GLOBAL_ACF_MISC_NB_NIC_AWADDR_PAR_OVRD (1 << 18) +/* Override the data parity calucation for write transactions going to IO-fabric */ +#define NB_GLOBAL_ACF_MISC_NB_NIC_WDATA_PAR_OVRD (1 << 19) +/* Override the address parity calucation for read transactions going to IO-fabric */ +#define NB_GLOBAL_ACF_MISC_NB_NIC_ARADDR_PAR_OVRD (1 << 20) +/* Halts CPU AXI interface (Ar/Aw channels), not allowing the CPU to send additional transactions */ +#define NB_GLOBAL_ACF_MISC_CPU_AXI_HALT (1 << 23) +/* Disable early arbar termination when fabric write buffer is enabled. */ +#define NB_GLOBAL_ACF_MISC_CCIWB_EARLY_ARBAR_TERM_DIS (1 << 24) +/* Enable wire interrupts connectivity to IO-GIC IRQs */ +#define NB_GLOBAL_ACF_MISC_IOGIC_CHIP_SPI_EN (1 << 25) +/* Enable DMB flush request to NB to SB PoS when barrier is terminted inside the processor cluster */ +#define NB_GLOBAL_ACF_MISC_CPU_DSB_FLUSH_DIS (1 << 26) +/* Enable DMB flush request to NB to SB PoS when barrier is terminted inside the processor cluster */ +#define NB_GLOBAL_ACF_MISC_CPU_DMB_FLUSH_DIS (1 << 27) +/* Peakrock only: remap CPU address above 40 bits to Slave Error +INTERNAL */ +#define NB_GLOBAL_ACF_MISC_ADDR43_40_REMAP_DIS (1 << 28) +/* Enable CPU WriteUnique to WriteNoSnoop trasform */ +#define NB_GLOBAL_ACF_MISC_CPU_WU2WNS_EN (1 << 29) +/* Disable device after device check */ +#define NB_GLOBAL_ACF_MISC_WR_POS_DEV_AFTER_DEV_DIS (1 << 30) +/* Disable wrap to inc on write */ +#define NB_GLOBAL_ACF_MISC_WR_INC2WRAP_EN (1 << 31) + +/**** Config_Bus_Control register ****/ +/* Write slave error enable */ +#define NB_GLOBAL_CONFIG_BUS_CONTROL_WR_SLV_ERR_EN (1 << 0) +/* Write decode error enable */ +#define NB_GLOBAL_CONFIG_BUS_CONTROL_WR_DEC_ERR_EN (1 << 1) +/* Read slave error enable */ +#define NB_GLOBAL_CONFIG_BUS_CONTROL_RD_SLV_ERR_EN (1 << 2) +/* Read decode error enable */ +#define NB_GLOBAL_CONFIG_BUS_CONTROL_RD_DEC_ERR_EN (1 << 3) +/* Ignore Write ID */ +#define NB_GLOBAL_CONFIG_BUS_CONTROL_IGNORE_WR_ID (1 << 4) +/* Timeout limit before terminating configuration bus access with slave error */ +#define NB_GLOBAL_CONFIG_BUS_CONTROL_TIMEOUT_LIMIT_MASK 0xFFFFFF00 +#define NB_GLOBAL_CONFIG_BUS_CONTROL_TIMEOUT_LIMIT_SHIFT 8 + +/**** Pos_ID_Match register ****/ +/* Enable Device (GRE and nGRE) after Device ID hazard */ +#define NB_GLOBAL_POS_ID_MATCH_ENABLE (1 << 0) +/* ID Field Mask +If set, corresonpding ID bits are not used for ID match */ +#define NB_GLOBAL_POS_ID_MATCH_MASK_MASK 0xFFFF0000 +#define NB_GLOBAL_POS_ID_MATCH_MASK_SHIFT 16 + +/**** sb_sel_override_awuser register ****/ +/* Select whether to use transaction awuser or sb_override_awuser value for awuser field on outgoing write transactions to SB. +Each bit if set to 1 selects the corresponding sb_override_awuser bit. Otherwise, selects the corersponding transaction awuser bit. */ +#define NB_GLOBAL_SB_SEL_OVERRIDE_AWUSER_SEL_MASK 0x03FFFFFF +#define NB_GLOBAL_SB_SEL_OVERRIDE_AWUSER_SEL_SHIFT 0 + +/**** sb_override_awuser register ****/ +/* Awuser to use on overriden transactions +Only applicable if sel_override_awuser.sel is set to 1'b1 for the coressponding bit */ +#define NB_GLOBAL_SB_OVERRIDE_AWUSER_AWUSER_MASK 0x03FFFFFF +#define NB_GLOBAL_SB_OVERRIDE_AWUSER_AWUSER_SHIFT 0 + +/**** sb_sel_override_aruser register ****/ +/* Select whether to use transaction aruser or sb_override_aruser value for aruser field on outgoing read transactions to SB. +Each bit if set to 1 selects the corresponding sb_override_aruser bit. Otherwise, selects the corersponding transaction aruser bit. */ +#define NB_GLOBAL_SB_SEL_OVERRIDE_ARUSER_SEL_MASK 0x03FFFFFF +#define NB_GLOBAL_SB_SEL_OVERRIDE_ARUSER_SEL_SHIFT 0 + +/**** sb_override_aruser register ****/ +/* Aruser to use on overriden transactions +Only applicable if sb_sel_override_aruser.sel is set to 1'b1 for the coressponding bit */ +#define NB_GLOBAL_SB_OVERRIDE_ARUSER_ARUSER_MASK 0x03FFFFFF +#define NB_GLOBAL_SB_OVERRIDE_ARUSER_ARUSER_SHIFT 0 + +/**** Coresight_PD register ****/ +/* ETF0 RAM force power down */ +#define NB_GLOBAL_CORESIGHT_PD_ETF0_RAM_FORCE_PD (1 << 0) +/* ETF1 RAM force power down */ +#define NB_GLOBAL_CORESIGHT_PD_ETF1_RAM_FORCE_PD (1 << 1) +/* ETF0 RAM force clock gate */ +#define NB_GLOBAL_CORESIGHT_PD_ETF0_RAM_FORCE_CG (1 << 2) +/* ETF1 RAM force clock gate */ +#define NB_GLOBAL_CORESIGHT_PD_ETF1_RAM_FORCE_CG (1 << 3) +/* APBIC clock enable */ +#define NB_GLOBAL_CORESIGHT_PD_APBICLKEN (1 << 4) +/* DAP system clock enable */ +#define NB_GLOBAL_CORESIGHT_PD_DAP_SYS_CLKEN (1 << 5) + +/**** Coresight_INTERNAL_0 register ****/ + +#define NB_GLOBAL_CORESIGHT_INTERNAL_0_CTIAPBSBYPASS (1 << 0) +/* CA15 CTM and Coresight CTI operate at same clock, bypass modes can be enabled but it's being set to bypass disable to break timing path. */ +#define NB_GLOBAL_CORESIGHT_INTERNAL_0_CISBYPASS (1 << 1) +/* CA15 CTM and Coresight CTI operate according to the same clock. +Bypass modes can be enabled, but it is set to bypass disable, to break the timing path. */ +#define NB_GLOBAL_CORESIGHT_INTERNAL_0_CIHSBYPASS_MASK 0x0000003C +#define NB_GLOBAL_CORESIGHT_INTERNAL_0_CIHSBYPASS_SHIFT 2 + +/**** Coresight_DBGROMADDR register ****/ +/* Valid signal for DBGROMADDR. +Connected to DBGROMADDRV */ +#define NB_GLOBAL_CORESIGHT_DBGROMADDR_VALID (1 << 0) +/* Specifies bits [39:12] of the ROM table physical address. */ +#define NB_GLOBAL_CORESIGHT_DBGROMADDR_ADDR_39_12_MASK 0x3FFFFFFC +#define NB_GLOBAL_CORESIGHT_DBGROMADDR_ADDR_39_12_SHIFT 2 + +/**** Coresight_DBGSELFADDR register ****/ +/* Valid signal for DBGROMADDR. +Connected to DBGROMADDRV */ +#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_VALID (1 << 0) +/* Specifies bits [18:17] of the two's complement signed offset from the ROM table physical address to the physical address where the debug registers are memory-mapped. +Note: The CA15 debug unit starts at offset 0x1 within the Coresight cluster. */ +#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_ADDR_18_17_MASK 0x00000180 +#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_ADDR_18_17_SHIFT 7 +/* Specifies bits [39:19] of the two's complement signed offset from the ROM table physical address to the physical address where the debug registers are memory-mapped. +Note: The CA15 debug unit starts at offset 0x1 within the Coresight cluster, so this offset if fixed to zero. */ +#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_ADDR_39_19_MASK 0x3FFFFE00 +#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_ADDR_39_19_SHIFT 9 + +/**** SB_force_same_id_cfg_0 register ****/ +/* Enables force same id mechanism for SB port 0 */ +#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_0_FORCE_SAME_ID_EN (1 << 0) +/* Enables MSIx stall when write transactions from same ID mechanism are in progress for SB port 0 */ +#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_0_FORCE_SAME_ID_MSIX_STALL_EN (1 << 1) +/* Mask for choosing which ID bits to match for indicating the originating master */ +#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_0_SB_MSTR_ID_MASK_MASK 0x000000F8 +#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_0_SB_MSTR_ID_MASK_SHIFT 3 + +/**** SB_force_same_id_cfg_1 register ****/ +/* Enables force same id mechanism for SB port 1 */ +#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_1_FORCE_SAME_ID_EN (1 << 0) +/* Enables MSIx stall when write transactions from same ID mechanism are in progress for SB port 1 */ +#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_1_FORCE_SAME_ID_MSIX_STALL_EN (1 << 1) +/* Mask for choosing which ID bits to match for indicating the originating master */ +#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_1_SB_MSTR_ID_MASK_MASK 0x000000F8 +#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_1_SB_MSTR_ID_MASK_SHIFT 3 + +/**** Cnt_Control register ****/ +/* System counter enable +Counter is enabled after reset. */ +#define NB_SYSTEM_COUNTER_CNT_CONTROL_EN (1 << 0) +/* System counter restart +Initial value is reloaded from Counter_Init_L and Counter_Init_H registers. +Transition from 0 to 1 reloads the register. */ +#define NB_SYSTEM_COUNTER_CNT_CONTROL_RESTART (1 << 1) +/* Disable CTI trigger out that halt the counter progress */ +#define NB_SYSTEM_COUNTER_CNT_CONTROL_CTI_TRIGOUT_HALT_DIS (1 << 2) +/* System counter tick +Specifies the counter tick rate relative to the Northbridge clock, e.g., the counter is incremented every 16 NB cycles if programmed to 0x0f. */ +#define NB_SYSTEM_COUNTER_CNT_CONTROL_SCALE_MASK 0x0000FF00 +#define NB_SYSTEM_COUNTER_CNT_CONTROL_SCALE_SHIFT 8 + +/**** CA15_RF_Misc register ****/ + +#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_NONECPU_RF_MISC_MASK 0x0000000F +#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_NONECPU_RF_MISC_SHIFT 0 + +#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_CPU_RF_MISC_MASK 0x00FFFF00 +#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_CPU_RF_MISC_SHIFT 8 +/* Pause for CPUs from the time all power is up to the time the SRAMs start opening. */ +#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_PWR_UP_PAUSE_MASK 0xF8000000 +#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_PWR_UP_PAUSE_SHIFT 27 + +/**** NB_RF_Misc register ****/ +/* SMMU TLB RAMs force power down */ +#define NB_RAMS_CONTROL_MISC_NB_RF_MISC_SMMU_RAM_FORCE_PD (1 << 0) + +/**** Lockn register ****/ +/* Semaphore Lock +CPU reads it: +If current value ==0, return 0 to CPU but set bit to 1. (CPU knows it captured the semaphore.) +If current value ==1, return 1 to CPU. (CPU knows it is already used and waits.) +CPU writes 0 to it to release the semaphore. */ +#define NB_SEMAPHORES_LOCKN_LOCK (1 << 0) + +/**** CA15_outputs_1 register ****/ +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_1_STANDBYWFI_MASK 0x0000000F +#define NB_DEBUG_CA15_OUTPUTS_1_STANDBYWFI_SHIFT 0 +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_1_CPU_PWR_DN_ACK_MASK 0x000000F0 +#define NB_DEBUG_CA15_OUTPUTS_1_CPU_PWR_DN_ACK_SHIFT 4 +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_1_IRQOUT_N_MASK 0x00000F00 +#define NB_DEBUG_CA15_OUTPUTS_1_IRQOUT_N_SHIFT 8 +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_1_FIQOUT_N_MASK 0x0000F000 +#define NB_DEBUG_CA15_OUTPUTS_1_FIQOUT_N_SHIFT 12 +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_1_CNTHPIRQ_N_MASK 0x000F0000 +#define NB_DEBUG_CA15_OUTPUTS_1_CNTHPIRQ_N_SHIFT 16 +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_1_NCNTPNSIRQ_N_MASK 0x00F00000 +#define NB_DEBUG_CA15_OUTPUTS_1_NCNTPNSIRQ_N_SHIFT 20 +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_1_NCNTPSIRQ_N_MASK 0x0F000000 +#define NB_DEBUG_CA15_OUTPUTS_1_NCNTPSIRQ_N_SHIFT 24 +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_1_NCNTVIRQ_N_MASK 0xF0000000 +#define NB_DEBUG_CA15_OUTPUTS_1_NCNTVIRQ_N_SHIFT 28 + +/**** CA15_outputs_2 register ****/ +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_2_STANDBYWFIL2 (1 << 0) +/* + */ +#define NB_DEBUG_CA15_OUTPUTS_2_L2RAM_PWR_DN_ACK (1 << 1) +/* Indicates for each CPU if coherency is enabled + */ +#define NB_DEBUG_CA15_OUTPUTS_2_SMPEN_MASK 0x0000003C +#define NB_DEBUG_CA15_OUTPUTS_2_SMPEN_SHIFT 2 + +/**** cpu_msg register ****/ +/* Status/ASCII code */ +#define NB_DEBUG_CPU_MSG_STATUS_MASK 0x000000FF +#define NB_DEBUG_CPU_MSG_STATUS_SHIFT 0 +/* Toggle with each ASCII write */ +#define NB_DEBUG_CPU_MSG_ASCII_TOGGLE (1 << 8) +/* Signals ASCII */ +#define NB_DEBUG_CPU_MSG_ASCII (1 << 9) + +#define NB_DEBUG_CPU_MSG_RESERVED_11_10_MASK 0x00000C00 +#define NB_DEBUG_CPU_MSG_RESERVED_11_10_SHIFT 10 +/* Signals new section started in S/W */ +#define NB_DEBUG_CPU_MSG_SECTION_START (1 << 12) + +#define NB_DEBUG_CPU_MSG_RESERVED_13 (1 << 13) +/* Signals a single CPU is done. */ +#define NB_DEBUG_CPU_MSG_CPU_DONE (1 << 14) +/* Signals test is done */ +#define NB_DEBUG_CPU_MSG_TEST_DONE (1 << 15) + +/**** ddrc register ****/ +/* External DLL calibration request. Also compensates for VT variations, such as an external request for the controller (can be performed automatically by the controller at the normal settings). */ +#define NB_DEBUG_DDRC_DLL_CALIB_EXT_REQ (1 << 0) +/* External request to perform short (long is performed during initialization) and/or ODT calibration. */ +#define NB_DEBUG_DDRC_ZQ_SHORT_CALIB_EXT_REQ (1 << 1) +/* External request to perform a refresh command to a specific bank. Usually performed automatically by the controller, however, the controller supports disabling of the automatic mechanism, and use of an external pulse instead. */ +#define NB_DEBUG_DDRC_RANK_REFRESH_EXT_REQ_MASK 0x0000003C +#define NB_DEBUG_DDRC_RANK_REFRESH_EXT_REQ_SHIFT 2 + +/**** ddrc_phy_smode_control register ****/ +/* DDR PHY special mode */ +#define NB_DEBUG_DDRC_PHY_SMODE_CONTROL_CTL_MASK 0x0000FFFF +#define NB_DEBUG_DDRC_PHY_SMODE_CONTROL_CTL_SHIFT 0 + +/**** ddrc_phy_smode_status register ****/ +/* DDR PHY special mode */ +#define NB_DEBUG_DDRC_PHY_SMODE_STATUS_STT_MASK 0x0000FFFF +#define NB_DEBUG_DDRC_PHY_SMODE_STATUS_STT_SHIFT 0 + +/**** pmc register ****/ +/* Enable system control on NB DRO */ +#define NB_DEBUG_PMC_SYS_EN (1 << 0) +/* NB PMC HVT35 counter value */ +#define NB_DEBUG_PMC_HVT35_VAL_14_0_MASK 0x0000FFFE +#define NB_DEBUG_PMC_HVT35_VAL_14_0_SHIFT 1 +/* NB PMC SVT31 counter value */ +#define NB_DEBUG_PMC_SVT31_VAL_14_0_MASK 0x7FFF0000 +#define NB_DEBUG_PMC_SVT31_VAL_14_0_SHIFT 16 + +/**** cpus_general register ****/ +/* Swaps sysaddr[16:14] with sysaddr[19:17] for DDR access*/ +#define NB_DEBUG_CPUS_GENERAL_ADDR_MAP_ECO (1 << 23) + +/**** cpus_int_out register ****/ +/* Defines which CPUs' FIQ will be triggered out through the cpus_int_out[1] pinout. */ +#define NB_DEBUG_CPUS_INT_OUT_FIQ_EN_MASK 0x0000000F +#define NB_DEBUG_CPUS_INT_OUT_FIQ_EN_SHIFT 0 +/* Defines which CPUs' IRQ will be triggered out through the cpus_int_out[0] pinout. */ +#define NB_DEBUG_CPUS_INT_OUT_IRQ_EN_MASK 0x000000F0 +#define NB_DEBUG_CPUS_INT_OUT_IRQ_EN_SHIFT 4 +/* Defines which CPUs' SEI will be triggered out through the cpus_int_out[0] pinout. */ +#define NB_DEBUG_CPUS_INT_OUT_IRQ_SEI_EN_MASK 0x00000F00 +#define NB_DEBUG_CPUS_INT_OUT_IRQ_SEI_EN_SHIFT 8 + +/**** latch_pc_req register ****/ +/* If set, request to latch execution PC from processor cluster */ +#define NB_DEBUG_LATCH_PC_REQ_EN (1 << 0) +/* target CPU id to latch its execution PC */ +#define NB_DEBUG_LATCH_PC_REQ_CPU_ID_MASK 0x000000F0 +#define NB_DEBUG_LATCH_PC_REQ_CPU_ID_SHIFT 4 + +/**** latch_pc_low register ****/ +/* Set by hardware when the processor cluster ack the PC latch request. +Clear on read latch_pc_high */ +#define NB_DEBUG_LATCH_PC_LOW_VALID (1 << 0) +/* Latched PC value [31:1] */ +#define NB_DEBUG_LATCH_PC_LOW_VAL_MASK 0xFFFFFFFE +#define NB_DEBUG_LATCH_PC_LOW_VAL_SHIFT 1 + +/**** track_dump_ctrl register ****/ +/* [24:16]: Queue entry pointer +[2] Target queue: 1'b0: HazardTrack or 1'b1: AmiRMI queues +[1:0]: CCI target master: 2'b00: M0, 2'b01: M1, 2'b10: M2 */ +#define NB_DEBUG_TRACK_DUMP_CTRL_PTR_MASK 0x7FFFFFFF +#define NB_DEBUG_TRACK_DUMP_CTRL_PTR_SHIFT 0 +/* Track Dump Request +If set, queue entry info is latched on track_dump_rdata register. +Program the pointer and target queue. +This is a full handshake register. +Read bit from track_dump_rdata register. If set, clear the request field before triggering a new request. */ +#define NB_DEBUG_TRACK_DUMP_CTRL_REQ (1 << 31) + +/**** track_dump_rdata_0 register ****/ +/* Valid */ +#define NB_DEBUG_TRACK_DUMP_RDATA_0_VALID (1 << 0) +/* Low data */ +#define NB_DEBUG_TRACK_DUMP_RDATA_0_DATA_MASK 0xFFFFFFFE +#define NB_DEBUG_TRACK_DUMP_RDATA_0_DATA_SHIFT 1 + +/**** pos_track_dump_ctrl register ****/ +/* [24:16]: queue entry pointer */ +#define NB_DEBUG_POS_TRACK_DUMP_CTRL_PTR_MASK 0x7FFFFFFF +#define NB_DEBUG_POS_TRACK_DUMP_CTRL_PTR_SHIFT 0 +/* Track Dump Request +If set, queue entry info is latched on track_dump_rdata register. +Program the pointer and target queue. +This is a full handshake register +Read bit from track_dump_rdata register. If set, clear the request field before triggering a new request. */ +#define NB_DEBUG_POS_TRACK_DUMP_CTRL_REQ (1 << 31) + +/**** pos_track_dump_rdata_0 register ****/ +/* Valid */ +#define NB_DEBUG_POS_TRACK_DUMP_RDATA_0_VALID (1 << 0) +/* Low data */ +#define NB_DEBUG_POS_TRACK_DUMP_RDATA_0_DATA_MASK 0xFFFFFFFE +#define NB_DEBUG_POS_TRACK_DUMP_RDATA_0_DATA_SHIFT 1 + +/**** c2swb_track_dump_ctrl register ****/ +/* [24:16]: Queue entry pointer */ +#define NB_DEBUG_C2SWB_TRACK_DUMP_CTRL_PTR_MASK 0x7FFFFFFF +#define NB_DEBUG_C2SWB_TRACK_DUMP_CTRL_PTR_SHIFT 0 +/* Track Dump Request +If set, queue entry info is latched on track_dump_rdata register. +Program the pointer and target queue. +This is a full handshake register +Read bit from track_dump_rdata register. If set, clear the request field before triggering a new request. */ +#define NB_DEBUG_C2SWB_TRACK_DUMP_CTRL_REQ (1 << 31) + +/**** c2swb_track_dump_rdata_0 register ****/ +/* Valid */ +#define NB_DEBUG_C2SWB_TRACK_DUMP_RDATA_0_VALID (1 << 0) +/* Low data */ +#define NB_DEBUG_C2SWB_TRACK_DUMP_RDATA_0_DATA_MASK 0xFFFFFFFE +#define NB_DEBUG_C2SWB_TRACK_DUMP_RDATA_0_DATA_SHIFT 1 + +/**** cpus_track_dump_ctrl register ****/ +/* [24:16]: Queue entry pointer +[3:2] Target queue - 0:ASI, 1: AMI +[1:0]: Target Processor Cluster - 0: Cluster0, 1: Cluster1 */ +#define NB_DEBUG_CPUS_TRACK_DUMP_CTRL_PTR_MASK 0x7FFFFFFF +#define NB_DEBUG_CPUS_TRACK_DUMP_CTRL_PTR_SHIFT 0 +/* Track Dump Request +If set, queue entry info is latched on track_dump_rdata register. +Program the pointer and target queue. +This is a full handshake register +Read bit from track_dump_rdata register. If set, clear the request field before triggering a new request. */ +#define NB_DEBUG_CPUS_TRACK_DUMP_CTRL_REQ (1 << 31) + +/**** cpus_track_dump_rdata_0 register ****/ +/* Valid */ +#define NB_DEBUG_CPUS_TRACK_DUMP_RDATA_0_VALID (1 << 0) +/* Low data */ +#define NB_DEBUG_CPUS_TRACK_DUMP_RDATA_0_DATA_MASK 0xFFFFFFFE +#define NB_DEBUG_CPUS_TRACK_DUMP_RDATA_0_DATA_SHIFT 1 + +/**** c2swb_bar_ovrd_high register ****/ +/* Read barrier is progressed downstream when not terminated in the CCI. +By specification, barrier address is 0x0. +This register enables barrier address OVRD to a programmable value. */ +#define NB_DEBUG_C2SWB_BAR_OVRD_HIGH_RD_ADDR_OVRD_EN (1 << 0) +/* Address bits 39:32 */ +#define NB_DEBUG_C2SWB_BAR_OVRD_HIGH_ADDR_39_32_MASK 0x00FF0000 +#define NB_DEBUG_C2SWB_BAR_OVRD_HIGH_ADDR_39_32_SHIFT 16 + +/**** Config register ****/ +/* Individual processor control of the endianness configuration at reset. It sets the initial value of the EE bit in the CP15 System Control Register (SCTLR) related to CFGEND input: +little - 0x0: Little endian +bit - 0x1: Bit endian */ +#define NB_CPUN_CONFIG_STATUS_CONFIG_ENDIAN (1 << 0) +/* Individual processor control of the default exception handling state. It sets the initial value of the TE bit in the CP15 System Control Register (SCTLR) related to CFGTE input: +arm: 0x0: Exception operates ARM code. +Thumb: 0x1: Exception operates Thumb code. */ +#define NB_CPUN_CONFIG_STATUS_CONFIG_TE (1 << 1) +/* Individual processor control of the location of the exception vectors at reset. It sets the initial value of the V bit in the CP15 System Control Register (SCTLR). +Connected to VINITHIGH input. +low - 0x0: Exception vectors start at address 0x00000000. +high - 0x1: Exception vectors start at address 0xFFFF0000. */ +#define NB_CPUN_CONFIG_STATUS_CONFIG_VINITHI (1 << 2) +/* Individual processor control to disable write access to some secure CP15 registers +connected to CP15SDISABLE input. */ +#define NB_CPUN_CONFIG_STATUS_CONFIG_CP15DISABLE (1 << 3) +/* Force Write init implementation to ConfigAARch64 register */ +#define NB_CPUN_CONFIG_STATUS_CONFIG_AARCH64_REG_FORCE_WINIT (1 << 4) +/* Force Write Once implementation to ConfigAARch64 register. */ +#define NB_CPUN_CONFIG_STATUS_CONFIG_AARCH64_REG_FORCE_WONCE (1 << 5) + +/**** Config_AARch64 register ****/ +/* Individual processor register width state. The register width states are: +0 AArch32. +1 AArch64. +This signal is only sampled during reset of the processor. +This is Write Init register */ +#define NB_CPUN_CONFIG_STATUS_CONFIG_AARCH64_AA64_NAA32 (1 << 0) +/* Individual processor Cryptography engine disable: +0 Enable the Cryptography engine. +1 Disable the Cryptography engine. +This signal is only sampled during reset of the processor */ +#define NB_CPUN_CONFIG_STATUS_CONFIG_AARCH64_CRYPTO_DIS (1 << 1) + +/**** Power_Ctrl register ****/ +/* Individual CPU power mode transition request +If requested to enter power mode other than normal mode, low power state is resumed whenever CPU reenters STNDBYWFI state: +normal: 0x0: normal power state +deep_idle: 0x2: Dormant power mode state +poweredoff: 0x3: Powered-off power mode */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_MASK 0x00000003 +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_SHIFT 0 +/* Normal power mode state */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_NORMAL \ + (0x0 << NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_SHIFT) +/* Dormant power mode state */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_DEEP_IDLE \ + (0x2 << NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_SHIFT) +/* Powered-off power mode */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_POWEREDOFF \ + (0x3 << NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_SHIFT) +/* Power down regret disable +When power down regret is enabled, the powerdown enter flow can be halted whenever a valid wakeup event occurs. */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PWRDN_RGRT_DIS (1 << 16) +/* Power down emulation enable +If set, the entire power down sequence is applied, but the CPU is placed in soft reset instead of hardware power down. */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PWRDN_EMULATE (1 << 17) +/* Disable wakeup from Local--GIC FIQ. */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_WU_LGIC_FIQ_DIS (1 << 18) +/* Disable wakeup from Local-GIC IRQ. */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_WU_LGIC_IRQ_DIS (1 << 19) +/* Disable wakeup from IO-GIC FIQ. */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_WU_IOGIC_FIQ_DIS (1 << 20) +/* Disable wakeup from IO-GIC IRQ. */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_WU_IOGIC_IRQ_DIS (1 << 21) +/* Disable scheduling of interrrupts in GIC(500) to non-active CPU */ +#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_IOGIC_DIS_CPU (1 << 22) + +/**** Power_Status register ****/ +/* Read-only bits that reflect the individual CPU power mode status. +Default value for non-exist CPU is 2b11: +normal - 0x0: Normal mode +por - 0x1: por on reset mode +deep_idle - 0x2: Dormant power mode state +poweredoff - 0x3: Powered-off power mode */ +#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_MASK 0x00000003 +#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT 0 +/* Normal power mode state */ +#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_NORMAL \ + (0x0 << NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT) +/* Idle power mode state (WFI) */ +#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_IDLE \ + (0x1 << NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT) +/* Dormant power mode state */ +#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_DEEP_IDLE \ + (0x2 << NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT) +/* Powered-off power mode */ +#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_POWEREDOFF \ + (0x3 << NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT) +/* WFI status */ +#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_WFI (1 << 2) +/* WFE status */ +#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_WFE (1 << 3) + +/**** Warm_Rst_Ctl register ****/ +/* Disable CPU Warm Reset when warmrstreq is asserted + +When the Reset Request bit in the RMR or RMR_EL3 register is set to 1 in the CPU Core , the processor asserts the WARMRSTREQ signal and the SoC reset controller use this request to trigger a Warm reset of the processor and change the register width state. */ +#define NB_CPUN_CONFIG_STATUS_WARM_RST_CTL_REQ_DIS (1 << 0) +/* Disable waiting WFI on Warm Reset */ +#define NB_CPUN_CONFIG_STATUS_WARM_RST_CTL_WFI_DIS (1 << 1) +/* CPU Core AARach64 reset vector bar +This is Write Once register (controlled by aarch64_reg_force_* fields) */ +#define NB_CPUN_CONFIG_STATUS_RVBAR_LOW_ADDR_31_2_MASK 0xFFFFFFFC +#define NB_CPUN_CONFIG_STATUS_RVBAR_LOW_ADDR_31_2_SHIFT 2 + +/**** Rvbar_High register ****/ +/* CPU Core AARach64 reset vector bar high bits +This is Write Once register (controlled by aarch64_reg_force_* fields) */ +#define NB_CPUN_CONFIG_STATUS_RVBAR_HIGH_ADDR_43_32_MASK 0x00000FFF +#define NB_CPUN_CONFIG_STATUS_RVBAR_HIGH_ADDR_43_32_SHIFT 0 + +/**** pmu_snapshot register ****/ +/* PMU Snapshot Request */ +#define NB_CPUN_CONFIG_STATUS_PMU_SNAPSHOT_REQ (1 << 0) +/* 0: HW deassert requests when received ack +1: SW deasserts request when received done */ +#define NB_CPUN_CONFIG_STATUS_PMU_SNAPSHOT_MODE (1 << 1) +/* Snapshot process completed */ +#define NB_CPUN_CONFIG_STATUS_PMU_SNAPSHOT_DONE (1 << 31) + +/**** cpu_msg_in register ****/ +/* CPU read this register to receive input (char) from simulation. */ +#define NB_CPUN_CONFIG_STATUS_CPU_MSG_IN_DATA_MASK 0x000000FF +#define NB_CPUN_CONFIG_STATUS_CPU_MSG_IN_DATA_SHIFT 0 +/* Indicates the data is valid. +Cleared on read */ +#define NB_CPUN_CONFIG_STATUS_CPU_MSG_IN_VALID (1 << 8) + +/**** PMU_Control register ****/ +/* Disable all counters +When this bit is clear, counter state is determined through the specific counter control register */ +#define NB_MC_PMU_PMU_CONTROL_DISABLE_ALL (1 << 0) +/* Pause all counters. +When this bit is clear, counter state is determined through the specific counter control register. */ +#define NB_MC_PMU_PMU_CONTROL_PAUSE_ALL (1 << 1) +/* Overflow interrupt enable: +disable - 0x0: Disable interrupt on overflow. +enable - 0x1: Enable interrupt on overflow. */ +#define NB_MC_PMU_PMU_CONTROL_OVRF_INTR_EN (1 << 2) +/* Number of monitored events supported by the PMU. */ +#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_MASK 0x00FC0000 +#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT 18 +#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT_ALPINE 19 +/* Number of counters implemented by PMU. */ +#define NB_MC_PMU_PMU_CONTROL_NUM_OF_CNTS_MASK 0x0F000000 +#define NB_MC_PMU_PMU_CONTROL_NUM_OF_CNTS_SHIFT 24 + +/**** Cfg register ****/ +/* Event select */ +#define NB_MC_PMU_COUNTERS_CFG_EVENT_SEL_MASK 0x0000003F +#define NB_MC_PMU_COUNTERS_CFG_EVENT_SEL_SHIFT 0 +/* Enable setting of counter low overflow status bit: +disable - 0x0: Disable setting. +enable - 0x1: Enable setting. */ +#define NB_MC_PMU_COUNTERS_CFG_OVRF_LOW_STT_EN (1 << 6) +/* Enable setting of counter high overflow status bit: +disable - 0x0: Disable setting. +enable - 0x1: Enable setting. */ +#define NB_MC_PMU_COUNTERS_CFG_OVRF_HIGH_STT_EN (1 << 7) +/* Enable pause on trigger in assertion: +disable - 0x0: Disable pause. +enable - 0x1: Enable pause. */ +#define NB_MC_PMU_COUNTERS_CFG_TRIGIN_PAUSE_EN (1 << 8) +/* Enable increment trigger out for trace. +Trigger is generated whenever counter reaches value: +disable - 0x0: Disable trigger out. +enable - 0x1: Enable trigger out. */ +#define NB_MC_PMU_COUNTERS_CFG_TRIGOUT_EN (1 << 9) +/* Trigger out granule value +Specifies the number of events counted between two consecutive trigger out events +0x0: 1 - Trigger out on every event occurrence. +0x1: 2 - Trigger out on every two events. +... +0xn: 2^(n-1) - Trigger out on event 2^(n-1) events. +... +0x1F: 2^31 */ +#define NB_MC_PMU_COUNTERS_CFG_TRIGOUT_GRANULA_MASK 0x00007C00 +#define NB_MC_PMU_COUNTERS_CFG_TRIGOUT_GRANULA_SHIFT 10 +/* Pause on overflow bitmask +If set for counter , current counter pauses counting when counter is overflowed, including self-pause. +Bit [16]: counter 0 +Bit [17]: counter 1 +Note: This field must be changed for larger counters. */ +#define NB_MC_PMU_COUNTERS_CFG_PAUSE_ON_OVRF_BITMASK_MASK 0x000F0000 +#define NB_MC_PMU_COUNTERS_CFG_PAUSE_ON_OVRF_BITMASK_SHIFT 16 + +/**** Cntl register ****/ +/* Set the counter state to disable, enable, or pause: +0x0 - disable: Disable counter. +0x1 - enable: Enable counter. +0x3 - pause: Pause counter. */ +#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_MASK 0x00000003 +#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_SHIFT 0 +/* Disable counter. */ +#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_DISABLE \ + (0x0 << NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_SHIFT) +/* Enable counter. */ +#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_ENABLE \ + (0x1 << NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_SHIFT) +/* Pause counter. */ +#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_PAUSE \ + (0x3 << NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_SHIFT) + +/**** High register ****/ +/* Counter high value */ +#define NB_MC_PMU_COUNTERS_HIGH_COUNTER_MASK 0x0000FFFF +#define NB_MC_PMU_COUNTERS_HIGH_COUNTER_SHIFT 0 + +/**** version register ****/ +/* Revision number (Minor) */ +#define NB_NB_VERSION_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF +#define NB_NB_VERSION_VERSION_RELEASE_NUM_MINOR_SHIFT 0 +/* Revision number (Major) */ +#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 +#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 +/* Date of release */ +#define NB_NB_VERSION_VERSION_DATE_DAY_MASK 0x001F0000 +#define NB_NB_VERSION_VERSION_DATE_DAY_SHIFT 16 +/* Month of release */ +#define NB_NB_VERSION_VERSION_DATA_MONTH_MASK 0x01E00000 +#define NB_NB_VERSION_VERSION_DATA_MONTH_SHIFT 21 +/* Year of release (starting from 2000) */ +#define NB_NB_VERSION_VERSION_DATE_YEAR_MASK 0x3E000000 +#define NB_NB_VERSION_VERSION_DATE_YEAR_SHIFT 25 +/* Reserved */ +#define NB_NB_VERSION_VERSION_RESERVED_MASK 0xC0000000 +#define NB_NB_VERSION_VERSION_RESERVED_SHIFT 30 + +/**** cpu_vmid register ****/ +/* Target VMID */ +#define NB_SRIOV_CPU_VMID_VAL_MASK 0x000000FF +#define NB_SRIOV_CPU_VMID_VAL_SHIFT 0 + +/**** DRAM_0_Control register ****/ +/* Controller Idle +Indicates to the DDR PHY, if set, that the memory controller is idle */ +#define NB_DRAM_CHANNELS_DRAM_0_CONTROL_DDR_PHY_CTL_IDLE (1 << 0) +/* Disable clear exclusive monitor request from DDR controller to CPU +Clear request is triggered whenever an exlusive monitor inside the DDR controller is being invalidated. */ +#define NB_DRAM_CHANNELS_DRAM_0_CONTROL_DDR_EXMON_REQ_DIS (1 << 1) + +/**** DRAM_0_Status register ****/ +/* Bypass Mode: Indicates if set that the PHY is in PLL bypass mod */ +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_DDR_PHY_BYP_MODE (1 << 0) +/* Number of available AXI transactions (used positions) in the DDR controller read address FIFO. */ +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_RAQ_WCOUNT_MASK 0x00000030 +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_RAQ_WCOUNT_SHIFT 4 +/* Number of available AXI transactions (used positions) in the DDR controller write address FIFO */ +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_WAQ_WCOUNT_0_MASK 0x000000C0 +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_WAQ_WCOUNT_0_SHIFT 6 +/* Number of available Low priority read CAM slots (free positions) in the DDR controller. +Each slots holds a DRAM burst */ +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_LPR_CREDIT_CNT_MASK 0x00007F00 +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_LPR_CREDIT_CNT_SHIFT 8 +/* Number of available High priority read CAM slots (free positions) in the DDR controller. +Each slots holds a DRAM burst */ +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_HPR_CREDIT_CNT_MASK 0x003F8000 +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_HPR_CREDIT_CNT_SHIFT 15 +/* Number of available write CAM slots (free positions) in the DDR controller. +Each slots holds a DRAM burst */ +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_WR_CREDIT_CNT_MASK 0x1FC00000 +#define NB_DRAM_CHANNELS_DRAM_0_STATUS_WR_CREDIT_CNT_SHIFT 22 + +/**** DDR_Int_Cause register ****/ +/* This interrupt is asserted when a correctable ECC error is detected */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_ECC_CORRECTED_ERR (1 << 0) +/* This interrupt is asserted when a uncorrectable ECC error is detected */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_ECC_UNCORRECTED_ERR (1 << 1) +/* This interrupt is asserted when a parity or CRC error is detected on the DFI interface */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_DFI_ALERT_ERR (1 << 2) +/* On-Chip Write data parity error interrupt on output */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_WDATA_OUT_ERR (1 << 3) +/* This interrupt is asserted when a parity error due to MRS is detected on the DFI interface */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_DFI_ALERT_ERR_FATL (1 << 4) +/* This interrupt is asserted when the CRC/parity retry counter reaches it maximum value */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_DFI_ALERT_ERR_MAX_REACHED (1 << 5) +/* AXI Read address parity error interrupt. +This interrupt is asserted when an on-chip parity error occurred on the DDR controller AXI read address. */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_RADDR_ERR (1 << 6) +/* AXI Read data parity error interrupt. +This interrupt is asserted when an on-chip parity error occurred on the DDR controller AXI read data */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_RDATA_ERR (1 << 7) +/* AXI Write address parity error interrupt. +This interrupt is asserted when an on-chip parity error occurred on the DDR controller AXI write address. */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_WADDR_ERR (1 << 8) +/* AXI Write data parity error interrupt on input. +This interrupt is asserted when an on-chip parity error occurred on the DDR controller AXI write data */ +#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_WDATA_IN_ERR (1 << 9) + +/**** Address_Map register ****/ +/* Controls which system address bit will be mapped to DDR row bit 2. +This field is only used when addrmap_part_en == 1 */ +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B2_MASK 0x0000000F +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B2_SHIFT 0 +/* Controls which system address bit will be mapped to DDR row bit 3. +This field is only used when addrmap_part_en == 1 */ +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B3_MASK 0x000003C0 +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B3_SHIFT 6 +/* Controls which system address bit will be mapped to DDR row bit 4. +This field is only used when addrmap_part_en == 1 */ +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B4_MASK 0x0000F000 +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B4_SHIFT 12 +/* Controls which system address bit will be mapped to DDR row bit 5. +This field is only used when addrmap_part_en == 1 */ +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B5_MASK 0x003C0000 +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B5_SHIFT 18 +/* Enables partitioning of the address mapping control. +When set, addrmap_row_b2-5 are used inside DDR controler instead of the built in address mapping registers */ +#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_PART_EN (1 << 31) + +/**** Reorder_ID_Mask register ****/ +/* DDR Read Reorder buffer ID mask. +If incoming read transaction ID ANDed with mask is equal Reorder_ID_Value, then the transaction is mapped to the DDR controller bypass channel. +Setting this register to 0 will disable the check */ +#define NB_DRAM_CHANNELS_REORDER_ID_MASK_MASK_MASK 0x003FFFFF +#define NB_DRAM_CHANNELS_REORDER_ID_MASK_MASK_SHIFT 0 + +/**** Reorder_ID_Value register ****/ +/* DDR Read Reorder buffer ID value +If incoming read transaction ID ANDed with Reorder_ID_Mask is equal to this register, then the transaction is mapped to the DDR controller bypass channel */ +#define NB_DRAM_CHANNELS_REORDER_ID_VALUE_VALUE_MASK 0x003FFFFF +#define NB_DRAM_CHANNELS_REORDER_ID_VALUE_VALUE_SHIFT 0 + +/**** MRR_Control_Status register ****/ +/* DDR4 Mode Register Read Data Valid */ +#define NB_DRAM_CHANNELS_MRR_CONTROL_STATUS_MRR_VLD (1 << 0) +/* MRR Ack, when asserted it clears the mrr_val indication and ready to load new MRR data. Write 1 to clear and then 0 */ +#define NB_DRAM_CHANNELS_MRR_CONTROL_STATUS_MRR_ACK (1 << 16) + +/**** pp_config register ****/ +/* Bypass PP module (formality equivalent) */ +#define NB_PUSH_PACKET_PP_CONFIG_FM_BYPASS (1 << 0) +/* Bypass PP module */ +#define NB_PUSH_PACKET_PP_CONFIG_BYPASS (1 << 1) +/* Force Cleanup of entries */ +#define NB_PUSH_PACKET_PP_CONFIG_CLEAR (1 << 2) +/* Enable forwarding DECERR response */ +#define NB_PUSH_PACKET_PP_CONFIG_DECERR_EN (1 << 3) +/* Enable forwarding SLVERR response */ +#define NB_PUSH_PACKET_PP_CONFIG_SLVERR_EN (1 << 4) +/* Enable forwarding of data parity generation */ +#define NB_PUSH_PACKET_PP_CONFIG_PAR_GEN_EN (1 << 5) +/* Select channel on 8K boundaries ([15:13]) instead of 64k boundaries ([18:16]). */ +#define NB_PUSH_PACKET_PP_CONFIG_SEL_8K (1 << 6) +/* Forces awuser to be as configured in ext_awuser register. +Not functional */ +#define NB_PUSH_PACKET_PP_CONFIG_SEL_EXT_AWUSER (1 << 7) +/* Enables PP channel. +1 bit per channel */ +#define NB_PUSH_PACKET_PP_CONFIG_CHANNEL_ENABLE_MASK 0x00030000 +#define NB_PUSH_PACKET_PP_CONFIG_CHANNEL_ENABLE_SHIFT 16 + +#define NB_PUSH_PACKET_PP_CONFIG_CHANNEL_ENABLE(i) \ + (1 << (NB_PUSH_PACKET_PP_CONFIG_CHANNEL_ENABLE_SHIFT + i)) + +/**** pp_ext_awuser register ****/ +/* Awuser to use on PP transactions +Only applicable if config.sel_ext_awuser is set to 1'b1 +Parity bits are still generated per transaction */ +#define NB_PUSH_PACKET_PP_EXT_AWUSER_AWUSER_MASK 0x03FFFFFF +#define NB_PUSH_PACKET_PP_EXT_AWUSER_AWUSER_SHIFT 0 + +/**** pp_sel_awuser register ****/ +/* Select whether to use addr[63:48] or PP awmisc as vmid. +Each bit if set to 1 selects the corresponding address bit. Otherwise, selects the corersponding awmis bit. */ +#define NB_PUSH_PACKET_PP_SEL_AWUSER_SEL_MASK 0x0000FFFF +#define NB_PUSH_PACKET_PP_SEL_AWUSER_SEL_SHIFT 0 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_NB_REGS_H__ */ + +/** @} end of ... group */ + + diff --git a/al_hal_pbs_regs.h b/al_hal_pbs_regs.h new file mode 100644 index 000000000000..b1f9c4f44d93 --- /dev/null +++ b/al_hal_pbs_regs.h @@ -0,0 +1,2751 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @{ + * @file al_hal_pbs_regs.h + * + * @brief ... registers + * + */ + +#ifndef __AL_HAL_PBS_REGS_H__ +#define __AL_HAL_PBS_REGS_H__ + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct al_pbs_unit { + /* [0x0] Conf_bus, Configuration of the SB */ + uint32_t conf_bus; + /* [0x4] PASW high */ + uint32_t dram_0_nb_bar_high; + /* [0x8] PASW low */ + uint32_t dram_0_nb_bar_low; + /* [0xc] PASW high */ + uint32_t dram_1_nb_bar_high; + /* [0x10] PASW low */ + uint32_t dram_1_nb_bar_low; + /* [0x14] PASW high */ + uint32_t dram_2_nb_bar_high; + /* [0x18] PASW low */ + uint32_t dram_2_nb_bar_low; + /* [0x1c] PASW high */ + uint32_t dram_3_nb_bar_high; + /* [0x20] PASW low */ + uint32_t dram_3_nb_bar_low; + /* [0x24] PASW high */ + uint32_t msix_nb_bar_high; + /* [0x28] PASW low */ + uint32_t msix_nb_bar_low; + /* [0x2c] PASW high */ + uint32_t dram_0_sb_bar_high; + /* [0x30] PASW low */ + uint32_t dram_0_sb_bar_low; + /* [0x34] PASW high */ + uint32_t dram_1_sb_bar_high; + /* [0x38] PASW low */ + uint32_t dram_1_sb_bar_low; + /* [0x3c] PASW high */ + uint32_t dram_2_sb_bar_high; + /* [0x40] PASW low */ + uint32_t dram_2_sb_bar_low; + /* [0x44] PASW high */ + uint32_t dram_3_sb_bar_high; + /* [0x48] PASW low */ + uint32_t dram_3_sb_bar_low; + /* [0x4c] PASW high */ + uint32_t msix_sb_bar_high; + /* [0x50] PASW low */ + uint32_t msix_sb_bar_low; + /* [0x54] PASW high */ + uint32_t pcie_mem0_bar_high; + /* [0x58] PASW low */ + uint32_t pcie_mem0_bar_low; + /* [0x5c] PASW high */ + uint32_t pcie_mem1_bar_high; + /* [0x60] PASW low */ + uint32_t pcie_mem1_bar_low; + /* [0x64] PASW high */ + uint32_t pcie_mem2_bar_high; + /* [0x68] PASW low */ + uint32_t pcie_mem2_bar_low; + /* [0x6c] PASW high */ + uint32_t pcie_ext_ecam0_bar_high; + /* [0x70] PASW low */ + uint32_t pcie_ext_ecam0_bar_low; + /* [0x74] PASW high */ + uint32_t pcie_ext_ecam1_bar_high; + /* [0x78] PASW low */ + uint32_t pcie_ext_ecam1_bar_low; + /* [0x7c] PASW high */ + uint32_t pcie_ext_ecam2_bar_high; + /* [0x80] PASW low */ + uint32_t pcie_ext_ecam2_bar_low; + /* [0x84] PASW high */ + uint32_t pbs_nor_bar_high; + /* [0x88] PASW low */ + uint32_t pbs_nor_bar_low; + /* [0x8c] PASW high */ + uint32_t pbs_spi_bar_high; + /* [0x90] PASW low */ + uint32_t pbs_spi_bar_low; + uint32_t rsrvd_0[3]; + /* [0xa0] PASW high */ + uint32_t pbs_nand_bar_high; + /* [0xa4] PASW low */ + uint32_t pbs_nand_bar_low; + /* [0xa8] PASW high */ + uint32_t pbs_int_mem_bar_high; + /* [0xac] PASW low */ + uint32_t pbs_int_mem_bar_low; + /* [0xb0] PASW high */ + uint32_t pbs_boot_bar_high; + /* [0xb4] PASW low */ + uint32_t pbs_boot_bar_low; + /* [0xb8] PASW high */ + uint32_t nb_int_bar_high; + /* [0xbc] PASW low */ + uint32_t nb_int_bar_low; + /* [0xc0] PASW high */ + uint32_t nb_stm_bar_high; + /* [0xc4] PASW low */ + uint32_t nb_stm_bar_low; + /* [0xc8] PASW high */ + uint32_t pcie_ecam_int_bar_high; + /* [0xcc] PASW low */ + uint32_t pcie_ecam_int_bar_low; + /* [0xd0] PASW high */ + uint32_t pcie_mem_int_bar_high; + /* [0xd4] PASW low */ + uint32_t pcie_mem_int_bar_low; + /* [0xd8] Control */ + uint32_t winit_cntl; + /* [0xdc] Control */ + uint32_t latch_bars; + /* [0xe0] Control */ + uint32_t pcie_conf_0; + /* [0xe4] Control */ + uint32_t pcie_conf_1; + /* [0xe8] Control */ + uint32_t serdes_mux_pipe; + /* [0xec] Control */ + uint32_t dma_io_master_map; + /* [0xf0] Status */ + uint32_t i2c_pld_status_high; + /* [0xf4] Status */ + uint32_t i2c_pld_status_low; + /* [0xf8] Status */ + uint32_t spi_dbg_status_high; + /* [0xfc] Status */ + uint32_t spi_dbg_status_low; + /* [0x100] Status */ + uint32_t spi_mst_status_high; + /* [0x104] Status */ + uint32_t spi_mst_status_low; + /* [0x108] Log */ + uint32_t mem_pbs_parity_err_high; + /* [0x10c] Log */ + uint32_t mem_pbs_parity_err_low; + /* [0x110] Log */ + uint32_t boot_strap; + /* [0x114] Conf */ + uint32_t cfg_axi_conf_0; + /* [0x118] Conf */ + uint32_t cfg_axi_conf_1; + /* [0x11c] Conf */ + uint32_t cfg_axi_conf_2; + /* [0x120] Conf */ + uint32_t cfg_axi_conf_3; + /* [0x124] Conf */ + uint32_t spi_mst_conf_0; + /* [0x128] Conf */ + uint32_t spi_mst_conf_1; + /* [0x12c] Conf */ + uint32_t spi_slv_conf_0; + /* [0x130] Conf */ + uint32_t apb_mem_conf_int; + /* [0x134] PASW remap register */ + uint32_t sb2nb_cfg_dram_remap; + /* [0x138] Control */ + uint32_t pbs_mux_sel_0; + /* [0x13c] Control */ + uint32_t pbs_mux_sel_1; + /* [0x140] Control */ + uint32_t pbs_mux_sel_2; + /* [0x144] Control */ + uint32_t pbs_mux_sel_3; + /* [0x148] PASW high */ + uint32_t sb_int_bar_high; + /* [0x14c] PASW low */ + uint32_t sb_int_bar_low; + /* [0x150] log */ + uint32_t ufc_pbs_parity_err_high; + /* [0x154] log */ + uint32_t ufc_pbs_parity_err_low; + /* [0x158] Cntl - internal */ + uint32_t gen_conf; + /* [0x15c] Device ID and Rev ID */ + uint32_t chip_id; + /* [0x160] Status - internal */ + uint32_t uart0_debug; + /* [0x164] Status - internal */ + uint32_t uart1_debug; + /* [0x168] Status - internal */ + uint32_t uart2_debug; + /* [0x16c] Status - internal */ + uint32_t uart3_debug; + /* [0x170] Control - internal */ + uint32_t uart0_conf_status; + /* [0x174] Control - internal */ + uint32_t uart1_conf_status; + /* [0x178] Control - internal */ + uint32_t uart2_conf_status; + /* [0x17c] Control - internal */ + uint32_t uart3_conf_status; + /* [0x180] Control - internal */ + uint32_t gpio0_conf_status; + /* [0x184] Control - internal */ + uint32_t gpio1_conf_status; + /* [0x188] Control - internal */ + uint32_t gpio2_conf_status; + /* [0x18c] Control - internal */ + uint32_t gpio3_conf_status; + /* [0x190] Control - internal */ + uint32_t gpio4_conf_status; + /* [0x194] Control - internal */ + uint32_t i2c_gen_conf_status; + /* [0x198] Control - internal */ + uint32_t i2c_gen_debug; + /* [0x19c] Cntl */ + uint32_t watch_dog_reset_out; + /* [0x1a0] Cntl */ + uint32_t otp_magic_num; + /* + * [0x1a4] Control - internal + */ + uint32_t otp_cntl; + /* [0x1a8] Cfg - internal */ + uint32_t otp_cfg_0; + /* [0x1ac] Cfg - internal */ + uint32_t otp_cfg_1; + /* [0x1b0] Cfg - internal */ + uint32_t otp_cfg_3; + /* [0x1b4] Cfg */ + uint32_t cfg_nand_0; + /* [0x1b8] Cfg */ + uint32_t cfg_nand_1; + /* [0x1bc] Cfg-- timing parameters internal. */ + uint32_t cfg_nand_2; + /* [0x1c0] Cfg - internal */ + uint32_t cfg_nand_3; + /* [0x1c4] PASW high */ + uint32_t nb_nic_regs_bar_high; + /* [0x1c8] PASW low */ + uint32_t nb_nic_regs_bar_low; + /* [0x1cc] PASW high */ + uint32_t sb_nic_regs_bar_high; + /* [0x1d0] PASW low */ + uint32_t sb_nic_regs_bar_low; + /* [0x1d4] Control */ + uint32_t serdes_mux_multi_0; + /* [0x1d8] Control */ + uint32_t serdes_mux_multi_1; + /* [0x1dc] Control - not in use any more - internal */ + uint32_t pbs_ulpi_mux_conf; + /* [0x1e0] Cntl */ + uint32_t wr_once_dbg_dis_ovrd_reg; + /* [0x1e4] Cntl - internal */ + uint32_t gpio5_conf_status; + /* [0x1e8] PASW high */ + uint32_t pcie_mem3_bar_high; + /* [0x1ec] PASW low */ + uint32_t pcie_mem3_bar_low; + /* [0x1f0] PASW high */ + uint32_t pcie_mem4_bar_high; + /* [0x1f4] PASW low */ + uint32_t pcie_mem4_bar_low; + /* [0x1f8] PASW high */ + uint32_t pcie_mem5_bar_high; + /* [0x1fc] PASW low */ + uint32_t pcie_mem5_bar_low; + /* [0x200] PASW high */ + uint32_t pcie_ext_ecam3_bar_high; + /* [0x204] PASW low */ + uint32_t pcie_ext_ecam3_bar_low; + /* [0x208] PASW high */ + uint32_t pcie_ext_ecam4_bar_high; + /* [0x20c] PASW low */ + uint32_t pcie_ext_ecam4_bar_low; + /* [0x210] PASW high */ + uint32_t pcie_ext_ecam5_bar_high; + /* [0x214] PASW low */ + uint32_t pcie_ext_ecam5_bar_low; + /* [0x218] PASW high */ + uint32_t low_latency_sram_bar_high; + /* [0x21c] PASW low */ + uint32_t low_latency_sram_bar_low; + /* [0x220] Control */ + uint32_t pbs_mux_sel_4; + /* [0x224] Control */ + uint32_t pbs_mux_sel_5; + /* [0x228] Control */ + uint32_t serdes_mux_eth; + /* [0x22c] Control */ + uint32_t serdes_mux_pcie; + /* [0x230] Control */ + uint32_t serdes_mux_sata; + uint32_t rsrvd[7]; +}; +struct al_pbs_low_latency_sram_remap { + /* [0x0] PBS MEM Remap */ + uint32_t bar1_orig; + /* [0x4] PBS MEM Remap */ + uint32_t bar1_remap; + /* [0x8] ETH0 MEM Remap */ + uint32_t bar2_orig; + /* [0xc] ETH0 MEM Remap */ + uint32_t bar2_remap; + /* [0x10] ETH1 MEM Remap */ + uint32_t bar3_orig; + /* [0x14] ETH1 MEM Remap */ + uint32_t bar3_remap; + /* [0x18] ETH2 MEM Remap */ + uint32_t bar4_orig; + /* [0x1c] ETH2 MEM Remap */ + uint32_t bar4_remap; + /* [0x20] ETH3 MEM Remap */ + uint32_t bar5_orig; + /* [0x24] ETH3 MEM Remap */ + uint32_t bar5_remap; + /* [0x28] CRYPTO0 MEM Remap */ + uint32_t bar6_orig; + /* [0x2c] CRYPTO0 MEM Remap */ + uint32_t bar6_remap; + /* [0x30] RAID0 MEM Remap */ + uint32_t bar7_orig; + /* [0x34] RAID0 MEM Remap */ + uint32_t bar7_remap; + /* [0x38] CRYPTO1 MEM Remap */ + uint32_t bar8_orig; + /* [0x3c] CRYPTO1 MEM Remap */ + uint32_t bar8_remap; + /* [0x40] RAID1 MEM Remap */ + uint32_t bar9_orig; + /* [0x44] RAID2 MEM Remap */ + uint32_t bar9_remap; + /* [0x48] RESERVED MEM Remap */ + uint32_t bar10_orig; + /* [0x4c] RESERVED MEM Remap */ + uint32_t bar10_remap; +}; +struct al_pbs_target_id_enforcement { + /* [0x0] target enforcement */ + uint32_t cpu; + /* [0x4] target enforcement mask (bits which are 0 are not compared) */ + uint32_t cpu_mask; + /* [0x8] target enforcement */ + uint32_t debug_nb; + /* [0xc] target enforcement mask (bits which are 0 are not compared) */ + uint32_t debug_nb_mask; + /* [0x10] target enforcement */ + uint32_t debug_sb; + /* [0x14] target enforcement mask (bits which are 0 are not compared) */ + uint32_t debug_sb_mask; + /* [0x18] target enforcement */ + uint32_t eth_0; + /* [0x1c] target enforcement mask (bits which are 0 are not compared) */ + uint32_t eth_0_mask; + /* [0x20] target enforcement */ + uint32_t eth_1; + /* [0x24] target enforcement mask (bits which are 0 are not compared) */ + uint32_t eth_1_mask; + /* [0x28] target enforcement */ + uint32_t eth_2; + /* [0x2c] target enforcement mask (bits which are 0 are not compared) */ + uint32_t eth_2_mask; + /* [0x30] target enforcement */ + uint32_t eth_3; + /* [0x34] target enforcement mask (bits which are 0 are not compared) */ + uint32_t eth_3_mask; + /* [0x38] target enforcement */ + uint32_t sata_0; + /* [0x3c] target enforcement mask (bits which are 0 are not compared) */ + uint32_t sata_0_mask; + /* [0x40] target enforcement */ + uint32_t sata_1; + /* [0x44] target enforcement mask (bits which are 0 are not compared) */ + uint32_t sata_1_mask; + /* [0x48] target enforcement */ + uint32_t crypto_0; + /* [0x4c] target enforcement mask (bits which are 0 are not compared) */ + uint32_t crypto_0_mask; + /* [0x50] target enforcement */ + uint32_t crypto_1; + /* [0x54] target enforcement mask (bits which are 0 are not compared) */ + uint32_t crypto_1_mask; + /* [0x58] target enforcement */ + uint32_t pcie_0; + /* [0x5c] target enforcement mask (bits which are 0 are not compared) */ + uint32_t pcie_0_mask; + /* [0x60] target enforcement */ + uint32_t pcie_1; + /* [0x64] target enforcement mask (bits which are 0 are not compared) */ + uint32_t pcie_1_mask; + /* [0x68] target enforcement */ + uint32_t pcie_2; + /* [0x6c] target enforcement mask (bits which are 0 are not compared) */ + uint32_t pcie_2_mask; + /* [0x70] target enforcement */ + uint32_t pcie_3; + /* [0x74] target enforcement mask (bits which are 0 are not compared) */ + uint32_t pcie_3_mask; + /* [0x78] Control */ + uint32_t latch; + uint32_t rsrvd[9]; +}; + +struct al_pbs_regs { + struct al_pbs_unit unit; /* [0x0] */ +struct al_pbs_low_latency_sram_remap low_latency_sram_remap; +/* [0x250] */ + uint32_t rsrvd_0[88]; + struct al_pbs_target_id_enforcement target_id_enforcement; /* [0x400] */ +}; + + +/* +* Registers Fields +*/ + + +/**** conf_bus register ****/ +/* Read slave error enable */ +#define PBS_UNIT_CONF_BUS_RD_SLVERR_EN (1 << 0) +/* Write slave error enable */ +#define PBS_UNIT_CONF_BUS_WR_SLVERR_EN (1 << 1) +/* Read decode error enable */ +#define PBS_UNIT_CONF_BUS_RD_DECERR_EN (1 << 2) +/* Write decode error enable */ +#define PBS_UNIT_CONF_BUS_WR_DECERR_EN (1 << 3) +/* For debug clear the APB SM */ +#define PBS_UNIT_CONF_BUS_CLR_APB_FSM (1 << 4) +/* For debug clear the WFIFO */ +#define PBS_UNIT_CONF_BUS_CLR_WFIFO_CLEAR (1 << 5) +/* Arbiter between read and write channel */ +#define PBS_UNIT_CONF_BUS_WRR_CNT_MASK 0x000001C0 +#define PBS_UNIT_CONF_BUS_WRR_CNT_SHIFT 6 + + +/* general PASWS */ +/* window size = 2 ^ (15 + win_size), zero value disable the win ... */ +#define PBS_PASW_WIN_SIZE_MASK 0x0000003F +#define PBS_PASW_WIN_SIZE_SHIFT 0 +/* reserved fields */ +#define PBS_PASW_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_PASW_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_PASW_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_PASW_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** dram_0_nb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_DRAM_0_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_DRAM_0_NB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DRAM_0_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_DRAM_0_NB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_DRAM_0_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_DRAM_0_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** dram_1_nb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_DRAM_1_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_DRAM_1_NB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DRAM_1_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_DRAM_1_NB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_DRAM_1_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_DRAM_1_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** dram_2_nb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_DRAM_2_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_DRAM_2_NB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DRAM_2_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_DRAM_2_NB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_DRAM_2_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_DRAM_2_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** dram_3_nb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_DRAM_3_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_DRAM_3_NB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DRAM_3_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_DRAM_3_NB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_DRAM_3_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_DRAM_3_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** msix_nb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_MSIX_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_MSIX_NB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_MSIX_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_MSIX_NB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_MSIX_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_MSIX_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** dram_0_sb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_DRAM_0_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_DRAM_0_SB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DRAM_0_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_DRAM_0_SB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_DRAM_0_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_DRAM_0_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** dram_1_sb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_DRAM_1_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_DRAM_1_SB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DRAM_1_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_DRAM_1_SB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_DRAM_1_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_DRAM_1_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** dram_2_sb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_DRAM_2_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_DRAM_2_SB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DRAM_2_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_DRAM_2_SB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_DRAM_2_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_DRAM_2_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** dram_3_sb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_DRAM_3_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_DRAM_3_SB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DRAM_3_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_DRAM_3_SB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_DRAM_3_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_DRAM_3_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** msix_sb_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_MSIX_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_MSIX_SB_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_MSIX_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_MSIX_SB_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_MSIX_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_MSIX_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_mem0_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_MEM0_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_MEM0_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_MEM0_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_MEM0_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PCIE_MEM0_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_MEM0_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_mem1_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_MEM1_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_MEM1_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_MEM1_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_MEM1_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PCIE_MEM1_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_MEM1_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_mem2_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_MEM2_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_MEM2_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_MEM2_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_MEM2_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PCIE_MEM2_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_MEM2_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_ext_ecam0_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_ext_ecam1_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_ext_ecam2_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pbs_nor_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PBS_NOR_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PBS_NOR_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PBS_NOR_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PBS_NOR_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PBS_NOR_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PBS_NOR_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pbs_spi_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PBS_SPI_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PBS_SPI_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PBS_SPI_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PBS_SPI_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PBS_SPI_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PBS_SPI_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pbs_nand_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PBS_NAND_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PBS_NAND_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PBS_NAND_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PBS_NAND_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PBS_NAND_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PBS_NAND_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pbs_int_mem_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pbs_boot_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PBS_BOOT_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PBS_BOOT_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PBS_BOOT_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PBS_BOOT_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PBS_BOOT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PBS_BOOT_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** nb_int_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_NB_INT_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_NB_INT_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_NB_INT_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_NB_INT_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_NB_INT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_NB_INT_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** nb_stm_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_NB_STM_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_NB_STM_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_NB_STM_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_NB_STM_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_NB_STM_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_NB_STM_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_ecam_int_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_mem_int_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** winit_cntl register ****/ +/* When set, enables access to winit regs, in normal mode. */ +#define PBS_UNIT_WINIT_CNTL_ENABLE_WINIT_REGS_ACCESS (1 << 0) +/* Reserved */ +#define PBS_UNIT_WINIT_CNTL_RSRVD_MASK 0xFFFFFFFE +#define PBS_UNIT_WINIT_CNTL_RSRVD_SHIFT 1 + +/**** latch_bars register ****/ +/* + * Software clears this bit before any bar update, and set it after all bars + * updated. + */ +#define PBS_UNIT_LATCH_BARS_ENABLE (1 << 0) +/* Reserved */ +#define PBS_UNIT_LATCH_BARS_RSRVD_MASK 0xFFFFFFFE +#define PBS_UNIT_LATCH_BARS_RSRVD_SHIFT 1 + +/**** pcie_conf_0 register ****/ +/* NOT_use, config internal inside each PCIe core */ +#define PBS_UNIT_PCIE_CONF_0_DEVS_TYPE_MASK 0x00000FFF +#define PBS_UNIT_PCIE_CONF_0_DEVS_TYPE_SHIFT 0 +/* sys_aux_det value */ +#define PBS_UNIT_PCIE_CONF_0_SYS_AUX_PWR_DET_VEC_MASK 0x00007000 +#define PBS_UNIT_PCIE_CONF_0_SYS_AUX_PWR_DET_VEC_SHIFT 12 +/* Reserved */ +#define PBS_UNIT_PCIE_CONF_0_RSRVD_MASK 0xFFFF8000 +#define PBS_UNIT_PCIE_CONF_0_RSRVD_SHIFT 15 + +/**** pcie_conf_1 register ****/ +/* + * Which PCIe exists? The PCIe device is under reset until the corresponding bit + * is set. + */ +#define PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_MASK 0x0000003F +#define PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT 0 +/* Reserved */ +#define PBS_UNIT_PCIE_CONF_1_RSRVD_MASK 0xFFFFFFC0 +#define PBS_UNIT_PCIE_CONF_1_RSRVD_SHIFT 6 + +/**** serdes_mux_pipe register ****/ +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_SERDES_2_MASK 0x00000007 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_SERDES_2_SHIFT 0 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_3 (1 << 3) +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_SERDES_3_MASK 0x00000070 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_SERDES_3_SHIFT 4 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_7 (1 << 7) +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_B_0_MASK 0x00000300 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_B_0_SHIFT 8 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_B_1_MASK 0x00000C00 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_B_1_SHIFT 10 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_C_0_MASK 0x00003000 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_C_0_SHIFT 12 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_C_1_MASK 0x0000C000 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_C_1_SHIFT 14 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_USB_A_0_MASK 0x00030000 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_USB_A_0_SHIFT 16 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_USB_B_0_MASK 0x000C0000 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_USB_B_0_SHIFT 18 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_CLKI_SER_2_MASK 0x00300000 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_CLKI_SER_2_SHIFT 20 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_23_22_MASK 0x00C00000 +#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_23_22_SHIFT 22 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_CLKI_SER_3_MASK 0x07000000 +#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_CLKI_SER_3_SHIFT 24 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_MASK 0xF8000000 +#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_SHIFT 27 + +/* + * 2'b01 - select pcie_b[0] + * 2'b10 - select pcie_a[2] + */ +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_2_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_2_SHIFT 0 +/* + * 2'b01 - select pcie_b[1] + * 2'b10 - select pcie_a[3] + */ +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_3_MASK 0x00000030 +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_3_SHIFT 4 +/* + * 2'b01 - select pcie_b[0] + * 2'b10 - select pcie_a[4] + */ +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_4_MASK 0x00000300 +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_4_SHIFT 8 +/* + * 2'b01 - select pcie_b[1] + * 2'b10 - select pcie_a[5] + */ +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_5_MASK 0x00003000 +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_5_SHIFT 12 +/* + * 2'b01 - select pcie_b[2] + * 2'b10 - select pcie_a[6] + */ +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_6_MASK 0x00030000 +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_6_SHIFT 16 +/* + * 2'b01 - select pcie_b[3] + * 2'b10 - select pcie_a[7] + */ +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_7_MASK 0x00300000 +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_7_SHIFT 20 +/* + * 2'b01 - select pcie_d[0] + * 2'b10 - select pcie_c[2] + */ +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_10_MASK 0x03000000 +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_10_SHIFT 24 +/* + * 2'b01 - select pcie_d[1] + * 2'b10 - select pcie_c[3] + */ +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_11_MASK 0x30000000 +#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_11_SHIFT 28 + +/**** dma_io_master_map register ****/ +/* + * [0]: When set, maps all the io_dma transactions to the NB/DRAM, regardless of + * the window hit. + * [1]: When set, maps all the eth_0 transactions to the NB/DRAM, regardless of + * the window hit. + * [2]: When set, maps all the eth_2 transaction to the NB/DRAM, regardless of + * the window hit. + * [3]: When set, maps all the sata_0 transactions to the NB/DRAM, regardless of + * the window hit. + * [4]: When set, maps all the sata_1 transactions to the NB/DRAM, regardless of + * the window hit. + * [5]: When set, maps all the pcie_0 master transactions to the NB/DRAM, + * regardless of the window hit. + * [6]: When set, maps all the SPI debug port transactions to the NB/DRAM, + * regardless of the window hit. + * [7]: When set, maps all the CPU debug port transactions to the NB/DRAM, + * regardless of the window hit. + * [8] When set, maps all the Crypto transactions to the NB/DRAM, regardless of + * the window hit. + * [15:9] - Reserved + */ +#define PBS_UNIT_DMA_IO_MASTER_MAP_CNTL_MASK 0x0000FFFF +#define PBS_UNIT_DMA_IO_MASTER_MAP_CNTL_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_DMA_IO_MASTER_MAP_RSRVD_MASK 0xFFFF0000 +#define PBS_UNIT_DMA_IO_MASTER_MAP_RSRVD_SHIFT 16 + +/**** i2c_pld_status_high register ****/ +/* I2C pre-load status */ +#define PBS_UNIT_I2C_PLD_STATUS_HIGH_STATUS_MASK 0x000000FF +#define PBS_UNIT_I2C_PLD_STATUS_HIGH_STATUS_SHIFT 0 + +/**** spi_dbg_status_high register ****/ +/* SPI DBG load status */ +#define PBS_UNIT_SPI_DBG_STATUS_HIGH_STATUS_MASK 0x000000FF +#define PBS_UNIT_SPI_DBG_STATUS_HIGH_STATUS_SHIFT 0 + +/**** spi_mst_status_high register ****/ +/* SP IMST load status */ +#define PBS_UNIT_SPI_MST_STATUS_HIGH_STATUS_MASK 0x000000FF +#define PBS_UNIT_SPI_MST_STATUS_HIGH_STATUS_SHIFT 0 + +/**** mem_pbs_parity_err_high register ****/ +/* Address latch in the case of a parity error */ +#define PBS_UNIT_MEM_PBS_PARITY_ERR_HIGH_ADDR_MASK 0x000000FF +#define PBS_UNIT_MEM_PBS_PARITY_ERR_HIGH_ADDR_SHIFT 0 + +/**** cfg_axi_conf_0 register ****/ +/* Sets the AXI field in the I2C preloader interface. */ +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_RD_ID_MASK 0x0000007F +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_RD_ID_SHIFT 0 +/* Sets the AXI field in the I2C preloader interface. */ +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_WR_ID_MASK 0x00003F80 +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_WR_ID_SHIFT 7 +/* Sets the AXI field in the I2C preloader interface. */ +#define PBS_UNIT_CFG_AXI_CONF_0_PLD_WR_ID_MASK 0x001FC000 +#define PBS_UNIT_CFG_AXI_CONF_0_PLD_WR_ID_SHIFT 14 +/* Sets the AXI field in the SPI debug interface. */ +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_AWCACHE_MASK 0x01E00000 +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_AWCACHE_SHIFT 21 +/* Sets the AXI field in the SPI debug interface. */ +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_ARCACHE_MASK 0x1E000000 +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_ARCACHE_SHIFT 25 +/* Sets the AXI field in the SPI debug interface. */ +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_AXPROT_MASK 0xE0000000 +#define PBS_UNIT_CFG_AXI_CONF_0_DBG_AXPROT_SHIFT 29 + +/**** cfg_axi_conf_1 register ****/ +/* Sets the AXI field in the SPI debug interface. */ +#define PBS_UNIT_CFG_AXI_CONF_1_DBG_ARUSER_MASK 0x03FFFFFF +#define PBS_UNIT_CFG_AXI_CONF_1_DBG_ARUSER_SHIFT 0 +/* Sets the AXI field in the SPI debug interface. */ +#define PBS_UNIT_CFG_AXI_CONF_1_DBG_ARQOS_MASK 0x3C000000 +#define PBS_UNIT_CFG_AXI_CONF_1_DBG_ARQOS_SHIFT 26 + +/**** cfg_axi_conf_2 register ****/ +/* Sets the AXI field in the SPI debug interface. */ +#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWUSER_MASK 0x03FFFFFF +#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWUSER_SHIFT 0 +/* Sets the AXI field in the SPI debug interface. */ +#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWQOS_MASK 0x3C000000 +#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWQOS_SHIFT 26 + +/**** spi_mst_conf_0 register ****/ +/* + * Sets the SPI master Configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SRL (1 << 0) +/* + * Sets the SPI master Configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SCPOL (1 << 1) +/* + * Sets the SPI master Configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SCPH (1 << 2) +/* + * Set the SPI master configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SER_MASK 0x00000078 +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SER_SHIFT 3 +/* + * Set the SPI master configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_BAUD_MASK 0x007FFF80 +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_BAUD_SHIFT 7 +/* + * Sets the SPI master configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_RD_CMD_MASK 0x7F800000 +#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_RD_CMD_SHIFT 23 + +/**** spi_mst_conf_1 register ****/ +/* + * Sets the SPI master Configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_WR_CMD_MASK 0x000000FF +#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_WR_CMD_SHIFT 0 +/* + * Sets the SPI master Configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_ADDR_BYTES_NUM_MASK 0x00000700 +#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_ADDR_BYTES_NUM_SHIFT 8 +/* + * Sets the SPI master Configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_TMODE_MASK 0x00001800 +#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_TMODE_SHIFT 11 +/* + * Sets the SPI master Configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_FAST_RD (1 << 13) + +/**** spi_slv_conf_0 register ****/ +/* + * Sets the SPI slave configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_BAUD_MASK 0x0000FFFF +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_BAUD_SHIFT 0 +/* Value. The reset value is according to bootstrap. */ +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SCPOL (1 << 16) +/* Value. The reset value is according to bootstrap. */ +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SCPH (1 << 17) +/* + * Sets the SPI slave configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SER_MASK 0x03FC0000 +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SER_SHIFT 18 +/* + * Sets the SPI slave configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SRL (1 << 26) +/* + * Sets the SPI slave configuration. For details see the SPI section in the + * documentation. + */ +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_TMODE_MASK 0x18000000 +#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_TMODE_SHIFT 27 + +/**** apb_mem_conf_int register ****/ +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_PBS_WRR_CNT_MASK 0x00000007 +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_PBS_WRR_CNT_SHIFT 0 +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_I2C_PLD_APB_MIX_ARB (1 << 3) +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_SPI_DBG_APB_MIX_ARB (1 << 4) +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_SPI_MST_APB_MIX_ARB (1 << 5) +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_I2C_PLD_CLEAR_FSM (1 << 6) +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_SPI_DBG_CLEAR_FSM (1 << 7) +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_SPI_MST_CLEAR_FSM (1 << 8) +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_PBS_AXI_FSM_CLEAR (1 << 9) +/* Value-- internal */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_PBS_AXI_FIFOS_CLEAR (1 << 10) +/* Enables parity protection on the integrated SRAM. */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_BOOTROM_PARITY_EN (1 << 11) +/* + * When set, reports a slave error whenthe slave returns an AXI slave error, for + * configuration access to the internal configuration space. + */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_RD_SLV_ERR_EN (1 << 12) +/* + * When set, reports a decode error when timeout has occurred for configuration + * access to the internal configuration space. + */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_RD_DEC_ERR_EN (1 << 13) +/* + * When set, reports a slave error, when the slave returns an AXI slave error, + * for configuration access to the internal configuration space. + */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_WR_SLV_ERR_EN (1 << 14) +/* + * When set, reports a decode error when timeout has occurred for configuration + * access to the internal configuration space. + */ +#define PBS_UNIT_APB_MEM_CONF_INT_CFG_WR_DEC_ERR_EN (1 << 15) + +/**** sb_int_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_SB_INT_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_SB_INT_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_SB_INT_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_SB_INT_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_SB_INT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_SB_INT_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** ufc_pbs_parity_err_high register ****/ +/* + * Address latch in the case of a parity error in the Flash Controller internal + * memories. + */ +#define PBS_UNIT_UFC_PBS_PARITY_ERR_HIGH_ADDR_MASK 0x000000FF +#define PBS_UNIT_UFC_PBS_PARITY_ERR_HIGH_ADDR_SHIFT 0 + +/**** chip_id register ****/ +/* [15:0] : Dev Rev ID */ +#define PBS_UNIT_CHIP_ID_DEV_REV_ID_MASK 0x0000FFFF +#define PBS_UNIT_CHIP_ID_DEV_REV_ID_SHIFT 0 +/* [31:16] : 0x0 - Dev ID */ +#define PBS_UNIT_CHIP_ID_DEV_ID_MASK 0xFFFF0000 +#define PBS_UNIT_CHIP_ID_DEV_ID_SHIFT 16 + +#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE 0 +#define PBS_UNIT_CHIP_ID_DEV_ID_PEAKROCK 1 +#define PBS_UNIT_CHIP_ID_DEV_ID_COYOTE 2 + +/**** uart0_conf_status register ****/ +/* + * Conf: + * // [0] -- DSR_N RW bit + * // [1] -- DCD_N RW bit + * // [2] -- RI_N bit + * // [3] -- dma_tx_ack_n + * // [4] -- dma_rx_ack_n + */ +#define PBS_UNIT_UART0_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_UART0_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: + * // [16] -- dtr_n RO bit + * // [17] -- OUT1_N RO bit + * // [18] -- OUT2_N RO bit + * // [19] -- dma_tx_req_n RO bit + * // [20] -- dma_tx_single_n RO bit + * // [21] -- dma_rx_req_n RO bit + * // [22] -- dma_rx_single_n RO bit + * // [23] -- uart_lp_req_pclk RO bit + * // [24] -- baudout_n RO bit + */ +#define PBS_UNIT_UART0_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_UART0_CONF_STATUS_STATUS_SHIFT 16 + +/**** uart1_conf_status register ****/ +/* + * Conf: // [0] -- DSR_N RW bit // [1] -- DCD_N RW bit // [2] -- RI_N bit // [3] + * -- dma_tx_ack_n // [4] - dma_rx_ack_n + */ +#define PBS_UNIT_UART1_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_UART1_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: // [16] -- dtr_n RO bit // [17] -- OUT1_N RO bit // [18] -- OUT2_N RO + * bit // [19] -- dma_tx_req_n RO bit // [20] -- dma_tx_single_n RO bit // [21] + * -- dma_rx_req_n RO bit // [22] -- dma_rx_single_n RO bit // [23] -- + * uart_lp_req_pclk RO bit // [24] -- baudout_n RO bit + */ +#define PBS_UNIT_UART1_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_UART1_CONF_STATUS_STATUS_SHIFT 16 + +/**** uart2_conf_status register ****/ +/* + * Conf: // [0] -- DSR_N RW bit // [1] -- DCD_N RW bit // [2] -- RI_N bit // [3] + * -- dma_tx_ack_n // [4] - dma_rx_ack_n + */ +#define PBS_UNIT_UART2_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_UART2_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: // [16] -- dtr_n RO bit // [17] -- OUT1_N RO bit // [18] -- OUT2_N RO + * bit // [19] -- dma_tx_req_n RO bit // [20] -- dma_tx_single_n RO bit // [21] + * -- dma_rx_req_n RO bit // [22] -- dma_rx_single_n RO bit // [23] -- + * uart_lp_req_pclk RO bit // [24] -- baudout_n RO bit + */ +#define PBS_UNIT_UART2_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_UART2_CONF_STATUS_STATUS_SHIFT 16 + +/**** uart3_conf_status register ****/ +/* + * Conf: // [0] -- DSR_N RW bit // [1] -- DCD_N RW bit // [2] -- RI_N bit // [3] + * -- dma_tx_ack_n // [4] - dma_rx_ack_n + */ +#define PBS_UNIT_UART3_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_UART3_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: // [16] -- dtr_n RO bit // [17] -- OUT1_N RO bit // [18] -- OUT2_N RO + * bit // [19] -- dma_tx_req_n RO bit // [20] -- dma_tx_single_n RO bit // [21] + * -- dma_rx_req_n RO bit // [22] -- dma_rx_single_n RO bit // [23] -- + * uart_lp_req_pclk RO bit // [24] -- baudout_n RO bit + */ +#define PBS_UNIT_UART3_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_UART3_CONF_STATUS_STATUS_SHIFT 16 + +/**** gpio0_conf_status register ****/ +/* + * Cntl: + * // [7:0] nGPAFEN; // from regfile + * // [15:8] GPAFOUT; // from regfile + */ +#define PBS_UNIT_GPIO0_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_GPIO0_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: + * // [24:16] GPAFIN; // to regfile + */ +#define PBS_UNIT_GPIO0_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_GPIO0_CONF_STATUS_STATUS_SHIFT 16 + +/**** gpio1_conf_status register ****/ +/* + * Cntl: + * // [7:0] nGPAFEN; // from regfile + * // [15:8] GPAFOUT; // from regfile + */ +#define PBS_UNIT_GPIO1_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_GPIO1_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: + * // [24:16] GPAFIN; // to regfile + */ +#define PBS_UNIT_GPIO1_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_GPIO1_CONF_STATUS_STATUS_SHIFT 16 + +/**** gpio2_conf_status register ****/ +/* + * Cntl: + * // [7:0] nGPAFEN; // from regfile + * // [15:8] GPAFOUT; // from regfile + */ +#define PBS_UNIT_GPIO2_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_GPIO2_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: + * // [24:16] GPAFIN; // to regfile + */ +#define PBS_UNIT_GPIO2_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_GPIO2_CONF_STATUS_STATUS_SHIFT 16 + +/**** gpio3_conf_status register ****/ +/* + * Cntl: + * // [7:0] nGPAFEN; // from regfile + * // [15:8] GPAFOUT; // from regfile + */ +#define PBS_UNIT_GPIO3_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_GPIO3_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: + * // [24:16] GPAFIN; // to regfile + */ +#define PBS_UNIT_GPIO3_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_GPIO3_CONF_STATUS_STATUS_SHIFT 16 + +/**** gpio4_conf_status register ****/ +/* + * Cntl: + * // [7:0] nGPAFEN; // from regfile + * // [15:8] GPAFOUT; // from regfile + */ +#define PBS_UNIT_GPIO4_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_GPIO4_CONF_STATUS_CONF_SHIFT 0 +/* + * Status: + * // [24:16] GPAFIN; // to regfile + */ +#define PBS_UNIT_GPIO4_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_GPIO4_CONF_STATUS_STATUS_SHIFT 16 + +/**** i2c_gen_conf_status register ****/ +/* + * cntl + * // [0] -- dma_tx_ack + * // [1] -- dma_rx_ack + */ +#define PBS_UNIT_I2C_GEN_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_I2C_GEN_CONF_STATUS_CONF_SHIFT 0 +/* + * Status + * + * // [16] -- dma_tx_req RO bit + * // [17] -- dma_tx_single RO bit + * // [18] -- dma_rx_req RO bit + * // [19] -- dma_rx_single RO bit + */ +#define PBS_UNIT_I2C_GEN_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_I2C_GEN_CONF_STATUS_STATUS_SHIFT 16 + +/**** watch_dog_reset_out register ****/ +/* + * [0] If set to 1'b1, WD0 cannot generate reset_out_n + * [1] If set to 1'b1, WD1 cannot generate reset_out_n + * [2] If set to 1'b1, WD2 cannot generate reset_out_n + * [3] If set to 1'b1, WD3 cannot generate reset_out_n + * [4] If set to 1'b1, WD4 cannot generate reset_out_n + * [5] If set to 1'b1, WD5 cannot generate reset_out_n + * [6] If set to 1'b1, WD6 cannot generate reset_out_n + * [7] If set to 1'b1, WD7 cannot generate reset_out_n + */ +#define PBS_UNIT_WATCH_DOG_RESET_OUT_DISABLE_MASK 0x000000FF +#define PBS_UNIT_WATCH_DOG_RESET_OUT_DISABLE_SHIFT 0 + +/**** otp_cntl register ****/ +/* from reg file Config To bypass the copy from OTPW to OTPR */ +#define PBS_UNIT_OTP_CNTL_IGNORE_OTPW (1 << 0) +/* Not in use.Comes from bond. */ +#define PBS_UNIT_OTP_CNTL_IGNORE_PRELOAD (1 << 1) +/* Margin read from the fuse box */ +#define PBS_UNIT_OTP_CNTL_OTPW_MARGIN_READ (1 << 2) +/* Indicates when OTPis busy. */ +#define PBS_UNIT_OTP_CNTL_OTP_BUSY (1 << 3) + +/**** otp_cfg_0 register ****/ +/* Cfg to OTP cntl. */ +#define PBS_UNIT_OTP_CFG_0_CFG_OTPW_PWRDN_CNT_MASK 0x0000FFFF +#define PBS_UNIT_OTP_CFG_0_CFG_OTPW_PWRDN_CNT_SHIFT 0 +/* Cfg to OTP cntl. */ +#define PBS_UNIT_OTP_CFG_0_CFG_OTPW_READ_CNT_MASK 0xFFFF0000 +#define PBS_UNIT_OTP_CFG_0_CFG_OTPW_READ_CNT_SHIFT 16 + +/**** otp_cfg_1 register ****/ +/* Cfg to OTP cntl. */ +#define PBS_UNIT_OTP_CFG_1_CFG_OTPW_PGM_CNT_MASK 0x0000FFFF +#define PBS_UNIT_OTP_CFG_1_CFG_OTPW_PGM_CNT_SHIFT 0 +/* Cfg to OTP cntl. */ +#define PBS_UNIT_OTP_CFG_1_CFG_OTPW_PREP_CNT_MASK 0xFFFF0000 +#define PBS_UNIT_OTP_CFG_1_CFG_OTPW_PREP_CNT_SHIFT 16 + +/**** otp_cfg_3 register ****/ +/* Cfg to OTP cntl. */ +#define PBS_UNIT_OTP_CFG_3_CFG_OTPW_PS18_CNT_MASK 0x0000FFFF +#define PBS_UNIT_OTP_CFG_3_CFG_OTPW_PS18_CNT_SHIFT 0 +/* Cfg to OTP cntl. */ +#define PBS_UNIT_OTP_CFG_3_CFG_OTPW_PWRUP_CNT_MASK 0xFFFF0000 +#define PBS_UNIT_OTP_CFG_3_CFG_OTPW_PWRUP_CNT_SHIFT 16 + +/**** nb_nic_regs_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** sb_nic_regs_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_RSRVD_SHIFT 6 +/* bar low address 16 MSB bits */ +#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** serdes_mux_multi_0 register ****/ +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_8_MASK 0x00000007 +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_8_SHIFT 0 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_3 (1 << 3) +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_9_MASK 0x00000070 +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_9_SHIFT 4 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_7 (1 << 7) +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_10_MASK 0x00000700 +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_10_SHIFT 8 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_11 (1 << 11) +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_11_MASK 0x00007000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_11_SHIFT 12 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_15 (1 << 15) +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_12_MASK 0x00030000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_12_SHIFT 16 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_13_MASK 0x000C0000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_13_SHIFT 18 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_14_MASK 0x00300000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_14_SHIFT 20 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_15_MASK 0x00C00000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_15_SHIFT 22 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_MASK 0xFF000000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_SHIFT 24 + +/* + * 2'b01 - select sata_b[0] + * 2'b10 - select eth_a[0] + */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_8_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_8_SHIFT 0 +/* + * 3'b001 - select sata_b[1] + * 3'b010 - select eth_b[0] + * 3'b100 - select eth_a[1] + */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_9_MASK 0x00000070 +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_9_SHIFT 4 +/* + * 3'b001 - select sata_b[2] + * 3'b010 - select eth_c[0] + * 3'b100 - select eth_a[2] + */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_10_MASK 0x00000700 +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_10_SHIFT 8 +/* + * 3'b001 - select sata_b[3] + * 3'b010 - select eth_d[0] + * 3'b100 - select eth_a[3] + */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_11_MASK 0x00007000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_11_SHIFT 12 +/* + * 2'b01 - select eth_a[0] + * 2'b10 - select sata_a[0] + */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_12_MASK 0x00030000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_12_SHIFT 16 +/* + * 3'b001 - select eth_b[0] + * 3'b010 - select eth_c[1] + * 3'b100 - select sata_a[1] + */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_13_MASK 0x00700000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_13_SHIFT 20 +/* + * 3'b001 - select eth_a[0] + * 3'b010 - select eth_c[2] + * 3'b100 - select sata_a[2] + */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_14_MASK 0x07000000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_14_SHIFT 24 +/* + * 3'b001 - select eth_d[0] + * 3'b010 - select eth_c[3] + * 3'b100 - select sata_a[3] + */ +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_15_MASK 0x70000000 +#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_15_SHIFT 28 + +/**** serdes_mux_multi_1 register ****/ +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_A_0_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_A_0_SHIFT 0 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_3_2_MASK 0x0000000C +#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_3_2_SHIFT 2 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_B_0_MASK 0x00000070 +#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_B_0_SHIFT 4 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_7 (1 << 7) +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_C_0_MASK 0x00000300 +#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_C_0_SHIFT 8 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_11_10_MASK 0x00000C00 +#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_11_10_SHIFT 10 +/* SerDes one hot mux control. For details see datasheet. */ +#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_D_0_MASK 0x00007000 +#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_D_0_SHIFT 12 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_MASK 0xFFFF8000 +#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_SHIFT 15 + +/**** pbs_ulpi_mux_conf register ****/ +/* + * Value 0 - Select dedicated pins for the USB-1 inputs. + * Value 1 - Select PBS mux pins for the USB-1 inputs. + * [0] ULPI_B_CLK + * [1] ULPI_B_DIR + * [2] ULPI_B_NXT + * [10:3] ULPI_B_DATA[7:0] + */ +#define PBS_UNIT_PBS_ULPI_MUX_CONF_SEL_UPLI_IN_PBSMUX_MASK 0x000007FF +#define PBS_UNIT_PBS_ULPI_MUX_CONF_SEL_UPLI_IN_PBSMUX_SHIFT 0 +/* + * [3] - Force to zero + * [2] == 1 - Force register selection + * [1 : 0] -Binary selection of the input in bypass mode + */ +#define PBS_UNIT_PBS_ULPI_MUX_CONF_REG_MDIO_BYPASS_SEL_MASK 0x0000F000 +#define PBS_UNIT_PBS_ULPI_MUX_CONF_REG_MDIO_BYPASS_SEL_SHIFT 12 +/* + * [0] Sets the clk_ulpi OE for USB0, 1'b0 set to input, 1'b1 set to output. + * [1] Sets the clk_ulpi OE for USB01, 1'b0 set to input, 1'b1 set to output. + */ +#define PBS_UNIT_PBS_ULPI_MUX_CONF_RSRVD_MASK 0xFFFF0000 +#define PBS_UNIT_PBS_ULPI_MUX_CONF_RSRVD_SHIFT 16 + +/**** wr_once_dbg_dis_ovrd_reg register ****/ +/* This register can be written only once. Use in the secure boot process. */ +#define PBS_UNIT_WR_ONCE_DBG_DIS_OVRD_REG_WR_ONCE_DBG_DIS_OVRD (1 << 0) + +#define PBS_UNIT_WR_ONCE_DBG_DIS_OVRD_REG_RSRVD_MASK 0xFFFFFFFE +#define PBS_UNIT_WR_ONCE_DBG_DIS_OVRD_REG_RSRVD_SHIFT 1 + +/**** gpio5_conf_status register ****/ +/* + * Cntl: // [7:0] nGPAFEN; // from regfile // [15:8] GPAFOUT; // from regfile + */ +#define PBS_UNIT_GPIO5_CONF_STATUS_CONF_MASK 0x0000FFFF +#define PBS_UNIT_GPIO5_CONF_STATUS_CONF_SHIFT 0 +/* Status: // [24:16] GPAFIN; // to regfile */ +#define PBS_UNIT_GPIO5_CONF_STATUS_STATUS_MASK 0xFFFF0000 +#define PBS_UNIT_GPIO5_CONF_STATUS_STATUS_SHIFT 16 + +/**** pcie_mem3_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_MEM3_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_MEM3_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_MEM3_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_MEM3_BAR_LOW_RSRVD_SHIFT 6 +/* Reserved */ +#define PBS_UNIT_PCIE_MEM3_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_MEM3_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_mem4_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_MEM4_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_MEM4_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_MEM4_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_MEM4_BAR_LOW_RSRVD_SHIFT 6 +/* Reserved */ +#define PBS_UNIT_PCIE_MEM4_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_MEM4_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_mem5_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_MEM5_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_MEM5_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_MEM5_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_MEM5_BAR_LOW_RSRVD_SHIFT 6 +/* Reserved */ +#define PBS_UNIT_PCIE_MEM5_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_MEM5_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_ext_ecam3_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_RSRVD_SHIFT 6 +/* Reserved */ +#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_ext_ecam4_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_RSRVD_SHIFT 6 +/* Reserved */ +#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pcie_ext_ecam5_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_RSRVD_SHIFT 6 +/* Reserved */ +#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** low_latency_sram_bar_low register ****/ +/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ +#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_WIN_SIZE_MASK 0x0000003F +#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_RSRVD_MASK 0x0000FFC0 +#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_RSRVD_SHIFT 6 +/* Reserved */ +#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 +#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_ADDR_HIGH_SHIFT 16 + +/**** pbs_sb2nb_cfg_dram_remap register ****/ +#define PBS_UNIT_SB2NB_REMAP_BASE_ADDR_SHIFT 5 +#define PBS_UNIT_SB2NB_REMAP_BASE_ADDR_MASK 0x0000FFE0 +#define PBS_UNIT_SB2NB_REMAP_TRANSL_BASE_ADDR_SHIFT 21 +#define PBS_UNIT_SB2NB_REMAP_TRANSL_BASE_ADDR_MASK 0xFFE00000 + +/* For remapping are used bits [39 - 29] of DRAM 40bit Physical address */ +#define PBS_UNIT_DRAM_SRC_REMAP_BASE_ADDR_SHIFT 29 +#define PBS_UNIT_DRAM_DST_REMAP_BASE_ADDR_SHIFT 29 +#define PBS_UNIT_DRAM_REMAP_BASE_ADDR_MASK 0xFFE0000000UL + + +/**** serdes_mux_eth register ****/ +/* + * 2'b01 - eth_a[0] from serdes_8 + * 2'b10 - eth_a[0] from serdes_14 + */ +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_0_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_0_SHIFT 0 +/* + * 2'b01 - eth_b[0] from serdes_9 + * 2'b10 - eth_b[0] from serdes_13 + */ +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_B_0_MASK 0x00000030 +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_B_0_SHIFT 4 +/* + * 2'b01 - eth_c[0] from serdes_10 + * 2'b10 - eth_c[0] from serdes_12 + */ +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_0_MASK 0x00000300 +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_0_SHIFT 8 +/* + * 2'b01 - eth_d[0] from serdes_11 + * 2'b10 - eth_d[0] from serdes_15 + */ +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_D_0_MASK 0x00003000 +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_D_0_SHIFT 12 +/* which lane's is master clk */ +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_ICK_MASTER_MASK 0x00030000 +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_ICK_MASTER_SHIFT 16 +/* which lane's is master clk */ +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_ICK_MASTER_MASK 0x00300000 +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_ICK_MASTER_SHIFT 20 +/* enable xlaui on eth a */ +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_XLAUI_ENABLE (1 << 24) +/* enable xlaui on eth c */ +#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_XLAUI_ENABLE (1 << 28) + +/**** serdes_mux_pcie register ****/ +/* + * 2'b01 - select pcie_b[0] from serdes 2 + * 2'b10 - select pcie_b[0] from serdes 4 + */ +#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_0_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_0_SHIFT 0 +/* + * 2'b01 - select pcie_b[1] from serdes 3 + * 2'b10 - select pcie_b[1] from serdes 5 + */ +#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_1_MASK 0x00000030 +#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_1_SHIFT 4 +/* + * 2'b01 - select pcie_d[0] from serdes 10 + * 2'b10 - select pcie_d[0] from serdes 12 + */ +#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_0_MASK 0x00000300 +#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_0_SHIFT 8 +/* + * 2'b01 - select pcie_d[1] from serdes 11 + * 2'b10 - select pcie_d[1] from serdes 13 + */ +#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_1_MASK 0x00003000 +#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_1_SHIFT 12 + +/**** serdes_mux_sata register ****/ +/* + * 2'b01 - select sata_a from serdes group 1 + * 2'b10 - select sata_a from serdes group 3 + */ +#define PBS_UNIT_SERDES_MUX_SATA_SELECT_OH_SATA_A_MASK 0x00000003 +#define PBS_UNIT_SERDES_MUX_SATA_SELECT_OH_SATA_A_SHIFT 0 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_SATA_RESERVED_3_2_MASK 0x0000000C +#define PBS_UNIT_SERDES_MUX_SATA_RESERVED_3_2_SHIFT 2 +/* Reserved */ +#define PBS_UNIT_SERDES_MUX_SATA_RESERVED_MASK 0xFFFFFFF0 +#define PBS_UNIT_SERDES_MUX_SATA_RESERVED_SHIFT 4 + +/**** bar1_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar1_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar2_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar2_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar3_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar3_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar4_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar4_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar5_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar5_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar6_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar6_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar7_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar7_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar8_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar8_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar9_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar9_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_REMAP_ADDR_HIGH_SHIFT 12 + +/**** bar10_orig register ****/ +/* + * Window size = 2 ^ (11 + win_size). + * Zero value: disable the window. + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_WIN_SIZE_MASK 0x00000007 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_WIN_SIZE_SHIFT 0 +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_RSRVD_MASK 0x00000FF8 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_RSRVD_SHIFT 3 +/* + * offset within the SRAM, in resolution of 4KB. + * Only offsets which are inside the boundaries of the SRAM bar are allowed + */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_ADDR_HIGH_SHIFT 12 + +/**** bar10_remap register ****/ +/* Reserved fields */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_REMAP_RSRVD_MASK 0x00000FFF +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_REMAP_RSRVD_SHIFT 0 +/* remapped address */ +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_REMAP_ADDR_HIGH_MASK 0xFFFFF000 +#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_REMAP_ADDR_HIGH_SHIFT 12 + +/**** cpu register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_CPU_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_DRAM_SHIFT 28 + +/**** cpu_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_DRAM_SHIFT 28 + +/**** debug_nb register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_DRAM_SHIFT 28 + +/**** debug_nb_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_DRAM_SHIFT 28 + +/**** debug_sb register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_DRAM_SHIFT 28 + +/**** debug_sb_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_DRAM_SHIFT 28 + +/**** eth_0 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_DRAM_SHIFT 28 + +/**** eth_0_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_DRAM_SHIFT 28 + +/**** eth_1 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_DRAM_SHIFT 28 + +/**** eth_1_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_DRAM_SHIFT 28 + +/**** eth_2 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_DRAM_SHIFT 28 + +/**** eth_2_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_DRAM_SHIFT 28 + +/**** eth_3 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_DRAM_SHIFT 28 + +/**** eth_3_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_DRAM_SHIFT 28 + +/**** sata_0 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_DRAM_SHIFT 28 + +/**** sata_0_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_DRAM_SHIFT 28 + +/**** sata_1 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_DRAM_SHIFT 28 + +/**** sata_1_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_DRAM_SHIFT 28 + +/**** crypto_0 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_DRAM_SHIFT 28 + +/**** crypto_0_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_DRAM_SHIFT 28 + +/**** crypto_1 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_DRAM_SHIFT 28 + +/**** crypto_1_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_DRAM_SHIFT 28 + +/**** pcie_0 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_DRAM_SHIFT 28 + +/**** pcie_0_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_DRAM_SHIFT 28 + +/**** pcie_1 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_DRAM_SHIFT 28 + +/**** pcie_1_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_DRAM_SHIFT 28 + +/**** pcie_2 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_DRAM_SHIFT 28 + +/**** pcie_2_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_DRAM_SHIFT 28 + +/**** pcie_3 register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_DRAM_SHIFT 28 + +/**** pcie_3_mask register ****/ +/* map transactions according to address decoding */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_NO_ENFORCEMENT_MASK 0x0000000F +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_NO_ENFORCEMENT_SHIFT 0 +/* map transactions to pcie_0 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_0_MASK 0x000000F0 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_0_SHIFT 4 +/* map transactions to pcie_1 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_1_MASK 0x00000F00 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_1_SHIFT 8 +/* map transactions to pcie_2 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_2_MASK 0x0000F000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_2_SHIFT 12 +/* map transactions to pcie_3 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_3_MASK 0x000F0000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_3_SHIFT 16 +/* map transactions to pcie_4 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_4_MASK 0x00F00000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_4_SHIFT 20 +/* map transactions to pcie_5 */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_5_MASK 0x0F000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_5_SHIFT 24 +/* map transactions to dram */ +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_DRAM_MASK 0xF0000000 +#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_DRAM_SHIFT 28 + +/**** latch register ****/ +/* + * Software clears this bit before any bar update, and set it after all bars + * updated. + */ +#define PBS_TARGET_ID_ENFORCEMENT_LATCH_ENABLE (1 << 0) + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_PBS_REGS_H__ */ + +/** @} end of ... group */ + + diff --git a/al_hal_pcie.c b/al_hal_pcie.c new file mode 100644 index 000000000000..3a221d365732 --- /dev/null +++ b/al_hal_pcie.c @@ -0,0 +1,2788 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include "al_hal_pcie.h" +#include "al_hal_pbs_regs.h" +#include "al_hal_unit_adapter_regs.h" + +/** + * Parameter definitions + */ +#define AL_PCIE_AXI_REGS_OFFSET 0x0 + +#define AL_PCIE_LTSSM_STATE_L0 0x11 +#define AL_PCIE_LTSSM_STATE_L0S 0x12 +#define AL_PCIE_DEVCTL_PAYLOAD_128B 0x00 +#define AL_PCIE_DEVCTL_PAYLOAD_256B 0x20 + +#define AL_PCIE_SECBUS_DEFAULT 0x1 +#define AL_PCIE_SUBBUS_DEFAULT 0x1 +#define AL_PCIE_LINKUP_WAIT_INTERVAL 50 /* measured in usec */ +#define AL_PCIE_LINKUP_WAIT_INTERVALS_PER_SEC 20 + +#define AL_PCIE_LINKUP_RETRIES 8 + +#define AL_PCIE_MAX_32_MEMORY_BAR_SIZE (0x100000000ULL) +#define AL_PCIE_MIN_MEMORY_BAR_SIZE (1 << 12) +#define AL_PCIE_MIN_IO_BAR_SIZE (1 << 8) + +/** + * inbound header credits and outstanding outbound reads defaults + */ +/** RC - Revisions 1/2 */ +#define AL_PCIE_REV_1_2_RC_OB_OS_READS_DEFAULT (8) +#define AL_PCIE_REV_1_2_RC_NOF_CPL_HDR_DEFAULT (41) +#define AL_PCIE_REV_1_2_RC_NOF_NP_HDR_DEFAULT (25) +#define AL_PCIE_REV_1_2_RC_NOF_P_HDR_DEFAULT (31) +/** EP - Revisions 1/2 */ +#define AL_PCIE_REV_1_2_EP_OB_OS_READS_DEFAULT (15) +#define AL_PCIE_REV_1_2_EP_NOF_CPL_HDR_DEFAULT (76) +#define AL_PCIE_REV_1_2_EP_NOF_NP_HDR_DEFAULT (6) +#define AL_PCIE_REV_1_2_EP_NOF_P_HDR_DEFAULT (15) +/** RC - Revision 3 */ +#define AL_PCIE_REV_3_RC_OB_OS_READS_DEFAULT (32) +#define AL_PCIE_REV_3_RC_NOF_CPL_HDR_DEFAULT (161) +#define AL_PCIE_REV_3_RC_NOF_NP_HDR_DEFAULT (38) +#define AL_PCIE_REV_3_RC_NOF_P_HDR_DEFAULT (60) +/** EP - Revision 3 */ +#define AL_PCIE_REV_3_EP_OB_OS_READS_DEFAULT (32) +#define AL_PCIE_REV_3_EP_NOF_CPL_HDR_DEFAULT (161) +#define AL_PCIE_REV_3_EP_NOF_NP_HDR_DEFAULT (38) +#define AL_PCIE_REV_3_EP_NOF_P_HDR_DEFAULT (60) + +/** + * MACROS + */ +#define AL_PCIE_PARSE_LANES(v) (((1 << v) - 1) << \ + PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT) + +/** + * Static functions + */ +static void +al_pcie_port_wr_to_ro_set(struct al_pcie_port *pcie_port, al_bool enable) +{ + /* when disabling writes to RO, make sure any previous writes to + * config space were committed + */ + if (enable == AL_FALSE) + al_local_data_memory_barrier(); + + al_reg_write32(&pcie_port->regs->port_regs->rd_only_wr_en, + (enable == AL_TRUE) ? 1 : 0); + + /* when enabling writes to RO, make sure it is committed before trying + * to write to RO config space + */ + if (enable == AL_TRUE) + al_local_data_memory_barrier(); +} + +/** helper function to access dbi_cs2 registers */ +static void +al_reg_write32_dbi_cs2( + struct al_pcie_port *pcie_port, + uint32_t *offset, + uint32_t val) +{ + uintptr_t cs2_bit = + (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? 0x4000 : 0x1000; + + al_reg_write32((uint32_t *)((uintptr_t)offset | cs2_bit), val); +} + +static unsigned int +al_pcie_speed_gen_code(enum al_pcie_link_speed speed) +{ + if (speed == AL_PCIE_LINK_SPEED_GEN1) + return 1; + if (speed == AL_PCIE_LINK_SPEED_GEN2) + return 2; + if (speed == AL_PCIE_LINK_SPEED_GEN3) + return 3; + /* must not be reached */ + return 0; +} + +static inline void +al_pcie_port_link_speed_ctrl_set( + struct al_pcie_port *pcie_port, + enum al_pcie_link_speed max_speed) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); + + if (max_speed != AL_PCIE_LINK_SPEED_DEFAULT) { + uint16_t max_speed_val = (uint16_t)al_pcie_speed_gen_code(max_speed); + al_reg_write32_masked( + (uint32_t __iomem *)(regs->core_space[0].pcie_link_cap_base), + 0xF, max_speed_val); + al_reg_write32_masked( + (uint32_t __iomem *)(regs->core_space[0].pcie_cap_base + + (AL_PCI_EXP_LNKCTL2 >> 2)), + 0xF, max_speed_val); + } + + al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); +} + +static int +al_pcie_port_link_config( + struct al_pcie_port *pcie_port, + const struct al_pcie_link_params *link_params) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint8_t max_lanes = pcie_port->max_lanes; + + if ((link_params->max_payload_size != AL_PCIE_MPS_DEFAULT) && + (link_params->max_payload_size != AL_PCIE_MPS_128) && + (link_params->max_payload_size != AL_PCIE_MPS_256)) { + al_err("PCIe %d: unsupported Max Payload Size (%u)\n", + pcie_port->port_id, link_params->max_payload_size); + return -EINVAL; + } + + al_dbg("PCIe %d: link config: max speed gen %d, max lanes %d, reversal %s\n", + pcie_port->port_id, link_params->max_speed, + pcie_port->max_lanes, link_params->enable_reversal? "enable" : "disable"); + + al_pcie_port_link_speed_ctrl_set(pcie_port, link_params->max_speed); + + /* Change Max Payload Size, if needed. + * The Max Payload Size is only valid for PF0. + */ + if (link_params->max_payload_size != AL_PCIE_MPS_DEFAULT) + al_reg_write32_masked(regs->core_space[0].pcie_dev_ctrl_status, + PCIE_PORT_DEV_CTRL_STATUS_MPS_MASK, + link_params->max_payload_size << + PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT); + + /** Snap from PCIe core spec: + * Link Mode Enable. Sets the number of lanes in the link that you want + * to connect to the link partner. When you have unused lanes in your + * system, then you must change the value in this register to reflect + * the number of lanes. You must also change the value in the + * "Predetermined Number of Lanes" field of the "Link Width and Speed + * Change Control Register". + * 000001: x1 + * 000011: x2 + * 000111: x4 + * 001111: x8 + * 011111: x16 + * 111111: x32 (not supported) + */ + al_reg_write32_masked(®s->port_regs->gen2_ctrl, + PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_MASK, + max_lanes << PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_SHIFT); + al_reg_write32_masked(®s->port_regs->port_link_ctrl, + PCIE_PORT_LINK_CTRL_LINK_CAPABLE_MASK, + (max_lanes + (max_lanes-1)) + << PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT); + + /* TODO: add support for reversal mode */ + if (link_params->enable_reversal) { + al_err("PCIe %d: enabling reversal mode not implemented\n", + pcie_port->port_id); + return -ENOSYS; + } + return 0; +} + +static void +al_pcie_port_ram_parity_int_config( + struct al_pcie_port *pcie_port, + al_bool enable) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_reg_write32(®s->app.parity->en_core, + (enable == AL_TRUE) ? 0xffffffff : 0x0); + + al_reg_write32_masked(®s->app.int_grp_b->mask, + PCIE_W_INT_GRP_B_CAUSE_B_PARITY_ERROR_CORE, + (enable != AL_TRUE) ? + PCIE_W_INT_GRP_B_CAUSE_B_PARITY_ERROR_CORE : 0); + +} + +static void +al_pcie_port_axi_parity_int_config( + struct al_pcie_port *pcie_port, + al_bool enable) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t parity_enable_mask = 0xffffffff; + + /** + * Addressing RMN: 5603 + * + * RMN description: + * u4_ram2p signal false parity error + * + * Software flow: + * Disable parity check for this memory + */ + if (pcie_port->rev_id >= AL_PCIE_REV_ID_3) + parity_enable_mask &= ~PCIE_AXI_PARITY_EN_AXI_U4_RAM2P; + + al_reg_write32(regs->axi.parity.en_axi, + (enable == AL_TRUE) ? parity_enable_mask : 0x0); + + if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + al_reg_write32_masked(regs->axi.ctrl.global, + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR | + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD | + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV | + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR, + (enable == AL_TRUE) ? + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR | + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD | + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV | + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR : + PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV); + } else { + al_reg_write32_masked(regs->axi.ctrl.global, + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR | + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD | + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV | + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR, + (enable == AL_TRUE) ? + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR | + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD | + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV | + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR : + PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV); + } + + al_reg_write32_masked(®s->axi.int_grp_a->mask, + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_DATA_PATH_RD | + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_RD | + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_WR | + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_DATA_WR | + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERROR_AXI, + (enable != AL_TRUE) ? + (PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_DATA_PATH_RD | + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_RD | + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_WR | + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_DATA_WR | + PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERROR_AXI) : 0); +} + +static void +al_pcie_port_relaxed_pcie_ordering_config( + struct al_pcie_port *pcie_port, + struct al_pcie_relaxed_ordering_params *relaxed_ordering_params) +{ + struct al_pcie_regs *regs = pcie_port->regs; + enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); + /** + * Default: + * - RC: Rx relaxed ordering only + * - EP: TX relaxed ordering only + */ + al_bool tx_relaxed_ordering = (op_mode == AL_PCIE_OPERATING_MODE_RC ? AL_FALSE : AL_TRUE); + al_bool rx_relaxed_ordering = (op_mode == AL_PCIE_OPERATING_MODE_RC ? AL_TRUE : AL_FALSE); + + if (relaxed_ordering_params) { + tx_relaxed_ordering = relaxed_ordering_params->enable_tx_relaxed_ordering; + rx_relaxed_ordering = relaxed_ordering_params->enable_rx_relaxed_ordering; + } + + /** PCIe ordering: + * - disable outbound completion must be stalled behind outbound write + * ordering rule enforcement is disabled for root-port + * - disables read completion on the master port push slave writes for end-point + */ + al_reg_write32_masked( + regs->axi.ordering.pos_cntl, + PCIE_AXI_POS_ORDER_BYPASS_CMPL_AFTER_WR_FIX | + PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_DIS | + PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_SUPPORT_INTERLV_DIS | + PCIE_AXI_POS_ORDER_SEGMENT_BUFFER_DONT_WAIT_FOR_P_WRITES, + (tx_relaxed_ordering ? + (PCIE_AXI_POS_ORDER_BYPASS_CMPL_AFTER_WR_FIX | + PCIE_AXI_POS_ORDER_SEGMENT_BUFFER_DONT_WAIT_FOR_P_WRITES) : 0) | + (rx_relaxed_ordering ? + (PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_DIS | + PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_SUPPORT_INTERLV_DIS) : 0)); +} + +static int +al_pcie_rev_id_get( + void __iomem *pbs_reg_base, + void __iomem *pcie_reg_base) +{ + uint32_t chip_id; + uint16_t chip_id_dev; + uint8_t rev_id; + struct al_pbs_regs *pbs_regs = pbs_reg_base; + + /* get revision ID from PBS' chip_id register */ + chip_id = al_reg_read32(&pbs_regs->unit.chip_id); + chip_id_dev = AL_REG_FIELD_GET(chip_id, + PBS_UNIT_CHIP_ID_DEV_ID_MASK, + PBS_UNIT_CHIP_ID_DEV_ID_SHIFT); + + if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE) { + rev_id = AL_REG_FIELD_GET( + chip_id, + PBS_UNIT_CHIP_ID_DEV_REV_ID_MASK, + PBS_UNIT_CHIP_ID_DEV_REV_ID_SHIFT); + } else if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_PEAKROCK) { + struct al_pcie_revx_regs __iomem *regs = + (struct al_pcie_revx_regs __iomem *)pcie_reg_base; + uint32_t dev_id; + + dev_id = al_reg_read32(®s->axi.device_id.device_rev_id) & + PCIE_AXI_DEVICE_ID_REG_DEV_ID_MASK; + if (dev_id == PCIE_AXI_DEVICE_ID_REG_DEV_ID_X4) { + rev_id = AL_PCIE_REV_ID_2; + } else if (dev_id == PCIE_AXI_DEVICE_ID_REG_DEV_ID_X8) { + rev_id = AL_PCIE_REV_ID_3; + } else { + al_warn("%s: Revision ID is unknown\n", + __func__); + return -EINVAL; + } + } else { + al_warn("%s: Revision ID is unknown\n", + __func__); + return -EINVAL; + } + return rev_id; +} + +static int +al_pcie_port_lat_rply_timers_config( + struct al_pcie_port *pcie_port, + const struct al_pcie_latency_replay_timers *lat_rply_timers) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t reg = 0; + + AL_REG_FIELD_SET(reg, 0xFFFF, 0, lat_rply_timers->round_trip_lat_limit); + AL_REG_FIELD_SET(reg, 0xFFFF0000, 16, lat_rply_timers->replay_timer_limit); + + al_reg_write32(®s->port_regs->ack_lat_rply_timer, reg); + return 0; +} + +static void +al_pcie_ib_hcrd_os_ob_reads_config_default( + struct al_pcie_port *pcie_port) +{ + + struct al_pcie_ib_hcrd_os_ob_reads_config ib_hcrd_os_ob_reads_config; + + switch (al_pcie_operating_mode_get(pcie_port)) { + case AL_PCIE_OPERATING_MODE_RC: + if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads = + AL_PCIE_REV_3_RC_OB_OS_READS_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_cpl_hdr = + AL_PCIE_REV_3_RC_NOF_CPL_HDR_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_np_hdr = + AL_PCIE_REV_3_RC_NOF_NP_HDR_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_p_hdr = + AL_PCIE_REV_3_RC_NOF_P_HDR_DEFAULT; + } else { + ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads = + AL_PCIE_REV_1_2_RC_OB_OS_READS_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_cpl_hdr = + AL_PCIE_REV_1_2_RC_NOF_CPL_HDR_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_np_hdr = + AL_PCIE_REV_1_2_RC_NOF_NP_HDR_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_p_hdr = + AL_PCIE_REV_1_2_RC_NOF_P_HDR_DEFAULT; + } + break; + + case AL_PCIE_OPERATING_MODE_EP: + if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads = + AL_PCIE_REV_3_EP_OB_OS_READS_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_cpl_hdr = + AL_PCIE_REV_3_EP_NOF_CPL_HDR_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_np_hdr = + AL_PCIE_REV_3_EP_NOF_NP_HDR_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_p_hdr = + AL_PCIE_REV_3_EP_NOF_P_HDR_DEFAULT; + } else { + ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads = + AL_PCIE_REV_1_2_EP_OB_OS_READS_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_cpl_hdr = + AL_PCIE_REV_1_2_EP_NOF_CPL_HDR_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_np_hdr = + AL_PCIE_REV_1_2_EP_NOF_NP_HDR_DEFAULT; + ib_hcrd_os_ob_reads_config.nof_p_hdr = + AL_PCIE_REV_1_2_EP_NOF_P_HDR_DEFAULT; + } + break; + + default: + al_err("PCIe %d: outstanding outbound transactions could not be configured - unknown operating mode\n", + pcie_port->port_id); + al_assert(0); + } + + al_pcie_port_ib_hcrd_os_ob_reads_config(pcie_port, &ib_hcrd_os_ob_reads_config); +}; + +/** return AL_TRUE is link started (LTSSM enabled) and AL_FALSE otherwise */ +static al_bool +al_pcie_is_link_started(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; + + uint32_t port_init = al_reg_read32(regs->app.global_ctrl.port_init); + uint8_t ltssm_en = AL_REG_FIELD_GET(port_init, + PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK, + PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT); + + return ltssm_en; +} + +/** return AL_TRUE if link is up, AL_FALSE otherwise */ +static al_bool +al_pcie_check_link( + struct al_pcie_port *pcie_port, + uint8_t *ltssm_ret) +{ + struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; + uint32_t info_0; + uint8_t ltssm_state; + + info_0 = al_reg_read32(®s->app.debug->info_0); + + ltssm_state = AL_REG_FIELD_GET(info_0, + PCIE_W_DEBUG_INFO_0_LTSSM_STATE_MASK, + PCIE_W_DEBUG_INFO_0_LTSSM_STATE_SHIFT); + + al_dbg("PCIe %d: Port Debug 0: 0x%08x. LTSSM state :0x%x\n", + pcie_port->port_id, info_0, ltssm_state); + + if (ltssm_ret) + *ltssm_ret = ltssm_state; + + if ((ltssm_state == AL_PCIE_LTSSM_STATE_L0) || + (ltssm_state == AL_PCIE_LTSSM_STATE_L0S)) + return AL_TRUE; + return AL_FALSE; +} + +static int +al_pcie_port_gen2_params_config(struct al_pcie_port *pcie_port, + const struct al_pcie_gen2_params *gen2_params) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t gen2_ctrl; + + al_dbg("PCIe %d: Gen2 params config: Tx Swing %s, interrupt on link Eq %s, set Deemphasis %s\n", + pcie_port->port_id, + gen2_params->tx_swing_low ? "Low" : "Full", + gen2_params->tx_compliance_receive_enable? "enable" : "disable", + gen2_params->set_deemphasis? "enable" : "disable"); + + gen2_ctrl = al_reg_read32(®s->port_regs->gen2_ctrl); + + if (gen2_params->tx_swing_low) + AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT); + else + AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT); + + if (gen2_params->tx_compliance_receive_enable) + AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT); + else + AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT); + + if (gen2_params->set_deemphasis) + AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT); + else + AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT); + + al_reg_write32(®s->port_regs->gen2_ctrl, gen2_ctrl); + + return 0; +} + + +static uint16_t +gen3_lane_eq_param_to_val(const struct al_pcie_gen3_lane_eq_params *eq_params) +{ + uint16_t eq_control = 0; + + eq_control = eq_params->downstream_port_transmitter_preset & 0xF; + eq_control |= (eq_params->downstream_port_receiver_preset_hint & 0x7) << 4; + eq_control |= (eq_params->upstream_port_transmitter_preset & 0xF) << 8; + eq_control |= (eq_params->upstream_port_receiver_preset_hint & 0x7) << 12; + + return eq_control; +} + +static int +al_pcie_port_gen3_params_config(struct al_pcie_port *pcie_port, + const struct al_pcie_gen3_params *gen3_params) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t reg = 0; + uint16_t __iomem *lanes_eq_base = (uint16_t __iomem *)(regs->core_space[0].pcie_sec_ext_cap_base + (0xC >> 2)); + int i; + + al_dbg("PCIe %d: Gen3 params config: Equalization %s, interrupt on link Eq %s\n", + pcie_port->port_id, + gen3_params->perform_eq ? "enable" : "disable", + gen3_params->interrupt_enable_on_link_eq_request? "enable" : "disable"); + + if (gen3_params->perform_eq) + AL_REG_BIT_SET(reg, 0); + if (gen3_params->interrupt_enable_on_link_eq_request) + AL_REG_BIT_SET(reg, 1); + + al_reg_write32(regs->core_space[0].pcie_sec_ext_cap_base + (4 >> 2), + reg); + + al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); + + for (i = 0; i < gen3_params->eq_params_elements; i += 2) { + uint32_t eq_control = + (uint32_t)gen3_lane_eq_param_to_val(gen3_params->eq_params + i) | + (uint32_t)gen3_lane_eq_param_to_val(gen3_params->eq_params + i + 1) << 16; + + al_dbg("PCIe %d: Set EQ (0x%08x) for lane %d, %d\n", pcie_port->port_id, eq_control, i, i + 1); + al_reg_write32((uint32_t *)(lanes_eq_base + i), eq_control); + } + + al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); + + reg = al_reg_read32(®s->port_regs->gen3_ctrl); + if (gen3_params->eq_disable) + AL_REG_BIT_SET(reg, PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT); + else + AL_REG_BIT_CLEAR(reg, PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT); + + if (gen3_params->eq_phase2_3_disable) + AL_REG_BIT_SET(reg, PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT); + else + AL_REG_BIT_CLEAR(reg, PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT); + + al_reg_write32(®s->port_regs->gen3_ctrl, reg); + + reg = 0; + AL_REG_FIELD_SET(reg, PCIE_PORT_GEN3_EQ_LF_MASK, + PCIE_PORT_GEN3_EQ_LF_SHIFT, + gen3_params->local_lf); + AL_REG_FIELD_SET(reg, PCIE_PORT_GEN3_EQ_FS_MASK, + PCIE_PORT_GEN3_EQ_FS_SHIFT, + gen3_params->local_fs); + + al_reg_write32(®s->port_regs->gen3_eq_fs_lf, reg); + + reg = 0; + AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_MASK, + PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_SHIFT, + gen3_params->local_lf); + AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_MASK, + PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_SHIFT, + gen3_params->local_fs); + al_reg_write32(regs->axi.conf.zero_lane0, reg); + al_reg_write32(regs->axi.conf.zero_lane1, reg); + al_reg_write32(regs->axi.conf.zero_lane2, reg); + al_reg_write32(regs->axi.conf.zero_lane3, reg); + if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + al_reg_write32(regs->axi.conf.zero_lane4, reg); + al_reg_write32(regs->axi.conf.zero_lane5, reg); + al_reg_write32(regs->axi.conf.zero_lane6, reg); + al_reg_write32(regs->axi.conf.zero_lane7, reg); + } + + /* + * Gen3 EQ Control Register: + * - Preset Request Vector - request 9 + * - Behavior After 24 ms Timeout (when optimal settings are not + * found): Recovery.Equalization.RcvrLock + * - Phase2_3 2 ms Timeout Disable + * - Feedback Mode - Figure Of Merit + */ + reg = 0x00020031; + al_reg_write32(®s->port_regs->gen3_eq_ctrl, reg); + + return 0; +} + +static int +al_pcie_port_tl_credits_config( + struct al_pcie_port *pcie_port, + const struct al_pcie_tl_credits_params *tl_credits __attribute__((__unused__))) +{ + al_err("PCIe %d: transport layer credits config not implemented\n", + pcie_port->port_id); + + return -ENOSYS; + +} + +static int +al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, + const struct al_pcie_pf_config_params *pf_params) +{ + struct al_pcie_port *pcie_port = pcie_pf->pcie_port; + struct al_pcie_regs *regs = pcie_port->regs; + unsigned int pf_num = pcie_pf->pf_num; + int bar_idx; + int ret; + + al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); + + /* Disable D1 and D3hot capabilities */ + if (pf_params->cap_d1_d3hot_dis) + al_reg_write32_masked( + regs->core_space[pf_num].pcie_pm_cap_base, + AL_FIELD_MASK(26, 25) | AL_FIELD_MASK(31, 28), 0); + + /* Disable FLR capability */ + if (pf_params->cap_flr_dis) + al_reg_write32_masked( + regs->core_space[pf_num].pcie_dev_cap_base, + AL_BIT(28), 0); + + /* Disable ASPM capability */ + if (pf_params->cap_aspm_dis) { + al_reg_write32_masked( + regs->core_space[pf_num].pcie_cap_base + (AL_PCI_EXP_LNKCAP >> 2), + AL_PCI_EXP_LNKCAP_ASPMS, 0); + } else if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { + al_warn("%s: ASPM support is enabled, please disable it\n", + __func__); + ret = -EINVAL; + goto done; + } + + if (!pf_params->bar_params_valid) { + ret = 0; + goto done; + } + + for (bar_idx = 0; bar_idx < 6;){ /* bar_idx will be incremented depending on bar type */ + const struct al_pcie_ep_bar_params *params = pf_params->bar_params + bar_idx; + uint32_t mask = 0; + uint32_t ctrl = 0; + uint32_t __iomem *bar_addr = ®s->core_space[pf_num].config_header[(AL_PCI_BASE_ADDRESS_0 >> 2) + bar_idx]; + + if (params->enable) { + uint64_t size = params->size; + + if (params->memory_64_bit) { + const struct al_pcie_ep_bar_params *next_params = params + 1; + /* 64 bars start at even index (BAR0, BAR 2 or BAR 4) */ + if (bar_idx & 1) { + ret = -EINVAL; + goto done; + } + + /* next BAR must be disabled */ + if (next_params->enable) { + ret = -EINVAL; + goto done; + } + + /* 64 bar must be memory bar */ + if (!params->memory_space) { + ret = -EINVAL; + goto done; + } + } else { + if (size > AL_PCIE_MAX_32_MEMORY_BAR_SIZE) + return -EINVAL; + /* 32 bit space can't be prefetchable */ + if (params->memory_is_prefetchable) { + ret = -EINVAL; + goto done; + } + } + + if (params->memory_space) { + if (size < AL_PCIE_MIN_MEMORY_BAR_SIZE) { + al_err("PCIe %d: memory BAR %d: size (0x%llx) less that minimal allowed value\n", + pcie_port->port_id, bar_idx, size); + ret = -EINVAL; + goto done; + } + } else { + /* IO can't be prefetchable */ + if (params->memory_is_prefetchable) { + ret = -EINVAL; + goto done; + } + + if (size < AL_PCIE_MIN_IO_BAR_SIZE) { + al_err("PCIe %d: IO BAR %d: size (0x%llx) less that minimal allowed value\n", + pcie_port->port_id, bar_idx, size); + ret = -EINVAL; + goto done; + } + } + + /* size must be power of 2 */ + if (size & (size - 1)) { + al_err("PCIe %d: BAR %d:size (0x%llx) must be " + "power of 2\n", + pcie_port->port_id, bar_idx, size); + ret = -EINVAL; + goto done; + } + + /* If BAR is 64-bit, disable the next BAR before + * configuring this one + */ + if (params->memory_64_bit) + al_reg_write32_dbi_cs2(pcie_port, bar_addr + 1, 0); + + mask = 1; /* enable bit*/ + mask |= (params->size - 1) & 0xFFFFFFFF; + + al_reg_write32_dbi_cs2(pcie_port, bar_addr , mask); + + if (params->memory_space == AL_FALSE) + ctrl = AL_PCI_BASE_ADDRESS_SPACE_IO; + if (params->memory_64_bit) + ctrl |= AL_PCI_BASE_ADDRESS_MEM_TYPE_64; + if (params->memory_is_prefetchable) + ctrl |= AL_PCI_BASE_ADDRESS_MEM_PREFETCH; + al_reg_write32(bar_addr, ctrl); + + if (params->memory_64_bit) { + mask = ((params->size - 1) >> 32) & 0xFFFFFFFF; + al_reg_write32_dbi_cs2(pcie_port, bar_addr + 1, mask); + } + + } else { + al_reg_write32_dbi_cs2(pcie_port, bar_addr , mask); + } + if (params->enable && params->memory_64_bit) + bar_idx += 2; + else + bar_idx += 1; + } + + if (pf_params->exp_bar_params.enable) { + if (pcie_port->rev_id != AL_PCIE_REV_ID_3) { + al_err("PCIe %d: Expansion BAR enable not supported\n", pcie_port->port_id); + ret = -ENOSYS; + goto done; + } else { + /* Enable exp ROM */ + uint32_t __iomem *exp_rom_bar_addr = + ®s->core_space[pf_num].config_header[AL_PCI_EXP_ROM_BASE_ADDRESS >> 2]; + uint32_t mask = 1; /* enable bit*/ + mask |= (pf_params->exp_bar_params.size - 1) & 0xFFFFFFFF; + al_reg_write32_dbi_cs2(pcie_port, exp_rom_bar_addr , mask); + } + } else if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + /* Disable exp ROM */ + uint32_t __iomem *exp_rom_bar_addr = + ®s->core_space[pf_num].config_header[AL_PCI_EXP_ROM_BASE_ADDRESS >> 2]; + al_reg_write32_dbi_cs2(pcie_port, exp_rom_bar_addr , 0); + } + + /* Open CPU generated msi and legacy interrupts in pcie wrapper logic */ + if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || + (pcie_port->rev_id == AL_PCIE_REV_ID_1)) { + al_reg_write32(regs->app.soc_int[pf_num].mask_inta_leg_0, (1 << 21)); + } else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) || + (pcie_port->rev_id == AL_PCIE_REV_ID_3)) { + al_reg_write32(regs->app.soc_int[pf_num].mask_inta_leg_3, (1 << 18)); + } else { + al_assert(0); + ret = -ENOSYS; + goto done; + } + + /** + * Addressing RMN: 1547 + * + * RMN description: + * 1. Whenever writing to 0x2xx offset, the write also happens to + * 0x3xx address, meaning two registers are written instead of one. + * 2. Read and write from 0x3xx work ok. + * + * Software flow: + * Backup the value of the app.int_grp_a.mask_a register, because + * app.int_grp_a.mask_clear_a gets overwritten during the write to + * app.soc.mask_msi_leg_0 register. + * Restore the original value after the write to app.soc.mask_msi_leg_0 + * register. + */ + if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { + uint32_t backup; + + backup = al_reg_read32(®s->app.int_grp_a->mask); + al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22)); + al_reg_write32(®s->app.int_grp_a->mask, backup); + } else if (pcie_port->rev_id == AL_PCIE_REV_ID_1) { + al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22)); + } else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) || + (pcie_port->rev_id == AL_PCIE_REV_ID_3)) { + al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_3, (1 << 19)); + } else { + al_assert(0); + ret = -ENOSYS; + goto done; + } + + ret = 0; + +done: + al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); + + return ret; +} + +static void +al_pcie_port_features_config( + struct al_pcie_port *pcie_port, + const struct al_pcie_features *features) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_assert(pcie_port->rev_id > AL_PCIE_REV_ID_0); + + al_reg_write32_masked( + ®s->app.ctrl_gen->features, + PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX, + features->sata_ep_msi_fix ? + PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX : 0); +} + +static int +al_pcie_port_sris_config( + struct al_pcie_port *pcie_port, + struct al_pcie_sris_params *sris_params, + enum al_pcie_link_speed link_speed) +{ + int rc = 0; + struct al_pcie_regs *regs = pcie_port->regs; + + if (sris_params->use_defaults) { + sris_params->kp_counter_gen3 = (pcie_port->rev_id > AL_PCIE_REV_ID_1) ? + PCIE_SRIS_KP_COUNTER_GEN3_DEFAULT_VAL : 0; + sris_params->kp_counter_gen21 = PCIE_SRIS_KP_COUNTER_GEN21_DEFAULT_VAL; + + al_dbg("PCIe %d: configuring SRIS with default values kp_gen3[%d] kp_gen21[%d]\n", + pcie_port->port_id, + sris_params->kp_counter_gen3, + sris_params->kp_counter_gen21); + } + + switch (pcie_port->rev_id) { + case AL_PCIE_REV_ID_3: + case AL_PCIE_REV_ID_2: + al_reg_write32_masked(regs->app.global_ctrl.sris_kp_counter, + PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_MASK | + PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_MASK | + PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_PCIE_X4_SRIS_EN, + (sris_params->kp_counter_gen3 << + PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_SHIFT) | + (sris_params->kp_counter_gen21 << + PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_SHIFT) | + PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_PCIE_X4_SRIS_EN); + break; + + case AL_PCIE_REV_ID_1: + if ((link_speed == AL_PCIE_LINK_SPEED_GEN3) && (sris_params->kp_counter_gen3)) { + al_err("PCIe %d: cannot config Gen%d SRIS with rev_id[%d]\n", + pcie_port->port_id, al_pcie_speed_gen_code(link_speed), + pcie_port->rev_id); + return -EINVAL; + } + + al_reg_write32_masked(®s->port_regs->filter_mask_reg_1, + PCIE_FLT_MASK_SKP_INT_VAL_MASK, + sris_params->kp_counter_gen21); + break; + + default: + al_err("PCIe %d: SRIS config is not supported in rev_id[%d]\n", + pcie_port->port_id, pcie_port->rev_id); + al_assert(0); + return -EINVAL; + } + + return rc; +} + +static void +al_pcie_port_ib_hcrd_config(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_reg_write32_masked( + ®s->port_regs->vc0_posted_rcv_q_ctrl, + RADM_PQ_HCRD_VC0_MASK, + (pcie_port->ib_hcrd_config.nof_p_hdr - 1) + << RADM_PQ_HCRD_VC0_SHIFT); + + al_reg_write32_masked( + ®s->port_regs->vc0_non_posted_rcv_q_ctrl, + RADM_NPQ_HCRD_VC0_MASK, + (pcie_port->ib_hcrd_config.nof_np_hdr - 1) + << RADM_NPQ_HCRD_VC0_SHIFT); +} + +static unsigned int +al_pcie_port_max_num_of_pfs_get(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t max_func_num; + uint32_t max_num_of_pfs; + + /** + * Only in REV3, when port is already enabled, max_num_of_pfs is already + * initialized, return it. Otherwise, return default: 1 PF + */ + if ((pcie_port->rev_id == AL_PCIE_REV_ID_3) + && al_pcie_port_is_enabled(pcie_port)) { + max_func_num = al_reg_read32(®s->port_regs->timer_ctrl_max_func_num); + max_num_of_pfs = AL_REG_FIELD_GET(max_func_num, PCIE_PORT_GEN3_MAX_FUNC_NUM, 0) + 1; + return max_num_of_pfs; + } + return 1; +} + +/******************************************************************************/ +/***************************** API Implementation *****************************/ +/******************************************************************************/ + +/*************************** PCIe Initialization API **************************/ + +/** + * Initializes a PCIe port handle structure + * Caution: this function should not read/write to any register except for + * reading RO register (REV_ID for example) + */ +int +al_pcie_port_handle_init( + struct al_pcie_port *pcie_port, + void __iomem *pcie_reg_base, + void __iomem *pbs_reg_base, + unsigned int port_id) +{ + int i, ret; + + pcie_port->pcie_reg_base = pcie_reg_base; + pcie_port->regs = &pcie_port->regs_ptrs; + pcie_port->ex_regs = NULL; + pcie_port->pbs_regs = pbs_reg_base; + pcie_port->port_id = port_id; + pcie_port->max_lanes = 0; + + ret = al_pcie_rev_id_get(pbs_reg_base, pcie_reg_base); + if (ret < 0) + return ret; + + pcie_port->rev_id = ret; + + /* Zero all regs */ + al_memset(pcie_port->regs, 0, sizeof(struct al_pcie_regs)); + + if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || + (pcie_port->rev_id == AL_PCIE_REV_ID_1)) { + struct al_pcie_rev1_regs __iomem *regs = + (struct al_pcie_rev1_regs __iomem *)pcie_reg_base; + + pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; + pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; + pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; + pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; + pcie_port->regs->axi.ob_ctrl.cfg_target_bus = ®s->axi.ob_ctrl.cfg_target_bus; + pcie_port->regs->axi.ob_ctrl.cfg_control = ®s->axi.ob_ctrl.cfg_control; + pcie_port->regs->axi.ob_ctrl.io_start_l = ®s->axi.ob_ctrl.io_start_l; + pcie_port->regs->axi.ob_ctrl.io_start_h = ®s->axi.ob_ctrl.io_start_h; + pcie_port->regs->axi.ob_ctrl.io_limit_l = ®s->axi.ob_ctrl.io_limit_l; + pcie_port->regs->axi.ob_ctrl.io_limit_h = ®s->axi.ob_ctrl.io_limit_h; + pcie_port->regs->axi.pcie_global.conf = ®s->axi.pcie_global.conf; + pcie_port->regs->axi.conf.zero_lane0 = ®s->axi.conf.zero_lane0; + pcie_port->regs->axi.conf.zero_lane1 = ®s->axi.conf.zero_lane1; + pcie_port->regs->axi.conf.zero_lane2 = ®s->axi.conf.zero_lane2; + pcie_port->regs->axi.conf.zero_lane3 = ®s->axi.conf.zero_lane3; + pcie_port->regs->axi.status.lane[0] = ®s->axi.status.lane0; + pcie_port->regs->axi.status.lane[1] = ®s->axi.status.lane1; + pcie_port->regs->axi.status.lane[2] = ®s->axi.status.lane2; + pcie_port->regs->axi.status.lane[3] = ®s->axi.status.lane3; + pcie_port->regs->axi.parity.en_axi = ®s->axi.parity.en_axi; + pcie_port->regs->axi.ordering.pos_cntl = ®s->axi.ordering.pos_cntl; + pcie_port->regs->axi.pre_configuration.pcie_core_setup = ®s->axi.pre_configuration.pcie_core_setup; + pcie_port->regs->axi.init_fc.cfg = ®s->axi.init_fc.cfg; + pcie_port->regs->axi.int_grp_a = ®s->axi.int_grp_a; + + pcie_port->regs->app.global_ctrl.port_init = ®s->app.global_ctrl.port_init; + pcie_port->regs->app.global_ctrl.pm_control = ®s->app.global_ctrl.pm_control; + pcie_port->regs->app.global_ctrl.events_gen[0] = ®s->app.global_ctrl.events_gen; + pcie_port->regs->app.debug = ®s->app.debug; + pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = ®s->app.soc_int.mask_inta_leg_0; + pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = ®s->app.soc_int.mask_msi_leg_0; + pcie_port->regs->app.ctrl_gen = ®s->app.ctrl_gen; + pcie_port->regs->app.parity = ®s->app.parity; + pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair; + pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair; + + if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { + pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a_m0; + pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b_m0; + } else { + pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a; + pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b; + } + + pcie_port->regs->core_space[0].config_header = regs->core_space.config_header; + pcie_port->regs->core_space[0].pcie_pm_cap_base = ®s->core_space.pcie_pm_cap_base; + pcie_port->regs->core_space[0].pcie_cap_base = ®s->core_space.pcie_cap_base; + pcie_port->regs->core_space[0].pcie_dev_cap_base = ®s->core_space.pcie_dev_cap_base; + pcie_port->regs->core_space[0].pcie_dev_ctrl_status = ®s->core_space.pcie_dev_ctrl_status; + pcie_port->regs->core_space[0].pcie_link_cap_base = ®s->core_space.pcie_link_cap_base; + pcie_port->regs->core_space[0].msix_cap_base = ®s->core_space.msix_cap_base; + pcie_port->regs->core_space[0].aer = ®s->core_space.aer; + pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = ®s->core_space.pcie_sec_ext_cap_base; + + pcie_port->regs->port_regs = ®s->core_space.port_regs; + + } else if (pcie_port->rev_id == AL_PCIE_REV_ID_2) { + struct al_pcie_rev2_regs __iomem *regs = + (struct al_pcie_rev2_regs __iomem *)pcie_reg_base; + + pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; + pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; + pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; + pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; + pcie_port->regs->axi.ob_ctrl.cfg_target_bus = ®s->axi.ob_ctrl.cfg_target_bus; + pcie_port->regs->axi.ob_ctrl.cfg_control = ®s->axi.ob_ctrl.cfg_control; + pcie_port->regs->axi.ob_ctrl.io_start_l = ®s->axi.ob_ctrl.io_start_l; + pcie_port->regs->axi.ob_ctrl.io_start_h = ®s->axi.ob_ctrl.io_start_h; + pcie_port->regs->axi.ob_ctrl.io_limit_l = ®s->axi.ob_ctrl.io_limit_l; + pcie_port->regs->axi.ob_ctrl.io_limit_h = ®s->axi.ob_ctrl.io_limit_h; + pcie_port->regs->axi.pcie_global.conf = ®s->axi.pcie_global.conf; + pcie_port->regs->axi.conf.zero_lane0 = ®s->axi.conf.zero_lane0; + pcie_port->regs->axi.conf.zero_lane1 = ®s->axi.conf.zero_lane1; + pcie_port->regs->axi.conf.zero_lane2 = ®s->axi.conf.zero_lane2; + pcie_port->regs->axi.conf.zero_lane3 = ®s->axi.conf.zero_lane3; + pcie_port->regs->axi.status.lane[0] = ®s->axi.status.lane0; + pcie_port->regs->axi.status.lane[1] = ®s->axi.status.lane1; + pcie_port->regs->axi.status.lane[2] = ®s->axi.status.lane2; + pcie_port->regs->axi.status.lane[3] = ®s->axi.status.lane3; + pcie_port->regs->axi.parity.en_axi = ®s->axi.parity.en_axi; + pcie_port->regs->axi.ordering.pos_cntl = ®s->axi.ordering.pos_cntl; + pcie_port->regs->axi.pre_configuration.pcie_core_setup = ®s->axi.pre_configuration.pcie_core_setup; + pcie_port->regs->axi.init_fc.cfg = ®s->axi.init_fc.cfg; + pcie_port->regs->axi.int_grp_a = ®s->axi.int_grp_a; + + pcie_port->regs->app.global_ctrl.port_init = ®s->app.global_ctrl.port_init; + pcie_port->regs->app.global_ctrl.pm_control = ®s->app.global_ctrl.pm_control; + pcie_port->regs->app.global_ctrl.events_gen[0] = ®s->app.global_ctrl.events_gen; + pcie_port->regs->app.global_ctrl.corr_err_sts_int = ®s->app.global_ctrl.pended_corr_err_sts_int; + pcie_port->regs->app.global_ctrl.uncorr_err_sts_int = ®s->app.global_ctrl.pended_uncorr_err_sts_int; + pcie_port->regs->app.debug = ®s->app.debug; + pcie_port->regs->app.ap_user_send_msg = ®s->app.ap_user_send_msg; + pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = ®s->app.soc_int.mask_inta_leg_0; + pcie_port->regs->app.soc_int[0].mask_inta_leg_3 = ®s->app.soc_int.mask_inta_leg_3; + pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = ®s->app.soc_int.mask_msi_leg_0; + pcie_port->regs->app.soc_int[0].mask_msi_leg_3 = ®s->app.soc_int.mask_msi_leg_3; + pcie_port->regs->app.ctrl_gen = ®s->app.ctrl_gen; + pcie_port->regs->app.parity = ®s->app.parity; + pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair; + pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair; + pcie_port->regs->app.status_per_func[0] = ®s->app.status_per_func; + pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a; + pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b; + + pcie_port->regs->core_space[0].config_header = regs->core_space.config_header; + pcie_port->regs->core_space[0].pcie_pm_cap_base = ®s->core_space.pcie_pm_cap_base; + pcie_port->regs->core_space[0].pcie_cap_base = ®s->core_space.pcie_cap_base; + pcie_port->regs->core_space[0].pcie_dev_cap_base = ®s->core_space.pcie_dev_cap_base; + pcie_port->regs->core_space[0].pcie_dev_ctrl_status = ®s->core_space.pcie_dev_ctrl_status; + pcie_port->regs->core_space[0].pcie_link_cap_base = ®s->core_space.pcie_link_cap_base; + pcie_port->regs->core_space[0].msix_cap_base = ®s->core_space.msix_cap_base; + pcie_port->regs->core_space[0].aer = ®s->core_space.aer; + pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = ®s->core_space.pcie_sec_ext_cap_base; + + pcie_port->regs->port_regs = ®s->core_space.port_regs; + + } else if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + struct al_pcie_rev3_regs __iomem *regs = + (struct al_pcie_rev3_regs __iomem *)pcie_reg_base; + pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; + pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; + pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; + pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; + pcie_port->regs->axi.ob_ctrl.cfg_target_bus = ®s->axi.ob_ctrl.cfg_target_bus; + pcie_port->regs->axi.ob_ctrl.cfg_control = ®s->axi.ob_ctrl.cfg_control; + pcie_port->regs->axi.ob_ctrl.io_start_l = ®s->axi.ob_ctrl.io_start_l; + pcie_port->regs->axi.ob_ctrl.io_start_h = ®s->axi.ob_ctrl.io_start_h; + pcie_port->regs->axi.ob_ctrl.io_limit_l = ®s->axi.ob_ctrl.io_limit_l; + pcie_port->regs->axi.ob_ctrl.io_limit_h = ®s->axi.ob_ctrl.io_limit_h; + pcie_port->regs->axi.pcie_global.conf = ®s->axi.pcie_global.conf; + pcie_port->regs->axi.conf.zero_lane0 = ®s->axi.conf.zero_lane0; + pcie_port->regs->axi.conf.zero_lane1 = ®s->axi.conf.zero_lane1; + pcie_port->regs->axi.conf.zero_lane2 = ®s->axi.conf.zero_lane2; + pcie_port->regs->axi.conf.zero_lane3 = ®s->axi.conf.zero_lane3; + pcie_port->regs->axi.conf.zero_lane4 = ®s->axi.conf.zero_lane4; + pcie_port->regs->axi.conf.zero_lane5 = ®s->axi.conf.zero_lane5; + pcie_port->regs->axi.conf.zero_lane6 = ®s->axi.conf.zero_lane6; + pcie_port->regs->axi.conf.zero_lane7 = ®s->axi.conf.zero_lane7; + pcie_port->regs->axi.status.lane[0] = ®s->axi.status.lane0; + pcie_port->regs->axi.status.lane[1] = ®s->axi.status.lane1; + pcie_port->regs->axi.status.lane[2] = ®s->axi.status.lane2; + pcie_port->regs->axi.status.lane[3] = ®s->axi.status.lane3; + pcie_port->regs->axi.status.lane[4] = ®s->axi.status.lane4; + pcie_port->regs->axi.status.lane[5] = ®s->axi.status.lane5; + pcie_port->regs->axi.status.lane[6] = ®s->axi.status.lane6; + pcie_port->regs->axi.status.lane[7] = ®s->axi.status.lane7; + pcie_port->regs->axi.parity.en_axi = ®s->axi.parity.en_axi; + pcie_port->regs->axi.ordering.pos_cntl = ®s->axi.ordering.pos_cntl; + pcie_port->regs->axi.pre_configuration.pcie_core_setup = ®s->axi.pre_configuration.pcie_core_setup; + pcie_port->regs->axi.init_fc.cfg = ®s->axi.init_fc.cfg; + pcie_port->regs->axi.int_grp_a = ®s->axi.int_grp_a; + pcie_port->regs->axi.axi_attr_ovrd.write_msg_ctrl_0 = ®s->axi.axi_attr_ovrd.write_msg_ctrl_0; + pcie_port->regs->axi.axi_attr_ovrd.write_msg_ctrl_1 = ®s->axi.axi_attr_ovrd.write_msg_ctrl_1; + pcie_port->regs->axi.axi_attr_ovrd.pf_sel = ®s->axi.axi_attr_ovrd.pf_sel; + + for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_0 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_0; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_1 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_1; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_2 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_2; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_3 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_3; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_4 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_4; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_5 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_5; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_6 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_6; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_7 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_7; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_8 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_8; + pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_9 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_9; + } + + pcie_port->regs->axi.msg_attr_axuser_table.entry_vec = ®s->axi.msg_attr_axuser_table.entry_vec; + + pcie_port->regs->app.global_ctrl.port_init = ®s->app.global_ctrl.port_init; + pcie_port->regs->app.global_ctrl.pm_control = ®s->app.global_ctrl.pm_control; + pcie_port->regs->app.global_ctrl.corr_err_sts_int = ®s->app.global_ctrl.pended_corr_err_sts_int; + pcie_port->regs->app.global_ctrl.uncorr_err_sts_int = ®s->app.global_ctrl.pended_uncorr_err_sts_int; + + for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { + pcie_port->regs->app.global_ctrl.events_gen[i] = ®s->app.events_gen_per_func[i].events_gen; + } + + pcie_port->regs->app.global_ctrl.sris_kp_counter = ®s->app.global_ctrl.sris_kp_counter_value; + pcie_port->regs->app.debug = ®s->app.debug; + + for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { + pcie_port->regs->app.soc_int[i].mask_inta_leg_0 = ®s->app.soc_int_per_func[i].mask_inta_leg_0; + pcie_port->regs->app.soc_int[i].mask_inta_leg_3 = ®s->app.soc_int_per_func[i].mask_inta_leg_3; + pcie_port->regs->app.soc_int[i].mask_msi_leg_0 = ®s->app.soc_int_per_func[i].mask_msi_leg_0; + pcie_port->regs->app.soc_int[i].mask_msi_leg_3 = ®s->app.soc_int_per_func[i].mask_msi_leg_3; + } + + pcie_port->regs->app.ap_user_send_msg = ®s->app.ap_user_send_msg; + pcie_port->regs->app.ctrl_gen = ®s->app.ctrl_gen; + pcie_port->regs->app.parity = ®s->app.parity; + pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair; + pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair; + + for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) + pcie_port->regs->app.status_per_func[i] = ®s->app.status_per_func[i]; + + pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a; + pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b; + pcie_port->regs->app.int_grp_c = ®s->app.int_grp_c; + pcie_port->regs->app.int_grp_d = ®s->app.int_grp_d; + + for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { + pcie_port->regs->core_space[i].config_header = regs->core_space.func[i].config_header; + pcie_port->regs->core_space[i].pcie_pm_cap_base = ®s->core_space.func[i].pcie_pm_cap_base; + pcie_port->regs->core_space[i].pcie_cap_base = ®s->core_space.func[i].pcie_cap_base; + pcie_port->regs->core_space[i].pcie_dev_cap_base = ®s->core_space.func[i].pcie_dev_cap_base; + pcie_port->regs->core_space[i].pcie_dev_ctrl_status = ®s->core_space.func[i].pcie_dev_ctrl_status; + pcie_port->regs->core_space[i].pcie_link_cap_base = ®s->core_space.func[i].pcie_link_cap_base; + pcie_port->regs->core_space[i].msix_cap_base = ®s->core_space.func[i].msix_cap_base; + pcie_port->regs->core_space[i].aer = ®s->core_space.func[i].aer; + pcie_port->regs->core_space[i].tph_cap_base = ®s->core_space.func[i].tph_cap_base; + + } + + /* secondary extension capability only for PF0 */ + pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = ®s->core_space.func[0].pcie_sec_ext_cap_base; + + pcie_port->regs->port_regs = ®s->core_space.func[0].port_regs; + + } else { + al_warn("%s: Revision ID is unknown\n", + __func__); + return -EINVAL; + } + + /* set maximum number of physical functions */ + pcie_port->max_num_of_pfs = al_pcie_port_max_num_of_pfs_get(pcie_port); + + al_dbg("pcie port handle initialized. port id: %d, rev_id %d, regs base %p\n", + port_id, pcie_port->rev_id, pcie_reg_base); + return 0; +} + +/** + * Initializes a PCIe Physical function handle structure + * Caution: this function should not read/write to any register except for + * reading RO register (REV_ID for example) + */ +int +al_pcie_pf_handle_init( + struct al_pcie_pf *pcie_pf, + struct al_pcie_port *pcie_port, + unsigned int pf_num) +{ + enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); + al_assert(pf_num < pcie_port->max_num_of_pfs); + + if (op_mode != AL_PCIE_OPERATING_MODE_EP) { + al_err("PCIe %d: can't init PF handle with operating mode [%d]\n", + pcie_port->port_id, op_mode); + return -EINVAL; + } + + pcie_pf->pf_num = pf_num; + pcie_pf->pcie_port = pcie_port; + + al_dbg("PCIe %d: pf handle initialized. pf number: %d, rev_id %d, regs %p\n", + pcie_port->port_id, pcie_pf->pf_num, pcie_port->rev_id, + pcie_port->regs); + return 0; +} + +/************************** Pre PCIe Port Enable API **************************/ + +/** configure pcie operating mode (root complex or endpoint) */ +int +al_pcie_port_operating_mode_config( + struct al_pcie_port *pcie_port, + enum al_pcie_operating_mode mode) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t reg, device_type, new_device_type; + + if (al_pcie_port_is_enabled(pcie_port)) { + al_err("PCIe %d: already enabled, cannot set operating mode\n", + pcie_port->port_id); + return -EINVAL; + } + + reg = al_reg_read32(regs->axi.pcie_global.conf); + + device_type = AL_REG_FIELD_GET(reg, + PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK, + PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT); + if (mode == AL_PCIE_OPERATING_MODE_EP) { + new_device_type = PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP; + } else if (mode == AL_PCIE_OPERATING_MODE_RC) { + new_device_type = PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC; + + if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + /* config 1 PF in RC mode */ + al_reg_write32_masked(regs->axi.axi_attr_ovrd.pf_sel, + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_AXUSER | + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_REG | + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_ADDR_OFFSET_MASK | + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT0_OVRD | + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_AXUSER | + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_REG | + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_ADDR_OFFSET_MASK | + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT1_OVRD, + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_REG | + PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_REG); + } + } else { + al_err("PCIe %d: unknown operating mode: %d\n", pcie_port->port_id, mode); + return -EINVAL; + } + + if (new_device_type == device_type) { + al_dbg("PCIe %d: operating mode already set to %s\n", + pcie_port->port_id, (mode == AL_PCIE_OPERATING_MODE_EP) ? + "EndPoint" : "Root Complex"); + return 0; + } + al_info("PCIe %d: set operating mode to %s\n", + pcie_port->port_id, (mode == AL_PCIE_OPERATING_MODE_EP) ? + "EndPoint" : "Root Complex"); + AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK, + PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT, + new_device_type); + + al_reg_write32(regs->axi.pcie_global.conf, reg); + + return 0; +} + +int +al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + if (al_pcie_port_is_enabled(pcie_port)) { + al_err("PCIe %d: already enabled, cannot set max lanes\n", + pcie_port->port_id); + return -EINVAL; + } + + /* convert to bitmask format (4 ->'b1111, 2 ->'b11, 1 -> 'b1) */ + uint32_t active_lanes_val = AL_PCIE_PARSE_LANES(lanes); + + al_reg_write32_masked(regs->axi.pcie_global.conf, + (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? + PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK : + PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK, + active_lanes_val); + + pcie_port->max_lanes = lanes; + return 0; +} + +int +al_pcie_port_max_num_of_pfs_set( + struct al_pcie_port *pcie_port, + uint8_t max_num_of_pfs) +{ + if (al_pcie_port_is_enabled(pcie_port)) { + al_err("PCIe %d: already enabled, cannot set max num of PFs\n", + pcie_port->port_id); + return -EINVAL; + } + + if (pcie_port->rev_id == AL_PCIE_REV_ID_3) + al_assert(max_num_of_pfs <= REV3_MAX_NUM_OF_PFS); + else + al_assert(max_num_of_pfs == REV1_2_MAX_NUM_OF_PFS); + + pcie_port->max_num_of_pfs = max_num_of_pfs; + + return 0; +} + +/* Inbound header credits and outstanding outbound reads configuration */ +int +al_pcie_port_ib_hcrd_os_ob_reads_config( + struct al_pcie_port *pcie_port, + struct al_pcie_ib_hcrd_os_ob_reads_config *ib_hcrd_os_ob_reads_config) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + if (al_pcie_port_is_enabled(pcie_port)) { + al_err("PCIe %d: already enabled, cannot configure IB credits and OB OS reads\n", + pcie_port->port_id); + return -EINVAL; + } + + al_assert(ib_hcrd_os_ob_reads_config->nof_np_hdr > 0); + + al_assert(ib_hcrd_os_ob_reads_config->nof_p_hdr > 0); + + al_assert(ib_hcrd_os_ob_reads_config->nof_cpl_hdr > 0); + + if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + al_assert( + (ib_hcrd_os_ob_reads_config->nof_cpl_hdr + + ib_hcrd_os_ob_reads_config->nof_np_hdr + + ib_hcrd_os_ob_reads_config->nof_p_hdr) == + AL_PCIE_REV3_IB_HCRD_SUM); + + al_reg_write32_masked( + regs->axi.init_fc.cfg, + PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_MASK | + PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_MASK | + PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_MASK, + (ib_hcrd_os_ob_reads_config->nof_p_hdr << + PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_SHIFT) | + (ib_hcrd_os_ob_reads_config->nof_np_hdr << + PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_SHIFT) | + (ib_hcrd_os_ob_reads_config->nof_cpl_hdr << + PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_SHIFT)); + } else { + al_assert( + (ib_hcrd_os_ob_reads_config->nof_cpl_hdr + + ib_hcrd_os_ob_reads_config->nof_np_hdr + + ib_hcrd_os_ob_reads_config->nof_p_hdr) == + AL_PCIE_REV_1_2_IB_HCRD_SUM); + + al_reg_write32_masked( + regs->axi.init_fc.cfg, + PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_MASK | + PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_MASK | + PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_MASK, + (ib_hcrd_os_ob_reads_config->nof_p_hdr << + PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_SHIFT) | + (ib_hcrd_os_ob_reads_config->nof_np_hdr << + PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_SHIFT) | + (ib_hcrd_os_ob_reads_config->nof_cpl_hdr << + PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_SHIFT)); + } + + al_reg_write32_masked( + regs->axi.pre_configuration.pcie_core_setup, + PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_MASK, + ib_hcrd_os_ob_reads_config->nof_outstanding_ob_reads << + PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_SHIFT); + + /* Store 'nof_p_hdr' and 'nof_np_hdr' to be set in the core later */ + pcie_port->ib_hcrd_config.nof_np_hdr = + ib_hcrd_os_ob_reads_config->nof_np_hdr; + pcie_port->ib_hcrd_config.nof_p_hdr = + ib_hcrd_os_ob_reads_config->nof_p_hdr; + + return 0; +} + +enum al_pcie_operating_mode +al_pcie_operating_mode_get( + struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t reg, device_type; + + al_assert(pcie_port); + + reg = al_reg_read32(regs->axi.pcie_global.conf); + + device_type = AL_REG_FIELD_GET(reg, + PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK, + PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT); + + switch (device_type) { + case PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP: + return AL_PCIE_OPERATING_MODE_EP; + case PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC: + return AL_PCIE_OPERATING_MODE_RC; + default: + al_err("PCIe %d: unknown device type (%d) in global conf register.\n", + pcie_port->port_id, device_type); + } + return AL_PCIE_OPERATING_MODE_UNKNOWN; +} + +/**************************** PCIe Port Enable API ****************************/ + +/** Enable PCIe port (deassert reset) */ +int +al_pcie_port_enable(struct al_pcie_port *pcie_port) +{ + struct al_pbs_regs *pbs_reg_base = + (struct al_pbs_regs *)pcie_port->pbs_regs; + struct al_pcie_regs *regs = pcie_port->regs; + unsigned int port_id = pcie_port->port_id; + + /* pre-port-enable default functionality should be here */ + + /** + * Set inbound header credit and outstanding outbound reads defaults + * Must be called before port enable (PCIE_EXIST) + */ + al_pcie_ib_hcrd_os_ob_reads_config_default(pcie_port); + + /* + * Disable ATS capability + * - must be done before core reset deasserted + * - rev_id 0 - no effect, but no harm + */ + if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || + (pcie_port->rev_id == AL_PCIE_REV_ID_1) || + (pcie_port->rev_id == AL_PCIE_REV_ID_2)) { + al_reg_write32_masked( + regs->axi.ordering.pos_cntl, + PCIE_AXI_CORE_SETUP_ATS_CAP_DIS, + PCIE_AXI_CORE_SETUP_ATS_CAP_DIS); + } + + /* Deassert core reset */ + al_reg_write32_masked( + &pbs_reg_base->unit.pcie_conf_1, + 1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT), + 1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT)); + + return 0; +} + +/** Disable PCIe port (assert reset) */ +void +al_pcie_port_disable(struct al_pcie_port *pcie_port) +{ + struct al_pbs_regs *pbs_reg_base = + (struct al_pbs_regs *)pcie_port->pbs_regs; + unsigned int port_id = pcie_port->port_id; + + if (!al_pcie_port_is_enabled(pcie_port)) { + al_warn("PCIe %d: trying to disable a non-enabled port\n", + pcie_port->port_id); + } + + /* Assert core reset */ + al_reg_write32_masked( + &pbs_reg_base->unit.pcie_conf_1, + 1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT), + 0); +} + +int +al_pcie_port_memory_shutdown_set( + struct al_pcie_port *pcie_port, + al_bool enable) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? + PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN : + PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN; + + if (!al_pcie_port_is_enabled(pcie_port)) { + al_err("PCIe %d: not enabled, cannot shutdown memory\n", + pcie_port->port_id); + return -EINVAL; + } + + al_reg_write32_masked(regs->axi.pcie_global.conf, + mask, enable == AL_TRUE ? mask : 0); + + return 0; +} + +al_bool +al_pcie_port_is_enabled(struct al_pcie_port *pcie_port) +{ + struct al_pbs_regs *pbs_reg_base = (struct al_pbs_regs *)pcie_port->pbs_regs; + uint32_t pcie_exist = al_reg_read32(&pbs_reg_base->unit.pcie_conf_1); + + uint32_t ports_enabled = AL_REG_FIELD_GET(pcie_exist, + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_MASK, + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT); + + return (AL_REG_FIELD_GET(ports_enabled, AL_BIT(pcie_port->port_id), + pcie_port->port_id) == 1); +} + +/*************************** PCIe Configuration API ***************************/ + +/** configure pcie port (link params, etc..) */ +int +al_pcie_port_config(struct al_pcie_port *pcie_port, + const struct al_pcie_port_config_params *params) +{ + struct al_pcie_regs *regs = pcie_port->regs; + enum al_pcie_operating_mode op_mode; + int status = 0; + int i; + + if (!al_pcie_port_is_enabled(pcie_port)) { + al_err("PCIe %d: port not enabled, cannot configure port\n", + pcie_port->port_id); + return -EINVAL; + } + + if (al_pcie_is_link_started(pcie_port)) { + al_err("PCIe %d: link already started, cannot configure port\n", + pcie_port->port_id); + return -EINVAL; + } + + al_assert(pcie_port); + al_assert(params); + + al_dbg("PCIe %d: port config\n", pcie_port->port_id); + + op_mode = al_pcie_operating_mode_get(pcie_port); + + /* if max lanes not specifies, read it from register */ + if (pcie_port->max_lanes == 0) { + uint32_t global_conf = al_reg_read32(regs->axi.pcie_global.conf); + uint32_t act_lanes = AL_REG_FIELD_GET(global_conf, + (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? + PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK : + PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK, + PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT); + + switch(act_lanes) { + case 0x1: + pcie_port->max_lanes = 1; + break; + case 0x3: + pcie_port->max_lanes = 2; + break; + case 0xf: + pcie_port->max_lanes = 4; + break; + case 0xff: + pcie_port->max_lanes = 8; + break; + default: + pcie_port->max_lanes = 0; + al_err("PCIe %d: invalid max lanes val (0x%x)\n", pcie_port->port_id, act_lanes); + break; + } + } + + if (params->link_params) + status = al_pcie_port_link_config(pcie_port, params->link_params); + if (status) + goto done; + + /* Change max read request size to 256 bytes + * Max Payload Size is remained untouched- it is the responsibility of + * the host to change the MPS, if needed. + */ + for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { + al_reg_write32_masked(regs->core_space[i].pcie_dev_ctrl_status, + PCIE_PORT_DEV_CTRL_STATUS_MRRS_MASK, + PCIE_PORT_DEV_CTRL_STATUS_MRRS_VAL_256); + if (pcie_port->rev_id != AL_PCIE_REV_ID_3) + break; + } + + if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { + /* Set maximum physical function numbers */ + al_reg_write32_masked( + ®s->port_regs->timer_ctrl_max_func_num, + PCIE_PORT_GEN3_MAX_FUNC_NUM, + pcie_port->max_num_of_pfs - 1); + + al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); + + /** + * in EP mode, when we have more than 1 PF we need to assert + * multi-pf support so the host scan all PFs + */ + if ((op_mode == AL_PCIE_OPERATING_MODE_EP) && (pcie_port->max_num_of_pfs > 1)) { + al_reg_write32_masked((uint32_t __iomem *) + (®s->core_space[0].config_header[0] + + (PCIE_BIST_HEADER_TYPE_BASE >> 2)), + PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK, + PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK); + } + + /* Disable TPH next pointer */ + for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { + al_reg_write32_masked(regs->core_space[i].tph_cap_base, + PCIE_TPH_NEXT_POINTER, 0); + } + + al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); + } + + + status = al_pcie_port_snoop_config(pcie_port, params->enable_axi_snoop); + if (status) + goto done; + + al_pcie_port_ram_parity_int_config(pcie_port, params->enable_ram_parity_int); + + al_pcie_port_axi_parity_int_config(pcie_port, params->enable_axi_parity_int); + + al_pcie_port_relaxed_pcie_ordering_config(pcie_port, params->relaxed_ordering_params); + + if (params->lat_rply_timers) + status = al_pcie_port_lat_rply_timers_config(pcie_port, params->lat_rply_timers); + if (status) + goto done; + + if (params->gen2_params) + status = al_pcie_port_gen2_params_config(pcie_port, params->gen2_params); + if (status) + goto done; + + if (params->gen3_params) + status = al_pcie_port_gen3_params_config(pcie_port, params->gen3_params); + if (status) + goto done; + + if (params->tl_credits) + status = al_pcie_port_tl_credits_config(pcie_port, params->tl_credits); + if (status) + goto done; + + if (params->features) + al_pcie_port_features_config(pcie_port, params->features); + + if (params->sris_params) + status = al_pcie_port_sris_config(pcie_port, params->sris_params, + params->link_params->max_speed); + if (status) + goto done; + + al_pcie_port_ib_hcrd_config(pcie_port); + + if (params->fast_link_mode) { + al_reg_write32_masked(®s->port_regs->port_link_ctrl, + 1 << PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT, + 1 << PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT); + } + + if (params->enable_axi_slave_err_resp) + al_reg_write32_masked(®s->port_regs->axi_slave_err_resp, + 1 << PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT, + 1 << PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT); + + /** + * Addressing RMN: 5477 + * + * RMN description: + * address-decoder logic performs sub-target decoding even for transactions + * which undergo target enforcement. thus, in case transaction's address is + * inside any ECAM bar, the sub-target decoding will be set to ECAM, which + * causes wrong handling by PCIe unit + * + * Software flow: + * on EP mode only, turning on the iATU-enable bit (with the relevant mask + * below) allows the PCIe unit to discard the ECAM bit which was asserted + * by-mistake in the address-decoder + */ + if (op_mode == AL_PCIE_OPERATING_MODE_EP) { + al_reg_write32_masked(regs->axi.ob_ctrl.cfg_target_bus, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK, + (0) << PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT); + al_reg_write32_masked(regs->axi.ob_ctrl.cfg_control, + PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_IATU_EN, + PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_IATU_EN); + } + + if (op_mode == AL_PCIE_OPERATING_MODE_RC) { + /** + * enable memory and I/O access from port when in RC mode + * in RC mode, only core_space[0] is valid. + */ + al_reg_write16_masked( + (uint16_t __iomem *)(®s->core_space[0].config_header[0] + (0x4 >> 2)), + 0x7, /* Mem, MSE, IO */ + 0x7); + + /* change the class code to match pci bridge */ + al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); + + al_reg_write32_masked( + (uint32_t __iomem *)(®s->core_space[0].config_header[0] + + (PCI_CLASS_REVISION >> 2)), + 0xFFFFFF00, + 0x06040000); + + al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); + + /** + * Addressing RMN: 5702 + * + * RMN description: + * target bus mask default value in HW is: 0xFE, this enforces + * setting the target bus for ports 1 and 3 when running on RC + * mode since bit[20] in ECAM address in these cases is set + * + * Software flow: + * on RC mode only, set target-bus value to 0xFF to prevent this + * enforcement + */ + al_reg_write32_masked(regs->axi.ob_ctrl.cfg_target_bus, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK); + } +done: + al_dbg("PCIe %d: port config %s\n", pcie_port->port_id, status? "failed": "done"); + + return status; +} + +int +al_pcie_pf_config( + struct al_pcie_pf *pcie_pf, + const struct al_pcie_pf_config_params *params) +{ + struct al_pcie_port *pcie_port; + int status = 0; + + al_assert(pcie_pf); + al_assert(params); + + pcie_port = pcie_pf->pcie_port; + + if (!al_pcie_port_is_enabled(pcie_port)) { + al_err("PCIe %d: port not enabled, cannot configure port\n", pcie_port->port_id); + return -EINVAL; + } + + al_dbg("PCIe %d: pf %d config\n", pcie_port->port_id, pcie_pf->pf_num); + + if (params) + status = al_pcie_port_pf_params_config(pcie_pf, params); + if (status) + goto done; + +done: + al_dbg("PCIe %d: pf %d config %s\n", + pcie_port->port_id, pcie_pf->pf_num, status ? "failed" : "done"); + + return status; +} + +/************************** PCIe Link Operations API **************************/ + +/* start pcie link */ +int +al_pcie_link_start(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; + + if (!al_pcie_port_is_enabled(pcie_port)) { + al_err("PCIe %d: port not enabled, cannot start link\n", + pcie_port->port_id); + return -EINVAL; + } + + al_dbg("PCIe_%d: start port link.\n", pcie_port->port_id); + + al_reg_write32_masked( + regs->app.global_ctrl.port_init, + PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK, + PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK); + + return 0; +} + +/* stop pcie link */ +int +al_pcie_link_stop(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; + + if (!al_pcie_is_link_started(pcie_port)) { + al_warn("PCIe %d: trying to stop a non-started link\n", + pcie_port->port_id); + } + + al_dbg("PCIe_%d: stop port link.\n", pcie_port->port_id); + + al_reg_write32_masked( + regs->app.global_ctrl.port_init, + PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK, + ~PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK); + + return 0; +} + +/* wait for link up indication */ +int +al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms) +{ + int wait_count = timeout_ms * AL_PCIE_LINKUP_WAIT_INTERVALS_PER_SEC; + + while (wait_count-- > 0) { + if (al_pcie_check_link(pcie_port, NULL)) { + al_info("PCIe_%d: <<<<<<<<< Link up >>>>>>>>>\n", pcie_port->port_id); + return 0; + } else + al_dbg("PCIe_%d: No link up, %d attempts remaining\n", + pcie_port->port_id, wait_count); + + al_udelay(AL_PCIE_LINKUP_WAIT_INTERVAL); + } + al_info("PCIE_%d: link is not established in time\n", + pcie_port->port_id); + + return ETIMEDOUT; +} + +/** get link status */ +int +al_pcie_link_status(struct al_pcie_port *pcie_port, + struct al_pcie_link_status *status) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint16_t pcie_lnksta; + + al_assert(status); + + status->link_up = al_pcie_check_link(pcie_port, &status->ltssm_state); + + if (!status->link_up) { + status->speed = AL_PCIE_LINK_SPEED_DEFAULT; + status->lanes = 0; + return 0; + } + + pcie_lnksta = al_reg_read16((uint16_t __iomem *)regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKSTA >> 1)); + + switch(pcie_lnksta & AL_PCI_EXP_LNKSTA_CLS) { + case AL_PCI_EXP_LNKSTA_CLS_2_5GB: + status->speed = AL_PCIE_LINK_SPEED_GEN1; + break; + case AL_PCI_EXP_LNKSTA_CLS_5_0GB: + status->speed = AL_PCIE_LINK_SPEED_GEN2; + break; + case AL_PCI_EXP_LNKSTA_CLS_8_0GB: + status->speed = AL_PCIE_LINK_SPEED_GEN3; + break; + default: + status->speed = AL_PCIE_LINK_SPEED_DEFAULT; + al_err("PCIe %d: unknown link speed indication. PCIE LINK STATUS %x\n", + pcie_port->port_id, pcie_lnksta); + } + status->lanes = (pcie_lnksta & AL_PCI_EXP_LNKSTA_NLW) >> AL_PCI_EXP_LNKSTA_NLW_SHIFT; + al_info("PCIe %d: Link up. speed gen%d negotiated width %d\n", + pcie_port->port_id, status->speed, status->lanes); + + return 0; +} + +/** get lane status */ +void +al_pcie_lane_status_get( + struct al_pcie_port *pcie_port, + unsigned int lane, + struct al_pcie_lane_status *status) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t lane_status; + uint32_t *reg_ptr; + + al_assert(pcie_port); + al_assert(status); + al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_1) || (lane < REV1_2_MAX_NUM_LANES)); + al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_2) || (lane < REV1_2_MAX_NUM_LANES)); + al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_3) || (lane < REV3_MAX_NUM_LANES)); + + reg_ptr = regs->axi.status.lane[lane]; + + /* Reset field is valid only when same value is read twice */ + do { + lane_status = al_reg_read32(reg_ptr); + status->is_reset = !!(lane_status & PCIE_AXI_STATUS_LANE_IS_RESET); + } while (status->is_reset != (!!(al_reg_read32(reg_ptr) & PCIE_AXI_STATUS_LANE_IS_RESET))); + + status->requested_speed = + (lane_status & PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_MASK) >> + PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_SHIFT; +} + +/** trigger hot reset */ +int +al_pcie_link_hot_reset(struct al_pcie_port *pcie_port, al_bool enable) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t events_gen; + al_bool app_reset_state; + enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); + + if (op_mode != AL_PCIE_OPERATING_MODE_RC) { + al_err("PCIe %d: hot-reset is applicable only for RC mode\n", pcie_port->port_id); + return -EINVAL; + } + + if (!al_pcie_is_link_started(pcie_port)) { + al_err("PCIe %d: link not started, cannot trigger hot-reset\n", pcie_port->port_id); + return -EINVAL; + } + + events_gen = al_reg_read32(regs->app.global_ctrl.events_gen[0]); + app_reset_state = events_gen & PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT; + + if (enable && app_reset_state) { + al_err("PCIe %d: link is already in hot-reset state\n", pcie_port->port_id); + return -EINVAL; + } else if ((!enable) && (!(app_reset_state))) { + al_err("PCIe %d: link is already in non-hot-reset state\n", pcie_port->port_id); + return -EINVAL; + } else { + al_dbg("PCIe %d: %s hot-reset\n", pcie_port->port_id, + (enable ? "enabling" : "disabling")); + /* hot-reset functionality is implemented only for function 0 */ + al_reg_write32_masked(regs->app.global_ctrl.events_gen[0], + PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT, + (enable ? PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT + : ~PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT)); + return 0; + } +} + +/** disable port link */ +int +al_pcie_link_disable(struct al_pcie_port *pcie_port, al_bool disable) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t pcie_lnkctl; + al_bool link_disable_state; + enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); + + if (op_mode != AL_PCIE_OPERATING_MODE_RC) { + al_err("PCIe %d: hot-reset is applicable only for RC mode\n", pcie_port->port_id); + return -EINVAL; + } + + if (!al_pcie_is_link_started(pcie_port)) { + al_err("PCIe %d: link not started, cannot disable link\n", pcie_port->port_id); + return -EINVAL; + } + + pcie_lnkctl = al_reg_read32(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1)); + link_disable_state = pcie_lnkctl & AL_PCI_EXP_LNKCTL_LNK_DIS; + + if (disable && link_disable_state) { + al_err("PCIe %d: link is already in disable state\n", pcie_port->port_id); + return -EINVAL; + } else if ((!disable) && (!(link_disable_state))) { + al_err("PCIe %d: link is already in enable state\n", pcie_port->port_id); + return -EINVAL; + } + + al_dbg("PCIe %d: %s port\n", pcie_port->port_id, (disable ? "disabling" : "enabling")); + al_reg_write32_masked(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1), + AL_PCI_EXP_LNKCTL_LNK_DIS, + (disable ? AL_PCI_EXP_LNKCTL_LNK_DIS : ~AL_PCI_EXP_LNKCTL_LNK_DIS)); + return 0; +} + +/** retrain link */ +int +al_pcie_link_retrain(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); + + if (op_mode != AL_PCIE_OPERATING_MODE_RC) { + al_err("PCIe %d: link-retrain is applicable only for RC mode\n", + pcie_port->port_id); + return -EINVAL; + } + + if (!al_pcie_is_link_started(pcie_port)) { + al_err("PCIe %d: link not started, cannot link-retrain\n", pcie_port->port_id); + return -EINVAL; + } + + al_reg_write32_masked(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1), + AL_PCI_EXP_LNKCTL_LNK_RTRN, AL_PCI_EXP_LNKCTL_LNK_RTRN); + + return 0; +} + +/* trigger speed change */ +int +al_pcie_link_change_speed(struct al_pcie_port *pcie_port, + enum al_pcie_link_speed new_speed) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + if (!al_pcie_is_link_started(pcie_port)) { + al_err("PCIe %d: link not started, cannot change speed\n", pcie_port->port_id); + return -EINVAL; + } + + al_dbg("PCIe %d: changing speed to %d\n", pcie_port->port_id, new_speed); + + al_pcie_port_link_speed_ctrl_set(pcie_port, new_speed); + + al_reg_write32_masked(®s->port_regs->gen2_ctrl, + PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE, + PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE); + + return 0; +} + +/* TODO: check if this function needed */ +int +al_pcie_link_change_width(struct al_pcie_port *pcie_port, + uint8_t width __attribute__((__unused__))) +{ + al_err("PCIe %d: link change width not implemented\n", + pcie_port->port_id); + + return -ENOSYS; +} + +/**************************** Post Link Start API *****************************/ + +/************************** Snoop Configuration API ***************************/ + +int +al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, al_bool enable_axi_snoop) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + /* Set snoop mode */ + al_info("PCIE_%d: snoop mode %s\n", + pcie_port->port_id, enable_axi_snoop ? "enable" : "disable"); + + if (enable_axi_snoop) { + al_reg_write32_masked(regs->axi.ctrl.master_arctl, + PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP, + PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP); + + al_reg_write32_masked(regs->axi.ctrl.master_awctl, + PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP, + PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP); + } else { + al_reg_write32_masked(regs->axi.ctrl.master_arctl, + PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP, + PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP); + + al_reg_write32_masked(regs->axi.ctrl.master_awctl, + PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP, + PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP); + } + return 0; +} + +/************************** Configuration Space API ***************************/ + +/** get base address of pci configuration space header */ +int +al_pcie_config_space_get(struct al_pcie_pf *pcie_pf, + uint8_t __iomem **addr) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + + *addr = (uint8_t __iomem *)®s->core_space[pcie_pf->pf_num].config_header[0]; + return 0; +} + +/* Read data from the local configuration space */ +uint32_t +al_pcie_local_cfg_space_read( + struct al_pcie_pf *pcie_pf, + unsigned int reg_offset) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + uint32_t data; + + data = al_reg_read32(®s->core_space[pcie_pf->pf_num].config_header[reg_offset]); + + return data; +} + +/* Write data to the local configuration space */ +void +al_pcie_local_cfg_space_write( + struct al_pcie_pf *pcie_pf, + unsigned int reg_offset, + uint32_t data, + al_bool cs2, + al_bool allow_ro_wr) +{ + struct al_pcie_port *pcie_port = pcie_pf->pcie_port; + struct al_pcie_regs *regs = pcie_port->regs; + unsigned int pf_num = pcie_pf->pf_num; + uint32_t *offset = ®s->core_space[pf_num].config_header[reg_offset]; + + if (allow_ro_wr) + al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); + + if (cs2 == AL_FALSE) + al_reg_write32(offset, data); + else + al_reg_write32_dbi_cs2(pcie_port, offset, data); + + if (allow_ro_wr) + al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); +} + +/** set target_bus and mask_target_bus */ +int +al_pcie_target_bus_set( + struct al_pcie_port *pcie_port, + uint8_t target_bus, + uint8_t mask_target_bus) +{ + struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; + uint32_t reg; + + reg = al_reg_read32(regs->axi.ob_ctrl.cfg_target_bus); + AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT, + mask_target_bus); + AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_MASK, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_SHIFT, + target_bus); + al_reg_write32(regs->axi.ob_ctrl.cfg_target_bus, reg); + return 0; +} + +/** get target_bus and mask_target_bus */ +int +al_pcie_target_bus_get( + struct al_pcie_port *pcie_port, + uint8_t *target_bus, + uint8_t *mask_target_bus) +{ + struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; + uint32_t reg; + + al_assert(target_bus); + al_assert(mask_target_bus); + + reg = al_reg_read32(regs->axi.ob_ctrl.cfg_target_bus); + + *mask_target_bus = AL_REG_FIELD_GET(reg, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT); + *target_bus = AL_REG_FIELD_GET(reg, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_MASK, + PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_SHIFT); + return 0; +} + +/** Set secondary bus number */ +int +al_pcie_secondary_bus_set(struct al_pcie_port *pcie_port, uint8_t secbus) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + uint32_t secbus_val = (secbus << + PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_SHIFT); + + al_reg_write32_masked( + regs->axi.ob_ctrl.cfg_control, + PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_MASK, + secbus_val); + return 0; +} + +/** Set sub-ordinary bus number */ +int +al_pcie_subordinary_bus_set(struct al_pcie_port *pcie_port, uint8_t subbus) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + uint32_t subbus_val = (subbus << + PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_SHIFT); + + al_reg_write32_masked( + regs->axi.ob_ctrl.cfg_control, + PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_MASK, + subbus_val); + return 0; +} + +/* Enable/disable deferring incoming configuration requests */ +void +al_pcie_app_req_retry_set( + struct al_pcie_port *pcie_port, + al_bool en) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? + PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN : + PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN; + + al_reg_write32_masked(regs->app.global_ctrl.pm_control, + mask, (en == AL_TRUE) ? mask : 0); +} + +/*************** Internal Address Translation Unit (ATU) API ******************/ + +/** program internal ATU region entry */ +int +al_pcie_atu_region_set( + struct al_pcie_port *pcie_port, + struct al_pcie_atu_region *atu_region) +{ + struct al_pcie_regs *regs = pcie_port->regs; + enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); + uint32_t reg = 0; + + /** + * Addressing RMN: 5384 + * + * RMN description: + * From SNPS (also included in the data book) Dynamic iATU Programming + * With AHB/AXI Bridge Module When the bridge slave interface clock + * (hresetn or slv_aclk) is asynchronous to the PCIe native core clock + * (core_clk), you must not update the iATU registers while operations + * are in progress on the AHB/AXI bridge slave interface. The iATU + * registers are in the core_clk clock domain. The register outputs are + * used in the AHB/AXI bridge slave interface clock domain. There is no + * synchronization logic between these registers and the AHB/AXI bridge + * slave interface. + * + * Software flow: + * Do not allow configuring Outbound iATU after link is started + */ + if ((atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) + && (al_pcie_is_link_started(pcie_port))) { + if (!atu_region->enforce_ob_atu_region_set) { + al_err("PCIe %d: setting OB iATU after link is started is not allowed\n", + pcie_port->port_id); + return -EINVAL; + } else { + al_info("PCIe %d: setting OB iATU even after link is started\n", + pcie_port->port_id); + } + } + + /*TODO : add sanity check */ + AL_REG_FIELD_SET(reg, 0xF, 0, atu_region->index); + AL_REG_BIT_VAL_SET(reg, 31, atu_region->direction); + al_reg_write32(®s->port_regs->iatu.index, reg); + + al_reg_write32(®s->port_regs->iatu.lower_base_addr, + (uint32_t)(atu_region->base_addr & 0xFFFFFFFF)); + al_reg_write32(®s->port_regs->iatu.upper_base_addr, + (uint32_t)((atu_region->base_addr >> 32)& 0xFFFFFFFF)); + al_reg_write32(®s->port_regs->iatu.lower_target_addr, + (uint32_t)(atu_region->target_addr & 0xFFFFFFFF)); + al_reg_write32(®s->port_regs->iatu.upper_target_addr, + (uint32_t)((atu_region->target_addr >> 32)& 0xFFFFFFFF)); + + /* configure the limit, not needed when working in BAR match mode */ + if (atu_region->match_mode == 0) { + uint32_t limit_reg_val; + if (pcie_port->rev_id > AL_PCIE_REV_ID_0) { + uint32_t *limit_ext_reg = + (atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) ? + ®s->app.atu.out_mask_pair[atu_region->index / 2] : + ®s->app.atu.in_mask_pair[atu_region->index / 2]; + uint32_t limit_ext_reg_mask = + (atu_region->index % 2) ? + PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_MASK : + PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_MASK; + unsigned int limit_ext_reg_shift = + (atu_region->index % 2) ? + PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT : + PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT; + uint64_t limit_sz_msk = + atu_region->limit - atu_region->base_addr; + uint32_t limit_ext_reg_val = (uint32_t)(((limit_sz_msk) >> + 32) & 0xFFFFFFFF); + + if (limit_ext_reg_val) { + limit_reg_val = (uint32_t)((limit_sz_msk) & 0xFFFFFFFF); + al_assert(limit_reg_val == 0xFFFFFFFF); + } else { + limit_reg_val = (uint32_t)(atu_region->limit & + 0xFFFFFFFF); + } + + al_reg_write32_masked( + limit_ext_reg, + limit_ext_reg_mask, + limit_ext_reg_val << limit_ext_reg_shift); + } else { + limit_reg_val = (uint32_t)(atu_region->limit & 0xFFFFFFFF); + } + + al_reg_write32(®s->port_regs->iatu.limit_addr, + limit_reg_val); + } + + reg = 0; + AL_REG_FIELD_SET(reg, 0x1F, 0, atu_region->tlp_type); + AL_REG_FIELD_SET(reg, 0x3 << 9, 9, atu_region->attr); + + + if ((pcie_port->rev_id == AL_PCIE_REV_ID_3) + && (op_mode == AL_PCIE_OPERATING_MODE_EP) + && (atu_region->function_match_bypass_mode)) { + AL_REG_FIELD_SET(reg, + PCIE_IATU_CR1_FUNC_NUM_MASK, + PCIE_IATU_CR1_FUNC_NUM_SHIFT, + atu_region->function_match_bypass_mode_number); + } + + al_reg_write32(®s->port_regs->iatu.cr1, reg); + + /* Enable/disable the region. */ + reg = 0; + AL_REG_FIELD_SET(reg, 0xFF, 0, atu_region->msg_code); + AL_REG_FIELD_SET(reg, 0x700, 8, atu_region->bar_number); + AL_REG_FIELD_SET(reg, 0x3 << 24, 24, atu_region->response); + AL_REG_BIT_VAL_SET(reg, 16, atu_region->enable_attr_match_mode == AL_TRUE); + AL_REG_BIT_VAL_SET(reg, 21, atu_region->enable_msg_match_mode == AL_TRUE); + AL_REG_BIT_VAL_SET(reg, 28, atu_region->cfg_shift_mode == AL_TRUE); + AL_REG_BIT_VAL_SET(reg, 29, atu_region->invert_matching == AL_TRUE); + if (atu_region->tlp_type == AL_PCIE_TLP_TYPE_MEM || atu_region->tlp_type == AL_PCIE_TLP_TYPE_IO) + AL_REG_BIT_VAL_SET(reg, 30, !!atu_region->match_mode); + AL_REG_BIT_VAL_SET(reg, 31, !!atu_region->enable); + + /* In outbound, enable function bypass + * In inbound, enable function match mode + * Note: this is the same bit, has different meanings in ob/ib ATUs + */ + if (op_mode == AL_PCIE_OPERATING_MODE_EP) + AL_REG_FIELD_SET(reg, + PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_MASK, + PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_SHIFT, + atu_region->function_match_bypass_mode ? 0x1 : 0x0); + + al_reg_write32(®s->port_regs->iatu.cr2, reg); + + return 0; +} + +/** obtains internal ATU region base/target addresses */ +void +al_pcie_atu_region_get_fields( + struct al_pcie_port *pcie_port, + enum al_pcie_atu_dir direction, uint8_t index, + al_bool *enable, uint64_t *base_addr, uint64_t *target_addr) +{ + struct al_pcie_regs *regs = pcie_port->regs; + uint64_t high_addr; + uint32_t reg = 0; + + AL_REG_FIELD_SET(reg, 0xF, 0, index); + AL_REG_BIT_VAL_SET(reg, 31, direction); + al_reg_write32(®s->port_regs->iatu.index, reg); + + *base_addr = al_reg_read32(®s->port_regs->iatu.lower_base_addr); + high_addr = al_reg_read32(®s->port_regs->iatu.upper_base_addr); + high_addr <<= 32; + *base_addr |= high_addr; + + *target_addr = al_reg_read32(®s->port_regs->iatu.lower_target_addr); + high_addr = al_reg_read32(®s->port_regs->iatu.upper_target_addr); + high_addr <<= 32; + *target_addr |= high_addr; + + reg = al_reg_read32(®s->port_regs->iatu.cr1); + *enable = AL_REG_BIT_GET(reg, 31) ? AL_TRUE : AL_FALSE; +} + +void +al_pcie_axi_io_config( + struct al_pcie_port *pcie_port, + al_phys_addr_t start, + al_phys_addr_t end) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_reg_write32(regs->axi.ob_ctrl.io_start_h, + (uint32_t)((start >> 32) & 0xFFFFFFFF)); + + al_reg_write32(regs->axi.ob_ctrl.io_start_l, + (uint32_t)(start & 0xFFFFFFFF)); + + al_reg_write32(regs->axi.ob_ctrl.io_limit_h, + (uint32_t)((end >> 32) & 0xFFFFFFFF)); + + al_reg_write32(regs->axi.ob_ctrl.io_limit_l, + (uint32_t)(end & 0xFFFFFFFF)); + + al_reg_write32_masked(regs->axi.ctrl.slv_ctl, + PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN, + PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN); +} + +/************** Interrupt generation (Endpoint mode Only) API *****************/ + +/** generate INTx Assert/DeAssert Message */ +int +al_pcie_legacy_int_gen( + struct al_pcie_pf *pcie_pf, + al_bool assert, + enum al_pcie_legacy_int_type type) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + unsigned int pf_num = pcie_pf->pf_num; + uint32_t reg; + + al_assert(type == AL_PCIE_LEGACY_INTA); /* only INTA supported */ + reg = al_reg_read32(regs->app.global_ctrl.events_gen[pf_num]); + AL_REG_BIT_VAL_SET(reg, 3, !!assert); + al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg); + + return 0; +} + +/** generate MSI interrupt */ +int +al_pcie_msi_int_gen(struct al_pcie_pf *pcie_pf, uint8_t vector) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + unsigned int pf_num = pcie_pf->pf_num; + uint32_t reg; + + /* set msi vector and clear MSI request */ + reg = al_reg_read32(regs->app.global_ctrl.events_gen[pf_num]); + AL_REG_BIT_CLEAR(reg, 4); + AL_REG_FIELD_SET(reg, + PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_MASK, + PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_SHIFT, + vector); + al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg); + /* set MSI request */ + AL_REG_BIT_SET(reg, 4); + al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg); + + return 0; +} + +/** configure MSIX capability */ +int +al_pcie_msix_config( + struct al_pcie_pf *pcie_pf, + struct al_pcie_msix_params *msix_params) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + unsigned int pf_num = pcie_pf->pf_num; + uint32_t msix_reg0; + + al_pcie_port_wr_to_ro_set(pcie_pf->pcie_port, AL_TRUE); + + msix_reg0 = al_reg_read32(regs->core_space[pf_num].msix_cap_base); + + msix_reg0 &= ~(AL_PCI_MSIX_MSGCTRL_TBL_SIZE << AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT); + msix_reg0 |= ((msix_params->table_size - 1) & AL_PCI_MSIX_MSGCTRL_TBL_SIZE) << + AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT; + al_reg_write32(regs->core_space[pf_num].msix_cap_base, msix_reg0); + + /* Table offset & BAR */ + al_reg_write32(regs->core_space[pf_num].msix_cap_base + (AL_PCI_MSIX_TABLE >> 2), + (msix_params->table_offset & AL_PCI_MSIX_TABLE_OFFSET) | + (msix_params->table_bar & AL_PCI_MSIX_TABLE_BAR)); + /* PBA offset & BAR */ + al_reg_write32(regs->core_space[pf_num].msix_cap_base + (AL_PCI_MSIX_PBA >> 2), + (msix_params->pba_offset & AL_PCI_MSIX_PBA_OFFSET) | + (msix_params->pba_bar & AL_PCI_MSIX_PBA_BAR)); + + al_pcie_port_wr_to_ro_set(pcie_pf->pcie_port, AL_FALSE); + + return 0; +} + +/** check whether MSIX is enabled */ +al_bool +al_pcie_msix_enabled(struct al_pcie_pf *pcie_pf) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + uint32_t msix_reg0 = al_reg_read32(regs->core_space[pcie_pf->pf_num].msix_cap_base); + + if (msix_reg0 & AL_PCI_MSIX_MSGCTRL_EN) + return AL_TRUE; + return AL_FALSE; +} + +/** check whether MSIX is masked */ +al_bool +al_pcie_msix_masked(struct al_pcie_pf *pcie_pf) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + uint32_t msix_reg0 = al_reg_read32(regs->core_space[pcie_pf->pf_num].msix_cap_base); + + if (msix_reg0 & AL_PCI_MSIX_MSGCTRL_MASK) + return AL_TRUE; + return AL_FALSE; +} + +/******************** Advanced Error Reporting (AER) API **********************/ + +/** configure AER capability */ +int +al_pcie_aer_config( + struct al_pcie_pf *pcie_pf, + struct al_pcie_aer_params *params) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; + uint32_t reg_val; + + reg_val = al_reg_read32(&aer_regs->header); + + if (((reg_val & PCIE_AER_CAP_ID_MASK) >> PCIE_AER_CAP_ID_SHIFT) != + PCIE_AER_CAP_ID_VAL) + return -EIO; + + if (((reg_val & PCIE_AER_CAP_VER_MASK) >> PCIE_AER_CAP_VER_SHIFT) != + PCIE_AER_CAP_VER_VAL) + return -EIO; + + al_reg_write32(&aer_regs->corr_err_mask, ~params->enabled_corr_err); + + al_reg_write32(&aer_regs->uncorr_err_mask, + (~params->enabled_uncorr_non_fatal_err) | + (~params->enabled_uncorr_fatal_err)); + + al_reg_write32(&aer_regs->uncorr_err_severity, + params->enabled_uncorr_fatal_err); + + al_reg_write32(&aer_regs->cap_and_ctrl, + (params->ecrc_gen_en ? PCIE_AER_CTRL_STAT_ECRC_GEN_EN : 0) | + (params->ecrc_chk_en ? PCIE_AER_CTRL_STAT_ECRC_CHK_EN : 0)); + + al_reg_write32_masked( + regs->core_space[pcie_pf->pf_num].pcie_dev_ctrl_status, + PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN | + PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN | + PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN | + PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN, + (params->enabled_corr_err ? + PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN : 0) | + (params->enabled_uncorr_non_fatal_err ? + PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN : 0) | + (params->enabled_uncorr_fatal_err ? + PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN : 0) | + ((params->enabled_uncorr_non_fatal_err & + AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR) ? + PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN : 0) | + ((params->enabled_uncorr_fatal_err & + AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR) ? + PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN : 0)); + + return 0; +} + +/** AER uncorretable errors get and clear */ +unsigned int +al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; + uint32_t reg_val; + + reg_val = al_reg_read32(&aer_regs->uncorr_err_stat); + al_reg_write32(&aer_regs->uncorr_err_stat, reg_val); + + return reg_val; +} + +/** AER corretable errors get and clear */ +unsigned int +al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; + uint32_t reg_val; + + reg_val = al_reg_read32(&aer_regs->corr_err_stat); + al_reg_write32(&aer_regs->corr_err_stat, reg_val); + + return reg_val; +} + +#if (AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS != 4) +#error Wrong assumption! +#endif + +/** AER get the header for the TLP corresponding to a detected error */ +void +al_pcie_aer_err_tlp_hdr_get( + struct al_pcie_pf *pcie_pf, + uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]) +{ + struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; + struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; + int i; + + for (i = 0; i < AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS; i++) + hdr[i] = al_reg_read32(&aer_regs->header_log[i]); +} + +/********************** Loopback mode (RC and Endpoint modes) ************/ + +/** enter local pipe loopback mode */ +int +al_pcie_local_pipe_loopback_enter(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_dbg("PCIe %d: Enter LOCAL PIPE Loopback mode", pcie_port->port_id); + + al_reg_write32_masked(®s->port_regs->pipe_loopback_ctrl, + 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT, + 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT); + + al_reg_write32_masked(®s->port_regs->port_link_ctrl, + 1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT, + 1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT); + + return 0; +} + +/** + * @brief exit local pipe loopback mode + * + * @param pcie_port pcie port handle + * @return 0 if no error found + */ +int +al_pcie_local_pipe_loopback_exit(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_dbg("PCIe %d: Exit LOCAL PIPE Loopback mode", pcie_port->port_id); + + al_reg_write32_masked(®s->port_regs->pipe_loopback_ctrl, + 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT, + 0); + + al_reg_write32_masked(®s->port_regs->port_link_ctrl, + 1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT, + 0); + return 0; +} + +/** enter remote loopback mode */ +int +al_pcie_remote_loopback_enter(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_dbg("PCIe %d: Enter REMOTE Loopback mode", pcie_port->port_id); + + al_reg_write32_masked(®s->port_regs->port_link_ctrl, + 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT, + 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT); + + return 0; +} + +/** + * @brief exit remote loopback mode + * + * @param pcie_port pcie port handle + * @return 0 if no error found + */ +int +al_pcie_remote_loopback_exit(struct al_pcie_port *pcie_port) +{ + struct al_pcie_regs *regs = pcie_port->regs; + + al_dbg("PCIe %d: Exit REMOTE Loopback mode", pcie_port->port_id); + + al_reg_write32_masked(®s->port_regs->port_link_ctrl, + 1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT, + 0); + return 0; +} diff --git a/al_hal_pcie.h b/al_hal_pcie.h new file mode 100644 index 000000000000..1ddc8eb70749 --- /dev/null +++ b/al_hal_pcie.h @@ -0,0 +1,1157 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @defgroup grouppcie PCI Express Controller + * @{ + * @section overview Overview + * This header file provide API for the HAL driver of the pcie port, the driver + * provides the following functionalities: + * - Port initialization + * - Link operation + * - Interrupts transactions generation (Endpoint mode). + * - Configuration Access management functions + * - Internal Translation Unit programming + * + * This API does not provide the following: + * - PCIe transactions generation and reception (except interrupts as mentioned + * above) as this functionality is done by the port without need for sw + * intervention. + * - Configuration Access: those transactions are generated automatically by + * the port (ECAM or ATU mode) when the CPU issues memory transaction + * through the fabric toward the PCIe port. This API provides management + * function for controlling the Configuration Access type and bus destination + * - Interrupt Handling. + * - Message Generation: common used messages are automatically generated, also, + * the ATU generic mechanism for generating various kind of messages. + * - PCIe Port Management: both link and port power management features can be + * managed using the PCI/PCIe standard power management and PCIe capabilities + * registers. + * - PCIe link and protocol error handling: the feature can be managed using + * the Advanced Error Handling PCIe capability registers. + * + * @section flows Software Flows + * @subsection init Initialization + * - allocation and set zeros al_pcie_port and al_pcie_pf structures handles + * - call al_pcie_port_handle_init() with pointer to the allocated + * al_pcie_port handle, address of the port internal registers space, and + * port id. + * - call al_pcie_pf_handle_init() with pointer to the al_pcie_port handle + * and pf_number. + * - set the port mode, End-Point or Root-Compex (default). + * - set number of lanes connected to the controller. + * - enable the controller using the al_pcie_port_enable(). note that this + * function expect the virtual address of the PBS Functional Registers. + * - wait for 2000 South-bridge cycles. + * - prepare al_pcie_port_config_params and al_pcie_pf_config_params + * structures depending on chip, board and system configuration. + * for example, when using the port as root complex, the operating_mode + * field should be set to AL_PCIE_OPERATING_MODE_RC. In this example we + * prepare the following configuration: + * For port configuration + * - Root Complex mode + * - Set the Max Link Speed to Gen2 + * - Set the max lanes width to 2 (x2) + * - Disable reversal mode + * - Enable Snoops to support I/O Hardware cache coherency + * - Enable pcie core RAM parity + * - Enable pcie core AXI parity + * - Keep transaction layer default credits + * For pf configuration + * - No EP parameters + * - No SR-IOV parameters + * so the structures we prepare: + * @code + * - struct al_pcie_link_params link_params = { + * AL_PCIE_LINK_SPEED_GEN2, + * AL_FALSE, // disable reversal mode + * AL_PCIE_MPS_DEFAULT}; + * + * - struct al_pcie_port_config_params config_params = { + * &link_params, + * AL_TRUE, // enable Snoop for inbound memory transactions + * AL_TRUE, // enable pcie port RAM parity + * AL_TRUE, // enable pcie port AXI parity + * NULL, // use default latency/replay timers + * NULL, // use default gen2 pipe params + * NULL, // gen3_params not needed when max speed set to Gen2 + * NULL, // don't change TL credits + * NULL, // end point params not needed + * AL_FALSE, //no fast link + * AL_FALSE}; //return 0xFFFFFFFF for read transactions with + * //pci target error + * @endcode + * - now call al_pcie_port_config() with pcie_port and port_config_params + * @subsection link-init Link Initialization + * - once the port configured, we can start PCIe link: + * - call al_pcie_link_start() + * - call al_pcie_link_up_wait() + * - allocate al_pcie_link_status struct and call al_pcie_link_status() and + * check the link is established. + * + * @subsection cap Configuration Access Preparation + * - Once the link is established, we can prepare the port for pci + * configuration access, this stage requires system knowledge about the PCI + * buses enumeration. For example, if 5 buses were discovered on previously + * scanned root complex port, then we should start enumeration from bus 5 (PCI + * secondary bus), the sub-ordinary bus will be temporarily set to maximum + * value (255) until the scan process under this bus is finished, then it will + * updated to the maximum bus value found. So we use the following sequence: + * - call al_pcie_secondary_bus_set() with sec-bus = 5 + * - call al_pcie_subordinary_bus_set() with sub-bus = 255 + * + * @subsection cfg Configuration (Cfg) Access Generation + * - we assume using ECAM method, in this method, the software issues pcie Cfg + * access by accessing the ECAM memory space of the pcie port. For example, to + * issue 4 byte Cfg Read from bus B, Device D, Function F and register R, the + * software issues 4 byte read access to the following physical address + * ECAM base address of the port + (B << 20) + (D << 15) + (F << 12) + R. + * But, as the default size of the ECAM address space is less than + * needed full range (256MB), we modify the target_bus value prior to Cfg + * access in order make the port generate Cfg access with bus value set to the + * value of the target_bus rather than bits 27:20 of the physical address. + * - call al_pcie_target_bus_set() with target_bus set to the required bus of + * the next Cfg access to be issued, mask_target_bus will be set to 0xff. + * no need to call that function if the next Cfg access bus equals to the last + * value set to target_bus. + * + * @file al_hal_pcie.h + * @brief HAL Driver Header for the Annapurna Labs PCI Express port. + */ + +#ifndef _AL_HAL_PCIE_H_ +#define _AL_HAL_PCIE_H_ + +#include "al_hal_common.h" +#include "al_hal_pcie_regs.h" + +/******************************************************************************/ +/********************************* Constants **********************************/ +/******************************************************************************/ + +/** Inbound header credits sum - rev 0/1/2 */ +#define AL_PCIE_REV_1_2_IB_HCRD_SUM 97 +/** Inbound header credits sum - rev 3 */ +#define AL_PCIE_REV3_IB_HCRD_SUM 259 + +/** Number of extended registers */ +#define AL_PCIE_EX_REGS_NUM 40 + +/******************************************************************************* + * PCIe AER uncorrectable error bits + * To be used with the following functions: + * - al_pcie_aer_config + * - al_pcie_aer_uncorr_get_and_clear + ******************************************************************************/ +/** Data Link Protocol Error */ +#define AL_PCIE_AER_UNCORR_DLP_ERR AL_BIT(4) +/** Poisoned TLP */ +#define AL_PCIE_AER_UNCORR_POISIONED_TLP AL_BIT(12) +/** Flow Control Protocol Error */ +#define AL_PCIE_AER_UNCORR_FLOW_CTRL_ERR AL_BIT(13) +/** Completion Timeout */ +#define AL_PCIE_AER_UNCORR_COMPL_TO AL_BIT(14) +/** Completer Abort */ +#define AL_PCIE_AER_UNCORR_COMPL_ABT AL_BIT(15) +/** Unexpected Completion */ +#define AL_PCIE_AER_UNCORR_UNEXPCTED_COMPL AL_BIT(16) +/** Receiver Overflow */ +#define AL_PCIE_AER_UNCORR_RCV_OVRFLW AL_BIT(17) +/** Malformed TLP */ +#define AL_PCIE_AER_UNCORR_MLFRM_TLP AL_BIT(18) +/** ECRC Error */ +#define AL_PCIE_AER_UNCORR_ECRC_ERR AL_BIT(19) +/** Unsupported Request Error */ +#define AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR AL_BIT(20) +/** Uncorrectable Internal Error */ +#define AL_PCIE_AER_UNCORR_INT_ERR AL_BIT(22) +/** AtomicOp Egress Blocked */ +#define AL_PCIE_AER_UNCORR_ATOMIC_EGRESS_BLK AL_BIT(24) + +/******************************************************************************* + * PCIe AER correctable error bits + * To be used with the following functions: + * - al_pcie_aer_config + * - al_pcie_aer_corr_get_and_clear + ******************************************************************************/ +/** Receiver Error */ +#define AL_PCIE_AER_CORR_RCV_ERR AL_BIT(0) +/** Bad TLP */ +#define AL_PCIE_AER_CORR_BAD_TLP AL_BIT(6) +/** Bad DLLP */ +#define AL_PCIE_AER_CORR_BAD_DLLP AL_BIT(7) +/** REPLAY_NUM Rollover */ +#define AL_PCIE_AER_CORR_RPLY_NUM_ROLL_OVR AL_BIT(8) +/** Replay Timer Timeout */ +#define AL_PCIE_AER_CORR_RPLY_TMR_TO AL_BIT(12) +/** Advisory Non-Fatal Error */ +#define AL_PCIE_AER_CORR_ADVISORY_NON_FTL_ERR AL_BIT(13) +/** Corrected Internal Error */ +#define AL_PCIE_AER_CORR_INT_ERR AL_BIT(14) + +/** The AER erroneous TLP header length [num DWORDs] */ +#define AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS 4 + +/******************************************************************************/ +/************************* Data Structures and Types **************************/ +/******************************************************************************/ + +/** + * al_pcie_ib_hcrd_config: data structure internally used in order to config + * inbound posted/non-posted parameters. + * Note: it's required to have this structure in pcie_port handle since it has + * a state (required/not-required) which is determined by outbound + * outstanding configuration + */ +struct al_pcie_ib_hcrd_config { + /* Internally used - see 'al_pcie_ib_hcrd_os_ob_reads_config' */ + unsigned int nof_np_hdr; + + /* Internally used - see 'al_pcie_ib_hcrd_os_ob_reads_config' */ + unsigned int nof_p_hdr; +}; + +/* The Max Payload Size. Measured in bytes. + * DEFAULT: do not change the current MPS + */ +enum al_pcie_max_payload_size { + AL_PCIE_MPS_DEFAULT, + AL_PCIE_MPS_128 = 0, + AL_PCIE_MPS_256 = 1, + AL_PCIE_MPS_512 = 2, + AL_PCIE_MPS_1024 = 3, + AL_PCIE_MPS_2048 = 4, + AL_PCIE_MPS_4096 = 5, +}; + +/** + * al_pcie_port: data structure used by the HAL to handle a specific pcie port. + * this structure is allocated and set to zeros by the upper layer, then it is + * initialized by the al_pcie_port_handle_init() that should be called before any + * other function of this API. later, this handle passed to the API functions. + */ +struct al_pcie_port { + void __iomem *pcie_reg_base; + struct al_pcie_regs regs_ptrs; + struct al_pcie_regs *regs; + uint32_t *ex_regs_ptrs[AL_PCIE_EX_REGS_NUM]; + void *ex_regs; + void __iomem *pbs_regs; + + /* Revision ID */ + uint8_t rev_id; + unsigned int port_id; + uint8_t max_lanes; + uint8_t max_num_of_pfs; + + /* Internally used */ + struct al_pcie_ib_hcrd_config ib_hcrd_config; +}; + +/** + * al_pcie_pf: the pf handle, a data structure used to handle PF specific + * functionality. Initialized using "al_pcie_pf_handle_init()" + */ +struct al_pcie_pf { + unsigned int pf_num; + struct al_pcie_port *pcie_port; +}; + +/** Operating mode (endpoint, root complex) */ +enum al_pcie_operating_mode { + AL_PCIE_OPERATING_MODE_EP, + AL_PCIE_OPERATING_MODE_RC, + AL_PCIE_OPERATING_MODE_UNKNOWN +}; + +/* The maximum link speed, measured GT/s (Giga transfer / second) + * DEFAULT: do not change the current speed + * GEN1: 2.5 GT/s + * GEN2: 5 GT/s + * GEN3: 8GT/s + * + * Note: The values of this enumerator are important for proper behavior + */ +enum al_pcie_link_speed { + AL_PCIE_LINK_SPEED_DEFAULT, + AL_PCIE_LINK_SPEED_GEN1 = 1, + AL_PCIE_LINK_SPEED_GEN2 = 2, + AL_PCIE_LINK_SPEED_GEN3 = 3 +}; + +/** PCIe capabilities that supported by a specific port */ +struct al_pcie_max_capability { + al_bool end_point_mode_supported; + al_bool root_complex_mode_supported; + enum al_pcie_link_speed max_speed; + uint8_t max_lanes; + al_bool reversal_supported; + uint8_t atu_regions_num; + uint32_t atu_min_size; +}; + +/** PCIe link related parameters */ +struct al_pcie_link_params { + enum al_pcie_link_speed max_speed; + al_bool enable_reversal; + enum al_pcie_max_payload_size max_payload_size; + +}; + +/** PCIe gen2 link parameters */ +struct al_pcie_gen2_params { + al_bool tx_swing_low; /* set tx swing low when true, and tx swing full when false */ + al_bool tx_compliance_receive_enable; + al_bool set_deemphasis; +}; + +/** PCIe gen 3 standard per lane equalization parameters */ +struct al_pcie_gen3_lane_eq_params { + uint8_t downstream_port_transmitter_preset; + uint8_t downstream_port_receiver_preset_hint; + uint8_t upstream_port_transmitter_preset; + uint8_t upstream_port_receiver_preset_hint; +}; + +/** PCIe gen 3 equalization parameters */ +struct al_pcie_gen3_params { + al_bool perform_eq; + al_bool interrupt_enable_on_link_eq_request; + struct al_pcie_gen3_lane_eq_params *eq_params; /* array of lanes params */ + int eq_params_elements; /* number of elements in the eq_params array */ + + al_bool eq_disable; /* disables the equalization feature */ + al_bool eq_phase2_3_disable; /* Equalization Phase 2 and Phase 3 */ + /* Disable (RC mode only) */ + uint8_t local_lf; /* Full Swing (FS) Value for Gen3 Transmit Equalization */ + /* Value Range: 12 through 63 (decimal).*/ + + uint8_t local_fs; /* Low Frequency (LF) Value for Gen3 Transmit Equalization */ +}; + +/** Transport Layer credits parameters */ +struct al_pcie_tl_credits_params { +}; + +/** Various configuration features */ +struct al_pcie_features { + /** + * Enable MSI fix from the SATA to the PCIe EP + * Only valid for port 0, when enabled as EP + */ + al_bool sata_ep_msi_fix; +}; + +/** + * Inbound posted/non-posted header credits and outstanding outbound reads + * completion header configuration + * + * Constraints: + * - nof_cpl_hdr + nof_np_hdr + nof_p_hdr == + * AL_PCIE_REV_1_2_IB_HCRD_SUM/AL_PCIE_REV3_IB_HCRD_SUM + * - nof_cpl_hdr > 0 + * - nof_p_hdr > 0 + * - nof_np_hdr > 0 + */ +struct al_pcie_ib_hcrd_os_ob_reads_config { + /** Max number of outstanding outbound reads */ + uint8_t nof_outstanding_ob_reads; + + /** + * This value set the possible outstanding headers CMPLs , the core + * can get (the core always advertise infinite credits for CMPLs). + */ + unsigned int nof_cpl_hdr; + + /** + * This value set the possible outstanding headers reads (non-posted + * transactions), the core can get (it set the value in the init FC + * process). + */ + unsigned int nof_np_hdr; + + /** + * This value set the possible outstanding headers writes (posted + * transactions), the core can get (it set the value in the init FC + * process). + */ + unsigned int nof_p_hdr; +}; + +/** PCIe Ack/Nak Latency and Replay timers */ +struct al_pcie_latency_replay_timers { + uint16_t round_trip_lat_limit; + uint16_t replay_timer_limit; +}; + +/* SRIS KP counter values */ +struct al_pcie_sris_params { + /** set to AL_TRUE to use defaults and ignore the other parameters */ + al_bool use_defaults; + uint16_t kp_counter_gen3; /* only for Gen3 */ + uint16_t kp_counter_gen21; +}; + +/** Relaxed ordering params */ +struct al_pcie_relaxed_ordering_params { + al_bool enable_tx_relaxed_ordering; + al_bool enable_rx_relaxed_ordering; +}; + +/** PCIe port configuration parameters + * This structure includes the parameters that the HAL should apply to the port + * (by al_pcie_port_config()). + * The fields that are pointers (e.g. link_params) can be set to NULL, in that + * case, the al_pcie_port_config() will keep the current HW settings. + */ +struct al_pcie_port_config_params { + struct al_pcie_link_params *link_params; + al_bool enable_axi_snoop; + al_bool enable_ram_parity_int; + al_bool enable_axi_parity_int; + struct al_pcie_latency_replay_timers *lat_rply_timers; + struct al_pcie_gen2_params *gen2_params; + struct al_pcie_gen3_params *gen3_params; + struct al_pcie_tl_credits_params *tl_credits; + struct al_pcie_features *features; + /* Sets all internal timers to Fast Mode for speeding up simulation.*/ + al_bool fast_link_mode; + /* + * when true, the PCI unit will return Slave Error/Decoding Error to the master unit in case + * of error. when false, the value 0xFFFFFFFF will be returned without error indication. + */ + al_bool enable_axi_slave_err_resp; + struct al_pcie_sris_params *sris_params; + struct al_pcie_relaxed_ordering_params *relaxed_ordering_params; +}; + +/** BAR register configuration parameters (Endpoint Mode only) */ +struct al_pcie_ep_bar_params { + al_bool enable; + al_bool memory_space; /**< memory or io */ + al_bool memory_64_bit; /**< is memory space is 64 bit */ + al_bool memory_is_prefetchable; + uint64_t size; /* the bar size in bytes */ +}; + +/** PF config params (EP mode only) */ +struct al_pcie_pf_config_params { + al_bool cap_d1_d3hot_dis; + al_bool cap_flr_dis; + al_bool cap_aspm_dis; + al_bool bar_params_valid; + struct al_pcie_ep_bar_params bar_params[6]; + struct al_pcie_ep_bar_params exp_bar_params;/* expansion ROM BAR*/ +}; + +/** PCIe link status */ +struct al_pcie_link_status { + al_bool link_up; + enum al_pcie_link_speed speed; + uint8_t lanes; + uint8_t ltssm_state; +}; + +/** PCIe lane status */ +struct al_pcie_lane_status { + al_bool is_reset; + enum al_pcie_link_speed requested_speed; +}; + +/** PCIe MSIX capability configuration parameters */ +struct al_pcie_msix_params { + uint16_t table_size; + uint16_t table_offset; + uint8_t table_bar; + uint16_t pba_offset; + uint16_t pba_bar; +}; + +/** PCIE AER capability parameters */ +struct al_pcie_aer_params { + /** ECRC Generation Enable */ + al_bool ecrc_gen_en; + /** ECRC Check Enable */ + al_bool ecrc_chk_en; + + /** + * Enabled reporting of correctable errors (bit mask) + * See 'AL_PCIE_AER_CORR_*' for details + * 0 - no reporting at all + */ + unsigned int enabled_corr_err; + /** + * Enabled reporting of non-fatal uncorrectable errors (bit mask) + * See 'AL_PCIE_AER_UNCORR_*' for details + * 0 - no reporting at all + */ + unsigned int enabled_uncorr_non_fatal_err; + /** + * Enabled reporting of fatal uncorrectable errors (bit mask) + * See 'AL_PCIE_AER_UNCORR_*' for details + * 0 - no reporting at all + */ + unsigned int enabled_uncorr_fatal_err; +}; + +/******************************************************************************/ +/********************************** PCIe API **********************************/ +/******************************************************************************/ + +/*************************** PCIe Initialization API **************************/ + +/** + * Initializes a PCIe port handle structure. + * + * @param pcie_port an allocated, non-initialized instance. + * @param pcie_reg_base the virtual base address of the port internal + * registers + * @param pbs_reg_base the virtual base address of the pbs functional + * registers + * @param port_id the port id (used mainly for debug messages) + * + * @return 0 if no error found. + */ +int al_pcie_port_handle_init(struct al_pcie_port *pcie_port, + void __iomem *pcie_reg_base, + void __iomem *pbs_reg_base, + unsigned int port_id); + +/** + * Initializes a PCIe pf handle structure + * @param pcie_pf an allocated, non-initialized instance of pf handle + * @param pcie_port pcie port handle + * @param pf_num physical function number + * @return 0 if no error found + */ +int al_pcie_pf_handle_init( + struct al_pcie_pf *pcie_pf, + struct al_pcie_port *pcie_port, + unsigned int pf_num); + +/************************** Pre PCIe Port Enable API **************************/ + +/** + * @brief set current pcie operating mode (root complex or endpoint) + * This function can be called only before enabling the controller using + * al_pcie_port_enable(). + * + * @param pcie_port pcie port handle + * @param mode pcie operating mode + * + * @return 0 if no error found. + */ +int al_pcie_port_operating_mode_config(struct al_pcie_port *pcie_port, + enum al_pcie_operating_mode mode); + +/** + * Configure number of lanes connected to this port. + * This function can be called only before enabling the controller using al_pcie_port_enable(). + * + * @param pcie_port pcie port handle + * @param lanes number of lanes + * Note: this function must be called before any al_pcie_port_config() calls + * + * @return 0 if no error found. + */ +int al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes); + +/** + * Set maximum physical function numbers + * @param pcie_port pcie port handle + * @param max_num_of_pfs number of physical functions + * Note: this function must be called before any al_pcie_pf_config() calls + */ +int al_pcie_port_max_num_of_pfs_set( + struct al_pcie_port *pcie_port, + uint8_t max_num_of_pfs); + +/** + * @brief Inbound posted/non-posted header credits and outstanding outbound + * reads completion header configuration + * + * @param pcie_port pcie port handle + * @param ib_hcrd_os_ob_reads_config + * Inbound header credits and outstanding outbound reads + * configuration + */ +int al_pcie_port_ib_hcrd_os_ob_reads_config( + struct al_pcie_port *pcie_port, + struct al_pcie_ib_hcrd_os_ob_reads_config *ib_hcrd_os_ob_reads_config); + +/** return PCIe operating mode + * @param pcie_port pcie port handle + * @return operating mode + */ +enum al_pcie_operating_mode al_pcie_operating_mode_get( + struct al_pcie_port *pcie_port); + +/**************************** PCIe Port Enable API ****************************/ + +/** Enable PCIe unit (deassert reset) + * + * @param pcie_port pcie port handle + * + * @return 0 if no error found. + */ +int al_pcie_port_enable(struct al_pcie_port *pcie_port); + +/** Disable PCIe unit (assert reset) + * + * @param pcie_port pcie port handle + */ +void al_pcie_port_disable(struct al_pcie_port *pcie_port); + +/** + * Port memory shutdown/up + * Caution: This function can be called only when the controller is disabled + * + * @param pcie_port pcie port handle + * @param enable memory shutdown enable or disable + * + */ +int al_pcie_port_memory_shutdown_set( + struct al_pcie_port *pcie_port, + al_bool enable); + +/** + * Check if port enabled or not + * @param pcie_port pcie port handle + * @return AL_TRUE of port enabled and AL_FALSE otherwise + */ +al_bool al_pcie_port_is_enabled(struct al_pcie_port *pcie_port); + +/*************************** PCIe Configuration API ***************************/ + +/** + * @brief configure pcie port (mode, link params, etc..) + * this function must be called before initializing the link + * + * @param pcie_port pcie port handle + * @param params configuration structure. + * + * @return 0 if no error found + */ +int al_pcie_port_config(struct al_pcie_port *pcie_port, + const struct al_pcie_port_config_params *params); + +/** + * @brief Configure a specific PF (EP params, sriov params, ...) + * this function must be called before any datapath transactions + * + * @param pcie_pf pcie pf handle + * @param params configuration structure. + * + * @return 0 if no error found + */ +int al_pcie_pf_config( + struct al_pcie_pf *pcie_pf, + const struct al_pcie_pf_config_params *params); + +/************************** PCIe Link Operations API **************************/ + +/** + * @brief start pcie link + * + * @param pcie_port pcie port handle + * + * @return 0 if no error found + */ +int al_pcie_link_start(struct al_pcie_port *pcie_port); + +/** + * @brief stop pcie link + * + * @param pcie_port pcie port handle + * + * @return 0 if no error found + */ +int al_pcie_link_stop(struct al_pcie_port *pcie_port); + +/** + * @brief trigger link-disable + * + * @param pcie_port pcie port handle + * @param disable AL_TRUE to disable the link and AL_FALSE to enable it + * + * Note: this functionality differs from "al_pcie_link_stop" as it's a spec + * functionality where both sides of the PCIe agrees to disable the link + * @return 0 if no error found + */ +int al_pcie_link_disable(struct al_pcie_port *pcie_port, al_bool disable); + +/** + * @brief wait for link up indication + * this function waits for link up indication, it polls LTSSM state until link is ready + * + * @param pcie_port pcie port handle + * @param timeout_ms maximum timeout in milli-seconds to wait for link up + * + * @return 0 if link up indication detected + * -ETIME if not. + */ +int al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms); + +/** + * @brief get link status + * + * @param pcie_port pcie port handle + * @param status structure for link status + * + * @return 0 if no error found + */ +int al_pcie_link_status(struct al_pcie_port *pcie_port, struct al_pcie_link_status *status); + +/** + * @brief get lane status + * + * @param pcie_port + * pcie port handle + * @param lane + * PCIe lane + * @param status + * Pointer to returned structure for lane status + * + */ +void al_pcie_lane_status_get( + struct al_pcie_port *pcie_port, + unsigned int lane, + struct al_pcie_lane_status *status); + +/** + * @brief trigger hot reset + * + * @param pcie_port pcie port handle + * @param enable AL_TRUE to enable hot-reset and AL_FALSE to disable it + * + * @return 0 if no error found + */ +int al_pcie_link_hot_reset(struct al_pcie_port *pcie_port, al_bool enable); + +/** + * @brief trigger link-retain + * this function initiates Link retraining by directing the Physical Layer LTSSM + * to the Recovery state. If the LTSSM is already in Recovery or Configuration, + * re-entering Recovery is permitted but not required. + + * @param pcie_port pcie port handle + * + * Note: there's no need to disable initiating link-retrain + * @return 0 if no error found + */ +int al_pcie_link_retrain(struct al_pcie_port *pcie_port); + +/** + * @brief change port speed + * this function changes the port speed, it doesn't wait for link re-establishment + * + * @param pcie_port pcie port handle + * @param new_speed the new speed gen to set + * + * @return 0 if no error found + */ +int al_pcie_link_change_speed(struct al_pcie_port *pcie_port, enum al_pcie_link_speed new_speed); + +/* TODO: check if this function needed */ +int al_pcie_link_change_width(struct al_pcie_port *pcie_port, uint8_t width); + +/**************************** Post Link Start API *****************************/ + +/************************** Snoop Configuration API ***************************/ + +/** + * @brief configure pcie port axi snoop + * + * @param pcie_port pcie port handle + * @param enable_axi_snoop enable snoop. + * + * @return 0 if no error found + */ +/* TODO: Can this API be called after port enable? */ +int al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, + al_bool enable_axi_snoop); + +/************************** Configuration Space API ***************************/ + +/** + * Configuration Space Access Through PCI-E_ECAM_Ext PASW (RC mode only) + */ + +/** + * @brief get base address of pci configuration space header + * @param pcie_pf pcie pf handle + * @param addr pointer for returned address; + * @return 0 if no error found + */ +int al_pcie_config_space_get( + struct al_pcie_pf *pcie_pf, + uint8_t __iomem **addr); + +/** + * Read data from the local configuration space + * + * @param pcie_pf pcie pf handle + * @param reg_offset Configuration space register offset + * @return Read data + */ +uint32_t al_pcie_local_cfg_space_read( + struct al_pcie_pf *pcie_pf, + unsigned int reg_offset); + +/** + * Write data to the local configuration space + * + * @param pcie_pf PCIe pf handle + * @param reg_offset Configuration space register offset + * @param data Data to write + * @param cs2 Should be AL_TRUE if dbi_cs2 must be asserted + * to enable writing to this register, according to + * the PCIe Core specifications + * @param allow_ro_wr AL_TRUE to allow writing into read-only regs + * + */ +void al_pcie_local_cfg_space_write( + struct al_pcie_pf *pcie_pf, + unsigned int reg_offset, + uint32_t data, + al_bool cs2, + al_bool allow_ro_wr); + +/** + * @brief set target_bus and mask_target_bus + * @param pcie_port pcie port handle + * @param target_bus + * @param mask_target_bus + * @return 0 if no error found + */ +int al_pcie_target_bus_set(struct al_pcie_port *pcie_port, + uint8_t target_bus, + uint8_t mask_target_bus); + +/** + * @brief get target_bus and mask_target_bus + * @param pcie_port pcie port handle + * @param target_bus + * @param mask_target_bus + * @return 0 if no error found + */ +int al_pcie_target_bus_get(struct al_pcie_port *pcie_port, + uint8_t *target_bus, + uint8_t *mask_target_bus); + +/** + * Set secondary bus number + * + * @param pcie_port pcie port handle + * @param secbus pci secondary bus number + * + * @return 0 if no error found. + */ +int al_pcie_secondary_bus_set(struct al_pcie_port *pcie_port, uint8_t secbus); + +/** + * Set subordinary bus number + * + * @param pcie_port pcie port handle + * @param subbus the highest bus number of all of the buses that can be reached + * downstream of the PCIE instance. + * + * @return 0 if no error found. + */ +int al_pcie_subordinary_bus_set(struct al_pcie_port *pcie_port,uint8_t subbus); + +/** + * @brief Enable/disable deferring incoming configuration requests until + * initialization is complete. When enabled, the core completes incoming + * configuration requests with a Configuration Request Retry Status. + * Other incoming Requests complete with Unsupported Request status. + * + * @param pcie_port pcie port handle + * @param en enable/disable + */ +void al_pcie_app_req_retry_set(struct al_pcie_port *pcie_port, al_bool en); + +/*************** Internal Address Translation Unit (ATU) API ******************/ + +enum al_pcie_atu_dir { + AL_PCIE_ATU_DIR_OUTBOUND = 0, + AL_PCIE_ATU_DIR_INBOUND = 1, +}; + +enum al_pcie_atu_tlp { + AL_PCIE_TLP_TYPE_MEM = 0, + AL_PCIE_TLP_TYPE_IO = 2, + AL_PCIE_TLP_TYPE_CFG0 = 4, + AL_PCIE_TLP_TYPE_CFG1 = 5, + AL_PCIE_TLP_TYPE_MSG = 0x10, + AL_PCIE_TLP_TYPE_RESERVED = 0x1f +}; + +enum al_pcie_atu_response { + AL_PCIE_RESPONSE_NORMAL = 0, + AL_PCIE_RESPONSE_UR = 1, + AL_PCIE_RESPONSE_CA = 2 +}; + +struct al_pcie_atu_region { + al_bool enable; + /* outbound or inbound */ + enum al_pcie_atu_dir direction; + /* region index */ + uint8_t index; + uint64_t base_addr; + /** limit marks the region's end address. only bits [39:0] are valid + * given the Alpine PoC maximum physical address space + */ + uint64_t limit; + /** the address that matches will be translated to this address + offset + */ + uint64_t target_addr; + al_bool invert_matching; + /* pcie tlp type*/ + enum al_pcie_atu_tlp tlp_type; + /* pcie frame header attr field*/ + uint8_t attr; + /** + * outbound specific params + */ + /* pcie message code */ + uint8_t msg_code; + al_bool cfg_shift_mode; + /** + * inbound specific params + */ + uint8_t bar_number; + /* BAR match mode, used in EP for MEM and IO tlps*/ + uint8_t match_mode; + /** + * For outbound: enables taking the function number of the translated + * TLP from the PCIe core. For inbound: enables ATU function match mode + * Note: this boolean is ignored in RC mode + */ + al_bool function_match_bypass_mode; + /** + * The function number to match/bypass (see previous parameter) + * Note: this parameter is ignored when previous param is FALSE + */ + uint8_t function_match_bypass_mode_number; + /* response code */ + enum al_pcie_atu_response response; + al_bool enable_attr_match_mode; + al_bool enable_msg_match_mode; + /** + * USE WITH CAUTION: setting this boolean to AL_TRUE allows setting the + * outbound ATU even after link is already started. DO NOT SET this + * boolean to AL_TRUE unless there have been NO traffic before calling + * al_pcie_atu_region_set function + */ + al_bool enforce_ob_atu_region_set; +}; + +/** + * @brief program internal ATU region entry + * @param pcie_port pcie port handle + * @param atu_region data structure that contains the region index and the + * translation parameters + * @return 0 if no error + */ +int al_pcie_atu_region_set( + struct al_pcie_port *pcie_port, + struct al_pcie_atu_region *atu_region); + +/** + * @brief get internal ATU is enabled and base/target addresses + * @param pcie_port pcie port handle + * @param direction input: iATU direction (IB/OB) + * @param index input: iATU index + * @param enable output: AL_TRUE if the iATU is enabled + * @param base_addr output: the iATU base address + * @param target_addr output: the iATU target address + */ +void al_pcie_atu_region_get_fields( + struct al_pcie_port *pcie_port, + enum al_pcie_atu_dir direction, uint8_t index, + al_bool *enable, uint64_t *base_addr, uint64_t *target_addr); + +/** + * @brief Configure axi io bar. + * every hit to this bar will override size to 4 bytes. + * @param pcie_port pcie port handle + * @param start the first address of the memory + * @param end the last address of the memory + * @return + */ +void al_pcie_axi_io_config( + struct al_pcie_port *pcie_port, + al_phys_addr_t start, + al_phys_addr_t end); + +/************** Interrupt generation (Endpoint mode Only) API *****************/ + +enum al_pcie_legacy_int_type{ + AL_PCIE_LEGACY_INTA = 0, + AL_PCIE_LEGACY_INTB, + AL_PCIE_LEGACY_INTC, + AL_PCIE_LEGACY_INTD +}; + +/** + * @brief generate INTx Assert/DeAssert Message + * @param pcie_pf pcie pf handle + * @param assert when true, Assert Message is sent + * @param type type of message (INTA, INTB, etc) + * @return 0 if no error found + */ +int al_pcie_legacy_int_gen( + struct al_pcie_pf *pcie_pf, + al_bool assert, + enum al_pcie_legacy_int_type type); + +/** + * @brief generate MSI interrupt + * @param pcie_pf pcie pf handle + * @param vector the vector index to send interrupt for. + * @return 0 if no error found + */ +int al_pcie_msi_int_gen(struct al_pcie_pf *pcie_pf, uint8_t vector); + +/** + * @brief configure MSIX capability + * @param pcie_pf pcie pf handle + * @param msix_params MSIX capability configuration parameters + * @return 0 if no error found + */ +int al_pcie_msix_config( + struct al_pcie_pf *pcie_pf, + struct al_pcie_msix_params *msix_params); + +/** + * @brief check whether MSIX capability is enabled + * @param pcie_pf pcie pf handle + * @return AL_TRUE if MSIX capability is enabled, AL_FALSE otherwise + */ +al_bool al_pcie_msix_enabled(struct al_pcie_pf *pcie_pf); + +/** + * @brief check whether MSIX capability is masked + * @param pcie_pf pcie pf handle + * @return AL_TRUE if MSIX capability is masked, AL_FALSE otherwise + */ +al_bool al_pcie_msix_masked(struct al_pcie_pf *pcie_pf); + +/******************** Advanced Error Reporting (AER) API **********************/ + +/** + * @brief configure AER capability + * @param pcie_pf pcie pf handle + * @param params AER capability configuration parameters + * @return 0 if no error found + */ +int al_pcie_aer_config( + struct al_pcie_pf *pcie_pf, + struct al_pcie_aer_params *params); + +/** + * @brief AER uncorretable errors get and clear + * @param pcie_pf pcie pf handle + * @return bit mask of uncorrectable errors - see 'AL_PCIE_AER_UNCORR_*' for + * details + */ +unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf); + +/** + * @brief AER corretable errors get and clear + * @param pcie_pf pcie pf handle + * @return bit mask of correctable errors - see 'AL_PCIE_AER_CORR_*' for + * details + */ +unsigned int al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf); + +/** + * @brief AER get the header for the TLP corresponding to a detected error + * @param pcie_pf pcie pf handle + * @param hdr pointer to an array for getting the header + */ +void al_pcie_aer_err_tlp_hdr_get( + struct al_pcie_pf *pcie_pf, + uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]); + +/******************** Loop-Back mode (RC and Endpoint modes) ******************/ + +/** + * @brief enter local pipe loop-back mode + * This mode will connect the pipe RX signals to TX. + * no need to start link when using this mode. + * Gen3 equalization must be disabled before enabling this mode + * The caller must make sure the port is ready to accept the TLPs it sends to + * itself. for example, BARs should be initialized before sending memory TLPs. + * + * @param pcie_port pcie port handle + * @return 0 if no error found + */ +int al_pcie_local_pipe_loopback_enter(struct al_pcie_port *pcie_port); + +/** + * @brief exit local pipe loopback mode + * + * @param pcie_port pcie port handle + * @return 0 if no error found + */ +int al_pcie_local_pipe_loopback_exit(struct al_pcie_port *pcie_port); + +/** + * @brief enter master remote loopback mode + * No need to configure the link partner to enter slave remote loopback mode + * as this should be done as response to special training sequence directives + * when master works in remote loopback mode. + * The caller must make sure the port is ready to accept the TLPs it sends to + * itself. for example, BARs should be initialized before sending memory TLPs. + * + * @param pcie_port pcie port handle + * @return 0 if no error found + */ +int al_pcie_remote_loopback_enter(struct al_pcie_port *pcie_port); + +/** + * @brief exit remote loopback mode + * + * @param pcie_port pcie port handle + * @return 0 if no error found + */ +int al_pcie_remote_loopback_exit(struct al_pcie_port *pcie_port); + +#endif +/** @} end of grouppcie group */ diff --git a/al_hal_pcie_axi_reg.h b/al_hal_pcie_axi_reg.h new file mode 100644 index 000000000000..04d4bfdbca3f --- /dev/null +++ b/al_hal_pcie_axi_reg.h @@ -0,0 +1,1501 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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 __AL_PCIE_HAL_AXI_REG_H__ +#define __AL_PCIE_HAL_AXI_REG_H__ + +#include "al_hal_plat_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct al_pcie_rev1_2_axi_ctrl { + /* [0x0] */ + uint32_t global; + uint32_t rsrvd_0; + /* [0x8] */ + uint32_t master_bctl; + /* [0xc] */ + uint32_t master_rctl; + /* [0x10] */ + uint32_t master_ctl; + /* [0x14] */ + uint32_t master_arctl; + /* [0x18] */ + uint32_t master_awctl; + /* [0x1c] */ + uint32_t slave_rctl; + /* [0x20] */ + uint32_t slv_wctl; + /* [0x24] */ + uint32_t slv_ctl; + /* [0x28] */ + uint32_t dbi_ctl; + /* [0x2c] */ + uint32_t vmid_mask; + uint32_t rsrvd[4]; +}; +struct al_pcie_rev3_axi_ctrl { + /* [0x0] */ + uint32_t global; + uint32_t rsrvd_0; + /* [0x8] */ + uint32_t master_bctl; + /* [0xc] */ + uint32_t master_rctl; + /* [0x10] */ + uint32_t master_ctl; + /* [0x14] */ + uint32_t master_arctl; + /* [0x18] */ + uint32_t master_awctl; + /* [0x1c] */ + uint32_t slave_rctl; + /* [0x20] */ + uint32_t slv_wctl; + /* [0x24] */ + uint32_t slv_ctl; + /* [0x28] */ + uint32_t dbi_ctl; + /* [0x2c] */ + uint32_t vmid_mask; +}; +struct al_pcie_rev1_axi_ob_ctrl { + /* [0x0] */ + uint32_t cfg_target_bus; + /* [0x4] */ + uint32_t cfg_control; + /* [0x8] */ + uint32_t io_start_l; + /* [0xc] */ + uint32_t io_start_h; + /* [0x10] */ + uint32_t io_limit_l; + /* [0x14] */ + uint32_t io_limit_h; + /* [0x18] */ + uint32_t msg_start_l; + /* [0x1c] */ + uint32_t msg_start_h; + /* [0x20] */ + uint32_t msg_limit_l; + /* [0x24] */ + uint32_t msg_limit_h; + uint32_t rsrvd[6]; +}; +struct al_pcie_rev2_axi_ob_ctrl { + /* [0x0] */ + uint32_t cfg_target_bus; + /* [0x4] */ + uint32_t cfg_control; + /* [0x8] */ + uint32_t io_start_l; + /* [0xc] */ + uint32_t io_start_h; + /* [0x10] */ + uint32_t io_limit_l; + /* [0x14] */ + uint32_t io_limit_h; + /* [0x18] */ + uint32_t msg_start_l; + /* [0x1c] */ + uint32_t msg_start_h; + /* [0x20] */ + uint32_t msg_limit_l; + /* [0x24] */ + uint32_t msg_limit_h; + /* + * [0x28] this register override the VMID field in the AXUSER [19:4], + * for the AXI master port. + */ + uint32_t vmid_reg_ovrd; + /* [0x2c] this register override the ADDR[63:32] AXI master port. */ + uint32_t addr_high_reg_ovrd_value; + /* [0x30] this register override the ADDR[63:32] AXI master port. */ + uint32_t addr_high_reg_ovrd_sel; + /* + * [0x34] Define the size to replace in the master axi address bits + * [63:32] + */ + uint32_t addr_size_replace; + uint32_t rsrvd[2]; +}; +struct al_pcie_rev3_axi_ob_ctrl { + /* [0x0] */ + uint32_t cfg_target_bus; + /* [0x4] */ + uint32_t cfg_control; + /* [0x8] */ + uint32_t io_start_l; + /* [0xc] */ + uint32_t io_start_h; + /* [0x10] */ + uint32_t io_limit_l; + /* [0x14] */ + uint32_t io_limit_h; + /* [0x18] */ + uint32_t aw_msg_start_l; + /* [0x1c] */ + uint32_t aw_msg_start_h; + /* [0x20] */ + uint32_t aw_msg_limit_l; + /* [0x24] */ + uint32_t aw_msg_limit_h; + /* [0x28] */ + uint32_t ar_msg_start_l; + /* [0x2c] */ + uint32_t ar_msg_start_h; + /* [0x30] */ + uint32_t ar_msg_limit_l; + /* [0x34] */ + uint32_t ar_msg_limit_h; + /* [0x38] */ + uint32_t io_addr_mask_h; + /* [0x3c] */ + uint32_t ar_msg_addr_mask_h; + /* [0x40] */ + uint32_t aw_msg_addr_mask_h; + /* + * [0x44] this register override the VMID field in the AXUSER [19:4], + * for the AXI master port. + */ + uint32_t vmid_reg_ovrd; + /* [0x48] this register override the ADDR[63:32] AXI master port. */ + uint32_t addr_high_reg_ovrd_value; + /* [0x4c] this register override the ADDR[63:32] AXI master port. */ + uint32_t addr_high_reg_ovrd_sel; + /* + * [0x50] Define the size to replace in the master axi address bits + * [63:32] + */ + uint32_t addr_size_replace; + uint32_t rsrvd[3]; +}; +struct al_pcie_revx_axi_msg { + /* [0x0] */ + uint32_t addr_high; + /* [0x4] */ + uint32_t addr_low; + /* [0x8] */ + uint32_t type; +}; +struct al_pcie_revx_axi_pcie_status { + /* [0x0] */ + uint32_t debug; +}; +struct al_pcie_revx_axi_rd_parity { + /* [0x0] */ + uint32_t log_high; + /* [0x4] */ + uint32_t log_low; +}; +struct al_pcie_revx_axi_rd_cmpl { + /* [0x0] */ + uint32_t cmpl_log_high; + /* [0x4] */ + uint32_t cmpl_log_low; +}; +struct al_pcie_revx_axi_rd_to { + /* [0x0] */ + uint32_t to_log_high; + /* [0x4] */ + uint32_t to_log_low; +}; +struct al_pcie_revx_axi_wr_cmpl { + /* [0x0] */ + uint32_t wr_cmpl_log_high; + /* [0x4] */ + uint32_t wr_cmpl_log_low; +}; +struct al_pcie_revx_axi_wr_to { + /* [0x0] */ + uint32_t wr_to_log_high; + /* [0x4] */ + uint32_t wr_to_log_low; +}; +struct al_pcie_revx_axi_pcie_global { + /* [0x0] */ + uint32_t conf; +}; +struct al_pcie_rev1_2_axi_status { + /* [0x0] */ + uint32_t lane0; + /* [0x4] */ + uint32_t lane1; + /* [0x8] */ + uint32_t lane2; + /* [0xc] */ + uint32_t lane3; +}; +struct al_pcie_rev3_axi_status { + /* [0x0] */ + uint32_t lane0; + /* [0x4] */ + uint32_t lane1; + /* [0x8] */ + uint32_t lane2; + /* [0xc] */ + uint32_t lane3; + /* [0x10] */ + uint32_t lane4; + /* [0x14] */ + uint32_t lane5; + /* [0x18] */ + uint32_t lane6; + /* [0x1c] */ + uint32_t lane7; + uint32_t rsrvd[8]; +}; +struct al_pcie_rev1_2_axi_conf { + /* [0x0] */ + uint32_t zero_lane0; + /* [0x4] */ + uint32_t zero_lane1; + /* [0x8] */ + uint32_t zero_lane2; + /* [0xc] */ + uint32_t zero_lane3; + /* [0x10] */ + uint32_t one_lane0; + /* [0x14] */ + uint32_t one_lane1; + /* [0x18] */ + uint32_t one_lane2; + /* [0x1c] */ + uint32_t one_lane3; +}; +struct al_pcie_rev3_axi_conf { + /* [0x0] */ + uint32_t zero_lane0; + /* [0x4] */ + uint32_t zero_lane1; + /* [0x8] */ + uint32_t zero_lane2; + /* [0xc] */ + uint32_t zero_lane3; + /* [0x10] */ + uint32_t zero_lane4; + /* [0x14] */ + uint32_t zero_lane5; + /* [0x18] */ + uint32_t zero_lane6; + /* [0x1c] */ + uint32_t zero_lane7; + /* [0x20] */ + uint32_t one_lane0; + /* [0x24] */ + uint32_t one_lane1; + /* [0x28] */ + uint32_t one_lane2; + /* [0x2c] */ + uint32_t one_lane3; + /* [0x30] */ + uint32_t one_lane4; + /* [0x34] */ + uint32_t one_lane5; + /* [0x38] */ + uint32_t one_lane6; + /* [0x3c] */ + uint32_t one_lane7; + uint32_t rsrvd[16]; +}; + +struct al_pcie_revx_axi_msg_attr_axuser_table { + /* [0x0] 4 option, the index comes from */ + uint32_t entry_vec; +}; + +struct al_pcie_revx_axi_parity { + /* [0x0] */ + uint32_t en_axi; + /* [0x4] */ + uint32_t status_axi; +}; +struct al_pcie_revx_axi_pos_logged { + /* [0x0] */ + uint32_t error_low; + /* [0x4] */ + uint32_t error_high; +}; +struct al_pcie_revx_axi_ordering { + /* [0x0] */ + uint32_t pos_cntl; +}; +struct al_pcie_revx_axi_link_down { + /* [0x0] */ + uint32_t reset_extend; +}; +struct al_pcie_revx_axi_pre_configuration { + /* [0x0] */ + uint32_t pcie_core_setup; +}; +struct al_pcie_revx_axi_init_fc { + /* + * Revision 1/2: + * [0x0] The sum of all the fields below must be 97 + * Revision 3: + * [0x0] The sum of all the fields below must be 259 + * */ + uint32_t cfg; +}; +struct al_pcie_revx_axi_int_grp_a_axi { + /* + * [0x0] Interrupt Cause Register + * Set by hardware. + * - If MSI-X is enabled, and auto_clear control bit =TRUE, + * automatically cleared after MSI-X message associated with this + * specific interrupt bit is sent (MSI-X acknowledge is received). + * - Software can set a bit in this register by writing 1 to the + * associated bit in the Interrupt Cause Set register. + * Write-0 clears a bit. Write-1 has no effect. + * - On CPU Read -- If clear_on_read control bit =TRUE, automatically + * cleared (all bits are cleared). + * When there is a conflict, and on the same clock cycle hardware tries + * to set a bit in the Interrupt Cause register, the specific bit is set + * to ensure the interrupt indication is not lost. + */ + uint32_t cause; + uint32_t rsrvd_0; + /* + * [0x8] Interrupt Cause Set Register + * Writing 1 to a bit in this register sets its corresponding cause bit, + * enabling software to generate a hardware interrupt. Write 0 has no + * effect. + */ + uint32_t cause_set; + uint32_t rsrvd_1; + /* + * [0x10] Interrupt Mask Register + * If Auto-mask control bit =TRUE, automatically set to 1 after MSI-X + * message associate to the associate interrupt bit is sent (AXI write + * acknowledge is received) + */ + uint32_t mask; + uint32_t rsrvd_2; + /* + * [0x18] Interrupt Mask Clear Register + * Used when auto-mask control bit=True. It enables the CPU to clear a + * specific bit, preventing a scenario in which the CPU overrides + * another bit with 1 (old value) that hardware has just cleared to 0. + * Writing 0 to this register clears its corresponding mask bit. Write 1 + * has no effect. + */ + uint32_t mask_clear; + uint32_t rsrvd_3; + /* + * [0x20] Interrupt Status Register + * This register latches the status of the interrupt source. + */ + uint32_t status; + uint32_t rsrvd_4; + /* [0x28] Interrupt Control Register */ + uint32_t control; + uint32_t rsrvd_5; + /* + * [0x30] Interrupt Mask Register + * Each bit in this register masks the corresponding cause bit for + * generating an Abort signal. Its default value is determined by unit + * instantiation. + * Abort = Wire-OR of Cause & !Interrupt_Abort_Mask). + * This register provides an error handling configuration for error + * interrupts. + */ + uint32_t abort_mask; + uint32_t rsrvd_6; + /* + * [0x38] Interrupt Log Register + * Each bit in this register masks the corresponding cause bit for + * capturing the log registers. Its default value is determined by unit + * instantiatio.n + * Log_capture = Wire-OR of Cause & !Interrupt_Log_Mask). + * This register provides an error handling configuration for error + * interrupts. + */ + uint32_t log_mask; + uint32_t rsrvd; +}; + +struct al_pcie_rev3_axi_eq_ovrd_tx_rx_values { + /* [0x0] */ + uint32_t cfg_0; + /* [0x4] */ + uint32_t cfg_1; + /* [0x8] */ + uint32_t cfg_2; + /* [0xc] */ + uint32_t cfg_3; + /* [0x10] */ + uint32_t cfg_4; + /* [0x14] */ + uint32_t cfg_5; + /* [0x18] */ + uint32_t cfg_6; + /* [0x1c] */ + uint32_t cfg_7; + /* [0x20] */ + uint32_t cfg_8; + /* [0x24] */ + uint32_t cfg_9; + /* [0x28] */ + uint32_t cfg_10; + /* [0x2c] */ + uint32_t cfg_11; + uint32_t rsrvd[12]; +}; +struct al_pcie_rev3_axi_dbg_outstading_trans_axi { + /* [0x0] */ + uint32_t read_master_counter; + /* [0x4] */ + uint32_t write_master_counter; + /* [0x8] */ + uint32_t read_slave_counter; +}; +struct al_pcie_revx_axi_device_id { + /* [0x0] */ + uint32_t device_rev_id; +}; +struct al_pcie_revx_axi_power_mang_ovrd_cntl { + /* [0x0] */ + uint32_t cfg_static_nof_elidle; + /* [0x4] */ + uint32_t cfg_l0s_wait_ovrd; + /* [0x8] */ + uint32_t cfg_l12_wait_ovrd; + /* [0xc] */ + uint32_t cfg_l0s_delay_in_p0s; + /* [0x10] */ + uint32_t cfg_l12_delay_in_p12; + /* [0x14] */ + uint32_t cfg_l12_delay_in_p12_clk_rst; + /* [0x18] */ + uint32_t cfg_delay_powerdown_bus; + uint32_t rsrvd; +}; +struct al_pcie_rev3_axi_dbg_outstading_trans_axi_write { + /* [0x0] */ + uint32_t slave_counter; +}; +struct al_pcie_rev3_axi_attr_ovrd { + /* + * [0x0] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t write_msg_ctrl_0; + /* [0x4] in case of message this register set the below attributes */ + uint32_t write_msg_ctrl_1; + /* + * [0x8] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t read_msg_ctrl_0; + /* [0xc] in case of message this register set the below attributes */ + uint32_t read_msg_ctrl_1; + /* [0x10] in case of message this register set the below attributes */ + uint32_t pf_sel; + uint32_t rsrvd[3]; +}; +struct al_pcie_rev3_axi_pf_axi_attr_ovrd { + /* + * [0x0] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_0; + /* [0x4] in case of message this register set the below attributes */ + uint32_t func_ctrl_1; + /* + * [0x8] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_2; + /* + * [0xc] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_3; + /* + * [0x10] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_4; + /* + * [0x14] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_5; + /* + * [0x18] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_6; + /* + * [0x1c] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_7; + /* + * [0x20] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_8; + /* + * [0x24] In case of hit on the io message bar and + * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this + * register + */ + uint32_t func_ctrl_9; + uint32_t rsrvd[6]; +}; + +struct al_pcie_revx_axi_regs { + uint32_t rsrvd_0[91]; + struct al_pcie_revx_axi_device_id device_id; /* [0x16c] */ +}; + +struct al_pcie_rev1_axi_regs { + struct al_pcie_rev1_2_axi_ctrl ctrl; /* [0x0] */ + struct al_pcie_rev1_axi_ob_ctrl ob_ctrl; /* [0x40] */ + uint32_t rsrvd_0[4]; + struct al_pcie_revx_axi_msg msg; /* [0x90] */ + struct al_pcie_revx_axi_pcie_status pcie_status; /* [0x9c] */ + struct al_pcie_revx_axi_rd_parity rd_parity; /* [0xa0] */ + struct al_pcie_revx_axi_rd_cmpl rd_cmpl; /* [0xa8] */ + struct al_pcie_revx_axi_rd_to rd_to; /* [0xb0] */ + struct al_pcie_revx_axi_wr_cmpl wr_cmpl; /* [0xb8] */ + struct al_pcie_revx_axi_wr_to wr_to; /* [0xc0] */ + struct al_pcie_revx_axi_pcie_global pcie_global; /* [0xc8] */ + struct al_pcie_rev1_2_axi_status status; /* [0xcc] */ + struct al_pcie_rev1_2_axi_conf conf; /* [0xdc] */ + struct al_pcie_revx_axi_parity parity; /* [0xfc] */ + struct al_pcie_revx_axi_pos_logged pos_logged; /* [0x104] */ + struct al_pcie_revx_axi_ordering ordering; /* [0x10c] */ + struct al_pcie_revx_axi_link_down link_down; /* [0x110] */ + struct al_pcie_revx_axi_pre_configuration pre_configuration; /* [0x114] */ + struct al_pcie_revx_axi_init_fc init_fc; /* [0x118] */ + uint32_t rsrvd_1[20]; + struct al_pcie_revx_axi_device_id device_id; /* [0x16c] */ + uint32_t rsrvd_2[36]; + struct al_pcie_revx_axi_int_grp_a_axi int_grp_a; /* [0x200] */ +}; + +struct al_pcie_rev2_axi_regs { + struct al_pcie_rev1_2_axi_ctrl ctrl; /* [0x0] */ + struct al_pcie_rev2_axi_ob_ctrl ob_ctrl; /* [0x40] */ + uint32_t rsrvd_0[4]; + struct al_pcie_revx_axi_msg msg; /* [0x90] */ + struct al_pcie_revx_axi_pcie_status pcie_status; /* [0x9c] */ + struct al_pcie_revx_axi_rd_parity rd_parity; /* [0xa0] */ + struct al_pcie_revx_axi_rd_cmpl rd_cmpl; /* [0xa8] */ + struct al_pcie_revx_axi_rd_to rd_to; /* [0xb0] */ + struct al_pcie_revx_axi_wr_cmpl wr_cmpl; /* [0xb8] */ + struct al_pcie_revx_axi_wr_to wr_to; /* [0xc0] */ + struct al_pcie_revx_axi_pcie_global pcie_global; /* [0xc8] */ + struct al_pcie_rev1_2_axi_status status; /* [0xcc] */ + struct al_pcie_rev1_2_axi_conf conf; /* [0xdc] */ + struct al_pcie_revx_axi_parity parity; /* [0xfc] */ + struct al_pcie_revx_axi_pos_logged pos_logged; /* [0x104] */ + struct al_pcie_revx_axi_ordering ordering; /* [0x10c] */ + struct al_pcie_revx_axi_link_down link_down; /* [0x110] */ + struct al_pcie_revx_axi_pre_configuration pre_configuration; /* [0x114] */ + struct al_pcie_revx_axi_init_fc init_fc; /* [0x118] */ + uint32_t rsrvd_1[20]; + struct al_pcie_revx_axi_device_id device_id; /* [0x16c] */ + uint32_t rsrvd_2[36]; + struct al_pcie_revx_axi_int_grp_a_axi int_grp_a; /* [0x200] */ +}; + +struct al_pcie_rev3_axi_regs { + struct al_pcie_rev3_axi_ctrl ctrl; /* [0x0] */ + struct al_pcie_rev3_axi_ob_ctrl ob_ctrl;/* [0x30] */ + struct al_pcie_revx_axi_msg msg; /* [0x90] */ + struct al_pcie_revx_axi_pcie_status pcie_status; /* [0x9c] */ + struct al_pcie_revx_axi_rd_parity rd_parity; /* [0xa0] */ + struct al_pcie_revx_axi_rd_cmpl rd_cmpl; /* [0xa8] */ + struct al_pcie_revx_axi_rd_to rd_to; /* [0xb0] */ + struct al_pcie_revx_axi_wr_cmpl wr_cmpl; /* [0xb8] */ + struct al_pcie_revx_axi_wr_to wr_to; /* [0xc0] */ + struct al_pcie_revx_axi_pcie_global pcie_global; /* [0xc8] */ + uint32_t rsrvd_0; + struct al_pcie_revx_axi_parity parity; /* [0xd0] */ + struct al_pcie_revx_axi_pos_logged pos_logged; /* [0xd8] */ + struct al_pcie_revx_axi_ordering ordering; /* [0xe0] */ + struct al_pcie_revx_axi_link_down link_down; /* [0xe4] */ + struct al_pcie_revx_axi_pre_configuration pre_configuration;/* [0xe8] */ + struct al_pcie_revx_axi_init_fc init_fc; /* [0xec] */ + uint32_t rsrvd_1[4]; + struct al_pcie_rev3_axi_eq_ovrd_tx_rx_values eq_ovrd_tx_rx_values;/* [0x100] */ + struct al_pcie_rev3_axi_dbg_outstading_trans_axi dbg_outstading_trans_axi;/* [0x160] */ + struct al_pcie_revx_axi_device_id device_id; /* [0x16c] */ + struct al_pcie_revx_axi_power_mang_ovrd_cntl power_mang_ovrd_cntl;/* [0x170] */ + struct al_pcie_rev3_axi_dbg_outstading_trans_axi_write dbg_outstading_trans_axi_write;/* [0x190] */ + uint32_t rsrvd_2[3]; + struct al_pcie_rev3_axi_attr_ovrd axi_attr_ovrd; /* [0x1a0] */ + struct al_pcie_rev3_axi_pf_axi_attr_ovrd pf_axi_attr_ovrd[REV3_MAX_NUM_OF_PFS];/* [0x1c0] */ + uint32_t rsrvd_3[64]; + struct al_pcie_rev3_axi_status status; /* [0x3c0] */ + struct al_pcie_rev3_axi_conf conf; /* [0x400] */ + uint32_t rsrvd_4[32]; + struct al_pcie_revx_axi_msg_attr_axuser_table msg_attr_axuser_table; /* [0x500] */ + uint32_t rsrvd_5[191]; + struct al_pcie_revx_axi_int_grp_a_axi int_grp_a; /* [0x800] */ +}; + +/* +* Registers Fields +*/ + +/**** Device ID register ****/ +#define PCIE_AXI_DEVICE_ID_REG_DEV_ID_MASK AL_FIELD_MASK(31, 16) +#define PCIE_AXI_DEVICE_ID_REG_DEV_ID_SHIFT 16 +#define PCIE_AXI_DEVICE_ID_REG_DEV_ID_X4 (0 << PCIE_AXI_DEVICE_ID_REG_DEV_ID_SHIFT) +#define PCIE_AXI_DEVICE_ID_REG_DEV_ID_X8 (2 << PCIE_AXI_DEVICE_ID_REG_DEV_ID_SHIFT) +#define PCIE_AXI_DEVICE_ID_REG_REV_ID_MASK AL_FIELD_MASK(15, 0) +#define PCIE_AXI_DEVICE_ID_REG_REV_ID_SHIFT 0 + +/**** Global register ****/ +/* + * Not in use. + * Disable completion after inbound posted ordering enforcement to AXI bridge. + */ +#define PCIE_AXI_CTRL_GLOBAL_CPL_AFTER_P_ORDER_DIS (1 << 0) +/* + * Not in use. + * Enforce completion after write ordering on AXI bridge. Only for CPU read + * requests. + */ +#define PCIE_AXI_CTRL_GLOBAL_CPU_CPL_ONLY_EN (1 << 1) +/* When linked down, map all transactions to PCIe to DEC ERR. */ +#define PCIE_AXI_CTRL_GLOBAL_BLOCK_PCIE_SLAVE_EN (1 << 2) +/* + * Wait for the NIC to flush before enabling reset to the PCIe core, on a link + * down event. + */ +#define PCIE_AXI_CTRL_GLOBAL_WAIT_SLV_FLUSH_EN (1 << 3) +/* + * When the BME is cleared and this bit is set, it causes all transactions that + * do not get to the PCIe to be returned with DECERR. + */ +#define PCIE_REV1_2_AXI_CTRL_GLOBAL_MEM_BAR_MAP_TO_ERR (1 << 4) +#define PCIE_REV3_AXI_CTRL_GLOBAL_MEM_BAR_MAP_TO_ERR_MASK 0x00000FF0 +#define PCIE_REV3_AXI_CTRL_GLOBAL_MEM_BAR_MAP_TO_ERR_SHIFT 4 +/* + * Wait for the DBI port (the port that enables access to the internal PCIe core + * registers) to flush before enabling reset to the PCIe core on link down + * event. + */ +#define PCIE_REV1_2_AXI_CTRL_GLOBAL_WAIT_DBI_FLUSH_EN (1 << 5) +#define PCIE_REV3_AXI_CTRL_GLOBAL_WAIT_DBI_FLUSH_EN (1 << 12) +/* Reserved. Read undefined; must read as zeros. */ +#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_FLUSH_DBI_AXI (1 << 13) +/* Reserved. Read undefined; must read as zeros. */ +#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_HOLD_LNKDWN_RESET_SW (1 << 14) +/* Reserved. Read undefined; must read as zeros. */ +#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_MASK_CORECLK_ACT_CLK_RST (1 << 15) +/* Reserved. Read undefined; must read as zeros. */ +#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_MASK_RXELECIDLE_CLK_RST (1 << 16) +/* Reserved. Read undefined; must read as zeros. */ +#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_ALLOW_NONSTICKY_RESET_WHEN_LNKDOWN_CLK_RST (1 << 17) + +/* + * When set, adds parity on the write and read address channels, and write data + * channel. + */ +#define PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR (1 << 16) +#define PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR (1 << 18) +/* When set, enables parity check on the read data. */ +#define PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD (1 << 17) +#define PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD (1 << 19) +/* + * When set, adds parity on the RD data channel. + */ +#define PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV (1 << 18) +#define PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV (1 << 20) +/* + * When set, enables parity check on the write data. + */ +#define PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR (1 << 19) +#define PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR (1 << 21) +/* + * When set, error track for timeout and parity is disabled, i.e., the logged + * address for parity/timeout/cmpl errors on the AXI master port is not valid, + * and timeout and completion errors check are disabled. + */ +#define PCIE_REV1_2_AXI_CTRL_GLOBAL_ERROR_TRACK_DIS (1 << 20) +#define PCIE_REV3_AXI_CTRL_GLOBAL_ERROR_TRACK_DIS (1 << 22) + +/**** Master_Arctl register ****/ +/* override arcache */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_OVR_ARCACHE (1 << 0) +/* arache value */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_ARACHE_VA_MASK 0x0000001E +#define PCIE_AXI_CTRL_MASTER_ARCTL_ARACHE_VA_SHIFT 1 +/* arprot override */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_OVR (1 << 5) +/* arprot value */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_VALUE_MASK 0x000001C0 +#define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_VALUE_SHIFT 6 +/* vmid val */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_VMID_VAL_MASK 0x01FFFE00 +#define PCIE_AXI_CTRL_MASTER_ARCTL_VMID_VAL_SHIFT 9 +/* IPA value */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_IPA_VAL (1 << 25) +/* overide snoop inidcation, if not set take it from mstr_armisc ... */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP (1 << 26) +/* +snoop indication value when override */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP (1 << 27) +/* +arqos value */ +#define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_MASK 0xF0000000 +#define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_SHIFT 28 + +/**** Master_Awctl register ****/ +/* override arcache */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_OVR_ARCACHE (1 << 0) +/* awache value */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_AWACHE_VA_MASK 0x0000001E +#define PCIE_AXI_CTRL_MASTER_AWCTL_AWACHE_VA_SHIFT 1 +/* awprot override */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_OVR (1 << 5) +/* awprot value */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_VALUE_MASK 0x000001C0 +#define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_VALUE_SHIFT 6 +/* vmid val */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_VMID_VAL_MASK 0x01FFFE00 +#define PCIE_AXI_CTRL_MASTER_AWCTL_VMID_VAL_SHIFT 9 +/* IPA value */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_IPA_VAL (1 << 25) +/* overide snoop inidcation, if not set take it from mstr_armisc ... */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP (1 << 26) +/* +snoop indication value when override */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP (1 << 27) +/* +awqos value */ +#define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_MASK 0xF0000000 +#define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_SHIFT 28 + +/**** slv_ctl register ****/ +#define PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN (1 << 6) + +/**** Cfg_Target_Bus register ****/ +/* + * Defines which MSBs to complete the number of the bust that arrived from ECAM. + * If set to 0, take the bit from the ECAM bar, otherwise from the busnum of + * this register. + * The LSB for the bus number comes on the addr[*:20]. + */ +#define PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK 0x000000FF +#define PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT 0 +/* Target bus number for outbound configuration type0 and type1 access */ +#define PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_MASK 0x0000FF00 +#define PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_SHIFT 8 + +/**** Cfg_Control register ****/ +/* Primary bus number */ +#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_PBUS_MASK 0x000000FF +#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_PBUS_SHIFT 0 +/* + * + * Subordinate bus number + */ +#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_MASK 0x0000FF00 +#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_SHIFT 8 +/* Secondary bus nnumber */ +#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_MASK 0x00FF0000 +#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_SHIFT 16 +/* Enable outbound configuration access through iATU. */ +#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_IATU_EN (1 << 31) + +/**** IO_Start_H register ****/ +/* + * + * Outbound ATIU I/O start address high + */ +#define PCIE_AXI_MISC_OB_CTRL_IO_START_H_ADDR_MASK 0x000003FF +#define PCIE_AXI_MISC_OB_CTRL_IO_START_H_ADDR_SHIFT 0 + +/**** IO_Limit_H register ****/ +/* + * + * Outbound ATIU I/O limit address high + */ +#define PCIE_AXI_MISC_OB_CTRL_IO_LIMIT_H_ADDR_MASK 0x000003FF +#define PCIE_AXI_MISC_OB_CTRL_IO_LIMIT_H_ADDR_SHIFT 0 + +/**** Msg_Start_H register ****/ +/* + * + * Outbound ATIU msg-no-data start address high + */ +#define PCIE_AXI_MISC_OB_CTRL_MSG_START_H_ADDR_MASK 0x000003FF +#define PCIE_AXI_MISC_OB_CTRL_MSG_START_H_ADDR_SHIFT 0 + +/**** Msg_Limit_H register ****/ +/* + * + * Outbound ATIU msg-no-data limit address high + */ +#define PCIE_AXI_MISC_OB_CTRL_MSG_LIMIT_H_ADDR_MASK 0x000003FF +#define PCIE_AXI_MISC_OB_CTRL_MSG_LIMIT_H_ADDR_SHIFT 0 + +/**** vmid_reg_ovrd register ****/ +/* + * select if to take the value from register or from address[63:48]: + * 1'b1: register value. + * 1'b0: from address[63:48] + */ +#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_SEL_MASK 0x0000FFFF +#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_SEL_SHIFT 0 +/* vmid override value. */ +#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_VALUE_MASK 0xFFFF0000 +#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_VALUE_SHIFT 16 + +/**** addr_size_replace register ****/ +/* + * Size in bits to replace from bit [63:64-N], when equal zero no replace is + * done. + */ +#define PCIE_AXI_MISC_OB_CTRL_ADDR_SIZE_REPLACE_VALUE_MASK 0x0000FFFF +#define PCIE_AXI_MISC_OB_CTRL_ADDR_SIZE_REPLACE_VALUE_SHIFT 0 +/* Reserved. */ +#define PCIE_AXI_MISC_OB_CTRL_ADDR_SIZE_REPLACE_RSRVD_MASK 0xFFFF0000 +#define PCIE_AXI_MISC_OB_CTRL_ADDR_SIZE_REPLACE_RSRVD_SHIFT 16 + +/**** type register ****/ +/* Type of message */ +#define PCIE_AXI_MISC_MSG_TYPE_TYPE_MASK 0x00FFFFFF +#define PCIE_AXI_MISC_MSG_TYPE_TYPE_SHIFT 0 +/* Reserved */ +#define PCIE_AXI_MISC_MSG_TYPE_RSRVD_MASK 0xFF000000 +#define PCIE_AXI_MISC_MSG_TYPE_RSRVD_SHIFT 24 + +/**** debug register ****/ +/* Causes ACI PCIe reset, including ,master/slave/DBI (registers). */ +#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_AXI_BRIDGE_RESET (1 << 0) +/* + * Causes reset of the entire PCIe core (including the AXI bridge). + * When set, the software must not address the PCI core (through the MEM space + * and REG space). + */ +#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_CORE_RESET (1 << 1) +/* + * Indicates that the SB is empty from the request to the PCIe (not including + * registers). + */ +#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_SB_FLUSH_OB_STATUS (1 << 2) +/* MAP and transaction to the PCIe core to ERROR. */ +#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_SB_MAP_TO_ERR (1 << 3) +/* Indicates that the pcie_core clock is gated off */ +#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_CORE_CLK_GATE_OFF (1 << 4) +/* Reserved */ +#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_RSRVD_MASK 0xFFFFFFE0 +#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_RSRVD_SHIFT 5 + +/**** conf register ****/ +/* + * Device Type + * Indicates the specific type of this PCI Express Function. It is also used to + * set the + * Device/Port Type field. + * + * 4'b0000: PCI Express Endpoint + * 4'b0001: Legacy PCI Express Endpoint + * 4'b0100: Root Port of PCI Express Root Complex + * + * Must be programmed before link training sequence, according to the reset + * strap. + * Change this register should be when the pci_exist (in the PBS regfile) is + * zero. + */ +#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK 0x0000000F +#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT 0 +/* + * [i] - Lane i active + * Change this register should be when the pci_exist (in the PBS regfile) is + * zero. + */ +#define PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK 0x000000F0 +#define PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_RESERVED_MASK 0xFFFFFF00 +#define PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_RESERVED_SHIFT 8 +#define PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT 4 +#define PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK 0x000FFFF0 +#define PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_RESERVED_MASK 0xFFF00000 +#define PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_RESERVED_SHIFT 20 + +#define PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN 0x100 +#define PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN 0x100000 + +/**** laneX register ****/ +#define PCIE_AXI_STATUS_LANE_IS_RESET AL_BIT(13) +#define PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_MASK AL_FIELD_MASK(2, 0) +#define PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_SHIFT 0 + +/**** zero_laneX register ****/ +/* phy_mac_local_fs */ +#define PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_MASK 0x0000003f +#define PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_SHIFT 0 +/* phy_mac_local_lf */ +#define PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_MASK 0x00000fc0 +#define PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_SHIFT 6 + +/**** en_axi register ****/ +/* u4_ram2p */ +#define PCIE_AXI_PARITY_EN_AXI_U4_RAM2P AL_BIT(1) + +/**** pos_cntl register ****/ +/* Disables POS. */ +#define PCIE_AXI_POS_ORDER_AXI_POS_BYPASS (1 << 0) +/* Clear the POS data structure. */ +#define PCIE_AXI_POS_ORDER_AXI_POS_CLEAR (1 << 1) +/* Read push all write. */ +#define PCIE_AXI_POS_ORDER_AXI_POS_RSO_ENABLE (1 << 2) +/* + * Causes the PCIe core to wait for all the BRESPs before issuing a read + * request. + */ +#define PCIE_AXI_POS_ORDER_AXI_DW_RD_FLUSH_WR (1 << 3) +/* + * When set, to 1'b1 supports interleaving data return from the PCIe core. Valid + * only when cfg_bypass_cmpl_after_write_fix is set. + */ +#define PCIE_AXI_POS_ORDER_RD_CMPL_AFTER_WR_SUPPORT_RD_INTERLV (1 << 4) +/* When set, to 1'b1 disables read completion after write ordering. */ +#define PCIE_AXI_POS_ORDER_BYPASS_CMPL_AFTER_WR_FIX (1 << 5) +/* + * When set, disables EP mode read cmpl on the master port push slave writes, + * when each read response from the master is not interleaved. + */ +#define PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_DIS (1 << 6) +/* When set, disables EP mode read cmpl on the master port push slave writes. */ +#define PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_SUPPORT_INTERLV_DIS (1 << 7) +/* should be zero */ +#define PCIE_AXI_POS_ORDER_9_8 AL_FIELD_MASK(9, 8) +/* Give the segmentation buffer not to wait for P writes to end in the AXI + * bridge before releasing the CMPL. + */ +#define PCIE_AXI_POS_ORDER_SEGMENT_BUFFER_DONT_WAIT_FOR_P_WRITES AL_BIT(10) +/* should be zero */ +#define PCIE_AXI_POS_ORDER_11 AL_BIT(11) +/** + * When set cause pcie core to send ready in the middle of the read data + * burst returning from the DRAM to the PCIe core + */ +#define PCIE_AXI_POS_ORDER_SEND_READY_ON_READ_DATA_BURST AL_BIT(12) +/* When set disable the ATS CAP. */ +#define PCIE_AXI_CORE_SETUP_ATS_CAP_DIS AL_BIT(13) +/* When set disable D3/D2/D1 PME support */ +#define PCIE_AXI_POS_ORDER_DISABLE_DX_PME AL_BIT(14) +/* When set enable nonsticky reset when linkdown hot reset */ +#define PCIE_AXI_POS_ORDER_ENABLE_NONSTICKY_RESET_ON_HOT_RESET AL_BIT(15) +/* When set, terminate message with data as UR request */ +#define PCIE_AXI_TERMINATE_DATA_MSG_AS_UR_REQ AL_BIT(16) + +/**** pcie_core_setup register ****/ +/* + * This Value delay the rate change to the serdes, until the EIOS is sent by the + * serdes. Should be program before the pcie_exist, is asserted. + */ +#define PCIE_AXI_CORE_SETUP_DELAY_MAC_PHY_RATE_MASK 0x000000FF +#define PCIE_AXI_CORE_SETUP_DELAY_MAC_PHY_RATE_SHIFT 0 +/* + * Limit the number of outstanding AXI reads that the PCIe core can get. Should + * be program before the pcie_exist, is asserted. + */ +#define PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_MASK 0x0000FF00 +#define PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_SHIFT 8 +/* Enable the sriov feature. */ +#define PCIE_AXI_REV1_2_CORE_SETUP_SRIOV_ENABLE AL_BIT(16) +/* not in use */ +#define PCIE_AXI_REV3_CORE_SETUP_NOT_IN_USE (1 << 16) +/* Reserved. Read undefined; must read as zeros. */ +#define PCIE_AXI_REV3_CORE_SETUP_CFG_DELAY_AFTER_PCIE_EXIST_MASK 0x0FFE0000 +#define PCIE_AXI_REV3_CORE_SETUP_CFG_DELAY_AFTER_PCIE_EXIST_SHIFT 17 + +/**** cfg register ****/ +/* This value set the possible out standing headers writes (post ... */ +#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_MASK 0x0000007F +#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_SHIFT 0 +/* This value set the possible out standing headers reads (non-p ... */ +#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_MASK 0x00003F80 +#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_SHIFT 7 +/* This value set the possible out standing headers CMPLs , the ... */ +#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_MASK 0x001FC000 +#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_SHIFT 14 + +#define PCIE_AXI_REV1_2_INIT_FC_CFG_RSRVD_MASK 0xFFE00000 +#define PCIE_AXI_REV1_2_INIT_FC_CFG_RSRVD_SHIFT 21 + +/* This value set the possible out standing headers writes (post ... */ +#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_MASK 0x000001FF +#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_SHIFT 0 +/* This value set the possible out standing headers reads (non-p ... */ +#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_MASK 0x0003FE00 +#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_SHIFT 9 +/* This value set the possible out standing headers CMPLs , the ... */ +#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_MASK 0x07FC0000 +#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_SHIFT 18 + /* + * [27] cfg_cpl_p_rr: do round robin on the SB output btw Posted and CPL. + * [28] cfg_np_pass_p_rr, in case RR between CPL AND P, allow to pass NP in case + * p is empty. + * [29] cfg_np_part_of_rr_arb: NP also is a part of the round robin arbiter. + */ +#define PCIE_AXI_REV3_INIT_FC_CFG_RSRVD_MASK 0xF8000000 +#define PCIE_AXI_REV3_INIT_FC_CFG_RSRVD_SHIFT 27 + +/**** write_msg_ctrl_0 register ****/ +/* + * choose if 17 in the AXUSER indicate message hint (1'b1) or no snoop + * indication (1'b0) + */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_OUTBOUND_MSG_NO_SNOOP_N (1 << 0) +/* this bit define if the message is with data or without */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_WITH_DATA (1 << 1) +/* message code for message with data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_CODE_DATA_MASK 0x000003FC +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_CODE_DATA_SHIFT 2 +/* message code for message without data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_CODE_MASK 0x0003FC00 +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_CODE_SHIFT 10 +/* message ST value */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_ST_MASK 0x03FC0000 +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_ST_SHIFT 18 +/* message NO-SNOOP */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_NO_SNOOP (1 << 26) +/* message TH bit */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_TH (1 << 27) +/* message PH bits */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_PH_MASK 0x30000000 +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_PH_SHIFT 28 +/* Rsrvd */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_RSRVD_MASK 0xC0000000 +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_RSRVD_SHIFT 30 + +/**** write_msg_ctrl_1 register ****/ +/* message type */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MISC_MSG_TYPE_VALUE_MASK 0x0000001F +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MISC_MSG_TYPE_VALUE_SHIFT 0 +/* this bit define if the message is with data or without */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_TYPE_VALUE_MASK 0x000003E0 +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_TYPE_VALUE_SHIFT 5 +/* override axi size for message with no data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_NO_DATA_AXI_SIZE_OVRD (1 << 10) +/* override the AXI size to the pcie core for message with no data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_NO_DATA_AXI_SIZE_MSG_MASK 0x00003800 +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_NO_DATA_AXI_SIZE_MSG_SHIFT 11 +/* override axi size for message with data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_AXI_SIZE_OVRD (1 << 14) +/* override the AXI size to the pcie core for message with data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_AXI_SIZE_MSG_MASK 0x00038000 +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_AXI_SIZE_MSG_SHIFT 15 +/* Rsrvd */ +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_RSRVD_MASK 0xFFFC0000 +#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_RSRVD_SHIFT 18 + +/**** read_msg_ctrl_0 register ****/ +/* + * choose if 17 in the AXUSER indicate message hint (1'b1) or no snoop + * indication (1'b0) + */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_OUTBOUND_MSG_NO_SNOOP_N (1 << 0) +/* this bit define if the message is with data or without */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_WITH_DATA (1 << 1) +/* message code for message with data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_CODE_DATA_MASK 0x000003FC +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_CODE_DATA_SHIFT 2 +/* message code for message without data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_CODE_MASK 0x0003FC00 +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_CODE_SHIFT 10 +/* message ST value */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_ST_MASK 0x03FC0000 +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_ST_SHIFT 18 +/* message NO-SNOOP */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_NO_SNOOP (1 << 26) +/* message TH bit */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_TH (1 << 27) +/* message PH bits */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_PH_MASK 0x30000000 +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_PH_SHIFT 28 +/* Rsrvd */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_RSRVD_MASK 0xC0000000 +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_RSRVD_SHIFT 30 + +/**** read_msg_ctrl_1 register ****/ +/* message type */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MISC_MSG_TYPE_VALUE_MASK 0x0000001F +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MISC_MSG_TYPE_VALUE_SHIFT 0 +/* this bit define if the message is with data or without */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_TYPE_VALUE_MASK 0x000003E0 +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_TYPE_VALUE_SHIFT 5 +/* override axi size for message with no data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_NO_DATA_AXI_SIZE_OVRD (1 << 10) +/* override the AXI size to the pcie core for message with no data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_NO_DATA_AXI_SIZE_MSG_MASK 0x00003800 +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_NO_DATA_AXI_SIZE_MSG_SHIFT 11 +/* override axi size for message with data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_AXI_SIZE_OVRD (1 << 14) +/* override the AXI size to the pcie core for message with data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_AXI_SIZE_MSG_MASK 0x00038000 +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_AXI_SIZE_MSG_SHIFT 15 +/* Rsrvd */ +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_RSRVD_MASK 0xFFFC0000 +#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_RSRVD_SHIFT 18 + +/**** pf_sel register ****/ +/* message type */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_AXUSER (1 << 0) +/* this bit define if the message is with data or without */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_REG (1 << 1) +/* override axi size for message with no data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_ADDR_OFFSET_MASK 0x0000003C +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_ADDR_OFFSET_SHIFT 2 +/* override the AXI size to the pcie core for message with no data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT0_OVRD (1 << 6) +/* Rsrvd */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_RSRVD_7 (1 << 7) +/* message type */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_AXUSER (1 << 8) +/* this bit define if the message is with data or without */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_REG (1 << 9) +/* override axi size for message with no data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_ADDR_OFFSET_MASK 0x00003C00 +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_ADDR_OFFSET_SHIFT 10 +/* override the AXI size to the pcie core for message with no data. */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT1_OVRD (1 << 14) +/* Rsrvd */ +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_RSRVD_MASK 0xFFFF8000 +#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_RSRVD_SHIFT 15 + + /**** func_ctrl_0 register ****/ +/* choose the field from the axuser */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_TH_OVRD_FROM_AXUSER (1 << 0) +/* choose the field from register */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_TH_OVRD_FROM_REG (1 << 1) +/* field offset from the address portions according to the spec */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_TH_ADDR_OFFSET_MASK 0x0000003C +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_TH_ADDR_OFFSET_SHIFT 2 +/* register value override */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_CFG_TH_OVRD (1 << 6) +/* choose the field from the axuser */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_ST_VEC_OVRD_FROM_AXUSER_MASK 0x00007F80 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_ST_VEC_OVRD_FROM_AXUSER_SHIFT 7 +/* choose the field from register */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_ST_VEC_OVRD_FROM_REG_MASK 0x007F8000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_ST_VEC_OVRD_FROM_REG_SHIFT 15 +/* register value override */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_CFG_ST_VEC_OVRD_MASK 0x7F800000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_CFG_ST_VEC_OVRD_SHIFT 23 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_RSRVD (1 << 31) + +/**** func_ctrl_2 register ****/ +/* choose the field from the axuser */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_OVRD_FROM_AXUSER_MASK 0x00000003 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_OVRD_FROM_AXUSER_SHIFT 0 +/* choose the field from register */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_OVRD_FROM_REG_MASK 0x0000000C +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_OVRD_FROM_REG_SHIFT 2 +/* in case the field take from the address, offset field for each bit. */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_ADDR_OFFSET_MASK 0x00000FF0 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_ADDR_OFFSET_SHIFT 4 +/* register value override */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_PH_VEC_OVRD_MASK 0x00003000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_PH_VEC_OVRD_SHIFT 12 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_14_15_MASK 0x0000C000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_14_15_SHIFT 14 +/* choose the field from the axuser */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_AXUSER_MASK 0x00030000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_AXUSER_SHIFT 16 +/* choose the field from register */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_REG_MASK 0x000C0000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_REG_SHIFT 18 +/* in case the field take from the address, offset field for each bit. */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_ADDR_OFFSET_MASK 0x0FF00000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_ADDR_OFFSET_SHIFT 20 +/* register value override */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_VMID89_VEC_OVRD_MASK 0x30000000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_VMID89_VEC_OVRD_SHIFT 28 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_MASK 0xC0000000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_SHIFT 30 + +/**** func_ctrl_3 register ****/ +/* + * When set take the corresponding bit address from register + * pf_vec_mem_addr44_53_ovrd + */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR44_53_SEL_MASK 0x000003FF +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR44_53_SEL_SHIFT 0 +/* override value. */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR44_53_OVRD_MASK 0x000FFC00 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR44_53_OVRD_SHIFT 10 +/* + * When set take the corresponding bit address from register + * pf_vec_mem_addr54_63_ovrd + */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR54_63_SEL_MASK 0x3FF00000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR54_63_SEL_SHIFT 20 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_RSRVD_MASK 0xC0000000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_RSRVD_SHIFT 30 + +/**** func_ctrl_4 register ****/ +/* When set take the corresponding bit address from vmid value. */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_VMID_MASK 0x000003FF +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_VMID_SHIFT 0 +/* override value. */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_OVRD_MASK 0x000FFC00 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_OVRD_SHIFT 10 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_RSRVD_MASK 0xFFF00000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_RSRVD_SHIFT 20 + +/**** func_ctrl_5 register ****/ +/* + * When set take the corresponding bit address [63:44] from + * aw_pf_vec_msg_addr_ovrd + */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_5_AW_PF_VEC_MSG_ADDR_SEL_MASK 0x000FFFFF +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_5_AW_PF_VEC_MSG_ADDR_SEL_SHIFT 0 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_5_RSRVD_MASK 0xFFF00000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_5_RSRVD_SHIFT 20 + +/**** func_ctrl_6 register ****/ +/* override value. */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_6_AW_PF_VEC_MSG_ADDR_OVRD_MASK 0x000FFFFF +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_6_AW_PF_VEC_MSG_ADDR_OVRD_SHIFT 0 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_6_RSRVD_MASK 0xFFF00000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_6_RSRVD_SHIFT 20 + +/**** func_ctrl_7 register ****/ +/* + * When set take the corresponding bit address [63:44] from + * ar_pf_vec_msg_addr_ovrd + */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_7_AR_PF_VEC_MSG_ADDR_SEL_MASK 0x000FFFFF +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_7_AR_PF_VEC_MSG_ADDR_SEL_SHIFT 0 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_7_RSRVD_MASK 0xFFF00000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_7_RSRVD_SHIFT 20 + +/**** func_ctrl_8 register ****/ +/* override value. */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_8_AR_PF_VEC_MSG_ADDR_OVRD_MASK 0x000FFFFF +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_8_AR_PF_VEC_MSG_ADDR_OVRD_SHIFT 0 +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_8_RSRVD_MASK 0xFFF00000 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_8_RSRVD_SHIFT 20 + +/**** func_ctrl_9 register ****/ +/* no snoop override */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_PF_VEC_NO_SNOOP_OVRD (1 << 0) +/* no snoop override value */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_PF_VEC_NO_SNOOP_OVRD_VALUE (1 << 1) +/* atu bypass override */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_PF_VEC_ATU_BYPASS_OVRD (1 << 2) +/* atu bypass override value */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_PF_VEC_ATU_BYPASS_OVRD_VALUE (1 << 3) +/* Rsrvd */ +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_RSRVD_MASK 0xFFFFFFF0 +#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_RSRVD_SHIFT 4 + +/**** entry_vec register ****/ +/* entry0 */ +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_0_MASK 0x0000001F +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_0_SHIFT 0 +/* entry1 */ +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_1_MASK 0x000003E0 +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_1_SHIFT 5 +/* entry2 */ +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_2_MASK 0x00007C00 +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_2_SHIFT 10 +/* entry3 */ +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_3_MASK 0x000F8000 +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_3_SHIFT 15 +/* atu bypass for message "write" */ +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_AW_MSG_ATU_BYPASS (1 << 20) +/* atu bypass for message "read" */ +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_AR_MSG_ATU_BYPASS (1 << 21) +/* Rsrvd */ +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_RSRVD_MASK 0xFFC00000 +#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_RSRVD_SHIFT 22 + +/**** int_cause_grp_A_axi register ****/ +/* + * Master Response Composer Lookup Error + * Overflow that occurred in a lookup table of the Outbound responses. This + * indicates that there was a violation for the number of outstanding NP + * requests issued for the Inbound direction. + * Write zero to clear. + */ +#define PCIE_AXI_INT_GRP_A_CAUSE_GM_COMPOSER_LOOKUP_ERR (1 << 0) +/* + * Indicates a PARITY ERROR on the master data read channel. + * Write zero to clear. + */ +#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_DATA_PATH_RD (1 << 2) +/* + * Indicates a PARITY ERROR on the slave addr read channel. + * Write zero to clear. + */ +#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_RD (1 << 3) +/* + * Indicates a PARITY ERROR on the slave addr write channel. + * Write zero to clear. + */ +#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_WR (1 << 4) +/* + * Indicates a PARITY ERROR on the slave data write channel. + * Write zero to clear. + */ +#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_DATA_WR (1 << 5) +/* Reserved */ +#define PCIE_AXI_INT_GRP_A_CAUSE_RESERVED_6 (1 << 6) +/* + * Software error: ECAM write request with invalid bus number. + * Write Zero to clear + */ +#define PCIE_AXI_INT_GRP_A_CAUSE_SW_ECAM_ERR_RD (1 << 7) +/* + * Software error: ECAM read request with invalid bus number. + * Write Zero to clear. + */ +#define PCIE_AXI_INT_GRP_A_CAUSE_SW_ECAM_ERR_WR (1 << 8) +/* Indicates an ERROR in the PCIe application cause register. */ +#define PCIE_AXI_INT_GRP_A_CAUSE_PCIE_CORE_INT (1 << 9) +/* + * Whenever the Master AXI finishes writing a message, it sets this bit. + * Whenever the int is cleared, the message information MSG_* regs are no longer + * valid. + */ +#define PCIE_AXI_INT_GRP_A_CAUSE_MSTR_AXI_GETOUT_MSG (1 << 10) +/* Read AXI compilation has ERROR. */ +#define PCIE_AXI_INT_GRP_A_CAUSE_RD_CMPL_ERR (1 << 11) +/* Write AXI compilation has ERROR. */ +#define PCIE_AXI_INT_GRP_A_CAUSE_WR_CMPL_ERR (1 << 12) +/* Read AXI compilation has timed out. */ +#define PCIE_AXI_INT_GRP_A_CAUSE_RD_CMPL_TO (1 << 13) +/* Write AXI compilation has timed out. */ +#define PCIE_AXI_INT_GRP_A_CAUSE_WR_CMPL_TO (1 << 14) +/* Parity error AXI domain */ +#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERROR_AXI (1 << 15) +/* POS error interrupt */ +#define PCIE_AXI_INT_GRP_A_CAUSE_POS_AXI_BRESP (1 << 16) +/* The outstanding write counter become full should never happen */ +#define PCIE_AXI_INT_GRP_A_CAUSE_WRITE_CNT_FULL_ERR (1 << 17) +/* BRESP received before the write counter increment. */ +#define PCIE_AXI_INT_GRP_A_CAUSE_BRESP_BEFORE_WR_CNT_INC_ERR (1 << 18) + +/**** int_control_grp_A_axi register ****/ +/* When Clear_on_Read =1, all bits of the Cause register are cleared on read. */ +#define PCIE_AXI_INT_GRP_A_CTRL_CLEAR_ON_READ (1 << 0) +/* + * (Must be set only when MSIX is enabled.) + * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its + * corresponding bit in the mask register is set, masking future interrupts. + */ +#define PCIE_AXI_INT_GRP_A_CTRL_AUTO_MASK (1 << 1) +/* + * Auto_Clear (RW) + * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared + * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. + */ +#define PCIE_AXI_INT_GRP_A_CTRL_AUTO_CLEAR (1 << 2) +/* + * When set,_on_Posedge =1, the bits in the Interrupt Cause register are set on + * the posedge of the interrupt source, i.e., when interrupt source =1 and + * Interrupt Status = 0. + * When set,_on_Posedge =0, the bits in the Interrupt Cause register are set + * when interrupt source =1. + */ +#define PCIE_AXI_INT_GRP_A_CTRL_SET_ON_POS (1 << 3) +/* + * When Moderation_Reset =1, all Moderation timers associated with the interrupt + * cause bits are cleared to 0, enabling immediate interrupt assertion if any + * unmasked cause bit is set to 1. This bit is self-negated. + */ +#define PCIE_AXI_INT_GRP_A_CTRL_MOD_RST (1 << 4) +/* + * When mask_msi_x =1, no MSI-X from this group is sent. This bit is set to 1 + * when the associate summary bit in this group is used to generate a single + * MSI-X for this group. + */ +#define PCIE_AXI_INT_GRP_A_CTRL_MASK_MSI_X (1 << 5) +/* MSI-X AWID value. Same ID for all cause bits. */ +#define PCIE_AXI_INT_GRP_A_CTRL_AWID_MASK 0x00000F00 +#define PCIE_AXI_INT_GRP_A_CTRL_AWID_SHIFT 8 +/* + * This value determines the interval between interrupts. Writing ZERO disables + * Moderation. + */ +#define PCIE_AXI_INT_GRP_A_CTRL_MOD_INTV_MASK 0x00FF0000 +#define PCIE_AXI_INT_GRP_A_CTRL_MOD_INTV_SHIFT 16 +/* + * This value determines the Moderation_Timer_Clock speed. + * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. + * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. + * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. + */ +#define PCIE_AXI_INT_GRP_A_CTRL_MOD_RES_MASK 0x0F000000 +#define PCIE_AXI_INT_GRP_A_CTRL_MOD_RES_SHIFT 24 + +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_pcie_axi_REG_H */ + +/** @} end of ... group */ diff --git a/al_hal_pcie_interrupts.h b/al_hal_pcie_interrupts.h new file mode 100644 index 000000000000..357971ca63cb --- /dev/null +++ b/al_hal_pcie_interrupts.h @@ -0,0 +1,271 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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 _AL_HAL_PCIE_INTERRUPTS_H_ +#define _AL_HAL_PCIE_INTERRUPTS_H_ + +#include "al_hal_common.h" +#include "al_hal_pcie.h" +#include "al_hal_iofic.h" + +/** + * @defgroup group_pcie_interrupts PCIe interrupts + * @ingroup grouppcie + * @{ + * The PCIe interrupts HAL can be used to control PCIe unit interrupts. + * There are 5 groups of interrupts: app group A, B, C, D and AXI. + * Only 2 interrupts go from the pcie unit to the GIC: + * 1. Summary for all the int groups (AXI+APP CORE). + * 2. INTA assert/deassert (RC only). + * For the specific GIC interrupt line, please check the architecture reference + * manual. + * The reset mask state of all interrupts is: Masked + * + * @file al_hal_pcie_interrupts.h + * + */ + +/** + * PCIe interrupt groups + */ +enum al_pcie_int_group { + AL_PCIE_INT_GRP_A, + AL_PCIE_INT_GRP_B, + AL_PCIE_INT_GRP_C, /* Rev3 only */ + AL_PCIE_INT_GRP_D, /* Rev3 only */ + AL_PCIE_INT_GRP_AXI_A, +}; + +/** + * App group A interrupts mask - don't change + * All interrupts not listed below should be masked + */ +enum al_pcie_app_int_grp_a { + /** [RC only] Deassert_INTD received */ + AL_PCIE_APP_INT_DEASSERT_INTD = AL_BIT(0), + /** [RC only] Deassert_INTC received */ + AL_PCIE_APP_INT_DEASSERT_INTC = AL_BIT(1), + /** [RC only] Deassert_INTB received */ + AL_PCIE_APP_INT_DEASSERT_INTB = AL_BIT(2), + /** + * [RC only] Deassert_INTA received - there's a didcated GIC interrupt + * line that reflects the status of ASSERT/DEASSERT of INTA + */ + AL_PCIE_APP_INT_DEASSERT_INTA = AL_BIT(3), + /** [RC only] Assert_INTD received */ + AL_PCIE_APP_INT_ASSERT_INTD = AL_BIT(4), + /** [RC only] Assert_INTC received */ + AL_PCIE_APP_INT_ASSERT_INTC = AL_BIT(5), + /** [RC only] Assert_INTB received */ + AL_PCIE_APP_INT_ASSERT_INTB = AL_BIT(6), + /** + * [RC only] Assert_INTA received - there's a didcated GIC interrupt + * line that reflects the status of ASSERT/DEASSERT of INTA + */ + AL_PCIE_APP_INT_ASSERT_INTA = AL_BIT(7), + /** [RC only] MSI Controller Interrupt */ + AL_PCIE_APP_INT_MSI_CNTR_RCV_INT = AL_BIT(8), + /** [EP only] MSI sent grant */ + AL_PCIE_APP_INT_MSI_TRNS_GNT = AL_BIT(9), + /** [RC only] System error detected (ERR_COR, ERR_FATAL, ERR_NONFATAL) */ + AL_PCIE_APP_INT_SYS_ERR_RC = AL_BIT(10), + /** [EP only] Software initiates FLR on a Physical Function */ + AL_PCIE_APP_INT_FLR_PF_ACTIVE = AL_BIT(11), + /** [RC only] Root Error Command register assertion notification */ + AL_PCIE_APP_INT_AER_RC_ERR = AL_BIT(12), + /** [RC only] Root Error Command register assertion notification With MSI or MSIX enabled */ + AL_PCIE_APP_INT_AER_RC_ERR_MSI = AL_BIT(13), + /** [RC only] PME Status bit assertion in the Root Status register With INTA */ + AL_PCIE_APP_INT_PME_INT = AL_BIT(15), + /** [RC only] PME Status bit assertion in the Root Status register With MSI or MSIX enabled */ + AL_PCIE_APP_INT_PME_MSI = AL_BIT(16), + /** [RC/EP] The core assert link down event, whenever the link is going down */ + AL_PCIE_APP_INT_LINK_DOWN = AL_BIT(21), + /** [EP only] When the EP gets a command to shut down, signal the software to block any new TLP. */ + AL_PCIE_APP_INT_PM_XTLH_BLOCK_TLP = AL_BIT(22), + /** [RC/EP] PHY/MAC link up */ + AL_PCIE_APP_INT_XMLH_LINK_UP = AL_BIT(23), + /** [RC/EP] Data link up */ + AL_PCIE_APP_INT_RDLH_LINK_UP = AL_BIT(24), + /** [RC/EP] The LTSSM is in RCVRY_LOCK state. */ + AL_PCIE_APP_INT_LTSSM_RCVRY_STATE = AL_BIT(25), + /** + * [RC/EP] CFG write transaction to the configuration space by the RC peer + * For RC the int/ will be set from DBI write (internal SoC write)] + */ + AL_PCIE_APP_INT_CFG_WR = AL_BIT(26), + /** [EP only] CFG access in EP mode */ + AL_PCIE_APP_INT_CFG_ACCESS = AL_BIT(31), +}; + +/** + * App group B interrupts mask - don't change + * All interrupts not listed below should be masked + */ +enum al_pcie_app_int_grp_b { + /** [RC only] PM_PME Message received */ + AL_PCIE_APP_INT_GRP_B_PM_PME_MSG_RCVD = AL_BIT(0), + /** [RC only] PME_TO_Ack Message received */ + AL_PCIE_APP_INT_GRP_B_PME_TO_ACK_MSG_RCVD = AL_BIT(1), + /** [EP only] PME_Turn_Off Message received */ + AL_PCIE_APP_INT_GRP_B_PME_TURN_OFF_MSG_RCVD = AL_BIT(2), + /** [RC only] ERR_CORR Message received */ + AL_PCIE_APP_INT_GRP_B_CORR_ERR_MSG_RCVD = AL_BIT(3), + /** [RC only] ERR_NONFATAL Message received */ + AL_PCIE_APP_INT_GRP_B_NON_FTL_ERR_MSG_RCVD = AL_BIT(4), + /** [RC only] ERR_FATAL Message received */ + AL_PCIE_APP_INT_GRP_B_FTL_ERR_MSG_RCVD = AL_BIT(5), + /** + * [RC/EP] Vendor Defined Message received + * Asserted when a vevdor message is received (with no data), buffers 2 + * messages only, and latch the headers in registers + */ + AL_PCIE_APP_INT_GRP_B_VNDR_MSG_A_RCVD = AL_BIT(6), + /** + * [RC/EP] Vendor Defined Message received + * Asserted when a vevdor message is received (with no data), buffers 2 + * messages only, and latch the headers in registers + */ + AL_PCIE_APP_INT_GRP_B_VNDR_MSG_B_RCVD = AL_BIT(7), + /** [EP only] Link Autonomous Bandwidth Status is updated */ + AL_PCIE_APP_INT_GRP_B_LNK_BW_UPD = AL_BIT(12), + /** [EP only] Link Equalization Request bit in the Link Status 2 Register has been set */ + AL_PCIE_APP_INT_GRP_B_LNK_EQ_REQ = AL_BIT(13), + /** [RC/EP] OB Vendor message request is granted by the PCIe core */ + AL_PCIE_APP_INT_GRP_B_OB_VNDR_MSG_REQ_GRNT = AL_BIT(14), + /** [RC only] CPL timeout from the PCIe core indiication */ + AL_PCIE_APP_INT_GRP_B_CPL_TO = AL_BIT(15), + /** [RC/EP] Slave Response Composer Lookup Error */ + AL_PCIE_APP_INT_GRP_B_SLV_RESP_COMP_LKUP_ERR = AL_BIT(16), + /** [RC/EP] Parity Error */ + AL_PCIE_APP_INT_GRP_B_PARITY_ERR = AL_BIT(17), + /** [EP only] Speed change request */ + AL_PCIE_APP_INT_GRP_B_SPEED_CHANGE = AL_BIT(31), +}; + +/** + * AXI interrupts mask - don't change + * These are internal errors that can happen on the internal chip interface + * between the PCIe port and the I/O Fabric over the AXI bus. The notion of + * master and slave refer to the PCIe port master interface towards the I/O + * Fabric (i.e. for inbound PCIe writes/reads toward the I/O Fabric), while the + * slave interface refer to the I/O Fabric to PCIe port interface where the + * internal chip DMAs and CPU cluster is initiating transactions. + * All interrupts not listed below should be masked. + */ +enum al_pcie_axi_int { + /** [RC/EP] Master Response Composer Lookup Error */ + AL_PCIE_AXI_INT_MSTR_RESP_COMP_LKUP_ERR = AL_BIT(0), + /** [RC/EP] PARITY ERROR on the master data read channel */ + AL_PCIE_AXI_INT_PARITY_ERR_MSTR_DATA_RD_CHNL = AL_BIT(2), + /** [RC/EP] PARITY ERROR on the slave addr read channel */ + AL_PCIE_AXI_INT_PARITY_ERR_SLV_ADDR_RD_CHNL = AL_BIT(3), + /** [RC/EP] PARITY ERROR on the slave addr write channel */ + AL_PCIE_AXI_INT_PARITY_ERR_SLV_ADDR_WR_CHNL = AL_BIT(4), + /** [RC/EP] PARITY ERROR on the slave data write channel */ + AL_PCIE_AXI_INT_PARITY_ERR_SLV_DATA_WR_CHNL = AL_BIT(5), + /** [RC only] Software error: ECAM write request with invalid bus number */ + AL_PCIE_AXI_INT_ECAM_WR_REQ_INVLD_BUS_NUM = AL_BIT(7), + /** [RC only] Software error: ECAM read request with invalid bus number */ + AL_PCIE_AXI_INT_ECAM_RD_REQ_INVLD_BUS_NUM = AL_BIT(8), + /** [RC/EP] Read AXI completion has ERROR */ + AL_PCIE_AXI_INT_RD_AXI_COMPL_ERR = AL_BIT(11), + /** [RC/EP] Write AXI completion has ERROR */ + AL_PCIE_AXI_INT_WR_AXI_COMPL_ERR = AL_BIT(12), + /** [RC/EP] Read AXI completion has timed out */ + AL_PCIE_AXI_INT_RD_AXI_COMPL_TO = AL_BIT(13), + /** [RC/EP] Write AXI completion has timed out */ + AL_PCIE_AXI_INT_WR_AXI_COMPL_TO = AL_BIT(14), + /** [RC/EP] Parity error AXI domain */ + AL_PCIE_AXI_INT_AXI_DOM_PARITY_ERR = AL_BIT(15), + /** [RC/EP] POS error interrupt */ + AL_PCIE_AXI_INT_POS_ERR = AL_BIT(16), +}; + +/** + * @brief Initialize and configure PCIe controller interrupts + * Doesn't change the mask state of the interrupts + * The reset mask state of all interrupts is: Masked + * + * @param pcie_port pcie port handle + */ +void al_pcie_ints_config(struct al_pcie_port *pcie_port); + +/** + * Unmask PCIe app group interrupts + * @param pcie_port pcie_port pcie port handle + * @param int_group interrupt group + * @param int_mask int_mask interrupts to unmask ('1' to unmask) + */ +void al_pcie_app_int_grp_unmask( + struct al_pcie_port *pcie_port, + enum al_pcie_int_group int_group, + uint32_t int_mask); + +/** + * Mask PCIe app group interrupts + * @param pcie_port pcie_port pcie port handle + * @param int_group interrupt group + * @param int_mask int_mask interrupts to unmask ('1' to mask) + */ +void al_pcie_app_int_grp_mask( + struct al_pcie_port *pcie_port, + enum al_pcie_int_group int_group, + uint32_t int_mask); + +/** + * Clear the PCIe app group interrupt cause + * @param pcie_port pcie port handle + * @param int_group interrupt group + * @param int_cause interrupt cause + */ +void al_pcie_app_int_grp_cause_clear( + struct al_pcie_port *pcie_port, + enum al_pcie_int_group int_group, + uint32_t int_cause); + +/** + * Read PCIe app group interrupt cause + * @param pcie_port pcie port handle + * @param int_group interrupt group + * @return interrupt cause or 0 in case the group is not supported + */ +uint32_t al_pcie_app_int_grp_cause_read( + struct al_pcie_port *pcie_port, + enum al_pcie_int_group int_group); + +#endif +/** @} end of group_pcie_interrupts group */ diff --git a/al_hal_pcie_regs.h b/al_hal_pcie_regs.h new file mode 100644 index 000000000000..15c5735e279f --- /dev/null +++ b/al_hal_pcie_regs.h @@ -0,0 +1,594 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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 __AL_HAL_PCIE_REGS_H__ +#define __AL_HAL_PCIE_REGS_H__ + +/* Note: Definitions before the includes so axi/wrapper regs sees them */ + +/** Maximum physical functions supported */ +#define REV1_2_MAX_NUM_OF_PFS 1 +#define REV3_MAX_NUM_OF_PFS 4 +#define AL_MAX_NUM_OF_PFS 4 /* the maximum between all Revisions */ + +#include "al_hal_pcie_axi_reg.h" +#ifndef AL_PCIE_EX +#include "al_hal_pcie_w_reg.h" +#else +#include "al_hal_pcie_w_reg_ex.h" +#endif + +/** + * Revision IDs: + * ID_0: SlickRock M0 + * ID_1: SlickRock A0 + * ID_2: PeakRock x4 + * ID_3: PeakRock x8 + */ +#define AL_PCIE_REV_ID_0 0 +#define AL_PCIE_REV_ID_1 1 +#define AL_PCIE_REV_ID_2 2 +#define AL_PCIE_REV_ID_3 3 + +#define AL_PCIE_AXI_REGS_OFFSET 0x0 +#define AL_PCIE_REV_1_2_APP_REGS_OFFSET 0x1000 +#define AL_PCIE_REV_3_APP_REGS_OFFSET 0x2000 +#define AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET 0x2000 +#define AL_PCIE_REV_3_CORE_CONF_BASE_OFFSET 0x10000 + +/** Maximum number of lanes supported */ +#define REV1_2_MAX_NUM_LANES 4 +#define REV3_MAX_NUM_LANES 8 +#define AL_MAX_NUM_OF_LANES 8 /* the maximum between all Revisions */ + +struct al_pcie_core_iatu_regs { + uint32_t index; + uint32_t cr1; + uint32_t cr2; + uint32_t lower_base_addr; + uint32_t upper_base_addr; + uint32_t limit_addr; + uint32_t lower_target_addr; + uint32_t upper_target_addr; + uint32_t cr3; + uint32_t rsrvd[(0x270 - 0x224) >> 2]; +}; + +struct al_pcie_core_port_regs { + uint32_t ack_lat_rply_timer; + uint32_t reserved1[(0x10 - 0x4) >> 2]; + uint32_t port_link_ctrl; + uint32_t reserved2[(0x18 - 0x14) >> 2]; + uint32_t timer_ctrl_max_func_num; + uint32_t filter_mask_reg_1; + uint32_t reserved3[(0x48 - 0x20) >> 2]; + uint32_t vc0_posted_rcv_q_ctrl; + uint32_t vc0_non_posted_rcv_q_ctrl; + uint32_t vc0_comp_rcv_q_ctrl; + uint32_t reserved4[(0x10C - 0x54) >> 2]; + uint32_t gen2_ctrl; + uint32_t reserved5[(0x190 - 0x110) >> 2]; + uint32_t gen3_ctrl; + uint32_t gen3_eq_fs_lf; + uint32_t gen3_eq_preset_to_coef_map; + uint32_t gen3_eq_preset_idx; + uint32_t reserved6; + uint32_t gen3_eq_status; + uint32_t gen3_eq_ctrl; + uint32_t reserved7[(0x1B8 - 0x1AC) >> 2]; + uint32_t pipe_loopback_ctrl; + uint32_t rd_only_wr_en; + uint32_t reserved8[(0x1D0 - 0x1C0) >> 2]; + uint32_t axi_slave_err_resp; + uint32_t reserved9[(0x200 - 0x1D4) >> 2]; + struct al_pcie_core_iatu_regs iatu; + uint32_t reserved10[(0x448 - 0x270) >> 2]; +}; + +struct al_pcie_core_aer_regs { + /* 0x0 - PCI Express Extended Capability Header */ + uint32_t header; + /* 0x4 - Uncorrectable Error Status Register */ + uint32_t uncorr_err_stat; + /* 0x8 - Uncorrectable Error Mask Register */ + uint32_t uncorr_err_mask; + /* 0xc - Uncorrectable Error Severity Register */ + uint32_t uncorr_err_severity; + /* 0x10 - Correctable Error Status Register */ + uint32_t corr_err_stat; + /* 0x14 - Correctable Error Mask Register */ + uint32_t corr_err_mask; + /* 0x18 - Advanced Error Capabilities and Control Register */ + uint32_t cap_and_ctrl; + /* 0x1c - Header Log Registers */ + uint32_t header_log[4]; + /* 0x2c - Root Error Command Register */ + uint32_t root_err_cmd; + /* 0x30 - Root Error Status Register */ + uint32_t root_err_stat; + /* 0x34 - Error Source Identification Register */ + uint32_t err_src_id; +}; + +struct al_pcie_core_reg_space_rev_1_2 { + uint32_t config_header[0x40 >> 2]; + uint32_t pcie_pm_cap_base; + uint32_t reserved1[(0x70 - 0x44) >> 2]; + uint32_t pcie_cap_base; + uint32_t pcie_dev_cap_base; + uint32_t pcie_dev_ctrl_status; + uint32_t pcie_link_cap_base; + uint32_t reserved2[(0xB0 - 0x80) >> 2]; + uint32_t msix_cap_base; + uint32_t reserved3[(0x100 - 0xB4) >> 2]; + struct al_pcie_core_aer_regs aer; + uint32_t reserved4[(0x150 - + (0x100 + + sizeof(struct al_pcie_core_aer_regs))) >> 2]; + uint32_t pcie_sec_ext_cap_base; + uint32_t reserved5[(0x700 - 0x154) >> 2]; + struct al_pcie_core_port_regs port_regs; + uint32_t reserved6[(0x1000 - + (0x700 + + sizeof(struct al_pcie_core_port_regs))) >> 2]; +}; + +struct al_pcie_core_reg_space_rev_3 { + uint32_t config_header[0x40 >> 2]; + uint32_t pcie_pm_cap_base; + uint32_t reserved1[(0x70 - 0x44) >> 2]; + uint32_t pcie_cap_base; + uint32_t pcie_dev_cap_base; + uint32_t pcie_dev_ctrl_status; + uint32_t pcie_link_cap_base; + uint32_t reserved2[(0xB0 - 0x80) >> 2]; + uint32_t msix_cap_base; + uint32_t reserved3[(0x100 - 0xB4) >> 2]; + struct al_pcie_core_aer_regs aer; + uint32_t reserved4[(0x158 - + (0x100 + + sizeof(struct al_pcie_core_aer_regs))) >> 2]; + /* pcie_sec_cap is only applicable for function 0 */ + uint32_t pcie_sec_ext_cap_base; + uint32_t reserved5[(0x178 - 0x15C) >> 2]; + /* tph capability is only applicable for rev3 */ + uint32_t tph_cap_base; + uint32_t reserved6[(0x700 - 0x17C) >> 2]; + /* port_regs is only applicable for function 0 */ + struct al_pcie_core_port_regs port_regs; + uint32_t reserved7[(0x1000 - + (0x700 + + sizeof(struct al_pcie_core_port_regs))) >> 2]; +}; + +struct al_pcie_rev3_core_reg_space { + struct al_pcie_core_reg_space_rev_3 func[REV3_MAX_NUM_OF_PFS]; +}; + +struct al_pcie_core_reg_space { + uint32_t *config_header; + uint32_t *pcie_pm_cap_base; + uint32_t *pcie_cap_base; + uint32_t *pcie_dev_cap_base; + uint32_t *pcie_dev_ctrl_status; + uint32_t *pcie_link_cap_base; + uint32_t *msix_cap_base; + struct al_pcie_core_aer_regs *aer; + uint32_t *pcie_sec_ext_cap_base; + uint32_t *tph_cap_base; +}; + +struct al_pcie_revx_regs { + struct al_pcie_revx_axi_regs __iomem axi; +}; + +struct al_pcie_rev1_regs { + struct al_pcie_rev1_axi_regs __iomem axi; + uint32_t reserved1[(AL_PCIE_REV_1_2_APP_REGS_OFFSET - + (AL_PCIE_AXI_REGS_OFFSET + + sizeof(struct al_pcie_rev1_axi_regs))) >> 2]; + struct al_pcie_rev1_w_regs __iomem app; + uint32_t reserved2[(AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET - + (AL_PCIE_REV_1_2_APP_REGS_OFFSET + + sizeof(struct al_pcie_rev1_w_regs))) >> 2]; + struct al_pcie_core_reg_space_rev_1_2 core_space; +}; + +struct al_pcie_rev2_regs { + struct al_pcie_rev2_axi_regs __iomem axi; + uint32_t reserved1[(AL_PCIE_REV_1_2_APP_REGS_OFFSET - + (AL_PCIE_AXI_REGS_OFFSET + + sizeof(struct al_pcie_rev2_axi_regs))) >> 2]; + struct al_pcie_rev2_w_regs __iomem app; + uint32_t reserved2[(AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET - + (AL_PCIE_REV_1_2_APP_REGS_OFFSET + + sizeof(struct al_pcie_rev2_w_regs))) >> 2]; + struct al_pcie_core_reg_space_rev_1_2 core_space; +}; + +struct al_pcie_rev3_regs { + struct al_pcie_rev3_axi_regs __iomem axi; + uint32_t reserved1[(AL_PCIE_REV_3_APP_REGS_OFFSET - + (AL_PCIE_AXI_REGS_OFFSET + + sizeof(struct al_pcie_rev3_axi_regs))) >> 2]; + struct al_pcie_rev3_w_regs __iomem app; + uint32_t reserved2[(AL_PCIE_REV_3_CORE_CONF_BASE_OFFSET - + (AL_PCIE_REV_3_APP_REGS_OFFSET + + sizeof(struct al_pcie_rev3_w_regs))) >> 2]; + struct al_pcie_rev3_core_reg_space core_space; +}; + +struct al_pcie_axi_ctrl { + uint32_t *global; + uint32_t *master_arctl; + uint32_t *master_awctl; + uint32_t *slv_ctl; +}; + +struct al_pcie_axi_ob_ctrl { + uint32_t *cfg_target_bus; + uint32_t *cfg_control; + uint32_t *io_start_l; + uint32_t *io_start_h; + uint32_t *io_limit_l; + uint32_t *io_limit_h; +}; + +struct al_pcie_axi_pcie_global { + uint32_t *conf; +}; + +struct al_pcie_axi_conf { + uint32_t *zero_lane0; + uint32_t *zero_lane1; + uint32_t *zero_lane2; + uint32_t *zero_lane3; + uint32_t *zero_lane4; + uint32_t *zero_lane5; + uint32_t *zero_lane6; + uint32_t *zero_lane7; +}; + +struct al_pcie_axi_status { + uint32_t *lane[AL_MAX_NUM_OF_LANES]; +}; + +struct al_pcie_axi_parity { + uint32_t *en_axi; +}; + +struct al_pcie_axi_ordering { + uint32_t *pos_cntl; +}; + +struct al_pcie_axi_pre_configuration { + uint32_t *pcie_core_setup; +}; + +struct al_pcie_axi_init_fc { + uint32_t *cfg; +}; + +struct al_pcie_axi_attr_ovrd { + uint32_t *write_msg_ctrl_0; + uint32_t *write_msg_ctrl_1; + uint32_t *pf_sel; +}; + +struct al_pcie_axi_pf_axi_attr_ovrd { + uint32_t *func_ctrl_0; + uint32_t *func_ctrl_1; + uint32_t *func_ctrl_2; + uint32_t *func_ctrl_3; + uint32_t *func_ctrl_4; + uint32_t *func_ctrl_5; + uint32_t *func_ctrl_6; + uint32_t *func_ctrl_7; + uint32_t *func_ctrl_8; + uint32_t *func_ctrl_9; +}; + +struct al_pcie_axi_msg_attr_axuser_table { + uint32_t *entry_vec; +}; + +struct al_pcie_axi_regs { + struct al_pcie_axi_ctrl ctrl; + struct al_pcie_axi_ob_ctrl ob_ctrl; + struct al_pcie_axi_pcie_global pcie_global; + struct al_pcie_axi_conf conf; + struct al_pcie_axi_status status; + struct al_pcie_axi_parity parity; + struct al_pcie_axi_ordering ordering; + struct al_pcie_axi_pre_configuration pre_configuration; + struct al_pcie_axi_init_fc init_fc; + struct al_pcie_revx_axi_int_grp_a_axi *int_grp_a; + /* Rev3 only */ + struct al_pcie_axi_attr_ovrd axi_attr_ovrd; + struct al_pcie_axi_pf_axi_attr_ovrd pf_axi_attr_ovrd[REV3_MAX_NUM_OF_PFS]; + struct al_pcie_axi_msg_attr_axuser_table msg_attr_axuser_table; +}; + +struct al_pcie_w_global_ctrl { + uint32_t *port_init; + uint32_t *pm_control; + uint32_t *events_gen[REV3_MAX_NUM_OF_PFS]; + uint32_t *corr_err_sts_int; + uint32_t *uncorr_err_sts_int; + uint32_t *sris_kp_counter; +}; + +struct al_pcie_w_soc_int { + uint32_t *mask_inta_leg_0; + uint32_t *mask_inta_leg_3; /* Rev 2/3 only */ + uint32_t *mask_msi_leg_0; + uint32_t *mask_msi_leg_3; /* Rev 2/3 only */ +}; +struct al_pcie_w_atu { + uint32_t *in_mask_pair; + uint32_t *out_mask_pair; +}; + +struct al_pcie_w_regs { + struct al_pcie_w_global_ctrl global_ctrl; + struct al_pcie_revx_w_debug *debug; + struct al_pcie_revx_w_ap_user_send_msg *ap_user_send_msg; + struct al_pcie_w_soc_int soc_int[REV3_MAX_NUM_OF_PFS]; + struct al_pcie_revx_w_cntl_gen *ctrl_gen; + struct al_pcie_revx_w_parity *parity; + struct al_pcie_w_atu atu; + struct al_pcie_revx_w_status_per_func *status_per_func[REV3_MAX_NUM_OF_PFS]; + struct al_pcie_revx_w_int_grp *int_grp_a; + struct al_pcie_revx_w_int_grp *int_grp_b; + struct al_pcie_revx_w_int_grp *int_grp_c; + struct al_pcie_revx_w_int_grp *int_grp_d; +}; + +struct al_pcie_regs { + struct al_pcie_axi_regs axi; + struct al_pcie_w_regs app; + struct al_pcie_core_port_regs *port_regs; + struct al_pcie_core_reg_space core_space[REV3_MAX_NUM_OF_PFS]; +}; + +#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP 0 +#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC 4 + +#define PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE AL_BIT(17) +#define PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT 18 +#define PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT 19 +#define PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT 20 +#define PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_MASK AL_FIELD_MASK(12, 8) +#define PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_SHIFT 8 + +#define PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT 9 +#define PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT 16 + +#define PCIE_PORT_GEN3_EQ_LF_SHIFT 0 +#define PCIE_PORT_GEN3_EQ_LF_MASK 0x3f +#define PCIE_PORT_GEN3_EQ_FS_SHIFT 6 +#define PCIE_PORT_GEN3_EQ_FS_MASK (0x3f << PCIE_PORT_GEN3_EQ_FS_SHIFT) + +#define PCIE_PORT_LINK_CTRL_LB_EN_SHIFT 2 +#define PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT 7 +#define PCIE_PORT_LINK_CTRL_LINK_CAPABLE_MASK AL_FIELD_MASK(21, 16) +#define PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT 16 + +#define PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT 31 + +#define PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT 0 + +/** timer_ctrl_max_func_num register + * Max physical function number (for example: 0 for 1PF, 3 for 4PFs) + */ +#define PCIE_PORT_GEN3_MAX_FUNC_NUM AL_FIELD_MASK(7, 0) + +/* filter_mask_reg_1 register */ +/** + * SKP Interval Value. + * The number of symbol times to wait between transmitting SKP ordered sets + */ +#define PCIE_FLT_MASK_SKP_INT_VAL_MASK AL_FIELD_MASK(10, 0) + +/* + * 0: Treat Function MisMatched TLPs as UR + * 1: Treat Function MisMatched TLPs as Supported + */ +#define CX_FLT_MASK_UR_FUNC_MISMATCH AL_BIT(16) + +/* + * 0: Treat CFG type1 TLPs as UR for EP; Supported for RC + * 1: Treat CFG type1 TLPs as Supported for EP; UR for RC + */ +#define CX_FLT_MASK_CFG_TYPE1_RE_AS_UR AL_BIT(19) + +/* + * 0: Enforce requester id match for received CPL TLPs. + * A violation results in cpl_abort, and possibly AER of unexp_cpl_err, + * cpl_rcvd_ur, cpl_rcvd_ca + * 1: Mask requester id match for received CPL TLPs + */ +#define CX_FLT_MASK_CPL_REQID_MATCH AL_BIT(22) + +/* + * 0: Enforce function match for received CPL TLPs. + * A violation results in cpl_abort, and possibly AER of unexp_cpl_err, + * cpl_rcvd_ur, cpl_rcvd_ca + * 1: Mask function match for received CPL TLPs + */ +#define CX_FLT_MASK_CPL_FUNC_MATCH AL_BIT(23) + +/* vc0_posted_rcv_q_ctrl register */ +#define RADM_PQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12) +#define RADM_PQ_HCRD_VC0_SHIFT 12 + +/* vc0_non_posted_rcv_q_ctrl register */ +#define RADM_NPQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12) +#define RADM_NPQ_HCRD_VC0_SHIFT 12 + +/* vc0_comp_rcv_q_ctrl register */ +#define RADM_CPLQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12) +#define RADM_CPLQ_HCRD_VC0_SHIFT 12 + +/**** iATU, Control Register 1 ****/ + +/** + * When the Address and BAR matching logic in the core indicate that a MEM-I/O + * transaction matches a BAR in the function corresponding to this value, then + * address translation proceeds. This check is only performed if the "Function + * Number Match Enable" bit of the "iATU Control 2 Register" is set + */ +#define PCIE_IATU_CR1_FUNC_NUM_MASK AL_FIELD_MASK(24, 20) +#define PCIE_IATU_CR1_FUNC_NUM_SHIFT 20 + +/**** iATU, Control Register 2 ****/ +/** For outbound regions, the Function Number Translation Bypass mode enables + * taking the function number of the translated TLP from the PCIe core + * interface and not from the "Function Number" field of CR1. + * For inbound regions, this bit should be asserted when physical function + * match mode needs to be enabled + */ +#define PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_MASK AL_BIT(19) +#define PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_SHIFT 19 + +/* pcie_dev_ctrl_status register */ +#define PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN AL_BIT(0) +#define PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN AL_BIT(1) +#define PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN AL_BIT(2) +#define PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN AL_BIT(3) + +#define PCIE_PORT_DEV_CTRL_STATUS_MPS_MASK AL_FIELD_MASK(7, 5) +#define PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT 5 +#define PCIE_PORT_DEV_CTRL_STATUS_MPS_VAL_256 (1 << PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT) + +#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_MASK AL_FIELD_MASK(14, 12) +#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_SHIFT 12 +#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_VAL_256 (1 << PCIE_PORT_DEV_CTRL_STATUS_MRRS_SHIFT) + +/****************************************************************************** + * AER registers + ******************************************************************************/ +/* PCI Express Extended Capability ID */ +#define PCIE_AER_CAP_ID_MASK AL_FIELD_MASK(15, 0) +#define PCIE_AER_CAP_ID_SHIFT 0 +#define PCIE_AER_CAP_ID_VAL 1 +/* Capability Version */ +#define PCIE_AER_CAP_VER_MASK AL_FIELD_MASK(19, 16) +#define PCIE_AER_CAP_VER_SHIFT 16 +#define PCIE_AER_CAP_VER_VAL 2 + +/* First Error Pointer */ +#define PCIE_AER_CTRL_STAT_FIRST_ERR_PTR_MASK AL_FIELD_MASK(4, 0) +#define PCIE_AER_CTRL_STAT_FIRST_ERR_PTR_SHIFT 0 +/* ECRC Generation Capability */ +#define PCIE_AER_CTRL_STAT_ECRC_GEN_SUPPORTED AL_BIT(5) +/* ECRC Generation Enable */ +#define PCIE_AER_CTRL_STAT_ECRC_GEN_EN AL_BIT(6) +/* ECRC Check Capable */ +#define PCIE_AER_CTRL_STAT_ECRC_CHK_SUPPORTED AL_BIT(7) +/* ECRC Check Enable */ +#define PCIE_AER_CTRL_STAT_ECRC_CHK_EN AL_BIT(8) + +/* Correctable Error Reporting Enable */ +#define PCIE_AER_ROOT_ERR_CMD_CORR_ERR_RPRT_EN AL_BIT(0) +/* Non-Fatal Error Reporting Enable */ +#define PCIE_AER_ROOT_ERR_CMD_NON_FTL_ERR_RPRT_EN AL_BIT(1) +/* Fatal Error Reporting Enable */ +#define PCIE_AER_ROOT_ERR_CMD_FTL_ERR_RPRT_EN AL_BIT(2) + +/* ERR_COR Received */ +#define PCIE_AER_ROOT_ERR_STAT_CORR_ERR AL_BIT(0) +/* Multiple ERR_COR Received */ +#define PCIE_AER_ROOT_ERR_STAT_CORR_ERR_MULTI AL_BIT(1) +/* ERR_FATAL/NONFATAL Received */ +#define PCIE_AER_ROOT_ERR_STAT_FTL_NON_FTL_ERR AL_BIT(2) +/* Multiple ERR_FATAL/NONFATAL Received */ +#define PCIE_AER_ROOT_ERR_STAT_FTL_NON_FTL_ERR_MULTI AL_BIT(3) +/* First Uncorrectable Fatal */ +#define PCIE_AER_ROOT_ERR_STAT_FIRST_UNCORR_FTL AL_BIT(4) +/* Non-Fatal Error Messages Received */ +#define PCIE_AER_ROOT_ERR_STAT_NON_FTL_RCVD AL_BIT(5) +/* Fatal Error Messages Received */ +#define PCIE_AER_ROOT_ERR_STAT_FTL_RCVD AL_BIT(6) +/* Advanced Error Interrupt Message Number */ +#define PCIE_AER_ROOT_ERR_STAT_ERR_INT_MSG_NUM_MASK AL_FIELD_MASK(31, 27) +#define PCIE_AER_ROOT_ERR_STAT_ERR_INT_MSG_NUM_SHIFT 27 + +/* ERR_COR Source Identification */ +#define PCIE_AER_SRC_ID_CORR_ERR_MASK AL_FIELD_MASK(15, 0) +#define PCIE_AER_SRC_ID_CORR_ERR_SHIFT 0 +/* ERR_FATAL/NONFATAL Source Identification */ +#define PCIE_AER_SRC_ID_CORR_ERR_FTL_NON_FTL_MASK AL_FIELD_MASK(31, 16) +#define PCIE_AER_SRC_ID_CORR_ERR_FTL_NON_FTL_SHIFT 16 + +/* AER message */ +#define PCIE_AER_MSG_REQID_MASK AL_FIELD_MASK(31, 16) +#define PCIE_AER_MSG_REQID_SHIFT 16 +#define PCIE_AER_MSG_TYPE_MASK AL_FIELD_MASK(15, 8) +#define PCIE_AER_MSG_TYPE_SHIFT 8 +#define PCIE_AER_MSG_RESERVED AL_FIELD_MASK(7, 1) +#define PCIE_AER_MSG_VALID AL_BIT(0) +/* AER message ack */ +#define PCIE_AER_MSG_ACK AL_BIT(0) +/* AER errors definitions */ +#define AL_PCIE_AER_TYPE_CORR (0x30) +#define AL_PCIE_AER_TYPE_NON_FATAL (0x31) +#define AL_PCIE_AER_TYPE_FATAL (0x33) +/* Requester ID Bus */ +#define AL_PCIE_REQID_BUS_NUM_SHIFT (8) + +/****************************************************************************** + * TPH registers + ******************************************************************************/ +#define PCIE_TPH_NEXT_POINTER AL_FIELD_MASK(31, 20) + +/****************************************************************************** + * Config Header registers + ******************************************************************************/ +/** + * see BIST_HEADER_TYPE_LATENCY_CACHE_LINE_SIZE_REG in core spec + * Note: valid only for EP mode + */ +#define PCIE_BIST_HEADER_TYPE_BASE 0xc +#define PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK AL_BIT(23) + +/****************************************************************************** + * SRIS KP counters default values + ******************************************************************************/ +#define PCIE_SRIS_KP_COUNTER_GEN3_DEFAULT_VAL (0x24) +#define PCIE_SRIS_KP_COUNTER_GEN21_DEFAULT_VAL (0x4B) + +#endif diff --git a/al_hal_pcie_w_reg.h b/al_hal_pcie_w_reg.h new file mode 100644 index 000000000000..44e9d952655d --- /dev/null +++ b/al_hal_pcie_w_reg.h @@ -0,0 +1,1505 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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 __AL_HAL_PCIE_W_REG_H__ +#define __AL_HAL_PCIE_W_REG_H__ + +#ifdef __cplusplus +extern "C" { +#endif +/* +* Unit Registers +*/ + + + +struct al_pcie_rev1_w_global_ctrl { + /* [0x0] */ + uint32_t port_init; + /* [0x4] */ + uint32_t port_status; + /* [0x8] */ + uint32_t pm_control; + uint32_t rsrvd_0; + /* [0x10] */ + uint32_t events_gen; + uint32_t rsrvd[3]; +}; +struct al_pcie_rev2_w_global_ctrl { + /* [0x0] */ + uint32_t port_init; + /* [0x4] */ + uint32_t port_status; + /* [0x8] */ + uint32_t pm_control; + uint32_t rsrvd_0; + /* [0x10] */ + uint32_t events_gen; + /* [0x14] */ + uint32_t pended_corr_err_sts_int; + /* [0x18] */ + uint32_t pended_uncorr_err_sts_int; + /* [0x1c] */ + uint32_t sris_kp_counter_value; +}; +struct al_pcie_rev3_w_global_ctrl { + /* [0x0] */ + uint32_t port_init; + /* [0x4] */ + uint32_t port_status; + /* [0x8] */ + uint32_t pm_control; + /* [0xc] */ + uint32_t pended_corr_err_sts_int; + /* [0x10] */ + uint32_t pended_uncorr_err_sts_int; + /* [0x14] */ + uint32_t sris_kp_counter_value; + uint32_t rsrvd[2]; +}; + +struct al_pcie_rev3_w_events_gen_per_func { + /* [0x0] */ + uint32_t events_gen; +}; +struct al_pcie_rev3_w_pm_state_per_func { + /* [0x0] */ + uint32_t pm_state_per_func; +}; +struct al_pcie_rev3_w_cfg_bars_ovrd { + /* [0x0] */ + uint32_t bar0_mask_lsb; + /* [0x4] */ + uint32_t bar0_mask_msb; + /* [0x8] */ + uint32_t bar0_limit_lsb; + /* [0xc] */ + uint32_t bar0_limit_msb; + /* [0x10] */ + uint32_t bar0_start_lsb; + /* [0x14] */ + uint32_t bar0_start_msb; + /* [0x18] */ + uint32_t bar0_ctrl; + /* [0x1c] */ + uint32_t bar1_mask_lsb; + /* [0x20] */ + uint32_t bar1_mask_msb; + /* [0x24] */ + uint32_t bar1_limit_lsb; + /* [0x28] */ + uint32_t bar1_limit_msb; + /* [0x2c] */ + uint32_t bar1_start_lsb; + /* [0x30] */ + uint32_t bar1_start_msb; + /* [0x34] */ + uint32_t bar1_ctrl; + /* [0x38] */ + uint32_t bar2_mask_lsb; + /* [0x3c] */ + uint32_t bar2_mask_msb; + /* [0x40] */ + uint32_t bar2_limit_lsb; + /* [0x44] */ + uint32_t bar2_limit_msb; + /* [0x48] */ + uint32_t bar2_start_lsb; + /* [0x4c] */ + uint32_t bar2_start_msb; + /* [0x50] */ + uint32_t bar2_ctrl; + /* [0x54] */ + uint32_t bar3_mask_lsb; + /* [0x58] */ + uint32_t bar3_mask_msb; + /* [0x5c] */ + uint32_t bar3_limit_lsb; + /* [0x60] */ + uint32_t bar3_limit_msb; + /* [0x64] */ + uint32_t bar3_start_lsb; + /* [0x68] */ + uint32_t bar3_start_msb; + /* [0x6c] */ + uint32_t bar3_ctrl; + /* [0x70] */ + uint32_t bar4_mask_lsb; + /* [0x74] */ + uint32_t bar4_mask_msb; + /* [0x78] */ + uint32_t bar4_limit_lsb; + /* [0x7c] */ + uint32_t bar4_limit_msb; + /* [0x80] */ + uint32_t bar4_start_lsb; + /* [0x84] */ + uint32_t bar4_start_msb; + /* [0x88] */ + uint32_t bar4_ctrl; + /* [0x8c] */ + uint32_t bar5_mask_lsb; + /* [0x90] */ + uint32_t bar5_mask_msb; + /* [0x94] */ + uint32_t bar5_limit_lsb; + /* [0x98] */ + uint32_t bar5_limit_msb; + /* [0x9c] */ + uint32_t bar5_start_lsb; + /* [0xa0] */ + uint32_t bar5_start_msb; + /* [0xa4] */ + uint32_t bar5_ctrl; + uint32_t rsrvd[2]; +}; + +struct al_pcie_revx_w_debug { + /* [0x0] */ + uint32_t info_0; + /* [0x4] */ + uint32_t info_1; + /* [0x8] */ + uint32_t info_2; + /* [0xc] */ + uint32_t info_3; +}; +struct al_pcie_revx_w_ob_ven_msg { + /* [0x0] */ + uint32_t control; + /* [0x4] */ + uint32_t param_1; + /* [0x8] */ + uint32_t param_2; + /* [0xc] */ + uint32_t data_high; + uint32_t rsrvd_0; + /* [0x14] */ + uint32_t data_low; +}; +struct al_pcie_revx_w_ap_user_send_msg { + /* [0x0] */ + uint32_t req_info; + /* [0x4] */ + uint32_t ack_info; +}; +struct al_pcie_revx_w_link_down { + /* [0x0] */ + uint32_t reset_delay; + /* [0x4] */ + uint32_t reset_extend_rsrvd; +}; +struct al_pcie_revx_w_cntl_gen { + /* [0x0] */ + uint32_t features; +}; +struct al_pcie_revx_w_parity { + /* [0x0] */ + uint32_t en_core; + /* [0x4] */ + uint32_t status_core; +}; +struct al_pcie_revx_w_last_wr { + /* [0x0] */ + uint32_t cfg_addr; +}; +struct al_pcie_rev1_2_w_atu { + /* [0x0] */ + uint32_t in_mask_pair[6]; + /* [0x18] */ + uint32_t out_mask_pair[6]; +}; +struct al_pcie_rev3_w_atu { + /* [0x0] */ + uint32_t in_mask_pair[12]; + /* [0x30] */ + uint32_t out_mask_pair[8]; + /* [0x50] */ + uint32_t reg_out_mask; + uint32_t rsrvd[11]; +}; +struct al_pcie_rev3_w_cfg_func_ext { + /* [0x0] */ + uint32_t cfg; +}; +struct al_pcie_rev3_w_app_hdr_interface_send { + /* [0x0] */ + uint32_t app_hdr_31_0; + /* [0x4] */ + uint32_t app_hdr_63_32; + /* [0x8] */ + uint32_t app_hdr_95_64; + /* [0xc] */ + uint32_t app_hdr_127_96; + /* [0x10] */ + uint32_t app_err_bus; + /* [0x14] */ + uint32_t app_func_num_advisory; + /* [0x18] */ + uint32_t app_hdr_cmd; +}; +struct al_pcie_rev3_w_diag_command { + /* [0x0] */ + uint32_t diag_ctrl; +}; +struct al_pcie_rev1_w_soc_int { + /* [0x0] */ + uint32_t status_0; + /* [0x4] */ + uint32_t status_1; + /* [0x8] */ + uint32_t status_2; + /* [0xc] */ + uint32_t mask_inta_leg_0; + /* [0x10] */ + uint32_t mask_inta_leg_1; + /* [0x14] */ + uint32_t mask_inta_leg_2; + /* [0x18] */ + uint32_t mask_msi_leg_0; + /* [0x1c] */ + uint32_t mask_msi_leg_1; + /* [0x20] */ + uint32_t mask_msi_leg_2; + /* [0x24] */ + uint32_t msi_leg_cntl; +}; +struct al_pcie_rev2_w_soc_int { + /* [0x0] */ + uint32_t status_0; + /* [0x4] */ + uint32_t status_1; + /* [0x8] */ + uint32_t status_2; + /* [0xc] */ + uint32_t status_3; + /* [0x10] */ + uint32_t mask_inta_leg_0; + /* [0x14] */ + uint32_t mask_inta_leg_1; + /* [0x18] */ + uint32_t mask_inta_leg_2; + /* [0x1c] */ + uint32_t mask_inta_leg_3; + /* [0x20] */ + uint32_t mask_msi_leg_0; + /* [0x24] */ + uint32_t mask_msi_leg_1; + /* [0x28] */ + uint32_t mask_msi_leg_2; + /* [0x2c] */ + uint32_t mask_msi_leg_3; + /* [0x30] */ + uint32_t msi_leg_cntl; +}; +struct al_pcie_rev3_w_soc_int_per_func { + /* [0x0] */ + uint32_t status_0; + /* [0x4] */ + uint32_t status_1; + /* [0x8] */ + uint32_t status_2; + /* [0xc] */ + uint32_t status_3; + /* [0x10] */ + uint32_t mask_inta_leg_0; + /* [0x14] */ + uint32_t mask_inta_leg_1; + /* [0x18] */ + uint32_t mask_inta_leg_2; + /* [0x1c] */ + uint32_t mask_inta_leg_3; + /* [0x20] */ + uint32_t mask_msi_leg_0; + /* [0x24] */ + uint32_t mask_msi_leg_1; + /* [0x28] */ + uint32_t mask_msi_leg_2; + /* [0x2c] */ + uint32_t mask_msi_leg_3; + /* [0x30] */ + uint32_t msi_leg_cntl; +}; + +struct al_pcie_revx_w_ap_err { + /* + * [0x0] latch the header in case of any error occur in the core, read + * on clear of the last register in the bind. + */ + uint32_t hdr_log; +}; +struct al_pcie_revx_w_status_per_func { + /* + * [0x0] latch the header in case of any error occure in the core, read + * on clear of the last register in the bind. + */ + uint32_t status_per_func; +}; +struct al_pcie_revx_w_int_grp { + /* + * [0x0] Interrupt Cause Register + * Set by hardware + * - If MSI-X is enabled and auto_clear control bit =TRUE, automatically + * cleared after MSI-X message associated with this specific interrupt + * bit is sent (MSI-X acknowledge is received). + * - Software can set a bit in this register by writing 1 to the + * associated bit in the Interrupt Cause Set register + * Write-0 clears a bit. Write-1 has no effect. + * - On CPU Read - If clear_on_read control bit =TRUE, automatically + * cleared (all bits are cleared). + * When there is a conflict and on the same clock cycle, hardware tries + * to set a bit in the Interrupt Cause register, the specific bit is set + * to ensure the interrupt indication is not lost. + */ + uint32_t cause; + uint32_t rsrvd_0; + /* + * [0x8] Interrupt Cause Set Register + * Writing 1 to a bit in this register sets its corresponding cause bit, + * enabling software to generate a hardware interrupt. Write 0 has no + * effect. + */ + uint32_t cause_set; + uint32_t rsrvd_1; + /* + * [0x10] Interrupt Mask Register + * If Auto-mask control bit =TRUE, automatically set to 1 after MSI-X + * message associatd with the associated interrupt bit is sent (AXI + * write acknowledge is received). + */ + uint32_t mask; + uint32_t rsrvd_2; + /* + * [0x18] Interrupt Mask Clear Register + * Used when auto-mask control bit=True. Enables CPU to clear a specific + * bit. It prevents a scenario in which the CPU overrides another bit + * with 1 (old value) that hardware has just cleared to 0. + * Write 0 to this register clears its corresponding mask bit. Write 1 + * has no effect. + */ + uint32_t mask_clear; + uint32_t rsrvd_3; + /* + * [0x20] Interrupt Status Register + * This register latches the status of the interrupt source. + */ + uint32_t status; + uint32_t rsrvd_4; + /* [0x28] Interrupt Control Register */ + uint32_t control; + uint32_t rsrvd_5; + /* + * [0x30] Interrupt Mask Register + * Each bit in this register masks the corresponding cause bit for + * generating an Abort signal. Its default value is determined by unit + * instantiation. + * (Abort = Wire-OR of Cause & !Interrupt_Abort_Mask) + * This register provides error handling configuration for error + * interrupts + */ + uint32_t abort_mask; + uint32_t rsrvd_6; + /* + * [0x38] Interrupt Log Register + * Each bit in this register masks the corresponding cause bit for + * capturing the log registers. Its default value is determined by unit + * instantiation. + * (Log_capture = Wire-OR of Cause & !Interrupt_Log_Mask) + * This register provides error handling configuration for error + * interrupts. + */ + uint32_t log_mask; + uint32_t rsrvd; +}; + +struct al_pcie_rev1_w_regs { + struct al_pcie_rev1_w_global_ctrl global_ctrl; /* [0x0] */ + uint32_t rsrvd_0[24]; + struct al_pcie_revx_w_debug debug; /* [0x80] */ + struct al_pcie_revx_w_ob_ven_msg ob_ven_msg; /* [0x90] */ + uint32_t rsrvd_1[86]; + struct al_pcie_rev1_w_soc_int soc_int; /* [0x200] */ + struct al_pcie_revx_w_link_down link_down; /* [0x228] */ + struct al_pcie_revx_w_cntl_gen ctrl_gen; /* [0x230] */ + struct al_pcie_revx_w_parity parity; /* [0x234] */ + struct al_pcie_revx_w_last_wr last_wr; /* [0x23c] */ + struct al_pcie_rev1_2_w_atu atu; /* [0x240] */ + uint32_t rsrvd_2[36]; + struct al_pcie_revx_w_int_grp int_grp_a_m0; /* [0x300] */ + struct al_pcie_revx_w_int_grp int_grp_b_m0; /* [0x340] */ + uint32_t rsrvd_3[32]; + struct al_pcie_revx_w_int_grp int_grp_a; /* [0x400] */ + struct al_pcie_revx_w_int_grp int_grp_b; /* [0x440] */ +}; + +struct al_pcie_rev2_w_regs { + struct al_pcie_rev2_w_global_ctrl global_ctrl; /* [0x0] */ + uint32_t rsrvd_0[24]; + struct al_pcie_revx_w_debug debug; /* [0x80] */ + struct al_pcie_revx_w_ob_ven_msg ob_ven_msg; /* [0x90] */ + struct al_pcie_revx_w_ap_user_send_msg ap_user_send_msg; /* [0xa8] */ + uint32_t rsrvd_1[20]; + struct al_pcie_rev2_w_soc_int soc_int; /* [0x100] */ + uint32_t rsrvd_2[61]; + struct al_pcie_revx_w_link_down link_down; /* [0x228] */ + struct al_pcie_revx_w_cntl_gen ctrl_gen; /* [0x230] */ + struct al_pcie_revx_w_parity parity; /* [0x234] */ + struct al_pcie_revx_w_last_wr last_wr; /* [0x23c] */ + struct al_pcie_rev1_2_w_atu atu; /* [0x240] */ + uint32_t rsrvd_3[6]; + struct al_pcie_revx_w_ap_err ap_err[4]; /* [0x288] */ + uint32_t rsrvd_4[26]; + struct al_pcie_revx_w_status_per_func status_per_func; /* [0x300] */ + uint32_t rsrvd_5[63]; + struct al_pcie_revx_w_int_grp int_grp_a; /* [0x400] */ + struct al_pcie_revx_w_int_grp int_grp_b; /* [0x440] */ +}; + +struct al_pcie_rev3_w_regs { + struct al_pcie_rev3_w_global_ctrl global_ctrl; /* [0x0] */ + uint32_t rsrvd_0[24]; + struct al_pcie_revx_w_debug debug; /* [0x80] */ + struct al_pcie_revx_w_ob_ven_msg ob_ven_msg; /* [0x90] */ + struct al_pcie_revx_w_ap_user_send_msg ap_user_send_msg; /* [0xa8] */ + uint32_t rsrvd_1[94]; + struct al_pcie_revx_w_link_down link_down; /* [0x228] */ + struct al_pcie_revx_w_cntl_gen ctrl_gen; /* [0x230] */ + struct al_pcie_revx_w_parity parity; /* [0x234] */ + struct al_pcie_revx_w_last_wr last_wr; /* [0x23c] */ + struct al_pcie_rev3_w_atu atu; /* [0x240] */ + uint32_t rsrvd_2[8]; + struct al_pcie_rev3_w_cfg_func_ext cfg_func_ext; /* [0x2e0] */ + struct al_pcie_rev3_w_app_hdr_interface_send app_hdr_interface_send;/* [0x2e4] */ + struct al_pcie_rev3_w_diag_command diag_command; /* [0x300] */ + uint32_t rsrvd_3[3]; + struct al_pcie_rev3_w_soc_int_per_func soc_int_per_func[REV3_MAX_NUM_OF_PFS]; /* [0x310] */ + uint32_t rsrvd_4[44]; + struct al_pcie_rev3_w_events_gen_per_func events_gen_per_func[REV3_MAX_NUM_OF_PFS]; /* [0x490] */ + uint32_t rsrvd_5[4]; + struct al_pcie_rev3_w_pm_state_per_func pm_state_per_func[REV3_MAX_NUM_OF_PFS];/* [0x4b0] */ + uint32_t rsrvd_6[16]; + struct al_pcie_rev3_w_cfg_bars_ovrd cfg_bars_ovrd[REV3_MAX_NUM_OF_PFS]; /* [0x500] */ + uint32_t rsrvd_7[176]; + uint32_t rsrvd_8[16]; + struct al_pcie_revx_w_ap_err ap_err[5]; /* [0xac0] */ + uint32_t rsrvd_9[11]; + struct al_pcie_revx_w_status_per_func status_per_func[4]; /* [0xb00] */ + uint32_t rsrvd_10[316]; + struct al_pcie_revx_w_int_grp int_grp_a; /* [0x1000] */ + struct al_pcie_revx_w_int_grp int_grp_b; /* [0x1040] */ + struct al_pcie_revx_w_int_grp int_grp_c; /* [0x1080] */ + struct al_pcie_revx_w_int_grp int_grp_d; /* [0x10c0] */ +}; + +/* +* Registers Fields +*/ + + +/**** Port_Init register ****/ +/* Enable port to start LTSSM Link Training */ +#define PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK (1 << 0) +#define PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT (0) +/* + * Device Type + * Indicates the specific type of this PCIe Function. It is also used to set the + * Device/Port Type field. + * 4'b0000: PCIe Endpoint + * 4'b0001: Legacy PCIe Endpoint + * 4'b0100: Root Port of PCIe Root Complex + * Must be programmed before link training sequence. According to the reset + * strap + */ +#define PCIE_W_GLOBAL_CTRL_PORT_INIT_DEVICE_TYPE_MASK 0x000000F0 +#define PCIE_W_GLOBAL_CTRL_PORT_INIT_DEVICE_TYPE_SHIFT 4 +/* + * Performs Manual Lane reversal for transmit Lanes. + * Must be programmed before link training sequence. + */ +#define PCIE_W_GLOBAL_CTRL_PORT_INIT_TX_LANE_FLIP_EN (1 << 8) +/* + * Performs Manual Lane reversal for receive Lanes. + * Must be programmed before link training sequence. + */ +#define PCIE_W_GLOBAL_CTRL_PORT_INIT_RX_LANE_FLIP_EN (1 << 9) +/* + * Auxiliary Power Detected + * Indicates that auxiliary power (Vaux) is present. This one move to reset + * strap from + */ +#define PCIE_W_GLOBAL_CTRL_PORT_INIT_SYS_AUX_PWR_DET_NOT_USE (1 << 10) + +/**** Port_Status register ****/ +/* PHY Link up/down indicator */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_PHY_LINK_UP (1 << 0) +/* + * Data Link Layer up/down indicator + * This status from the Flow Control Initialization State Machine indicates that + * Flow Control has been initiated and the Data Link Layer is ready to transmit + * and receive packets. + */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_DL_LINK_UP (1 << 1) +/* Reset request due to link down status. */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_LINK_REQ_RST (1 << 2) +/* Power management is in L0s state.. */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_LINKST_IN_L0S (1 << 3) +/* Power management is in L1 state. */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_LINKST_IN_L1 (1 << 4) +/* Power management is in L2 state. */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_LINKST_IN_L2 (1 << 5) +/* Power management is exiting L2 state. */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_LINKST_L2_EXIT (1 << 6) +/* Power state of the device. */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_DSTATE_MASK 0x00000380 +#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_DSTATE_SHIFT 7 +/* tie to zero. */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_XMLH_IN_RL0S (1 << 10) +/* Timeout count before flush */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_LINK_TOUT_FLUSH_NOT (1 << 11) +/* Segmentation buffer not empty */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_RADM_Q_NOT_EMPTY (1 << 12) +/* + * Clock Turnoff Request + * Allows clock generation module to turn off core_clk based on the current + * power management state: + * 0: core_clk is required to be active for the current power state. + * 1: The current power state allows core_clk to be shut down. + * This does not indicate the clock requirement for the PHY. + */ +#define PCIE_W_GLOBAL_CTRL_PORT_STS_CORE_CLK_REQ_N (1 << 31) + +/**** PM_Control register ****/ +/* + * Wake Up. Used by application logic to wake up the PMC state machine from a + * D1, D2, or D3 power state. EP mode only. Change the value from 0 to 1 to send + * the message. Per function the upper bits are not use for ocie core less than + * 8 functions + */ +#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_PM_XMT_PME (1 << 0) +#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_PM_XMT_PME_FUNC_MASK 0x000000FF +#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_PM_XMT_PME_FUNC_SHIFT 0 +/* + * Request to Enter ASPM L1. + * The core ignores the L1 entry request on app_req_entr_l1 when it is busy + * processing a transaction. + */ +#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_REQ_ENTR_L1 (1 << 3) +#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_REQ_ENTR_L1 (1 << 8) +/* + * Request to exit ASPM L1. + * Only effective if L1 is enabled. + */ +#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_REQ_EXIT_L1 (1 << 4) +#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_REQ_EXIT_L1 (1 << 9) +/* + * Indication that component is ready to enter the L23 state. The core delays + * sending PM_Enter_L23 (in response to PM_Turn_Off) until this signal becomes + * active. + * EP mode + */ +#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_READY_ENTR_L23 (1 << 5) +#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_READY_ENTR_L23 (1 << 10) +/* + * Request to generate a PM_Turn_Off Message to communicate transition to L2/L3 + * Ready state to downstream components. Host must wait PM_Turn_Off_Ack messages + * acceptance RC mode. + */ +#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_PM_XMT_TURNOFF (1 << 6) +#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_PM_XMT_TURNOFF (1 << 11) +/* + * Provides a capability to defer incoming Configuration Requests until + * initialization is complete. When app_req_retry_en is asserted, the core + * completes incoming Configuration Requests with a Configuration Request Retry + * Status. Other incoming Requests complete with Unsupported Request status. + */ +#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN (1 << 7) +#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN (1 << 12) +/* + * Core core gate enable + * If set, core_clk is gated off whenever a clock turnoff request allows the + * clock generation module to turn off core_clk (Port_Status.core_clk_req_n + * field), and the PHY supports a request to disable clock gating. If not, the + * core clock turns off in P2 mode in any case (PIPE). + */ +#define PCIE_W_GLOBAL_CTRL_PM_CONTROL_CORE_CLK_GATE (1 << 31) + +/**** sris_kp_counter_value register ****/ +/* skp counter when SRIS disable */ +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_NO_SRIS_MASK 0x000001FF +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_NO_SRIS_SHIFT 0 +/* skp counter when SRIS enable */ +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_MASK 0x0003FE00 +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_SHIFT 9 +/* skp counter when SRIS enable for gen3 */ +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_MASK 0x1FFC0000 +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_SHIFT 18 +/* mask the interrupt to the soc in case correctable error occur in the ARI. */ +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_RSRVD_MASK 0x60000000 +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_RSRVD_SHIFT 29 +/* not in use in the pcie_x8 core. */ +#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_PCIE_X4_SRIS_EN (1 << 31) + +/**** Events_Gen register ****/ +/* INT_D. Not supported */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTD (1 << 0) +/* INT_C. Not supported */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTC (1 << 1) +/* INT_B. Not supported */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTB (1 << 2) +/* Transmit INT_A Interrupt ControlEvery transition from 0 to 1 ... */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTA (1 << 3) +/* A request to generate an outbound MSI interrupt when MSI is e ... */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_TRNS_REQ (1 << 4) +/* Set the MSI vector before issuing msi_trans_req. */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_MASK 0x000003E0 +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_SHIFT 5 +/* The application requests hot reset to a downstream device */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT (1 << 10) +/* The application request unlock message to be sent */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_UNLOCK_GEN (1 << 30) +/* Indicates that FLR on a Physical Function has been completed */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE (1 << 31) + +/**** Cpl_TO_Info register ****/ +/* The Traffic Class of the timed out CPL */ +#define PCIE_W_LCL_LOG_CPL_TO_INFO_TC_MASK 0x00000003 +#define PCIE_W_LCL_LOG_CPL_TO_INFO_TC_SHIFT 0 +/* Indicates which Virtual Function (VF) had a CPL timeout */ +#define PCIE_W_LCL_LOG_CPL_TO_INFO_FUN_NUM_MASK 0x000000FC +#define PCIE_W_LCL_LOG_CPL_TO_INFO_FUN_NUM_SHIFT 2 +/* The Tag field of the timed out CPL */ +#define PCIE_W_LCL_LOG_CPL_TO_INFO_TAG_MASK 0x0000FF00 +#define PCIE_W_LCL_LOG_CPL_TO_INFO_TAG_SHIFT 8 +/* The Attributes field of the timed out CPL */ +#define PCIE_W_LCL_LOG_CPL_TO_INFO_ATTR_MASK 0x00030000 +#define PCIE_W_LCL_LOG_CPL_TO_INFO_ATTR_SHIFT 16 +/* The Len field of the timed out CPL */ +#define PCIE_W_LCL_LOG_CPL_TO_INFO_LEN_MASK 0x3FFC0000 +#define PCIE_W_LCL_LOG_CPL_TO_INFO_LEN_SHIFT 18 +/* + * Write 1 to this field to clear the information logged in the register. New + * logged information will only be valid when the interrupt is cleared . + */ +#define PCIE_W_LCL_LOG_CPL_TO_INFO_VALID (1 << 31) +#define PCIE_W_LCL_LOG_CPL_TO_INFO_VALID_SHIFT (31) + +/**** Rcv_Msg0_0 register ****/ +/* The Requester ID of the received message */ +#define PCIE_W_LCL_LOG_RCV_MSG0_0_REQ_ID_MASK 0x0000FFFF +#define PCIE_W_LCL_LOG_RCV_MSG0_0_REQ_ID_SHIFT 0 +/* + * Valid logged message + * Writing 1 to this bit enables new message capturing. Write one to clear + */ +#define PCIE_W_LCL_LOG_RCV_MSG0_0_VALID (1 << 31) + +/**** Rcv_Msg1_0 register ****/ +/* The Requester ID of the received message */ +#define PCIE_W_LCL_LOG_RCV_MSG1_0_REQ_ID_MASK 0x0000FFFF +#define PCIE_W_LCL_LOG_RCV_MSG1_0_REQ_ID_SHIFT 0 +/* + * Valid logged message + * Writing 1 to this bit enables new message capturing. Write one to clear + */ +#define PCIE_W_LCL_LOG_RCV_MSG1_0_VALID (1 << 31) + +/**** Core_Queues_Status register ****/ +/* + * Indicates which entries in the CPL lookup table + * have valid entries stored. NOT supported. + */ +#define PCIE_W_LCL_LOG_CORE_Q_STATUS_CPL_LUT_VALID_MASK 0x0000FFFF +#define PCIE_W_LCL_LOG_CORE_Q_STATUS_CPL_LUT_VALID_SHIFT 0 + +/**** Cpl_to register ****/ +#define PCIE_W_LCL_LOG_CPL_TO_REQID_MASK 0x0000FFFF +#define PCIE_W_LCL_LOG_CPL_TO_REQID_SHIFT 0 + +/**** Debug_Info_0 register ****/ +/* Indicates the current power state */ +#define PCIE_W_DEBUG_INFO_0_PM_CURRENT_STATE_MASK 0x00000007 +#define PCIE_W_DEBUG_INFO_0_PM_CURRENT_STATE_SHIFT 0 +/* Current state of the LTSSM */ +#define PCIE_W_DEBUG_INFO_0_LTSSM_STATE_MASK 0x000001F8 +#define PCIE_W_DEBUG_INFO_0_LTSSM_STATE_SHIFT 3 +/* Decode of the Recovery. Equalization LTSSM state */ +#define PCIE_W_DEBUG_INFO_0_LTSSM_STATE_RCVRY_EQ (1 << 9) +/* State of selected internal signals, for debug purposes only */ +#define PCIE_W_DEBUG_INFO_0_CXPL_DEBUG_INFO_EI_MASK 0x03FFFC00 +#define PCIE_W_DEBUG_INFO_0_CXPL_DEBUG_INFO_EI_SHIFT 10 + +/**** control register ****/ +/* Indication to send vendor message; when clear the message was sent. */ +#define PCIE_W_OB_VEN_MSG_CONTROL_REQ (1 << 0) + +/**** param_1 register ****/ +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_1_FMT_MASK 0x00000003 +#define PCIE_W_OB_VEN_MSG_PARAM_1_FMT_SHIFT 0 +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_1_TYPE_MASK 0x0000007C +#define PCIE_W_OB_VEN_MSG_PARAM_1_TYPE_SHIFT 2 +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_1_TC_MASK 0x00000380 +#define PCIE_W_OB_VEN_MSG_PARAM_1_TC_SHIFT 7 +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_1_TD (1 << 10) +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_1_EP (1 << 11) +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_1_ATTR_MASK 0x00003000 +#define PCIE_W_OB_VEN_MSG_PARAM_1_ATTR_SHIFT 12 +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_1_LEN_MASK 0x00FFC000 +#define PCIE_W_OB_VEN_MSG_PARAM_1_LEN_SHIFT 14 +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_1_TAG_MASK 0xFF000000 +#define PCIE_W_OB_VEN_MSG_PARAM_1_TAG_SHIFT 24 + +/**** param_2 register ****/ +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_2_REQ_ID_MASK 0x0000FFFF +#define PCIE_W_OB_VEN_MSG_PARAM_2_REQ_ID_SHIFT 0 +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_2_CODE_MASK 0x00FF0000 +#define PCIE_W_OB_VEN_MSG_PARAM_2_CODE_SHIFT 16 +/* Vendor message parameters */ +#define PCIE_W_OB_VEN_MSG_PARAM_2_RSVD_31_24_MASK 0xFF000000 +#define PCIE_W_OB_VEN_MSG_PARAM_2_RSVD_31_24_SHIFT 24 + +/**** ack_info register ****/ +/* Vendor message parameters */ +#define PCIE_W_AP_USER_SEND_MSG_ACK_INFO_ACK (1 << 0) + +/**** features register ****/ +/* Enable MSI fix from the SATA to the PCIe EP - Only valid for port zero */ +#define PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX AL_BIT(16) + +/**** in/out_mask_x_y register ****/ +/* When bit [i] set to 1 it maks the compare in the atu_in/out wind ... */ +#define PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_MASK 0x0000FFFF +#define PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT 0 +/* When bit [i] set to 1 it maks the compare in the atu_in/out wind ... */ +#define PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_MASK 0xFFFF0000 +#define PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT 16 + +/**** cfg register ****/ +/* + * The 2-bit TPH Requester Enabled field of each TPH + * Requester Control register. + */ +#define PCIE_W_CFG_FUNC_EXT_CFG_CFG_TPH_REQ_EN_MASK 0x000000FF +#define PCIE_W_CFG_FUNC_EXT_CFG_CFG_TPH_REQ_EN_SHIFT 0 +/* SRIS mode enable. */ +#define PCIE_W_CFG_FUNC_EXT_CFG_APP_SRIS_MODE (1 << 8) +/* + * + */ +#define PCIE_W_CFG_FUNC_EXT_CFG_RSRVD_MASK 0xFFFFFE00 +#define PCIE_W_CFG_FUNC_EXT_CFG_RSRVD_SHIFT 9 + +/**** app_func_num_advisory register ****/ +/* + * The number of the function that is reporting the error + * indicated app_err_bus, valid when app_hdr_valid is asserted. + * Correctable and Uncorrected Internal errors (app_err_bus[10:9]) are + * not function specific, and are recorded for all physical functions, + * regardless of the value this bus. Function numbering starts at '0'. + */ +#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_APP_ERR_FUNC_NUM_MASK 0x0000FFFF +#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_APP_ERR_FUNC_NUM_SHIFT 0 +/* + * Description: Indicates that your application error is an advisory + * error. Your application should assert app_err_advisory under either + * of the following conditions: + * - The core is configured to mask completion timeout errors, your + * application is reporting a completion timeout error app_err_bus, + * and your application intends to resend the request. In such cases + * the error is an advisory error, as described in PCI Express 3.0 + * Specification. When your application does not intend to resend + * the request, then your application must keep app_err_advisory + * de-asserted when reporting a completion timeout error. + * - The core is configured to forward poisoned TLPs to your + * application and your application is going to treat the poisoned + * TLP as a normal TLP, as described in PCI Express 3.0 + * Specification. Upon receipt of a poisoned TLP, your application + * must report the error app_err_bus, and either assert + * app_err_advisory (to indicate an advisory error) or de-assert + * app_err_advisory (to indicate that your application is dropping the + * TLP). + * For more details, see the PCI Express 3.0 Specification to determine + * when an application error is an advisory error. + */ +#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_APP_ERR_ADVISORY (1 << 16) +/* + * Rsrvd. + */ +#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_RSRVD_MASK 0xFFFE0000 +#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_RSRVD_SHIFT 17 + +/**** app_hdr_cmd register ****/ +/* + * When set the header is send (need to clear before sending the next message). + */ +#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_HDR_CMD_APP_HDR_VALID (1 << 0) +/* + * Rsrvd. + */ +#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_HDR_CMD_RSRVD_MASK 0xFFFFFFFE +#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_HDR_CMD_RSRVD_SHIFT 1 + +/**** diag_ctrl register ****/ +/* + * The 2-bit TPH Requester Enabled field of each TPH + * Requester Control register. + */ +#define PCIE_W_DIAG_COMMAND_DIAG_CTRL_DIAG_CTRL_BUS_MASK 0x00000007 +#define PCIE_W_DIAG_COMMAND_DIAG_CTRL_DIAG_CTRL_BUS_SHIFT 0 +/* + * + */ +#define PCIE_W_DIAG_COMMAND_DIAG_CTRL_RSRVD_MASK 0xFFFFFFF8 +#define PCIE_W_DIAG_COMMAND_DIAG_CTRL_RSRVD_SHIFT 3 + + +/**** Events_Gen register ****/ +/* INT_D. Not supported */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTD (1 << 0) +/* INT_C. Not supported */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTC (1 << 1) +/* INT_B. Not supported */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTB (1 << 2) +/* + * Transmit INT_A Interrupt Control + * Every transition from 0 to 1 schedules an Assert_ INT interrupt message for + * transmit. + * Every transition from 1 to 0, schedules a Deassert_INT interrupt message for + * transmit. Which interrupt, the PCIe only use INTA message. + */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTA (1 << 3) +/* + * A request to generate an outbound MSI interrupt when MSI is enabled. Change + * from 1'b0 to 1'b1 to create an MSI write to be sent. + */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_TRNS_REQ (1 << 4) +/* Set the MSI vector before issuing msi_trans_req. */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_MASK 0x000003E0 +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_SHIFT 5 +/* + * The application requests hot reset to a downstream device. Change the value + * from 0 to 1 to send hot reset. Only func 0 is supported. + */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT (1 << 10) +/* + * The application request unlock message to be sent. Change the value from 0 to + * 1 to send the message. Only func 0 is supported. + */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_UNLOCK_GEN (1 << 30) +/* Indicates that FLR on a Physical Function has been completed. */ +#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE (1 << 31) + +/**** pm_state_per_func register ****/ +/* + * Description: The current power management D-state of the + * function: + * \u25a0 000b: D0 + * \u25a0 001b: D1 + * \u25a0 010b: D2 + * \u25a0 011b: D3 + * \u25a0 100b: Uninitialized + * \u25a0 Other values: Not applicable + * There are 3 bits of pm_dstate for each configured function. + */ +#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_PM_DSTATE_MASK 0x0000000F +#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_PM_DSTATE_SHIFT 0 +/* + * PME Status bit from the PMCSR. There is 1 bit of + * pm_status for each configured function + */ +#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_PM_STATUS (1 << 4) +/* + * PME Enable bit in the PMCSR. There is 1 bit of + * pm_pme_en for each configured function. + */ +#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_PM_PME_EN (1 << 5) +/* + * Auxiliary Power Enable bit in the Device Control + * register. There is 1 bit of aux_pm_en for each configured function. + */ +#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_AUX_PME_EN (1 << 6) +/* + * This field should be set according to the MAX_FUNC_NUM set in the PCIe core, + * it uses as mask (bit per function) to the dsate when set to zero. + */ +#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_ASPM_PF_ENABLE_MAX_FUNC_NUMBER (1 << 7) +/* + * This field should be set according to the MAX_FUNC_NUM set in the PCIe core, + * it uses as mask (bit per function) to the ASPM contrl bit, when set to zero. + */ +#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_DSATE_PF_ENABLE_MAX_FUNC_NUMBER (1 << 8) + +/**** bar0_ctrl register ****/ +/* bar is en and override the internal PF bar. */ +#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_BAR_EN_MASK 0x00000003 +#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_BAR_EN_SHIFT 0 +/* bar is io */ +#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_BAR_IO_MASK 0x0000000C +#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_BAR_IO_SHIFT 2 +/* Reserved. */ +#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_RSRVS_MASK 0xFFFFFFF0 +#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_RSRVS_SHIFT 4 + +/**** bar1_ctrl register ****/ +/* bar is en and override the internal PF bar. */ +#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_BAR_EN_MASK 0x00000003 +#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_BAR_EN_SHIFT 0 +/* bar is io */ +#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_BAR_IO_MASK 0x0000000C +#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_BAR_IO_SHIFT 2 +/* Reserved. */ +#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_RSRVS_MASK 0xFFFFFFF0 +#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_RSRVS_SHIFT 4 + +/**** bar2_ctrl register ****/ +/* bar is en and override the internal PF bar. */ +#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_BAR_EN_MASK 0x00000003 +#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_BAR_EN_SHIFT 0 +/* bar is io */ +#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_BAR_IO_MASK 0x0000000C +#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_BAR_IO_SHIFT 2 +/* Reserved. */ +#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_RSRVS_MASK 0xFFFFFFF0 +#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_RSRVS_SHIFT 4 + +/**** bar3_ctrl register ****/ +/* bar is en and override the internal PF bar. */ +#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_BAR_EN_MASK 0x00000003 +#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_BAR_EN_SHIFT 0 +/* bar is io */ +#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_BAR_IO_MASK 0x0000000C +#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_BAR_IO_SHIFT 2 +/* Reserved. */ +#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_RSRVS_MASK 0xFFFFFFF0 +#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_RSRVS_SHIFT 4 + +/**** bar4_ctrl register ****/ +/* bar is en and override the internal PF bar. */ +#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_BAR_EN_MASK 0x00000003 +#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_BAR_EN_SHIFT 0 +/* bar is io */ +#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_BAR_IO_MASK 0x0000000C +#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_BAR_IO_SHIFT 2 +/* Reserved. */ +#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_RSRVS_MASK 0xFFFFFFF0 +#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_RSRVS_SHIFT 4 + +/**** bar5_ctrl register ****/ +/* bar is en and override the internal PF bar. */ +#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_BAR_EN_MASK 0x00000003 +#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_BAR_EN_SHIFT 0 +/* bar is io */ +#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_BAR_IO_MASK 0x0000000C +#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_BAR_IO_SHIFT 2 +/* Reserved. */ +#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_RSRVS_MASK 0xFFFFFFF0 +#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_RSRVS_SHIFT 4 + +/**** cause_A register ****/ +/* Deassert_INTD received. Write zero to clear this bit. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_DEASSERT_INTD (1 << 0) +/* Deassert_INTC received. Write zero to clear this bit. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_DEASSERT_INTC (1 << 1) +/* Deassert_INTB received. Write zero to clear this bit. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_DEASSERT_INTB (1 << 2) +/* Deassert_INTA received. Write zero to clear this bit. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_DEASSERT_INTA (1 << 3) +/* Assert_INTD received. Write zero to clear this bit. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_ASSERT_INTD (1 << 4) +/* Assert_INTC received. Write zero to clear this bit. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_ASSERT_INTC (1 << 5) +/* Assert_INTC received. Write zero to clear this bit. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_ASSERT_INTB (1 << 6) +/* Assert_INTA received. Write zero to clear this bit. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_ASSERT_INTA (1 << 7) +/* + * MSI Controller Interrupt + * MSI interrupt is being received. Write zero to clear this bit + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_MSI_CNTR_RCV_INT (1 << 8) +/* + * MSI sent grant. Write zero to clear this bit. + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_MSI_TRNS_GNT (1 << 9) +/* + * System error detected + * Indicates if any device in the hierarchy reports any of the following errors + * and the associated enable bit is set in the Root Control register: + * ERR_COR + * ERR_FATAL + * ERR_NONFATAL + * Also asserted when an internal error is detected. Write zero to clear this + * bit. + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_SYS_ERR_RC (1 << 10) +/* + * Set when software initiates FLR on a Physical Function by writing to the + * Initiate FLR register bit of that function Write zero to clear this bit. + */ +#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_FLR_PF_ACTIVE (1 << 11) +#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_11 (1 << 11) +/* + * Reported error condition causes a bit to be set in the Root Error Status + * register and the associated error message reporting enable bit is set in the + * Root Error Command Register. Write zero to clear this bit. + */ +#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_AER_RC_ERR (1 << 12) +#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_12 (1 << 12) +/* + * The core asserts aer_rc_err_msi when all of the following conditions are + * true: + * - MSI or MSI-X is enabled. + * - A reported error condition causes a bit to be set in the Root Error Status + * register. + * - The associated error message reporting enable bit is set in the Root Error + * Command register Write zero to clear this bit + */ +#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_AER_RC_ERR_MSI (1 << 13) +#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_13 (1 << 13) +/* + * Wake Up. Wake up from power management unit. + * The core generates wake to request the system to restore power and clock when + * a beacon has been detected. wake is an active high signal and its rising edge + * should be detected to drive the WAKE# on the connector Write zero to clear + * this bit + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_WAKE (1 << 14) +/* + * The core asserts cfg_pme_int when all of the following conditions are true: + * - INTx Assertion Disable bit in the Command register is 0. + * - PME Interrupt Enable bit in the Root Control register is set to 1. + * - PME Status bit in the Root Status register is set to 1. Write zero to clear + * this bit + */ +#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_PME_INT (1 << 15) +#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_15 (1 << 15) +/* + * The core asserts cfg_pme_msi when all of the following conditions are true: + * - MSI or MSI-X is enabled. + * - PME Interrupt Enable bit in the Root Control register is set to 1. + * - PME Status bit in the Root Status register is set to 1. Write zero to clear + * this bit + */ +#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_PME_MSI (1 << 16) +#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_16 (1 << 16) +/* + * The core asserts hp_pme when all of the following conditions are true: + * - The PME Enable bit in the Power Management Control and Status register is + * set to 1. + * - Any bit in the Slot Status register transitions from 0 to 1 and the + * associated event notification is enabled in the Slot Control register. Write + * zero to clear this bit + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_HP_PME (1 << 17) +/* + * The core asserts hp_int when all of the following conditions are true: + * - INTx Assertion Disable bit in the Command register is 0. + * - Hot-Plug interrupts are enabled in the Slot Control register. + * - Any bit in the Slot Status register is equal to 1, and the associated event + * notification is enabled in the Slot Control register. Write zero to clear + * this bit + */ +#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_HP_INT (1 << 18) +/* The outstanding write counter become full should never happen */ +#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_WRITE_COUNTER_FULL_ERR (1 << 18) + + +/* + * The core asserts hp_msi when the logical AND of the following conditions + * transitions from false to true: + * - MSI or MSI-X is enabled. + * - Hot-Plug interrupts are enabled in the Slot Control register. + * - Any bit in the Slot Status register transitions from 0 to 1 and the + * associated event notification is enabled in the Slot Control register. + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_HP_MSI (1 << 19) +/* Read VPD registers notification */ +#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_VPD_INT (1 << 20) +/* not use */ +#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_NOT_USE (1 << 20) + +/* + * The core assert link down event, whenever the link is going down. Write zero + * to clear this bit, pulse signal + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_LINK_DOWN_EVENT (1 << 21) +/* + * When the EP gets a command to shut down, signal the software to block any new + * TLP. + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_PM_XTLH_BLOCK_TLP (1 << 22) +/* PHY/MAC link up */ +#define PCIE_W_INT_GRP_A_CAUSE_A_XMLH_LINK_UP (1 << 23) +/* Data link up */ +#define PCIE_W_INT_GRP_A_CAUSE_A_RDLH_LINK_UP (1 << 24) +/* The ltssm is in RCVRY_LOCK state. */ +#define PCIE_W_INT_GRP_A_CAUSE_A_LTSSM_RCVRY_STATE (1 << 25) +/* + * Config write transaction to the config space by the RC peer, enable this + * interrupt only for EP mode. + */ +#define PCIE_W_INT_GRP_A_CAUSE_A_CFG_WR_EVENT (1 << 26) +/* AER error */ +#define PCIE_W_INT_GRP_A_CAUSE_A_AP_PENDED_CORR_ERR_STS_INT (1 << 28) +/* AER error */ +#define PCIE_W_INT_GRP_A_CAUSE_A_AP_PENDED_UNCORR_ERR_STS_INT (1 << 29) + +/**** control_A register ****/ +/* When Clear_on_Read =1, all bits of Cause register are cleared on read. */ +#define PCIE_W_INT_GRP_A_CONTROL_A_CLEAR_ON_READ (1 << 0) +/* + * (Must be set only when MSIX is enabled.) + * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its + * corresponding bit in the Mask register is set, masking future interrupts. + */ +#define PCIE_W_INT_GRP_A_CONTROL_A_AUTO_MASK (1 << 1) +/* + * Auto_Clear (RW) + * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared + * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. + */ +#define PCIE_W_INT_GRP_A_CONTROL_A_AUTO_CLEAR (1 << 2) +/* + * When Set_on_Posedge =1, the bits in the Interrupt Cause register are set on + * the posedge of the interrupt source, i.e., when interrupt source =1 and + * Interrupt Status = 0. + * When Set_on_Posedge =0, the bits in the Interrupt Cause register are set when + * interrupt source =1. + */ +#define PCIE_W_INT_GRP_A_CONTROL_A_SET_ON_POSEDGE (1 << 3) +/* + * When Moderation_Reset =1, all Moderation timers associated with the interrupt + * cause bits are cleared to 0, enabling immediate interrupt assertion if any + * unmasked cause bit is set to 1. This bit is self-negated. + */ +#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_RST (1 << 4) +/* + * When mask_msi_x =1, no MSI-X from this group is sent. This bit must be set to + * 1 when the associated summary bit in this group is used to generate a single + * MSI-X for this group. + */ +#define PCIE_W_INT_GRP_A_CONTROL_A_MASK_MSI_X (1 << 5) +/* MSI-X AWID value. Same ID for all cause bits. */ +#define PCIE_W_INT_GRP_A_CONTROL_A_AWID_MASK 0x00000F00 +#define PCIE_W_INT_GRP_A_CONTROL_A_AWID_SHIFT 8 +/* + * This value determines the interval between interrupts; writing ZERO disables + * Moderation. + */ +#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_INTV_MASK 0x00FF0000 +#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_INTV_SHIFT 16 +/* + * This value determines the Moderation_Timer_Clock speed. + * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. + * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. + * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. + */ +#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_RES_MASK 0x0F000000 +#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_RES_SHIFT 24 + +/**** cause_B register ****/ +/* Indicates that the core received a PM_PME Message. Write Zero to clear. */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_PM_PME (1 << 0) +/* + * Indicates that the core received a PME_TO_Ack Message. Write Zero to clear. + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_PM_TO_ACK (1 << 1) +/* + * Indicates that the core received an PME_Turn_Off Message. Write Zero to + * clear. + * EP mode only + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_PM_TURNOFF (1 << 2) +/* Indicates that the core received an ERR_CORR Message. Write Zero to clear. */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_CORRECTABLE_ERR (1 << 3) +/* + * Indicates that the core received an ERR_NONFATAL Message. Write Zero to + * clear. + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_NONFATAL_ERR (1 << 4) +/* + * Indicates that the core received an ERR_FATAL Message. Write Zero to clear. + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_FATAL_ERR (1 << 5) +/* + * Indicates that the core received a Vendor Defined Message. Write Zero to + * clear. + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_VENDOR_0 (1 << 6) +/* + * Indicates that the core received a Vendor Defined Message. Write Zero to + * clear. + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_VENDOR_1 (1 << 7) +/* Indicates that the core received an Unlock Message. Write Zero to clear. */ +#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_UNLOCK (1 << 8) +/* + * Notification when the Link Autonomous Bandwidth Status register (Link Status + * register bit 15) is updated and the Link Autonomous Bandwidth Interrupt + * Enable (Link Control register bit 11) is set. This bit is not applicable to, + * and is reserved, for Endpoint device. Write Zero to clear + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_LINK_AUTO_BW_INT (1 << 12) +/* + * Notification that the Link Equalization Request bit in the Link Status 2 + * Register has been set. Write Zero to clear. + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_LINK_EQ_REQ_INT (1 << 13) +/* + * OB Vendor message request is granted by the PCIe core Write Zero to clear. + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_VENDOR_MSG_GRANT (1 << 14) +/* CPL timeout from the PCIe core inidication. Write Zero to clear */ +#define PCIE_W_INT_GRP_B_CAUSE_B_CMP_TIME_OUT (1 << 15) +/* + * Slave Response Composer Lookup Error + * Indicates that an overflow occurred in a lookup table of the Inbound + * responses. This indicates that there was a violation of the number of + * outstanding NP requests issued for the Outbound direction. Write zero to + * clear + */ +#define PCIE_W_INT_GRP_B_CAUSE_B_RADMX_CMPOSER_LOOKUP_ERR (1 << 16) +/* Parity Error */ +#define PCIE_W_INT_GRP_B_CAUSE_B_PARITY_ERROR_CORE (1 << 17) + +/**** control_B register ****/ +/* When Clear_on_Read =1, all bits of the Cause register are cleared on read. */ +#define PCIE_W_INT_GRP_B_CONTROL_B_CLEAR_ON_READ (1 << 0) +/* + * (Must be set only when MSIX is enabled.) + * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its + * corresponding bit in the Mask register is set, masking future interrupts. + */ +#define PCIE_W_INT_GRP_B_CONTROL_B_AUTO_MASK (1 << 1) +/* + * Auto_Clear (RW) + * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared + * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. + */ +#define PCIE_W_INT_GRP_B_CONTROL_B_AUTO_CLEAR (1 << 2) +/* + * When Set_on_Posedge =1, the bits in the interrupt Cause register are set on + * the posedge of the interrupt source, i.e., when Interrupt Source =1 and + * Interrupt Status = 0. + * When Set_on_Posedge =0, the bits in the Interrupt Cause register are set when + * Interrupt Source =1. + */ +#define PCIE_W_INT_GRP_B_CONTROL_B_SET_ON_POSEDGE (1 << 3) +/* + * When Moderation_Reset =1, all Moderation timers associated with the interrupt + * cause bits are cleared to 0, enabling an immediate interrupt assertion if any + * unmasked cause bit is set to 1. This bit is self-negated. + */ +#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_RST (1 << 4) +/* + * When mask_msi_x =1, no MSI-X from this group is sent. This bit must be set to + * 1 when the associated summary bit in this group is used to generate a single + * MSI-X for this group. + */ +#define PCIE_W_INT_GRP_B_CONTROL_B_MASK_MSI_X (1 << 5) +/* MSI-X AWID value. Same ID for all cause bits. */ +#define PCIE_W_INT_GRP_B_CONTROL_B_AWID_MASK 0x00000F00 +#define PCIE_W_INT_GRP_B_CONTROL_B_AWID_SHIFT 8 +/* + * This value determines the interval between interrupts. Writing ZERO disables + * Moderation. + */ +#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_INTV_MASK 0x00FF0000 +#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_INTV_SHIFT 16 +/* + * This value determines the Moderation_Timer_Clock speed. + * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. + * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. + * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. + */ +#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_RES_MASK 0x0F000000 +#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_RES_SHIFT 24 + +/**** cause_C register ****/ +/* VPD interrupt, ot read/write frpm EEPROM */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_VPD_INT_FUNC_MASK 0x0000000F +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_VPD_INT_FUNC_SHIFT 0 +/* flr PF active */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_FLR_PF_ACTIVE_MASK 0x000000F0 +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_FLR_PF_ACTIVE_SHIFT 4 +/* System ERR RC. */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_SYS_ERR_RC_MASK 0x00000F00 +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_SYS_ERR_RC_SHIFT 8 +/* AER RC INT */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_AER_RC_ERR_INT_MASK 0x0000F000 +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_AER_RC_ERR_INT_SHIFT 12 +/* AER RC MSI */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_AER_RC_ERR_MSI_MASK 0x000F0000 +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_AER_RC_ERR_MSI_SHIFT 16 +/* PME MSI */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_PME_MSI_MASK 0x00F00000 +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_PME_MSI_SHIFT 20 +/* PME int */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_PME_INT_MASK 0x0F000000 +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_PME_INT_SHIFT 24 +/* SB overflow */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_RADM_QOVERFLOW (1 << 28) +/* ecrc was injected through the diag_ctrl bus */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_ECRC_INJECTED (1 << 29) +/* lcrc was injected through the diag_ctrl bus */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_LCRC_INJECTED (1 << 30) +/* lcrc was injected through the diag_ctrl bus */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_RSRVD (1 << 31) + +/**** control_C register ****/ +/* When Clear_on_Read =1, all bits of Cause register are cleared on read. */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_CLEAR_ON_READ (1 << 0) +/* + * (Must be set only when MSIX is enabled.) + * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its + * corresponding bit in the Mask register is set, masking future interrupts. + */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_AUTO_MASK (1 << 1) +/* + * Auto_Clear (RW) + * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared + * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. + */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_AUTO_CLEAR (1 << 2) +/* + * When Set_on_Posedge =1, the bits in the Interrupt Cause register are set on + * the posedge of the interrupt source, i.e., when interrupt source =1 and + * Interrupt Status = 0. + * When Set_on_Posedge =0, the bits in the Interrupt Cause register are set when + * interrupt source =1. + */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_SET_ON_POSEDGE (1 << 3) +/* + * When Moderation_Reset =1, all Moderation timers associated with the interrupt + * cause bits are cleared to 0, enabling immediate interrupt assertion if any + * unmasked cause bit is set to 1. This bit is self-negated. + */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_RST (1 << 4) +/* + * When mask_msi_x =1, no MSI-X from this group is sent. This bit must be set to + * 1 when the associated summary bit in this group is used to generate a single + * MSI-X for this group. + */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MASK_MSI_X (1 << 5) +/* MSI-X AWID value. Same ID for all cause bits. */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_AWID_MASK 0x00000F00 +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_AWID_SHIFT 8 +/* + * This value determines the interval between interrupts; writing ZERO disables + * Moderation. + */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_INTV_MASK 0x00FF0000 +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_INTV_SHIFT 16 +/* + * This value determines the Moderation_Timer_Clock speed. + * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. + * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. + * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. + */ +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_RES_MASK 0x0F000000 +#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_RES_SHIFT 24 + +/**** control_D register ****/ +/* When Clear_on_Read =1, all bits of Cause register are cleared on read. */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_CLEAR_ON_READ (1 << 0) +/* + * (Must be set only when MSIX is enabled.) + * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its + * corresponding bit in the Mask register is set, masking future interrupts. + */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_AUTO_MASK (1 << 1) +/* + * Auto_Clear (RW) + * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared + * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. + */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_AUTO_CLEAR (1 << 2) +/* + * When Set_on_Posedge =1, the bits in the Interrupt Cause register are set on + * the posedge of the interrupt source, i.e., when interrupt source =1 and + * Interrupt Status = 0. + * When Set_on_Posedge =0, the bits in the Interrupt Cause register are set when + * interrupt source =1. + */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_SET_ON_POSEDGE (1 << 3) +/* + * When Moderation_Reset =1, all Moderation timers associated with the interrupt + * cause bits are cleared to 0, enabling immediate interrupt assertion if any + * unmasked cause bit is set to 1. This bit is self-negated. + */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_RST (1 << 4) +/* + * When mask_msi_x =1, no MSI-X from this group is sent. This bit must be set to + * 1 when the associated summary bit in this group is used to generate a single + * MSI-X for this group. + */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MASK_MSI_X (1 << 5) +/* MSI-X AWID value. Same ID for all cause bits. */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_AWID_MASK 0x00000F00 +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_AWID_SHIFT 8 +/* + * This value determines the interval between interrupts; writing ZERO disables + * Moderation. + */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_INTV_MASK 0x00FF0000 +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_INTV_SHIFT 16 +/* + * This value determines the Moderation_Timer_Clock speed. + * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. + * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. + * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. + */ +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_RES_MASK 0x0F000000 +#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_RES_SHIFT 24 +#ifdef __cplusplus +} +#endif + +#endif /* __AL_HAL_PCIE_W_REG_H */ + +/** @} end of ... group */ + + diff --git a/al_hal_plat_services.h b/al_hal_plat_services.h new file mode 100644 index 000000000000..217bb927f69f --- /dev/null +++ b/al_hal_plat_services.h @@ -0,0 +1,419 @@ +/*- +******************************************************************************* +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @defgroup group_services Platform Services API + * @{ + * The Platform Services API provides miscellaneous system services to HAL + * drivers, such as: + * - Registers read/write + * - Assertions + * - Memory barriers + * - Endianness conversions + * + * And more. + * @file plat_api/sample/al_hal_plat_services.h + * + * @brief API for Platform services provided for to HAL drivers + * + * + */ + +#ifndef __PLAT_SERVICES_H__ +#define __PLAT_SERVICES_H__ + +#include +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +/* Prototypes for all the bus_space structure functions */ +bs_protos(generic); +bs_protos(generic_armv4); + +#define __UNUSED __attribute__((unused)) + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/* + * WMA: This is a hack which allows not modifying the __iomem accessing HAL code. + * On ARMv7, bus_handle holds the information about VA of accessed memory. It + * is possible to use direct load/store instruction instead of bus_dma machinery. + * WARNING: This is not guaranteed to stay that way forever, nor that + * on other architectures these variables behave similarly. Keep that + * in mind during porting to other systems. + */ +/** + * Read MMIO 8 bits register + * @param offset register offset + * + * @return register value + */ +static uint8_t al_reg_read8(uint8_t * offset); + +/** + * Read MMIO 16 bits register + * @param offset register offset + * + * @return register value + */ +static uint16_t al_reg_read16(uint16_t * offset); + +/** + * Read MMIO 32 bits register + * @param offset register offset + * + * @return register value + */ +static uint32_t al_reg_read32(uint32_t * offset); + +/** + * Read MMIO 64 bits register + * @param offset register offset + * + * @return register value + */ +uint64_t al_reg_read64(uint64_t * offset); + +/** + * Relaxed read MMIO 32 bits register + * + * Relaxed register read/write functions don't involve cpu instructions that + * force syncronization, nor ordering between the register access and memory + * data access. + * These instructions are used in performance critical code to avoid the + * overhead of the synchronization instructions. + * + * @param offset register offset + * + * @return register value + */ +#define al_bus_dma_to_va(bus_tag, bus_handle) ((void*)bus_handle) + +/** + * Relaxed read MMIO 32 bits register + * + * Relaxed register read/write functions don't involve cpu instructions that + * force syncronization, nor ordering between the register access and memory + * data access. + * These instructions are used in performance critical code to avoid the + * overhead of the synchronization instructions. + * + * @param offset register offset + * + * @return register value + */ +#define al_reg_read32_relaxed(l) generic_bs_r_4(NULL, (bus_space_handle_t)l, 0) + +/** + * Relaxed write to MMIO 32 bits register + * + * Relaxed register read/write functions don't involve cpu instructions that + * force syncronization, nor ordering between the register access and memory + * data access. + * These instructions are used in performance critical code to avoid the + * overhead of the synchronization instructions. + * + * @param offset register offset + * @param val value to write to the register + */ +#define al_reg_write32_relaxed(l,v) generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v) + +/** + * Write to MMIO 8 bits register + * @param offset register offset + * @param val value to write to the register + */ +#define al_reg_write8(l,v) do { dsb(); generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) + +/** + * Write to MMIO 16 bits register + * @param offset register offset + * @param val value to write to the register + */ +#define al_reg_write16(l,v) do { dsb(); generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) + +/** + * Write to MMIO 32 bits register + * @param offset register offset + * @param val value to write to the register + */ +#define al_reg_write32(l,v) do { dsb(); generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) + +/** + * Write to MMIO 64 bits register + * @param offset register offset + * @param val value to write to the register + */ +#define al_reg_write64(l,v) do { dsb(); generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) + +static inline uint8_t +al_reg_read8(uint8_t *l) +{ + dsb(); + + return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0)); +} + +static inline uint16_t +al_reg_read16(uint16_t *l) +{ + dsb(); + + return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0)); +} + +static inline uint32_t +al_reg_read32(uint32_t *l) +{ + dsb(); + + return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0)); +} + +#define AL_DBG_LEVEL_NONE 0 +#define AL_DBG_LEVEL_ERR 1 +#define AL_DBG_LEVEL_WARN 2 +#define AL_DBG_LEVEL_INFO 3 +#define AL_DBG_LEVEL_DBG 4 + +#define AL_DBG_LEVEL AL_DBG_LEVEL_ERR + +extern struct mtx al_dbg_lock; + +#define AL_DBG_LOCK() mtx_lock_spin(&al_dbg_lock) +#define AL_DBG_UNLOCK() mtx_unlock_spin(&al_dbg_lock) + +/** + * print message + * + * @param format The format string + * @param ... Additional arguments + */ +#define al_print(type, fmt, ...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_NONE) { AL_DBG_LOCK(); printf(fmt, ##__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) + +/** + * print error message + * + * @param format + */ +#define al_err(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_ERR) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) + +/** + * print warning message + * + * @param format + */ +#define al_warn(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_WARN) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) + +/** + * print info message + * + * @param format + */ +#define al_info(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_INFO) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) + +/** + * print debug message + * + * @param format + */ +#define al_dbg(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_DBG) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) + +/** + * Assertion + * + * @param condition + */ +#define al_assert(COND) \ + do { \ + if (!(COND)) \ + al_err( \ + "%s:%d:%s: Assertion failed! (%s)\n", \ + __FILE__, __LINE__, __func__, #COND); \ + } while(AL_FALSE) + +/** + * Make sure data will be visible by other masters (other CPUS and DMA). + * usually this is achieved by the ARM DMB instruction. + */ +static void al_data_memory_barrier(void); + +/** + * Make sure data will be visible by DMA masters, no restriction for other cpus + */ +static inline void +al_data_memory_barrier(void) +{ + dsb(); +} + +/** + * Make sure data will be visible in order by other cpus masters. + */ +static inline void +al_smp_data_memory_barrier(void) +{ + dsb(); +} + +/** + * Make sure write data will be visible in order by other cpus masters. + */ +static inline void +al_local_data_memory_barrier(void) +{ + dsb(); +} + +/** + * al_udelay - micro sec delay + */ +#define al_udelay(u) DELAY(u) + +/** + * al_msleep - mili sec delay + */ +#define al_msleep(m) DELAY((m) * 1000) + +/** + * swap half word to little endian + * + * @param x 16 bit value + * + * @return the value in little endian + */ +#define swap16_to_le(x) htole16(x) +/** + * swap word to little endian + * + * @param x 32 bit value + * + * @return the value in little endian + */ +#define swap32_to_le(x) htole32(x) + +/** + * swap 8 bytes to little endian + * + * @param x 64 bit value + * + * @return the value in little endian + */ +#define swap64_to_le(x) htole64(x) + +/** + * swap half word from little endian + * + * @param x 16 bit value + * + * @return the value in the cpu endianess + */ +#define swap16_from_le(x) le16toh(x) + +/** + * swap word from little endian + * + * @param x 32 bit value + * + * @return the value in the cpu endianess + */ +#define swap32_from_le(x) le32toh(x) + +/** + * swap 8 bytes from little endian + * + * @param x 64 bit value + * + * @return the value in the cpu endianess + */ +#define swap64_from_le(x) le64toh(x) + +/** + * Memory set + * + * @param p memory pointer + * @param val value for setting + * @param cnt number of bytes to set + */ +#define al_memset(p, val, cnt) memset(p, val, cnt) + +/** + * Memory copy + * + * @param p1 memory pointer + * @param p2 memory pointer + * @param cnt number of bytes to copy + */ +#define al_memcpy(p1, p2, cnt) memcpy(p1, p2, cnt) + +/** + * Memory compare + * + * @param p1 memory pointer + * @param p2 memory pointer + * @param cnt number of bytes to compare + */ +#define al_memcmp(p1, p2, cnt) memcmp(p1, p2, cnt) + +/** + * String compare + * + * @param s1 string pointer + * @param s2 string pointer + */ +#define al_strcmp(s1, s2) strcmp(s1, s2) + +#define al_get_cpu_id() 0 + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +/** @} end of Platform Services API group */ +#endif /* __PLAT_SERVICES_H__ */ diff --git a/al_hal_plat_types.h b/al_hal_plat_types.h new file mode 100644 index 000000000000..43896ae08f71 --- /dev/null +++ b/al_hal_plat_types.h @@ -0,0 +1,94 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @defgroup group_services Platform Services API + * @{ + * @file plat_api/sample/al_hal_plat_types.h + * + */ + +#ifndef __PLAT_TYPES_H__ +#define __PLAT_TYPES_H__ + +#include +#include +#include +#include + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/* Basic data types */ +typedef int al_bool; /** boolean */ +#define AL_TRUE 1 +#define AL_FALSE 0 + + +/* define types */ +#ifndef AL_HAVE_TYPES +typedef unsigned char uint8_t; /** unsigned 8 bits */ +typedef unsigned short uint16_t; /** unsigned 16 bits */ +typedef unsigned int uint32_t; /** unsigned 32 bits */ +typedef unsigned long long uint64_t; /** unsigned 64 bits */ + +typedef signed char int8_t; /** signed 8 bits */ +typedef short int int16_t; /** signed 16 bits */ +typedef signed int int32_t; /** signed 32 bits */ + +/** An unsigned int that is guaranteed to be the same size as a pointer */ +/** C99 standard */ +typedef unsigned long uintptr_t; +#endif + + +/** in LPAE mode, the address address is 40 bit, we extend it to 64 bit */ +typedef uint64_t al_phys_addr_t; + +/** this defines the cpu endiancess. */ +#define PLAT_ARCH_IS_LITTLE() AL_TRUE + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +/** @} end of Platform Services API group */ + +#endif /* __PLAT_TYPES_H__ */ diff --git a/al_hal_reg_utils.h b/al_hal_reg_utils.h new file mode 100644 index 000000000000..f29c3c5247b5 --- /dev/null +++ b/al_hal_reg_utils.h @@ -0,0 +1,188 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @defgroup group_common HAL Common Layer + * @{ + * @file al_hal_reg_utils.h + * + * @brief Register utilities used by HALs and platform layer + * + * + */ + +#ifndef __AL_HAL_REG_UTILS_H__ +#define __AL_HAL_REG_UTILS_H__ + +#include "al_hal_plat_types.h" +#include "al_hal_plat_services.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +#define AL_BIT(b) (1UL << (b)) + +#define AL_ADDR_LOW(x) ((uint32_t)((al_phys_addr_t)(x))) +#define AL_ADDR_HIGH(x) ((uint32_t)((((al_phys_addr_t)(x)) >> 16) >> 16)) + +/** get field out of 32 bit register */ +#define AL_REG_FIELD_GET(reg, mask, shift) (((reg) & (mask)) >> (shift)) + +/** set field of 32 bit register */ +#define AL_REG_FIELD_SET(reg, mask, shift, val) \ + (reg) = \ + (((reg) & (~(mask))) | \ + ((((unsigned)(val)) << (shift)) & (mask))) + +/** set field of 64 bit register */ +#define AL_REG_FIELD_SET_64(reg, mask, shift, val) \ + ((reg) = \ + (((reg) & (~(mask))) | \ + ((((uint64_t)(val)) << (shift)) & (mask)))) + +/** get single bit out of 32 bit register */ +#define AL_REG_BIT_GET(reg, shift) \ + AL_REG_FIELD_GET(reg, AL_BIT(shift), shift) + +#define AL_REG_BITS_FIELD(shift, val) \ + (((unsigned)(val)) << (shift)) + +/** set single bit field of 32 bit register to a given value */ +#define AL_REG_BIT_VAL_SET(reg, shift, val) \ + AL_REG_FIELD_SET(reg, AL_BIT(shift), shift, val) + +/** set single bit of 32 bit register to 1 */ +#define AL_REG_BIT_SET(reg, shift) \ + AL_REG_BIT_VAL_SET(reg, shift, 1) + +/** clear single bit of 32 bit register */ +#define AL_REG_BIT_CLEAR(reg, shift) \ + AL_REG_BIT_VAL_SET(reg, shift, 0) + + +#define AL_BIT_MASK(n) \ + (AL_BIT(n) - 1) + +#define AL_FIELD_MASK(msb, lsb) \ + (AL_BIT(msb) + AL_BIT_MASK(msb) - AL_BIT_MASK(lsb)) + +/** clear bits specified by clear_mask */ +#define AL_REG_MASK_CLEAR(reg, clear_mask) \ + ((reg) = (((reg) & (~(clear_mask))))) + +/** set bits specified by clear_mask */ +#define AL_REG_MASK_SET(reg, clear_mask) \ + ((reg) = (((reg) | (clear_mask)))) + + +/** clear bits specified by clear_mask, and set bits specified by set_mask */ +#define AL_REG_CLEAR_AND_SET(reg, clear_mask, set_mask) \ + (reg) = (((reg) & (~(clear_mask))) | (set_mask)) + +#define AL_ALIGN_UP(val, size) \ + ((size) * (((val) + (size) - 1) / (size))) + +/** take bits selected by mask from one data, the rest from background */ +#define AL_MASK_VAL(mask, data, background) \ + (((mask) & (data)) | ((~mask) & (background))) + +/** + * 8 bits register masked write + * + * @param reg + * register address + * @param mask + * bits not selected (1) by mask will be left unchanged + * @param data + * data to write. bits not selected by mask ignored. + */ +static inline void +al_reg_write8_masked(uint8_t __iomem *reg, uint8_t mask, uint8_t data) +{ + uint8_t temp; + temp = al_reg_read8(reg); + al_reg_write8(reg, AL_MASK_VAL(mask, data, temp)); +} + + +/** + * 16 bits register masked write + * + * @param reg + * register address + * @param mask + * bits not selected (1) by mask will be left unchanged + * @param data + * data to write. bits not selected by mask ignored. + */ +static inline void +al_reg_write16_masked(uint16_t __iomem *reg, uint16_t mask, uint16_t data) +{ + uint16_t temp; + temp = al_reg_read16(reg); + al_reg_write16(reg, AL_MASK_VAL(mask, data, temp)); +} + + +/** + * 32 bits register masked write + * + * @param reg + * register address + * @param mask + * bits not selected (1) by mask will be left unchanged + * @param data + * data to write. bits not selected by mask ignored. + */ +static inline void +al_reg_write32_masked(uint32_t __iomem *reg, uint32_t mask, uint32_t data) +{ + uint32_t temp; + temp = al_reg_read32(reg); + al_reg_write32(reg, AL_MASK_VAL(mask, data, temp)); +} + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +/** @} end of Common group */ +#endif + diff --git a/al_hal_types.h b/al_hal_types.h new file mode 100644 index 000000000000..cea839dcfdcc --- /dev/null +++ b/al_hal_types.h @@ -0,0 +1,117 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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. + +*******************************************************************************/ + +/** + * @defgroup group_common HAL Common Layer + * @{ + * @file al_hal_types.h + * + * @brief macros used by HALs and platform layer + * + */ + +#ifndef __AL_HAL_TYPES_H__ +#define __AL_HAL_TYPES_H__ + +#include "al_hal_plat_types.h" +#include "al_hal_plat_services.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/* Common defines */ + +#if (!AL_TRUE) || (AL_FALSE) +#error "AL_TRUE must be non zero and AL_FALSE must be zero" +#endif + +typedef int AL_RETURN; + +#if !defined(NULL) +#define NULL (void *)0 +#endif + +#if !defined(likely) +#define likely(x) (__builtin_expect(!!(x), 1)) +#define unlikely(x) (__builtin_expect(!!(x), 0)) +#endif + + +#ifdef __GNUC__ +#if !defined(__packed) +#define __packed __attribute__ ((packed)) +#endif + /* packed and alinged types */ +#define __packed_a4 __attribute__ ((packed, aligned(4))) +#define __packed_a8 __attribute__ ((packed, aligned(8))) +#define __packed_a16 __attribute__ ((packed, aligned(16))) + +#else +#if !defined(__packed) +#error "__packed is not defined!!" +#endif +#endif + +#if !defined(__iomem) +#define __iomem +#endif + +#if !defined(__cache_aligned) +#ifdef __GNUC__ +#define __cache_aligned __attribute__ ((__aligned__(64))) +#else +#define __cache_aligned +#endif +#endif + +#if !defined(INLINE) +#ifdef __GNUC__ +#define INLINE inline +#else +#define INLINE +#endif +#endif + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +/** @} end of Common group */ +#endif /* __TYPES_H__ */ diff --git a/al_hal_unit_adapter_regs.h b/al_hal_unit_adapter_regs.h new file mode 100644 index 000000000000..740b959ab43e --- /dev/null +++ b/al_hal_unit_adapter_regs.h @@ -0,0 +1,314 @@ +/*- +******************************************************************************** +Copyright (C) 2015 Annapurna Labs Ltd. + +This file may be licensed under the terms of the Annapurna Labs Commercial +License Agreement. + +Alternatively, this file can be distributed under the terms of the GNU General +Public License V2 as published by the Free Software Foundation and can be +found at http://www.gnu.org/licenses/gpl-2.0.html + +Alternatively, 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. + +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 __AL_HAL_UNIT_ADAPTER_REGS_H__ +#define __AL_HAL_UNIT_ADAPTER_REGS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define AL_PCI_COMMAND 0x04 /* 16 bits */ +#define AL_PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ +#define AL_PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ +#define AL_PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ + +#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */ + +#define AL_PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define AL_PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ +#define AL_PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ +#define AL_PCI_BASE_ADDRESS_DEVICE_ID 0x0c + +#define AL_PCI_BASE_ADDRESS_0 0x10 +#define AL_PCI_BASE_ADDRESS_0_HI 0x14 +#define AL_PCI_BASE_ADDRESS_2 0x18 +#define AL_PCI_BASE_ADDRESS_2_HI 0x1c +#define AL_PCI_BASE_ADDRESS_4 0x20 +#define AL_PCI_BASE_ADDRESS_4_HI 0x24 + +#define AL_PCI_EXP_ROM_BASE_ADDRESS 0x30 + +#define AL_PCI_AXI_CFG_AND_CTR_0 0x110 +#define AL_PCI_AXI_CFG_AND_CTR_1 0x130 +#define AL_PCI_AXI_CFG_AND_CTR_2 0x150 +#define AL_PCI_AXI_CFG_AND_CTR_3 0x170 + +#define AL_PCI_APP_CONTROL 0x220 + +#define AL_PCI_SRIOV_TOTAL_AND_INITIAL_VFS 0x30c + +#define AL_PCI_VF_BASE_ADDRESS_0 0x324 + + +#define AL_PCI_EXP_CAP_BASE 0x40 +#define AL_PCI_EXP_DEVCAP 4 /* Device capabilities */ +#define AL_PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */ +#define AL_PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */ +#define AL_PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */ +#define AL_PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */ +#define AL_PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */ +#define AL_PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ +#define AL_PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ +#define AL_PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ +#define AL_PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */ +#define AL_PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ +#define AL_PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ +#define AL_PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ +#define AL_PCI_EXP_DEVCTL 8 /* Device Control */ +#define AL_PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ +#define AL_PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ +#define AL_PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */ +#define AL_PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */ +#define AL_PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */ +#define AL_PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */ +#define AL_PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */ +#define AL_PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */ +#define AL_PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ +#define AL_PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ +#define AL_PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ +#define AL_PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ +#define AL_PCI_EXP_DEVSTA 0xA /* Device Status */ +#define AL_PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ +#define AL_PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */ +#define AL_PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */ +#define AL_PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */ +#define AL_PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ +#define AL_PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ +#define AL_PCI_EXP_LNKCAP 0xC /* Link Capabilities */ +#define AL_PCI_EXP_LNKCAP_SLS 0xf /* Supported Link Speeds */ +#define AL_PCI_EXP_LNKCAP_SLS_2_5GB 0x1 /* LNKCAP2 SLS Vector bit 0 (2.5GT/s) */ +#define AL_PCI_EXP_LNKCAP_SLS_5_0GB 0x2 /* LNKCAP2 SLS Vector bit 1 (5.0GT/s) */ +#define AL_PCI_EXP_LNKCAP_MLW 0x3f0 /* Maximum Link Width */ +#define AL_PCI_EXP_LNKCAP_ASPMS 0xc00 /* ASPM Support */ +#define AL_PCI_EXP_LNKCAP_L0SEL 0x7000 /* L0s Exit Latency */ +#define AL_PCI_EXP_LNKCAP_L1EL 0x38000 /* L1 Exit Latency */ +#define AL_PCI_EXP_LNKCAP_CLKPM 0x40000 /* L1 Clock Power Management */ +#define AL_PCI_EXP_LNKCAP_SDERC 0x80000 /* Surprise Down Error Reporting Capable */ +#define AL_PCI_EXP_LNKCAP_DLLLARC 0x100000 /* Data Link Layer Link Active Reporting Capable */ +#define AL_PCI_EXP_LNKCAP_LBNC 0x200000 /* Link Bandwidth Notification Capability */ +#define AL_PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */ + +#define AL_PCI_EXP_LNKCTL 0x10 /* Link Control */ +#define AL_PCI_EXP_LNKCTL_LNK_DIS 0x4 /* Link Disable Status */ +#define AL_PCI_EXP_LNKCTL_LNK_RTRN 0x5 /* Link Retrain Status */ + +#define AL_PCI_EXP_LNKSTA 0x12 /* Link Status */ +#define AL_PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */ +#define AL_PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */ +#define AL_PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */ +#define AL_PCI_EXP_LNKSTA_CLS_8_0GB 0x03 /* Current Link Speed 8.0GT/s */ +#define AL_PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */ +#define AL_PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */ +#define AL_PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */ +#define AL_PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */ +#define AL_PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ +#define AL_PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */ +#define AL_PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */ + +#define AL_PCI_EXP_LNKCTL2 0x30 /* Link Control 2 */ + +#define AL_PCI_MSIX_MSGCTRL 0 /* MSIX message control reg */ +#define AL_PCI_MSIX_MSGCTRL_TBL_SIZE 0x7ff /* MSIX table size */ +#define AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT 16 /* MSIX table size shift */ +#define AL_PCI_MSIX_MSGCTRL_EN 0x80000000 /* MSIX enable */ +#define AL_PCI_MSIX_MSGCTRL_MASK 0x40000000 /* MSIX mask */ + +#define AL_PCI_MSIX_TABLE 0x4 /* MSIX table offset and bar reg */ +#define AL_PCI_MSIX_TABLE_OFFSET 0xfffffff8 /* MSIX table offset */ +#define AL_PCI_MSIX_TABLE_BAR 0x7 /* MSIX table BAR */ + +#define AL_PCI_MSIX_PBA 0x8 /* MSIX pba offset and bar reg */ +#define AL_PCI_MSIX_PBA_OFFSET 0xfffffff8 /* MSIX pba offset */ +#define AL_PCI_MSIX_PBA_BAR 0x7 /* MSIX pba BAR */ + + +/* Adapter power management register 0 */ +#define AL_ADAPTER_PM_0 0x80 +#define AL_ADAPTER_PM_0_PM_NEXT_CAP_MASK 0xff00 +#define AL_ADAPTER_PM_0_PM_NEXT_CAP_SHIFT 8 +#define AL_ADAPTER_PM_0_PM_NEXT_CAP_VAL_MSIX 0x90 + +/* Adapter power management register 1 */ +#define AL_ADAPTER_PM_1 0x84 +#define AL_ADAPTER_PM_1_PME_EN 0x100 /* PM enable */ +#define AL_ADAPTER_PM_1_PWR_STATE_MASK 0x3 /* PM state mask */ +#define AL_ADAPTER_PM_1_PWR_STATE_D3 0x3 /* PM D3 state */ + +/* Sub Master Configuration & Control */ +#define AL_ADAPTER_SMCC 0x110 +#define AL_ADAPTER_SMCC_CONF_2 0x114 + +/* Interrupt_Cause register */ +#define AL_ADAPTER_INT_CAUSE 0x1B0 +#define AL_ADAPTER_INT_CAUSE_WR_ERR AL_BIT(1) +#define AL_ADAPTER_INT_CAUSE_RD_ERR AL_BIT(0) + +/* AXI_Master_Write_Error_Attribute_Latch register */ +/* AXI_Master_Read_Error_Attribute_Latch register */ +#define AL_ADAPTER_AXI_MSTR_WR_ERR_ATTR 0x1B4 +#define AL_ADAPTER_AXI_MSTR_RD_ERR_ATTR 0x1B8 + +#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_STAT_MASK AL_FIELD_MASK(1, 0) +#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_STAT_SHIFT 0 +#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_MSTR_ID_MASK AL_FIELD_MASK(4, 2) +#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_MSTR_ID_SHIFT 2 +#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_ADDR_TO AL_BIT(8) +#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_ERR AL_BIT(9) +#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_TO AL_BIT(10) +#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_ERR_BLK AL_BIT(11) +#define AL_ADAPTER_AXI_MSTR_RD_ERR_ATTR_RD_PARITY_ERR AL_BIT(12) + +/* Interrupt_Cause_mask register */ +#define AL_ADAPTER_INT_CAUSE_MASK 0x1BC +#define AL_ADAPTER_INT_CAUSE_MASK_WR_ERR AL_BIT(1) +#define AL_ADAPTER_INT_CAUSE_MASK_RD_ERR AL_BIT(0) + +/* AXI_Master_write_error_address_Latch register */ +#define AL_ADAPTER_AXI_MSTR_WR_ERR_LO_LATCH 0x1C0 + +/* AXI_Master_write_error_address_high_Latch register */ +#define AL_ADAPTER_AXI_MSTR_WR_ERR_HI_LATCH 0x1C4 + +/* AXI_Master_read_error_address_Latch register */ +#define AL_ADAPTER_AXI_MSTR_RD_ERR_LO_LATCH 0x1C8 + +/* AXI_Master_read_error_address_high_Latch register */ +#define AL_ADAPTER_AXI_MSTR_RD_ERR_HI_LATCH 0x1CC + +/* AXI_Master_Timeout register */ +#define AL_ADAPTER_AXI_MSTR_TO 0x1D0 +#define AL_ADAPTER_AXI_MSTR_TO_WR_MASK AL_FIELD_MASK(31, 16) +#define AL_ADAPTER_AXI_MSTR_TO_WR_SHIFT 16 +#define AL_ADAPTER_AXI_MSTR_TO_RD_MASK AL_FIELD_MASK(15, 0) +#define AL_ADAPTER_AXI_MSTR_TO_RD_SHIFT 0 + +/* + * Generic control registers + */ + +/* Control 0 */ +#define AL_ADAPTER_GENERIC_CONTROL_0 0x1E0 +/* Control 2 */ +#define AL_ADAPTER_GENERIC_CONTROL_2 0x1E8 +/* Control 3 */ +#define AL_ADAPTER_GENERIC_CONTROL_3 0x1EC +/* Control 9 */ +#define AL_ADAPTER_GENERIC_CONTROL_9 0x218 +/* Control 10 */ +#define AL_ADAPTER_GENERIC_CONTROL_10 0x21C +/* Control 11 */ +#define AL_ADAPTER_GENERIC_CONTROL_11 0x220 +/* Control 12 */ +#define AL_ADAPTER_GENERIC_CONTROL_12 0x224 +/* Control 13 */ +#define AL_ADAPTER_GENERIC_CONTROL_13 0x228 +/* Control 14 */ +#define AL_ADAPTER_GENERIC_CONTROL_14 0x22C +/* Control 15 */ +#define AL_ADAPTER_GENERIC_CONTROL_15 0x230 +/* Control 16 */ +#define AL_ADAPTER_GENERIC_CONTROL_16 0x234 +/* Control 17 */ +#define AL_ADAPTER_GENERIC_CONTROL_17 0x238 +/* Control 18 */ +#define AL_ADAPTER_GENERIC_CONTROL_18 0x23C +/* Control 19 */ +#define AL_ADAPTER_GENERIC_CONTROL_19 0x240 + +/* Enable clock gating */ +#define AL_ADAPTER_GENERIC_CONTROL_0_CLK_GATE_EN 0x01 +/* When set, all transactions through the PCI conf & mem BARs get timeout */ +#define AL_ADAPTER_GENERIC_CONTROL_0_ADAPTER_DIS 0x40 +#define AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC AL_BIT(18) +#define AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC_ON_FLR AL_BIT(26) + +/* + * SATA registers only + */ +/* Select 125MHz free running clock from IOFAB main PLL as SATA OOB clock + * instead of using power management ref clock + */ +#define AL_ADAPTER_GENERIC_CONTROL_10_SATA_OOB_CLK_SEL AL_BIT(26) +/* AXUSER selection and value per bit (1 = address, 0 = register) */ +/* Rx */ +#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_VAL_MASK AL_FIELD_MASK(15, 0) +#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_VAL_SHIFT 0 +#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_SEL_MASK AL_FIELD_MASK(31, 16) +#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_SEL_SHIFT 16 +/* Tx */ +#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_MASK AL_FIELD_MASK(15, 0) +#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_SHIFT 0 +#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_MASK AL_FIELD_MASK(31, 16) +#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_SHIFT 16 +/* Central VMID enabler. If set, then each entry will be used as programmed */ +#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_SEL AL_BIT(0) +/* Allow access to store VMID values per entry */ +#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_ACCESS_EN AL_BIT(1) +/* VMID Address select */ +/* Tx */ +#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_MASK AL_FIELD_MASK(13, 8) +#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_SHIFT 8 +/* Rx */ +#define AL_ADPTR_GEN_CTL_14_SATA_VM_AWADDR_SEL_MASK AL_FIELD_MASK(21, 16) +#define AL_ADPTR_GEN_CTL_14_SATA_VM_AWADDR_SEL_SHIFT 16 +/* Address Value */ +/* Rx */ +#define AL_ADPTR_GEN_CTL_15_SATA_VM_AWDDR_HI AL_FIELD_MASK(31, 0) +/* Tx */ +#define AL_ADPTR_GEN_CTL_16_SATA_VM_ARDDR_HI AL_FIELD_MASK(31, 0) + +/* + * ROB registers + */ +/* Read ROB_Enable, when disabled the read ROB is bypassed */ +#define AL_ADPTR_GEN_CTL_19_READ_ROB_EN AL_BIT(0) +/* Read force in-order of every read transaction */ +#define AL_ADPTR_GEN_CTL_19_READ_ROB_FORCE_INORDER AL_BIT(1) +/* Read software reset */ +#define AL_ADPTR_GEN_CTL_19_READ_ROB_SW_RESET AL_BIT(15) +/* Write ROB_Enable, when disabled_the_Write ROB is bypassed */ +#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_EN AL_BIT(16) +/* Write force in-order of every write transaction */ +#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_FORCE_INORDER AL_BIT(17) +/* Write software reset */ +#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_SW_RESET AL_BIT(31) + +#ifdef __cplusplus +} +#endif + +#endif From 267dbe63a1dfb8e05eae5f1fad1ed7cc5f7b4b27 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Mon, 27 Jul 2015 22:35:54 +0000 Subject: [PATCH 002/314] Provide consistent error causes whenever an ABORT chunk is sent. MFC after: 1 week --- sys/netinet/sctp_asconf.c | 8 +++++++- sys/netinet/sctp_indata.c | 5 ++++- sys/netinet/sctp_input.c | 10 +++++----- sys/netinet/sctp_output.c | 34 ++++++++++++++++++++++++++-------- sys/netinet/sctp_pcb.c | 26 +++++++++++++++++++++----- sys/netinet/sctp_timer.c | 4 ++-- sys/netinet/sctputil.c | 5 ++++- 7 files changed, 69 insertions(+), 23 deletions(-) diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index a64e7f95f730..540cc65ff08c 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -1680,8 +1680,14 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset, * abort the asoc, since someone probably just hijacked us... */ if (serial_num == (asoc->asconf_seq_out + 1)) { + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; + SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n"); - sctp_abort_an_association(stcb->sctp_ep, stcb, NULL, SCTP_SO_NOT_LOCKED); + snprintf(msg, sizeof(msg), "Never sent serial number %8.8x", + serial_num); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); *abort_no_unlock = 1; return; } diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index f8bf05ff7d24..6b2efc94163b 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -2488,8 +2488,11 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, */ if (SCTP_BASE_SYSCTL(sctp_strict_data_order)) { struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; - op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, ""); + snprintf(msg, sizeof(msg), "DATA chunk followwd by chunk of type %2.2x", + ch->ch.chunk_type); + op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); sctp_abort_association(inp, stcb, m, iphlen, src, dst, diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index aa7c30c6bf51..4e9fa88e72df 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -4624,7 +4624,7 @@ __attribute__((noinline)) } } if (stcb == NULL) { - snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); /* no association, so it's out of the blue... */ @@ -4668,7 +4668,7 @@ __attribute__((noinline)) if (locked_tcb) { SCTP_TCB_UNLOCK(locked_tcb); } - snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); sctp_handle_ootb(m, iphlen, *offset, src, dst, @@ -5834,7 +5834,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt */ SCTP_TCB_UNLOCK(stcb); stcb = NULL; - snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, @@ -5886,7 +5886,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt } if (stcb == NULL) { /* out of the blue DATA chunk */ - snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, @@ -5958,7 +5958,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt /* * We consider OOTB any data sent during asoc setup. */ - snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __FUNCTION__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err, diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 1beab07adbda..1c56f9ad9d4a 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -5524,7 +5524,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, if (op_err == NULL) { char msg[SCTP_DIAG_INFO_LEN]; - snprintf(msg, sizeof(msg), "%s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__); + snprintf(msg, sizeof(msg), "%s:%d at %s", __FILE__, __LINE__, __FUNCTION__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), msg); } @@ -6682,10 +6682,17 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue) && (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; + abort_anyway: + snprintf(msg, sizeof(msg), + "%s:%d at %s", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); atomic_add_int(&stcb->asoc.refcnt, 1); sctp_abort_an_association(stcb->sctp_ep, stcb, - NULL, SCTP_SO_NOT_LOCKED); + op_err, SCTP_SO_NOT_LOCKED); atomic_add_int(&stcb->asoc.refcnt, -1); goto no_chunk_output; } @@ -9454,12 +9461,16 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp, } if ((SCTP_BASE_SYSCTL(sctp_max_retran_chunk)) && (chk->snd_count >= SCTP_BASE_SYSCTL(sctp_max_retran_chunk))) { - /* Gak, we have exceeded max unlucky retran, abort! */ - SCTP_PRINTF("Gak, chk->snd_count:%d >= max:%d - send abort\n", - chk->snd_count, - SCTP_BASE_SYSCTL(sctp_max_retran_chunk)); + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; + + snprintf(msg, sizeof(msg), "TSN %8.8x retransmitted %d times, giving up", + chk->rec.data.TSN_seq, chk->snd_count); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); atomic_add_int(&stcb->asoc.refcnt, 1); - sctp_abort_an_association(stcb->sctp_ep, stcb, NULL, so_locked); + sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, + so_locked); SCTP_TCB_LOCK(stcb); atomic_subtract_int(&stcb->asoc.refcnt, 1); return (SCTP_RETRAN_EXIT); @@ -13344,13 +13355,20 @@ sctp_lower_sosend(struct socket *so, if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue) && (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; + abort_anyway: if (free_cnt_applied) { atomic_add_int(&stcb->asoc.refcnt, -1); free_cnt_applied = 0; } + snprintf(msg, sizeof(msg), + "%s:%d at %s", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); sctp_abort_an_association(stcb->sctp_ep, stcb, - NULL, SCTP_SO_LOCKED); + op_err, SCTP_SO_LOCKED); /* * now relock the stcb so everything * is sane diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 541d4ca3b6c2..07119f15d9ff 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -6250,12 +6250,20 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, */ if (stcb_tmp) { if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) { + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; + /* * in setup state we * abort this guy */ + snprintf(msg, sizeof(msg), + "%s:%d at %s", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); sctp_abort_an_association(stcb_tmp->sctp_ep, - stcb_tmp, NULL, SCTP_SO_NOT_LOCKED); + stcb_tmp, op_err, + SCTP_SO_NOT_LOCKED); goto add_it_now; } SCTP_TCB_UNLOCK(stcb_tmp); @@ -6339,18 +6347,26 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, * strange, address is in another * assoc? straighten out locks. */ - if (stcb_tmp) + if (stcb_tmp) { if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) { + struct mbuf *op_err; + char msg[SCTP_DIAG_INFO_LEN]; + /* * in setup state we * abort this guy */ + snprintf(msg, sizeof(msg), + "%s:%d at %s", __FILE__, __LINE__, __FUNCTION__); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + msg); sctp_abort_an_association(stcb_tmp->sctp_ep, - stcb_tmp, NULL, SCTP_SO_NOT_LOCKED); + stcb_tmp, op_err, + SCTP_SO_NOT_LOCKED); goto add_it_now6; } - SCTP_TCB_UNLOCK(stcb_tmp); - + SCTP_TCB_UNLOCK(stcb_tmp); + } if (stcb->asoc.state == 0) { /* the assoc was freed? */ return (-21); diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index 257d18845b23..6c8589eea1df 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -153,7 +153,7 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* Abort notification sends a ULP notify */ struct mbuf *op_err; - op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), "Association error counter exceeded"); inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_2; sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); @@ -1046,7 +1046,7 @@ sctp_cookie_timer(struct sctp_inpcb *inp, /* FOOBAR! */ struct mbuf *op_err; - op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), "Cookie timer expired, but no cookie"); inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_3; sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index b613992fb5ae..069ed34c346a 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1445,6 +1445,7 @@ sctp_timeout_handler(void *t) struct sctp_tcb *stcb; struct sctp_nets *net; struct sctp_timer *tmr; + struct mbuf *op_err; #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) struct socket *so; @@ -1756,7 +1757,9 @@ sctp_timeout_handler(void *t) break; } SCTP_STAT_INCR(sctps_timoshutdownguard); - sctp_abort_an_association(inp, stcb, NULL, SCTP_SO_NOT_LOCKED); + op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), + "Shutdown guard timer expired"); + sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); /* no need to unlock on tcb its gone */ goto out_decr; From 033af09de113cdcba4b72685dd5311fffb1025c5 Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Tue, 28 Jul 2015 02:32:40 +0000 Subject: [PATCH 003/314] Staticfy and constify some variables and clean up the code a bit to make it more readable. No functional change. Differential Revision: D3166 Reviewed by: kib Sponsored by: gandi.net --- libexec/ypxfr/ypxfr_getmap.c | 4 ++-- libexec/ypxfr/ypxfr_main.c | 12 ++++++------ libexec/ypxfr/ypxfrd_getmap.c | 2 +- usr.bin/ypcat/ypcat.c | 6 +++--- usr.bin/ypmatch/ypmatch.c | 4 ++-- usr.bin/ypwhich/ypwhich.c | 4 ++-- usr.sbin/yp_mkdb/yp_mkdb.c | 4 ---- usr.sbin/yppush/yppush_main.c | 24 ++++++++++++------------ usr.sbin/ypserv/yp_access.c | 8 ++++---- usr.sbin/ypserv/yp_dblookup.c | 2 +- usr.sbin/ypserv/yp_error.c | 6 +++--- usr.sbin/ypserv/yp_main.c | 6 ++---- 12 files changed, 38 insertions(+), 44 deletions(-) diff --git a/libexec/ypxfr/ypxfr_getmap.c b/libexec/ypxfr/ypxfr_getmap.c index 4b8794f317e7..458971f893c5 100644 --- a/libexec/ypxfr/ypxfr_getmap.c +++ b/libexec/ypxfr/ypxfr_getmap.c @@ -43,8 +43,8 @@ __FBSDID("$FreeBSD$"); extern bool_t xdr_ypresp_all_seq(XDR *, unsigned long *); -int (*ypresp_allfn)(); -void *ypresp_data; +static int (*ypresp_allfn)(); +static void *ypresp_data; extern DB *specdbp; extern enum ypstat yp_errno; diff --git a/libexec/ypxfr/ypxfr_main.c b/libexec/ypxfr/ypxfr_main.c index 03a30f6307c8..03ebbe12fcaf 100644 --- a/libexec/ypxfr/ypxfr_main.c +++ b/libexec/ypxfr/ypxfr_main.c @@ -54,12 +54,12 @@ __FBSDID("$FreeBSD$"); char *progname = "ypxfr"; char *yp_dir = _PATH_YP; int _rpcpmstart = 0; -int ypxfr_use_yplib = 0; /* Assume the worst. */ -int ypxfr_clear = 1; -int ypxfr_prognum = 0; -struct sockaddr_in ypxfr_callback_addr; -struct yppushresp_xfr ypxfr_resp; -DB *dbp; +static int ypxfr_use_yplib = 0; /* Assume the worst. */ +static int ypxfr_clear = 1; +static int ypxfr_prognum = 0; +static struct sockaddr_in ypxfr_callback_addr; +static struct yppushresp_xfr ypxfr_resp; +static DB *dbp; static void ypxfr_exit(ypxfrstat retval, char *temp) diff --git a/libexec/ypxfr/ypxfrd_getmap.c b/libexec/ypxfr/ypxfrd_getmap.c index b1424ac552fc..a5ac92da578d 100644 --- a/libexec/ypxfr/ypxfrd_getmap.c +++ b/libexec/ypxfr/ypxfrd_getmap.c @@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include "ypxfr_extern.h" -int fp = 0; +static int fp = 0; static bool_t xdr_my_xfr(register XDR *xdrs, xfr *objp) diff --git a/usr.bin/ypcat/ypcat.c b/usr.bin/ypcat/ypcat.c index 3484bc9c1f4c..b3d90336c61a 100644 --- a/usr.bin/ypcat/ypcat.c +++ b/usr.bin/ypcat/ypcat.c @@ -47,9 +47,9 @@ __FBSDID("$FreeBSD$"); #include #include -struct ypalias { +const struct ypalias { char *alias, *name; -} ypaliases[] = { +} static ypaliases[] = { { "passwd", "passwd.byname" }, { "master.passwd", "master.passwd.byname" }, { "shadow", "shadow.byname" }, @@ -62,7 +62,7 @@ struct ypalias { { "ethers", "ethers.byname" }, }; -int key; +static int key; static void usage(void) diff --git a/usr.bin/ypmatch/ypmatch.c b/usr.bin/ypmatch/ypmatch.c index a9c32ea72c48..d6b58c2c5d31 100644 --- a/usr.bin/ypmatch/ypmatch.c +++ b/usr.bin/ypmatch/ypmatch.c @@ -47,9 +47,9 @@ __FBSDID("$FreeBSD$"); #include #include -struct ypalias { +const struct ypalias { char *alias, *name; -} ypaliases[] = { +} static ypaliases[] = { { "passwd", "passwd.byname" }, { "master.passwd", "master.passwd.byname" }, { "shadow", "shadow.byname" }, diff --git a/usr.bin/ypwhich/ypwhich.c b/usr.bin/ypwhich/ypwhich.c index b31dcae2cb6c..d02461ebafb9 100644 --- a/usr.bin/ypwhich/ypwhich.c +++ b/usr.bin/ypwhich/ypwhich.c @@ -59,9 +59,9 @@ __FBSDID("$FreeBSD$"); extern bool_t xdr_domainname(); -struct ypalias { +const struct ypalias { char *alias, *name; -} ypaliases[] = { +} static ypaliases[] = { { "passwd", "passwd.byname" }, { "master.passwd", "master.passwd.byname" }, { "shadow", "shadow.byname" }, diff --git a/usr.sbin/yp_mkdb/yp_mkdb.c b/usr.sbin/yp_mkdb/yp_mkdb.c index f1f629a42b5b..290e40500de6 100644 --- a/usr.sbin/yp_mkdb/yp_mkdb.c +++ b/usr.sbin/yp_mkdb/yp_mkdb.c @@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$"); #include "ypxfr_extern.h" char *yp_dir = ""; /* No particular default needed. */ -int _rpcpmstart = 0; int debug = 1; static void @@ -66,7 +65,6 @@ usage(void) } #define PERM_SECURE (S_IRUSR|S_IWUSR) - static DB * open_db(char *path, int flags) { @@ -185,7 +183,6 @@ main(int argc, char *argv[]) * write to stdout; the db library doesn't let you * write to a file stream like that. */ - if (!strcmp(infile, "-")) { ifp = stdin; } else { @@ -327,7 +324,6 @@ main(int argc, char *argv[]) (void)(dbp->close)(dbp); doclear: - if (clear) { char in = 0; char *out = NULL; diff --git a/usr.sbin/yppush/yppush_main.c b/usr.sbin/yppush/yppush_main.c index 6c665158c4ad..5a712e5a41b0 100644 --- a/usr.sbin/yppush/yppush_main.c +++ b/usr.sbin/yppush/yppush_main.c @@ -58,15 +58,15 @@ int debug = 1; int _rpcpmstart = 0; char *yp_dir = _PATH_YP; -char *yppush_mapname = NULL; /* Map to transfer. */ -char *yppush_domain = NULL; /* Domain in which map resides. */ -char *yppush_master = NULL; /* Master NIS server for said domain. */ -int skip_master = 0; /* Do not attempt to push map to master. */ -int verbose = 0; /* Toggle verbose mode. */ -unsigned long yppush_transid = 0; -int yppush_timeout = 80; /* Default timeout. */ -int yppush_jobs = 1; /* Number of allowed concurrent jobs. */ -int yppush_running_jobs = 0; /* Number of currently running jobs. */ +static char *yppush_mapname = NULL; /* Map to transfer. */ +static char *yppush_domain = NULL; /* Domain in which map resides. */ +static char *yppush_master = NULL; /* Master NIS server for said domain. */ +static int skip_master = 0; /* Do not attempt to push map to master. */ +static int verbose = 0; /* Toggle verbose mode. */ +static unsigned long yppush_transid = 0; +static int yppush_timeout = 80; /* Default timeout. */ +static int yppush_jobs = 1; /* Number of allowed concurrent jobs. */ +static int yppush_running_jobs = 0; /* Number of currently running jobs. */ /* Structure for holding information about a running job. */ struct jobs { @@ -80,8 +80,7 @@ struct jobs { struct jobs *next; }; -struct jobs *yppush_joblist; /* Linked list of running jobs. */ - +static struct jobs *yppush_joblist; /* Linked list of running jobs. */ static int yppush_svc_run(int); /* @@ -464,7 +463,8 @@ yppush_foreach(int status, char *key, int keylen, char *val, int vallen, return (0); } -static void usage() +static void +usage() { fprintf (stderr, "%s\n%s\n", "usage: yppush [-d domain] [-t timeout] [-j #parallel jobs] [-h host]", diff --git a/usr.sbin/ypserv/yp_access.c b/usr.sbin/ypserv/yp_access.c index c82f8c7bbbee..a4ba5049f20c 100644 --- a/usr.sbin/ypserv/yp_access.c +++ b/usr.sbin/ypserv/yp_access.c @@ -57,8 +57,8 @@ __FBSDID("$FreeBSD$"); extern int debug; - /* NIS v1 */ -const char *yp_procs[] = { +static const char *yp_procs[] = { + /* NIS v1 */ "ypoldproc_null", "ypoldproc_domain", "ypoldproc_domain_nonack", @@ -71,7 +71,7 @@ const char *yp_procs[] = { "badproc1", /* placeholder */ "badproc2", /* placeholder */ "badproc3", /* placeholder */ - + /* NIS v2 */ "ypproc_null", "ypproc_domain", @@ -93,7 +93,7 @@ struct securenet { struct securenet *next; }; -struct securenet *securenets; +static struct securenet *securenets; #define LINEBUFSZ 1024 diff --git a/usr.sbin/ypserv/yp_dblookup.c b/usr.sbin/ypserv/yp_dblookup.c index 61944dc44bbe..6a3bf1c462a0 100644 --- a/usr.sbin/ypserv/yp_dblookup.c +++ b/usr.sbin/ypserv/yp_dblookup.c @@ -405,7 +405,7 @@ yp_open_db(const char *domain, const char *map) #ifdef DB_CACHE again: #endif - dbp = dbopen(buf,O_RDONLY, PERM_SECURE, DB_HASH, NULL); + dbp = dbopen(buf, O_RDONLY, PERM_SECURE, DB_HASH, NULL); if (dbp == NULL) { switch (errno) { diff --git a/usr.sbin/ypserv/yp_error.c b/usr.sbin/ypserv/yp_error.c index 8d488f3bdb6a..a5b12902d0d1 100644 --- a/usr.sbin/ypserv/yp_error.c +++ b/usr.sbin/ypserv/yp_error.c @@ -46,13 +46,13 @@ __FBSDID("$FreeBSD$"); #include "yp_extern.h" int debug; + extern int _rpcpmstart; - extern char *progname; - static void __verr(const char *fmt, va_list ap) __printflike(1, 0); -static void __verr(const char *fmt, va_list ap) +static void +__verr(const char *fmt, va_list ap) { if (debug && !_rpcpmstart) { fprintf(stderr,"%s: ",progname); diff --git a/usr.sbin/ypserv/yp_main.c b/usr.sbin/ypserv/yp_main.c index 958d3a62d18c..8c538ca8ca46 100644 --- a/usr.sbin/ypserv/yp_main.c +++ b/usr.sbin/ypserv/yp_main.c @@ -72,13 +72,11 @@ __FBSDID("$FreeBSD$"); #define _RPCSVC_CLOSEDOWN 120 int _rpcpmstart; /* Started by a port monitor ? */ -static int _rpcfdtype; - /* Whether Stream or Datagram ? */ +static int _rpcfdtype; /* Whether Stream or Datagram? */ static int _rpcaf; static int _rpcfd; - /* States a server can be in wrt request */ - +/* States a server can be in wrt request */ #define _IDLE 0 #define _SERVED 1 #define _SERVING 2 From f40c76d8dedcc7cf095b00787567a4f1d575280f Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Tue, 28 Jul 2015 04:54:05 +0000 Subject: [PATCH 004/314] Check the sync operation. --- sys/dev/proto/proto_busdma.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/dev/proto/proto_busdma.c b/sys/dev/proto/proto_busdma.c index 52f1146ffdd0..6f6bf7b08916 100644 --- a/sys/dev/proto/proto_busdma.c +++ b/sys/dev/proto/proto_busdma.c @@ -325,7 +325,12 @@ static int proto_busdma_sync(struct proto_busdma *busdma, struct proto_md *md, struct proto_ioc_busdma *ioc) { - + u_int ops; + + ops = BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE | + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE; + if (ioc->u.sync.op & ~ops) + return (EINVAL); if (!md->physaddr) return (ENXIO); bus_dmamap_sync(md->bd_tag, md->bd_map, ioc->u.sync.op); From cec575201a4c9c10aa39dda868fbed5c64908c17 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 28 Jul 2015 06:36:49 +0000 Subject: [PATCH 005/314] Make fstat() and friends work. Summary: CloudABI provides access to two different stat structures: - fdstat, containing file descriptor level status: oflags, file descriptor type and Capsicum rights, used by cap_rights_get(), fcntl(F_GETFL), getsockopt(SO_TYPE). - filestat, containing your regular file status: timestamps, inode number, used by fstat(). Unlike FreeBSD's stat::st_mode, CloudABI file descriptor types don't have overloaded meanings (e.g., returning S_ISCHR() for kqueues). Add a utility function to extract the type of a file descriptor accurately. CloudABI does not work with O_ACCMODEs. File descriptors have two sets of Capsicum-style rights: rights that apply to the file descriptor itself ('base') and rights that apply to any new file descriptors yielded through openat() ('inheriting'). Though not perfect, we can pretty safely decompose Capsicum rights to such a pair. This is done in convert_capabilities(). Test Plan: Tests for these system calls are fairly extensive in cloudlibc. Reviewers: jonathan, mjg, #manpages Reviewed By: mjg Subscribers: imp Differential Revision: https://reviews.freebsd.org/D3171 --- sys/compat/cloudabi/cloudabi_fd.c | 256 +++++++++++++++++++++++++++- sys/compat/cloudabi/cloudabi_file.c | 82 ++++++++- sys/compat/cloudabi/cloudabi_util.h | 4 + 3 files changed, 336 insertions(+), 6 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index 8b72c19cdf6f..23eb78b844d8 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -27,13 +27,64 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include +#include #include #include +#include #include +#include #include +#include +#include + +/* Translation between CloudABI and Capsicum rights. */ +#define RIGHTS_MAPPINGS \ + MAPPING(CLOUDABI_RIGHT_FD_DATASYNC, CAP_FSYNC) \ + MAPPING(CLOUDABI_RIGHT_FD_READ, CAP_READ) \ + MAPPING(CLOUDABI_RIGHT_FD_SEEK, CAP_SEEK) \ + MAPPING(CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS, CAP_FCNTL) \ + MAPPING(CLOUDABI_RIGHT_FD_SYNC, CAP_FSYNC) \ + MAPPING(CLOUDABI_RIGHT_FD_TELL, CAP_SEEK_TELL) \ + MAPPING(CLOUDABI_RIGHT_FD_WRITE, CAP_WRITE) \ + MAPPING(CLOUDABI_RIGHT_FILE_ADVISE) \ + MAPPING(CLOUDABI_RIGHT_FILE_ALLOCATE, CAP_WRITE) \ + MAPPING(CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY, CAP_MKDIRAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_CREATE_FILE, CAP_CREATE) \ + MAPPING(CLOUDABI_RIGHT_FILE_CREATE_FIFO, CAP_MKFIFOAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_LINK_SOURCE, CAP_LOOKUP) \ + MAPPING(CLOUDABI_RIGHT_FILE_LINK_TARGET, CAP_LINKAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_OPEN, CAP_LOOKUP) \ + MAPPING(CLOUDABI_RIGHT_FILE_READDIR, CAP_READ) \ + MAPPING(CLOUDABI_RIGHT_FILE_READLINK, CAP_LOOKUP) \ + MAPPING(CLOUDABI_RIGHT_FILE_RENAME_SOURCE, CAP_RENAMEAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_RENAME_TARGET, CAP_LINKAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_STAT_FGET, CAP_FSTAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE, CAP_FTRUNCATE) \ + MAPPING(CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES, CAP_FUTIMES) \ + MAPPING(CLOUDABI_RIGHT_FILE_STAT_GET, CAP_FSTATAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES, CAP_FUTIMESAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_SYMLINK, CAP_SYMLINKAT) \ + MAPPING(CLOUDABI_RIGHT_FILE_UNLINK, CAP_UNLINKAT) \ + MAPPING(CLOUDABI_RIGHT_MEM_MAP, CAP_MMAP) \ + MAPPING(CLOUDABI_RIGHT_MEM_MAP_EXEC, CAP_MMAP_X) \ + MAPPING(CLOUDABI_RIGHT_POLL_FD_READWRITE, CAP_EVENT) \ + MAPPING(CLOUDABI_RIGHT_POLL_MODIFY, CAP_KQUEUE_CHANGE) \ + MAPPING(CLOUDABI_RIGHT_POLL_PROC_TERMINATE, CAP_PDWAIT) \ + MAPPING(CLOUDABI_RIGHT_POLL_WAIT, CAP_KQUEUE_EVENT) \ + MAPPING(CLOUDABI_RIGHT_PROC_EXEC, CAP_FEXECVE) \ + MAPPING(CLOUDABI_RIGHT_SOCK_ACCEPT, CAP_ACCEPT) \ + MAPPING(CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY, CAP_BINDAT) \ + MAPPING(CLOUDABI_RIGHT_SOCK_BIND_SOCKET, CAP_BIND) \ + MAPPING(CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY, CAP_CONNECTAT) \ + MAPPING(CLOUDABI_RIGHT_SOCK_CONNECT_SOCKET, CAP_CONNECT) \ + MAPPING(CLOUDABI_RIGHT_SOCK_LISTEN, CAP_LISTEN) \ + MAPPING(CLOUDABI_RIGHT_SOCK_SHUTDOWN, CAP_SHUTDOWN) \ + MAPPING(CLOUDABI_RIGHT_SOCK_STAT_GET, CAP_GETPEERNAME, \ + CAP_GETSOCKNAME, CAP_GETSOCKOPT) int cloudabi_sys_fd_close(struct thread *td, struct cloudabi_sys_fd_close_args *uap) @@ -160,13 +211,214 @@ cloudabi_sys_fd_seek(struct thread *td, struct cloudabi_sys_fd_seek_args *uap) return (sys_lseek(td, &lseek_args)); } +/* Converts a file descriptor to a CloudABI file descriptor type. */ +cloudabi_filetype_t +cloudabi_convert_filetype(const struct file *fp) +{ + struct socket *so; + struct vnode *vp; + + switch (fp->f_type) { + case DTYPE_FIFO: + return (CLOUDABI_FILETYPE_FIFO); + case DTYPE_KQUEUE: + return (CLOUDABI_FILETYPE_POLL); + case DTYPE_PIPE: + return (CLOUDABI_FILETYPE_FIFO); + case DTYPE_PROCDESC: + return (CLOUDABI_FILETYPE_PROCESS); + case DTYPE_SHM: + return (CLOUDABI_FILETYPE_SHARED_MEMORY); + case DTYPE_SOCKET: + so = fp->f_data; + switch (so->so_type) { + case SOCK_DGRAM: + return (CLOUDABI_FILETYPE_SOCKET_DGRAM); + case SOCK_SEQPACKET: + return (CLOUDABI_FILETYPE_SOCKET_SEQPACKET); + case SOCK_STREAM: + return (CLOUDABI_FILETYPE_SOCKET_STREAM); + default: + return (CLOUDABI_FILETYPE_UNKNOWN); + } + case DTYPE_VNODE: + vp = fp->f_vnode; + switch (vp->v_type) { + case VBLK: + return (CLOUDABI_FILETYPE_BLOCK_DEVICE); + case VCHR: + return (CLOUDABI_FILETYPE_CHARACTER_DEVICE); + case VDIR: + return (CLOUDABI_FILETYPE_DIRECTORY); + case VFIFO: + return (CLOUDABI_FILETYPE_FIFO); + case VLNK: + return (CLOUDABI_FILETYPE_SYMBOLIC_LINK); + case VREG: + return (CLOUDABI_FILETYPE_REGULAR_FILE); + case VSOCK: + return (CLOUDABI_FILETYPE_SOCKET_STREAM); + default: + return (CLOUDABI_FILETYPE_UNKNOWN); + } + default: + return (CLOUDABI_FILETYPE_UNKNOWN); + } +} + +/* + * Converts FreeBSD's Capsicum rights to CloudABI's set of rights. + */ +static void +convert_capabilities(const cap_rights_t *capabilities, + cloudabi_filetype_t filetype, cloudabi_rights_t *base, + cloudabi_rights_t *inheriting) +{ + cloudabi_rights_t rights; + + /* Convert FreeBSD bits to CloudABI bits. */ + rights = 0; +#define MAPPING(cloudabi, ...) do { \ + if (cap_rights_is_set(capabilities, ##__VA_ARGS__)) \ + rights |= (cloudabi); \ +} while (0); + RIGHTS_MAPPINGS +#undef MAPPING + + /* + * CloudABI has a small number of additional rights bits to + * disambiguate between multiple purposes. Remove the bits that + * don't apply to the type of the file descriptor. + * + * As file descriptor access modes (O_ACCMODE) has been fully + * replaced by rights bits, CloudABI distinguishes between + * rights that apply to the file descriptor itself (base) versus + * rights of new file descriptors derived from them + * (inheriting). The code below approximates the pair by + * decomposing depending on the file descriptor type. + * + * We need to be somewhat accurate about which actions can + * actually be performed on the file descriptor, as functions + * like fcntl(fd, F_GETFL) are emulated on top of this. + */ + switch (filetype) { + case CLOUDABI_FILETYPE_DIRECTORY: + *base = rights & (CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS | + CLOUDABI_RIGHT_FD_SYNC | CLOUDABI_RIGHT_FILE_ADVISE | + CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY | + CLOUDABI_RIGHT_FILE_CREATE_FILE | + CLOUDABI_RIGHT_FILE_CREATE_FIFO | + CLOUDABI_RIGHT_FILE_LINK_SOURCE | + CLOUDABI_RIGHT_FILE_LINK_TARGET | + CLOUDABI_RIGHT_FILE_OPEN | + CLOUDABI_RIGHT_FILE_READDIR | + CLOUDABI_RIGHT_FILE_READLINK | + CLOUDABI_RIGHT_FILE_RENAME_SOURCE | + CLOUDABI_RIGHT_FILE_RENAME_TARGET | + CLOUDABI_RIGHT_FILE_STAT_FGET | + CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES | + CLOUDABI_RIGHT_FILE_STAT_GET | + CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES | + CLOUDABI_RIGHT_FILE_SYMLINK | + CLOUDABI_RIGHT_FILE_UNLINK | + CLOUDABI_RIGHT_POLL_FD_READWRITE | + CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY | + CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY); + *inheriting = rights; + break; + case CLOUDABI_FILETYPE_FIFO: + *base = rights & ~(CLOUDABI_RIGHT_FILE_ADVISE | + CLOUDABI_RIGHT_FILE_ALLOCATE | + CLOUDABI_RIGHT_FILE_READDIR); + *inheriting = 0; + break; + case CLOUDABI_FILETYPE_POLL: + *base = rights & ~CLOUDABI_RIGHT_FILE_ADVISE; + *inheriting = 0; + break; + case CLOUDABI_FILETYPE_PROCESS: + *base = rights & ~CLOUDABI_RIGHT_FILE_ADVISE; + *inheriting = 0; + break; + case CLOUDABI_FILETYPE_REGULAR_FILE: + *base = rights & ~CLOUDABI_RIGHT_FILE_READDIR; + *inheriting = 0; + break; + case CLOUDABI_FILETYPE_SHARED_MEMORY: + *base = rights & ~(CLOUDABI_RIGHT_FD_SEEK | + CLOUDABI_RIGHT_FD_TELL | + CLOUDABI_RIGHT_FILE_ADVISE | + CLOUDABI_RIGHT_FILE_ALLOCATE | + CLOUDABI_RIGHT_FILE_READDIR); + *inheriting = 0; + break; + case CLOUDABI_FILETYPE_SOCKET_DGRAM: + case CLOUDABI_FILETYPE_SOCKET_SEQPACKET: + case CLOUDABI_FILETYPE_SOCKET_STREAM: + *base = rights & (CLOUDABI_RIGHT_FD_READ | + CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS | + CLOUDABI_RIGHT_FD_WRITE | + CLOUDABI_RIGHT_FILE_STAT_FGET | + CLOUDABI_RIGHT_POLL_FD_READWRITE | + CLOUDABI_RIGHT_SOCK_ACCEPT | + CLOUDABI_RIGHT_SOCK_BIND_SOCKET | + CLOUDABI_RIGHT_SOCK_CONNECT_SOCKET | + CLOUDABI_RIGHT_SOCK_LISTEN | + CLOUDABI_RIGHT_SOCK_SHUTDOWN | + CLOUDABI_RIGHT_SOCK_STAT_GET); + *inheriting = rights; + break; + default: + *base = rights; + *inheriting = 0; + break; + } +} + int cloudabi_sys_fd_stat_get(struct thread *td, struct cloudabi_sys_fd_stat_get_args *uap) { + cloudabi_fdstat_t fsb = {}; + struct filedesc *fdp; + struct file *fp; + seq_t seq; + cap_rights_t rights; + int error, oflags; + bool modified; - /* Not implemented. */ - return (ENOSYS); + /* Obtain file descriptor properties. */ + fdp = td->td_proc->p_fd; + do { + error = fget_unlocked(fdp, uap->fd, cap_rights_init(&rights), + &fp, &seq); + if (error != 0) + return (error); + if (fp->f_ops == &badfileops) { + fdrop(fp, td); + return (EBADF); + } + + rights = *cap_rights(fdp, uap->fd); + oflags = OFLAGS(fp->f_flag); + fsb.fs_filetype = cloudabi_convert_filetype(fp); + + modified = fd_modified(fdp, uap->fd, seq); + fdrop(fp, td); + } while (modified); + + /* Convert file descriptor flags. */ + if (oflags & O_APPEND) + fsb.fs_flags |= CLOUDABI_FDFLAG_APPEND; + if (oflags & O_NONBLOCK) + fsb.fs_flags |= CLOUDABI_FDFLAG_NONBLOCK; + if (oflags & O_SYNC) + fsb.fs_flags |= CLOUDABI_FDFLAG_SYNC; + + /* Convert capabilities to CloudABI rights. */ + convert_capabilities(&rights, fsb.fs_filetype, + &fsb.fs_rights_base, &fsb.fs_rights_inheriting); + return (copyout(&fsb, (void *)uap->buf, sizeof(fsb))); } int diff --git a/sys/compat/cloudabi/cloudabi_file.c b/sys/compat/cloudabi/cloudabi_file.c index b5085173811a..3f917a0d84d8 100644 --- a/sys/compat/cloudabi/cloudabi_file.c +++ b/sys/compat/cloudabi/cloudabi_file.c @@ -27,14 +27,18 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include #include +#include +#include #include #include #include +#include static MALLOC_DEFINE(M_CLOUDABI_PATH, "cloudabipath", "CloudABI pathnames"); @@ -220,13 +224,50 @@ cloudabi_sys_file_rename(struct thread *td, return (error); } +/* Converts a FreeBSD stat structure to a CloudABI stat structure. */ +static void +convert_stat(const struct stat *sb, cloudabi_filestat_t *csb) +{ + cloudabi_filestat_t res = { + .st_dev = sb->st_dev, + .st_ino = sb->st_ino, + .st_nlink = sb->st_nlink, + .st_size = sb->st_size, + }; + + cloudabi_convert_timespec(&sb->st_atim, &res.st_atim); + cloudabi_convert_timespec(&sb->st_mtim, &res.st_mtim); + cloudabi_convert_timespec(&sb->st_ctim, &res.st_ctim); + *csb = res; +} + int cloudabi_sys_file_stat_fget(struct thread *td, struct cloudabi_sys_file_stat_fget_args *uap) { + struct stat sb; + cloudabi_filestat_t csb; + struct file *fp; + cap_rights_t rights; + cloudabi_filetype_t filetype; + int error; - /* Not implemented. */ - return (ENOSYS); + /* Fetch file descriptor attributes. */ + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FSTAT), &fp); + if (error != 0) + return (error); + error = fo_stat(fp, &sb, td->td_ucred, td); + if (error != 0) { + fdrop(fp, td); + return (error); + } + filetype = cloudabi_convert_filetype(fp); + fdrop(fp, td); + + /* Convert attributes to CloudABI's format. */ + convert_stat(&sb, &csb); + csb.st_filetype = filetype; + return (copyout(&csb, uap->buf, sizeof(csb))); } int @@ -242,9 +283,42 @@ int cloudabi_sys_file_stat_get(struct thread *td, struct cloudabi_sys_file_stat_get_args *uap) { + struct stat sb; + cloudabi_filestat_t csb; + char *path; + int error; - /* Not implemented. */ - return (ENOSYS); + error = copyin_path(uap->path, uap->pathlen, &path); + if (error != 0) + return (error); + + error = kern_statat(td, + (uap->fd & CLOUDABI_LOOKUP_SYMLINK_FOLLOW) != 0 ? 0 : + AT_SYMLINK_NOFOLLOW, uap->fd, path, UIO_SYSSPACE, &sb, NULL); + cloudabi_freestr(path); + if (error != 0) + return (error); + + /* Convert results and return them. */ + convert_stat(&sb, &csb); + if (S_ISBLK(sb.st_mode)) + csb.st_filetype = CLOUDABI_FILETYPE_BLOCK_DEVICE; + else if (S_ISCHR(sb.st_mode)) + csb.st_filetype = CLOUDABI_FILETYPE_CHARACTER_DEVICE; + else if (S_ISDIR(sb.st_mode)) + csb.st_filetype = CLOUDABI_FILETYPE_DIRECTORY; + else if (S_ISFIFO(sb.st_mode)) + csb.st_filetype = CLOUDABI_FILETYPE_FIFO; + else if (S_ISREG(sb.st_mode)) + csb.st_filetype = CLOUDABI_FILETYPE_REGULAR_FILE; + else if (S_ISSOCK(sb.st_mode)) { + /* Inaccurate, but the best that we can do. */ + csb.st_filetype = CLOUDABI_FILETYPE_SOCKET_STREAM; + } else if (S_ISLNK(sb.st_mode)) + csb.st_filetype = CLOUDABI_FILETYPE_SYMBOLIC_LINK; + else + csb.st_filetype = CLOUDABI_FILETYPE_UNKNOWN; + return (copyout(&csb, uap->buf, sizeof(csb))); } int diff --git a/sys/compat/cloudabi/cloudabi_util.h b/sys/compat/cloudabi/cloudabi_util.h index 5350d24c082c..557cf1759037 100644 --- a/sys/compat/cloudabi/cloudabi_util.h +++ b/sys/compat/cloudabi/cloudabi_util.h @@ -30,6 +30,7 @@ #include +struct file; struct thread; struct timespec; @@ -40,6 +41,9 @@ int cloudabi_clock_time_get(struct thread *, cloudabi_clockid_t, /* Converts a FreeBSD errno to a CloudABI errno. */ cloudabi_errno_t cloudabi_convert_errno(int); +/* Converts a file descriptor to a CloudABI file descriptor type. */ +cloudabi_filetype_t cloudabi_convert_filetype(const struct file *); + /* Converts a struct timespec to a CloudABI timestamp. */ int cloudabi_convert_timespec(const struct timespec *, cloudabi_timestamp_t *); From 29515a68a5dec8dcfeec9b306fd396330fb0d9c9 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 28 Jul 2015 06:50:47 +0000 Subject: [PATCH 006/314] Implement directory and FIFO creation. The file_create() system call can be used to create files of a given type. Right now it can only be used to create directories and FIFOs. As CloudABI does not expose filesystem permissions, this system call lacks a mode argument. Simply use 0777 or 0666 depending on the file type. --- sys/compat/cloudabi/cloudabi_file.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_file.c b/sys/compat/cloudabi/cloudabi_file.c index 3f917a0d84d8..72902ee20638 100644 --- a/sys/compat/cloudabi/cloudabi_file.c +++ b/sys/compat/cloudabi/cloudabi_file.c @@ -137,9 +137,31 @@ int cloudabi_sys_file_create(struct thread *td, struct cloudabi_sys_file_create_args *uap) { + char *path; + int error; - /* Not implemented. */ - return (ENOSYS); + error = copyin_path(uap->path, uap->pathlen, &path); + if (error != 0) + return (error); + + /* + * CloudABI processes cannot interact with UNIX credentials and + * permissions. Depend on the umask that is set prior to + * execution to restrict the file permissions. + */ + switch (uap->type) { + case CLOUDABI_FILETYPE_DIRECTORY: + error = kern_mkdirat(td, uap->fd, path, UIO_SYSSPACE, 0777); + break; + case CLOUDABI_FILETYPE_FIFO: + error = kern_mkfifoat(td, uap->fd, path, UIO_SYSSPACE, 0666); + break; + default: + error = EINVAL; + break; + } + cloudabi_freestr(path); + return (error); } int From 90a2db45eb84337a6c77f72d1fef7d2129f5812a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 28 Jul 2015 06:55:08 +0000 Subject: [PATCH 007/314] Add bit names for the IA32_MISC_ENABLE msr. Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/x86/include/specialreg.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sys/x86/include/specialreg.h b/sys/x86/include/specialreg.h index 6c849ffea72f..e88a4d7915fb 100644 --- a/sys/x86/include/specialreg.h +++ b/sys/x86/include/specialreg.h @@ -521,6 +521,17 @@ #define IA32_FEATURE_CONTROL_SMX_EN 0x02 /* enable VMX inside SMX */ #define IA32_FEATURE_CONTROL_VMX_EN 0x04 /* enable VMX outside SMX */ +/* MSR IA32_MISC_ENABLE */ +#define IA32_MISC_EN_FASTSTR 0x0000000000000001ULL +#define IA32_MISC_EN_ATCCE 0x0000000000000008ULL +#define IA32_MISC_EN_PERFMON 0x0000000000000080ULL +#define IA32_MISC_EN_PEBSU 0x0000000000001000ULL +#define IA32_MISC_EN_ESSTE 0x0000000000010000ULL +#define IA32_MISC_EN_MONE 0x0000000000040000ULL +#define IA32_MISC_EN_LIMCPUID 0x0000000000400000ULL +#define IA32_MISC_EN_xTPRD 0x0000000000800000ULL +#define IA32_MISC_EN_XDD 0x0000000400000000ULL + /* * PAT modes. */ From b4c0214605ab618c09926b780f3f915afe148f72 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 28 Jul 2015 06:58:10 +0000 Subject: [PATCH 008/314] Remove useless acquire semantic from the atomic_add operation before sosend(). The only release on the xp_snt_cnt is done after sosend(), with an intent to synchronize with load_acq in svc_vc_ack(). Reviewed by: alc Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/rpc/svc_vc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index 1d3d04190a3d..6056345b6eb7 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -860,7 +860,7 @@ svc_vc_reply(SVCXPRT *xprt, struct rpc_msg *msg, len = mrep->m_pkthdr.len; *mtod(mrep, uint32_t *) = htonl(0x80000000 | (len - sizeof(uint32_t))); - atomic_add_acq_32(&xprt->xp_snd_cnt, len); + atomic_add_32(&xprt->xp_snd_cnt, len); error = sosend(xprt->xp_socket, NULL, NULL, mrep, NULL, 0, curthread); if (!error) { From 1d1ec02c44239802aa3fcc176172aa17354b7efd Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 28 Jul 2015 07:04:51 +0000 Subject: [PATCH 009/314] Remove full barrier from the amd64 atomic_load_acq_*(). Strong ordering semantic of x86 CPUs makes only the compiler barrier neccessary to give the acquire behaviour. Existing implementation ensured sequentially consistent semantic for load_acq, making much stronger guarantee than required by standard's definition of the load acquire. Consumers which depend on the barrier are believed to be identified and already fixed to use proper operations. Noted by: alc (long time ago) Reviewed by: alc, bde Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/amd64/include/atomic.h | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h index 016aa70e04b0..30f594c3f7fe 100644 --- a/sys/amd64/include/atomic.h +++ b/sys/amd64/include/atomic.h @@ -269,13 +269,13 @@ atomic_testandset_long(volatile u_long *p, u_int v) * IA32 memory model, a simple store guarantees release semantics. * * However, a load may pass a store if they are performed on distinct - * addresses, so for atomic_load_acq we introduce a Store/Load barrier - * before the load in SMP kernels. We use "lock addl $0,mem", as - * recommended by the AMD Software Optimization Guide, and not mfence. - * In the kernel, we use a private per-cpu cache line as the target - * for the locked addition, to avoid introducing false data - * dependencies. In userspace, a word in the red zone on the stack - * (-8(%rsp)) is utilized. + * addresses, so we need a Store/Load barrier for sequentially + * consistent fences in SMP kernels. We use "lock addl $0,mem" for a + * Store/Load barrier, as recommended by the AMD Software Optimization + * Guide, and not mfence. In the kernel, we use a private per-cpu + * cache line as the target for the locked addition, to avoid + * introducing false data dependencies. In user space, we use a word + * in the stack's red zone (-8(%rsp)). * * For UP kernels, however, the memory of the single processor is * always consistent, so we only need to stop the compiler from @@ -319,22 +319,12 @@ __storeload_barrier(void) } #endif /* _KERNEL*/ -/* - * C11-standard acq/rel semantics only apply when the variable in the - * call is the same for acq as it is for rel. However, our previous - * (x86) implementations provided much stronger ordering than required - * (essentially what is called seq_cst order in C11). This - * implementation provides the historical strong ordering since some - * callers depend on it. - */ - #define ATOMIC_LOAD(TYPE) \ static __inline u_##TYPE \ atomic_load_acq_##TYPE(volatile u_##TYPE *p) \ { \ u_##TYPE res; \ \ - __storeload_barrier(); \ res = *p; \ __compiler_membar(); \ return (res); \ From ed0ed9b4249abcc7b229d2b8ae2e40ea9af19ecc Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Tue, 28 Jul 2015 07:30:07 +0000 Subject: [PATCH 010/314] Optimise the DWC OTG host mode driver's receive path: Remove NAKing limit and pause IN and OUT transactions for 125us in case of NAK response for BULK and CONTROL endpoints. This gets the receive latency down and improves USB network throughput at the cost of some CPU usage. MFC after: 1 month --- sys/dev/usb/controller/dwc_otg.c | 77 ++++++++++++-------------------- sys/dev/usb/controller/dwc_otg.h | 3 +- 2 files changed, 30 insertions(+), 50 deletions(-) diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index 17d792a5db54..51f083bc235d 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -453,8 +453,12 @@ static void dwc_otg_enable_sof_irq(struct dwc_otg_softc *sc) { /* In device mode we don't use the SOF interrupt */ - if (sc->sc_flags.status_device_mode != 0 || - (sc->sc_irq_mask & GINTMSK_SOFMSK) != 0) + if (sc->sc_flags.status_device_mode != 0) + return; + /* Ensure the SOF interrupt is not disabled */ + sc->sc_needsof = 1; + /* Check if the SOF interrupt is already enabled */ + if ((sc->sc_irq_mask & GINTMSK_SOFMSK) != 0) return; sc->sc_irq_mask |= GINTMSK_SOFMSK; DWC_OTG_WRITE_4(sc, DOTG_GINTMSK, sc->sc_irq_mask); @@ -775,7 +779,7 @@ dwc_otg_host_setup_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) case DWC_CHAN_ST_WAIT_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak++; + td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & (HCINT_ACK | HCINT_NYET)) { @@ -789,7 +793,7 @@ dwc_otg_host_setup_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) case DWC_CHAN_ST_WAIT_S_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak++; + td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & (HCINT_ACK | HCINT_NYET)) { @@ -801,7 +805,7 @@ dwc_otg_host_setup_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) if (hcint & HCINT_NYET) { goto send_cpkt; } else if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak++; + td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & HCINT_ACK) { @@ -1069,8 +1073,17 @@ dwc_otg_host_rate_check(struct dwc_otg_softc *sc, struct dwc_otg_td *td) if (!td->tt_scheduled) goto busy; td->tt_scheduled = 0; - } else if (td->did_nak >= DWC_OTG_NAK_MAX) { - goto busy; + } else if (td->did_nak != 0) { + uint8_t frame_num = (uint8_t)sc->sc_last_frame_num; + /* check if we should pause sending queries for 125us */ + if (td->tmr_res == frame_num) { + /* wait a bit */ + dwc_otg_enable_sof_irq(sc); + goto busy; + } + /* query for data one more time */ + td->tmr_res = frame_num; + td->did_nak = 0; } else if (td->set_toggle) { td->set_toggle = 0; td->toggle = 1; @@ -1257,7 +1270,7 @@ dwc_otg_host_data_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) goto receive_pkt; } } - td->did_nak++; + td->did_nak = 1; td->tt_scheduled = 0; if (td->hcsplt != 0) goto receive_spkt; @@ -1312,7 +1325,7 @@ dwc_otg_host_data_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) * case of interrupt and isochronous transfers: */ if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak++; + td->did_nak = 1; td->tt_scheduled = 0; goto receive_spkt; } else if (hcint & HCINT_NYET) { @@ -1638,7 +1651,7 @@ dwc_otg_host_data_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) case DWC_CHAN_ST_WAIT_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak++; + td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & (HCINT_ACK | HCINT_NYET)) { @@ -1664,7 +1677,7 @@ dwc_otg_host_data_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) case DWC_CHAN_ST_WAIT_S_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak++; + td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & (HCINT_ACK | HCINT_NYET)) { @@ -1677,7 +1690,7 @@ dwc_otg_host_data_tx(struct dwc_otg_softc *sc, struct dwc_otg_td *td) if (hcint & HCINT_NYET) { goto send_cpkt; } else if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak++; + td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & HCINT_ACK) { @@ -2280,8 +2293,6 @@ static void dwc_otg_timer(void *_sc) { struct dwc_otg_softc *sc = _sc; - struct usb_xfer *xfer; - struct dwc_otg_td *td; USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); @@ -2292,14 +2303,6 @@ dwc_otg_timer(void *_sc) /* increment timer value */ sc->sc_tmr_val++; - TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { - td = xfer->td_transfer_cache; - if (td != NULL) { - /* reset NAK counter */ - td->did_nak = 0; - } - } - /* enable SOF interrupt, which will poll jobs */ dwc_otg_enable_sof_irq(sc); @@ -2459,8 +2462,7 @@ dwc_otg_update_host_transfer_schedule_locked(struct dwc_otg_softc *sc) TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { td = xfer->td_transfer_cache; if (td == NULL || - td->ep_type != UE_CONTROL || - td->did_nak >= DWC_OTG_NAK_MAX) { + td->ep_type != UE_CONTROL) { continue; } @@ -2480,8 +2482,7 @@ dwc_otg_update_host_transfer_schedule_locked(struct dwc_otg_softc *sc) TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { td = xfer->td_transfer_cache; if (td == NULL || - td->ep_type != UE_BULK || - td->did_nak >= DWC_OTG_NAK_MAX) { + td->ep_type != UE_BULK) { continue; } @@ -3244,7 +3245,7 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) td->tmr_res = 1; } else { td->tmr_val = 0; - td->tmr_res = 0; + td->tmr_res = (uint8_t)sc->sc_last_frame_num; } break; case USB_SPEED_HIGH: @@ -3269,7 +3270,7 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) td->tmr_res = 1 << usbd_xfer_get_fps_shift(xfer); } else { td->tmr_val = 0; - td->tmr_res = 0; + td->tmr_res = (uint8_t)sc->sc_last_frame_num; } break; default: @@ -3309,8 +3310,6 @@ static void dwc_otg_start_standard_chain(struct usb_xfer *xfer) { struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(xfer->xroot->bus); - struct usb_xfer_root *xroot; - struct dwc_otg_td *td; DPRINTFN(9, "\n"); @@ -3341,24 +3340,6 @@ dwc_otg_start_standard_chain(struct usb_xfer *xfer) /* enable SOF interrupt, if any */ dwc_otg_enable_sof_irq(sc); - - td = xfer->td_transfer_cache; - if (td->ep_type != UE_BULK) - goto done; - - xroot = xfer->xroot; - - /* - * Optimise the ping-pong effect by waking up other BULK - * transfers belonging to the same device group: - */ - TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { - td = xfer->td_transfer_cache; - if (td == NULL || td->ep_type != UE_BULK || xfer->xroot != xroot) - continue; - /* reset NAK counter */ - td->did_nak = 0; - } done: USB_BUS_SPIN_UNLOCK(&sc->sc_bus); } diff --git a/sys/dev/usb/controller/dwc_otg.h b/sys/dev/usb/controller/dwc_otg.h index 1ba0a5e4ce7e..39c9529757c7 100644 --- a/sys/dev/usb/controller/dwc_otg.h +++ b/sys/dev/usb/controller/dwc_otg.h @@ -37,7 +37,6 @@ #define DWC_OTG_TT_SLOT_MAX 8 #define DWC_OTG_SLOT_IDLE_MAX 3 #define DWC_OTG_SLOT_IDLE_MIN 2 -#define DWC_OTG_NAK_MAX 16 /* 16 NAKs = 2 ms */ #ifndef DWC_OTG_TX_MAX_FIFO_SIZE #define DWC_OTG_TX_MAX_FIFO_SIZE DWC_OTG_MAX_TXN #endif @@ -68,7 +67,6 @@ struct dwc_otg_td { uint8_t errcnt; uint8_t tmr_res; uint8_t tmr_val; - uint8_t did_nak; /* NAK counter */ uint8_t ep_no; uint8_t ep_type; uint8_t channel; @@ -93,6 +91,7 @@ struct dwc_otg_td { uint8_t set_toggle:1; uint8_t got_short:1; uint8_t tt_scheduled:1; + uint8_t did_nak:1; }; struct dwc_otg_tt_info { From 9ae56375afc7ab115255a20c899838e30d519a89 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Tue, 28 Jul 2015 08:50:13 +0000 Subject: [PATCH 011/314] Fix a typo reported by Erik Cederstrand. MFC after: 1 week --- sys/netinet/sctp_indata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 6b2efc94163b..a5eb3c6941df 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -2490,7 +2490,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, struct mbuf *op_err; char msg[SCTP_DIAG_INFO_LEN]; - snprintf(msg, sizeof(msg), "DATA chunk followwd by chunk of type %2.2x", + snprintf(msg, sizeof(msg), "DATA chunk followed by chunk of type %2.2x", ch->ch.chunk_type); op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); sctp_abort_association(inp, stcb, From 3e437fd2c6ec2564c4e287cc1d81bfdebe199bce Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 28 Jul 2015 09:36:26 +0000 Subject: [PATCH 012/314] Fix a typo in r280169. Of course we are interested in deleting nsn only if we have just created it and we were the last reference. Submitted by: dhartmei --- sys/netpfil/pf/pf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 81d010fb17fd..122f02669f5c 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -3681,7 +3681,7 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, sh = &V_pf_srchash[pf_hashsrc(&nsn->addr, nsn->af)]; PF_HASHROW_LOCK(sh); - if (--nsn->states == 1 && nsn->expire == 0) { + if (--nsn->states == 0 && nsn->expire == 0) { pf_unlink_src_node(nsn); uma_zfree(V_pf_sources_z, nsn); counter_u64_add( From b1b98a2db7bbeb69e3299e953e63bea759db0ef0 Mon Sep 17 00:00:00 2001 From: Renato Botelho Date: Tue, 28 Jul 2015 10:31:34 +0000 Subject: [PATCH 013/314] Respect pf rule log option before log dropped packets with IP options or dangerous v6 headers Reviewed by: gnn, eri Approved by: gnn Obtained from: pfSense MFC after: 3 days Sponsored by: Netgate Differential Revision: https://reviews.freebsd.org/D3222 --- sys/netpfil/pf/pf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 122f02669f5c..49781a827f19 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -5895,7 +5895,8 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) { action = PF_DROP; REASON_SET(&reason, PFRES_IPOPTIONS); - log = 1; + if (r->log) + log = 1; DPFPRINTF(PF_DEBUG_MISC, ("pf: dropping packet with ip options\n")); } @@ -6329,7 +6330,8 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) { action = PF_DROP; REASON_SET(&reason, PFRES_IPOPTIONS); - log = 1; + if (r->log) + log = 1; DPFPRINTF(PF_DEBUG_MISC, ("pf: dropping packet with dangerous v6 headers\n")); } From 1635369e99fa2062b7832eb7df2419261aa85e0e Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Tue, 28 Jul 2015 11:19:38 +0000 Subject: [PATCH 014/314] Add warning about low KSTACK_PAGES for ZFS use As ZFS requires a more kernel stack pages than is the default on some architectures e.g. i386, warn if KSTACK_PAGES is less than ZFS_MIN_KSTACK_PAGES (which is 4 at the time of writing). MFC after: 3 days Sponsored by: Multiplay --- UPDATING | 8 ++++++++ .../contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/UPDATING b/UPDATING index 5756d78ef8f5..c4eeb1584de9 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20150728: + As ZFS requires a more kernel stack pages than is the default on some + architectures e.g. i386, it now warns if KSTACK_PAGES is less than + ZFS_MIN_KSTACK_PAGES (which is 4 at the time of writing). + + Please consider using 'options KSTACK_PAGES=X' where X is greater + than or equal to ZFS_MIN_KSTACK_PAGES i.e. 4 in such configurations. + 20150706: sendmail has been updated to 8.15.2. Starting with FreeBSD 11.0 and sendmail 8.15, sendmail uses uncompressed IPv6 addresses by diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index e3b6581c862d..432c2fb2e5f5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -6491,10 +6491,18 @@ static void zfs_shutdown(void *, int); static eventhandler_tag zfs_shutdown_event_tag; +#define ZFS_MIN_KSTACK_PAGES 4 + int zfs__init(void) { +#if KSTACK_PAGES < ZFS_MIN_KSTACK_PAGES + printf("ZFS NOTICE: KSTACK_PAGES is %d which could result in stack " + "overflow panic!\nPlease consider adding " + "'options KSTACK_PAGES=%d' to your kernel config\n", KSTACK_PAGES, + ZFS_MIN_KSTACK_PAGES); +#endif zfs_root_token = root_mount_hold("ZFS"); mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL); From 68d5f492def1f8729447093647c011c68cd2f261 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Tue, 28 Jul 2015 11:21:33 +0000 Subject: [PATCH 015/314] Correct typo in UPDATING message MFC after: 3 days Sponsored by: Multiplay --- UPDATING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPDATING b/UPDATING index c4eeb1584de9..ce3b74a354a6 100644 --- a/UPDATING +++ b/UPDATING @@ -32,7 +32,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: "ln -s 'abort:false,junk:false' /etc/malloc.conf".) 20150728: - As ZFS requires a more kernel stack pages than is the default on some + As ZFS requires more kernel stack pages than is the default on some architectures e.g. i386, it now warns if KSTACK_PAGES is less than ZFS_MIN_KSTACK_PAGES (which is 4 at the time of writing). From 87bf5e9212a3444030188424c539908272db1173 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Tue, 28 Jul 2015 12:20:57 +0000 Subject: [PATCH 016/314] when -n is passed to any pw subcommand it is always expected to be considered as a name so do not try to convert it to an id if it is a numeric value PR: 31933 Reported by: ted@impulse.net Sponsored by: gandi.net --- usr.sbin/pw/pw.c | 9 +-------- usr.sbin/pw/tests/pw_userdel.sh | 10 ++++++++++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index 5ad2511aeb10..3db427afe44b 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -287,14 +287,7 @@ main(int argc, char *argv[]) errstr); break; case 'n': - if (strspn(optarg, "0123456789") != strlen(optarg)) { - name = optarg; - break; - } - id = strtonum(optarg, 0, LONG_MAX, &errstr); - if (errstr != NULL) - errx(EX_USAGE, "Bad id '%s': %s", optarg, - errstr); + name = optarg; break; case 'H': if (conf.fd != -1) diff --git a/usr.sbin/pw/tests/pw_userdel.sh b/usr.sbin/pw/tests/pw_userdel.sh index 5ba87c258dea..1305cb74f847 100755 --- a/usr.sbin/pw/tests/pw_userdel.sh +++ b/usr.sbin/pw/tests/pw_userdel.sh @@ -50,8 +50,18 @@ delete_files_body() { fi } +atf_test_case delete_numeric_name +delete_numeric_name_body() { + populate_etc_skel + + atf_check ${PW} useradd -n foo -u 4001 + atf_check -e inline:"pw: no such user \`4001'\n" -s exit:67 \ + ${PW} userdel -n 4001 +} + atf_init_test_cases() { atf_add_test_case rmuser_seperate_group atf_add_test_case user_do_not_try_to_delete_root_if_user_unknown atf_add_test_case delete_files + atf_add_test_case delete_numeric_name } From 1d96fd8d9f96fbd472f8115f626c82ed8bcc5947 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 28 Jul 2015 12:57:19 +0000 Subject: [PATCH 017/314] Implement file attribute modification system calls for CloudABI. CloudABI uses a system call interface to modify file attributes that is more similar to KPI's/FUSE, namely where a stat structure is passed back to the kernel, together with a bitmask of attributes that should be changed. This would allow us to update any set of attributes atomically. That said, I'd rather not go as far as to actually implement it that way, as it would require us to duplicate more code than strictly needed. Let's just stick to the combinations that are actually used by cloudlibc. Obtained from: https://github.com/NuxiNL/freebsd --- sys/compat/cloudabi/cloudabi_file.c | 83 +++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_file.c b/sys/compat/cloudabi/cloudabi_file.c index 72902ee20638..45f658367485 100644 --- a/sys/compat/cloudabi/cloudabi_file.c +++ b/sys/compat/cloudabi/cloudabi_file.c @@ -292,13 +292,64 @@ cloudabi_sys_file_stat_fget(struct thread *td, return (copyout(&csb, uap->buf, sizeof(csb))); } +/* Converts timestamps to arguments to futimens() and utimensat(). */ +static void +convert_utimens_arguments(const cloudabi_filestat_t *fs, + cloudabi_fsflags_t flags, struct timespec *ts) +{ + + if ((flags & CLOUDABI_FILESTAT_ATIM_NOW) != 0) { + ts[0].tv_nsec = UTIME_NOW; + } else if ((flags & CLOUDABI_FILESTAT_ATIM) != 0) { + ts[0].tv_sec = fs->st_atim / 1000000000; + ts[0].tv_nsec = fs->st_atim % 1000000000; + } else { + ts[0].tv_nsec = UTIME_OMIT; + } + + if ((flags & CLOUDABI_FILESTAT_MTIM_NOW) != 0) { + ts[1].tv_nsec = UTIME_NOW; + } else if ((flags & CLOUDABI_FILESTAT_MTIM) != 0) { + ts[1].tv_sec = fs->st_mtim / 1000000000; + ts[1].tv_nsec = fs->st_mtim % 1000000000; + } else { + ts[1].tv_nsec = UTIME_OMIT; + } +} + int cloudabi_sys_file_stat_fput(struct thread *td, struct cloudabi_sys_file_stat_fput_args *uap) { + cloudabi_filestat_t fs; + struct timespec ts[2]; + int error; - /* Not implemented. */ - return (ENOSYS); + error = copyin(uap->buf, &fs, sizeof(fs)); + if (error != 0) + return (error); + + /* + * Only support truncation and timestamp modification separately + * for now, to prevent unnecessary code duplication. + */ + if ((uap->flags & CLOUDABI_FILESTAT_SIZE) != 0) { + /* Call into kern_ftruncate() for file truncation. */ + if ((uap->flags & ~CLOUDABI_FILESTAT_SIZE) != 0) + return (EINVAL); + return (kern_ftruncate(td, uap->fd, fs.st_size)); + } else if ((uap->flags & (CLOUDABI_FILESTAT_ATIM | + CLOUDABI_FILESTAT_ATIM_NOW | CLOUDABI_FILESTAT_MTIM | + CLOUDABI_FILESTAT_MTIM_NOW)) != 0) { + /* Call into kern_futimens() for timestamp modification. */ + if ((uap->flags & ~(CLOUDABI_FILESTAT_ATIM | + CLOUDABI_FILESTAT_ATIM_NOW | CLOUDABI_FILESTAT_MTIM | + CLOUDABI_FILESTAT_MTIM_NOW)) != 0) + return (EINVAL); + convert_utimens_arguments(&fs, uap->flags, ts); + return (kern_futimens(td, uap->fd, ts, UIO_SYSSPACE)); + } + return (EINVAL); } int @@ -347,9 +398,33 @@ int cloudabi_sys_file_stat_put(struct thread *td, struct cloudabi_sys_file_stat_put_args *uap) { + cloudabi_filestat_t fs; + struct timespec ts[2]; + char *path; + int error; - /* Not implemented. */ - return (ENOSYS); + /* + * Only support timestamp modification for now, as there is no + * truncateat(). + */ + if ((uap->flags & ~(CLOUDABI_FILESTAT_ATIM | + CLOUDABI_FILESTAT_ATIM_NOW | CLOUDABI_FILESTAT_MTIM | + CLOUDABI_FILESTAT_MTIM_NOW)) != 0) + return (EINVAL); + + error = copyin(uap->buf, &fs, sizeof(fs)); + if (error != 0) + return (error); + error = copyin_path(uap->path, uap->pathlen, &path); + if (error != 0) + return (error); + + convert_utimens_arguments(&fs, uap->flags, ts); + error = kern_utimensat(td, uap->fd, path, UIO_SYSSPACE, ts, + UIO_SYSSPACE, (uap->fd & CLOUDABI_LOOKUP_SYMLINK_FOLLOW) != 0 ? + 0 : AT_SYMLINK_NOFOLLOW); + cloudabi_freestr(path); + return (error); } int From 93d8f98ac7ea0275bd3341dd4d43140bf3c54d68 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 28 Jul 2015 13:09:16 +0000 Subject: [PATCH 018/314] Remove claim that the OS is Darwin from lldb(1) Reported by: bapt --- contrib/llvm/tools/lldb/docs/lldb.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/llvm/tools/lldb/docs/lldb.1 b/contrib/llvm/tools/lldb/docs/lldb.1 index 0d94dcbe6a78..57b0931385fe 100644 --- a/contrib/llvm/tools/lldb/docs/lldb.1 +++ b/contrib/llvm/tools/lldb/docs/lldb.1 @@ -1,6 +1,6 @@ .Dd June 7, 2012 \" DATE .Dt LLDB 1 \" Program name and manual section number -.Os Darwin \" Operating System +.Os .Sh NAME \" Section Header - required - don't modify .Nm lldb .Nd The debugger From 8b21d6ae5a8a943660ec0ec9167ff9dab7b3736c Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Tue, 28 Jul 2015 13:16:08 +0000 Subject: [PATCH 019/314] Limit ofw_cpu_early_foreach() to CPUs only On some platforms, the /cpus node contains cpu-to-cluster map which deffinitely is not a CPU node. Its presence was causing incrementing of "id" variable and reporting more CPUs available than it should. To make "id" valid, increment it only when an entry really is a CPU device. Reviewed by: andrew Obtained from: Semihalf Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3216 --- sys/dev/ofw/ofw_cpu.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/sys/dev/ofw/ofw_cpu.c b/sys/dev/ofw/ofw_cpu.c index 59e49eea6485..4b89b53b9966 100644 --- a/sys/dev/ofw/ofw_cpu.c +++ b/sys/dev/ofw/ofw_cpu.c @@ -281,11 +281,13 @@ ofw_cpu_early_foreach(ofw_cpu_foreach_cb callback, boolean_t only_runnable) phandle_t node, child; pcell_t addr_cells, reg[2]; char status[16]; - u_int id; + char device_type[16]; + u_int id, next_id; int count, rv; count = 0; id = 0; + next_id = 0; node = OF_finddevice("/cpus"); if (node == -1) @@ -296,7 +298,21 @@ ofw_cpu_early_foreach(ofw_cpu_foreach_cb callback, boolean_t only_runnable) sizeof(addr_cells)) < 0) return (-1); - for (child = OF_child(node); child != 0; child = OF_peer(child), id++) { + for (child = OF_child(node); child != 0; child = OF_peer(child), + id = next_id) { + + /* Check if child is a CPU */ + memset(device_type, 0, sizeof(device_type)); + rv = OF_getprop(child, "device_type", device_type, + sizeof(device_type) - 1); + if (rv < 0) + continue; + if (strcmp(device_type, "cpu") != 0) + continue; + + /* We're processing CPU, update next_id used in the next iteration */ + next_id++; + /* * If we are filtering by runnable then limit to only * those that have been enabled. From 3b82eb20f541229a2ab4641f8296c4bd7f803272 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 28 Jul 2015 13:48:19 +0000 Subject: [PATCH 020/314] Fix the r272906 description. --- release/doc/en_US.ISO8859-1/relnotes/article.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.xml b/release/doc/en_US.ISO8859-1/relnotes/article.xml index f00a2686fc07..3e2a6f3cdae7 100644 --- a/release/doc/en_US.ISO8859-1/relnotes/article.xml +++ b/release/doc/en_US.ISO8859-1/relnotes/article.xml @@ -1049,7 +1049,7 @@ The &man.alc.4; driver has been updated to support AR816x and AR817x ethernet controllers. - The &man.pfil.9; interface default hash + The &man.pf.4; packet filter default hash has been changed from Jenkins to Murmur3, providing a 3-percent performance increase in packets-per-second. From 299c819a75b9494ed8ab5a5a64f3d85db568d7e7 Mon Sep 17 00:00:00 2001 From: Renato Botelho Date: Tue, 28 Jul 2015 14:59:29 +0000 Subject: [PATCH 021/314] Simplify logic added in r285945 as suggested by glebius Approved by: glebius MFC after: 3 days Sponsored by: Netgate --- sys/netpfil/pf/pf.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 49781a827f19..fba04328237e 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -5895,8 +5895,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) { action = PF_DROP; REASON_SET(&reason, PFRES_IPOPTIONS); - if (r->log) - log = 1; + log = r->log; DPFPRINTF(PF_DEBUG_MISC, ("pf: dropping packet with ip options\n")); } @@ -6330,8 +6329,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) { action = PF_DROP; REASON_SET(&reason, PFRES_IPOPTIONS); - if (r->log) - log = 1; + log = r->log; DPFPRINTF(PF_DEBUG_MISC, ("pf: dropping packet with dangerous v6 headers\n")); } From 34f1f5d95ee3aec85eb7e154d76a5c8aaf40beaa Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Tue, 28 Jul 2015 17:20:35 +0000 Subject: [PATCH 022/314] Apply upstream changeset fa9e61: Fix --one-file-system to include the directory encountered rather than excluding it. --- libarchive/archive_read_disk_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c index a13dbbf812cf..1787d864ca92 100644 --- a/libarchive/archive_read_disk_posix.c +++ b/libarchive/archive_read_disk_posix.c @@ -974,7 +974,7 @@ next_entry(struct archive_read_disk *a, struct tree *t, t->initial_filesystem_id = t->current_filesystem_id; if (!a->traverse_mount_points) { if (t->initial_filesystem_id != t->current_filesystem_id) - return (ARCHIVE_RETRY); + descend = 0; } t->descend = descend; From 25d3ca0980e03d32bf4c9f9f053158a23456fdf6 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Tue, 28 Jul 2015 17:48:34 +0000 Subject: [PATCH 023/314] Apply upstream changeset bf4f6ec64e: Fix issue 356: properly skip a sparse file entry in a tar file. --- Makefile.am | 2 + libarchive/archive_read_support_format_tar.c | 16 ++- libarchive/test/CMakeLists.txt | 1 + .../test_read_format_gtar_sparse_skip_entry.c | 119 ++++++++++++++++++ ...ead_format_gtar_sparse_skip_entry.tar.Z.uu | 15 +++ 5 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 libarchive/test/test_read_format_gtar_sparse_skip_entry.c create mode 100644 libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu diff --git a/Makefile.am b/Makefile.am index 3fa2d22b6de6..9e22a9b34ade 100644 --- a/Makefile.am +++ b/Makefile.am @@ -395,6 +395,7 @@ libarchive_test_SOURCES= \ libarchive/test/test_read_format_gtar_gz.c \ libarchive/test/test_read_format_gtar_lzma.c \ libarchive/test/test_read_format_gtar_sparse.c \ + libarchive/test/test_read_format_gtar_sparse_skip_entry.c \ libarchive/test/test_read_format_iso_Z.c \ libarchive/test/test_read_format_iso_multi_extent.c \ libarchive/test/test_read_format_iso_xorriso.c \ @@ -622,6 +623,7 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/test_read_format_gtar_sparse_1_17_posix01.tar.uu \ libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tar.uu \ libarchive/test/test_read_format_gtar_sparse_1_17_posix10_modified.tar.uu \ + libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu \ libarchive/test/test_read_format_iso.iso.Z.uu \ libarchive/test/test_read_format_iso_2.iso.Z.uu \ libarchive/test/test_read_format_iso_joliet.iso.Z.uu \ diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c index e9523cb687c8..c6f405da6e3f 100644 --- a/libarchive/archive_read_support_format_tar.c +++ b/libarchive/archive_read_support_format_tar.c @@ -585,13 +585,23 @@ static int archive_read_format_tar_skip(struct archive_read *a) { int64_t bytes_skipped; + int64_t request; + struct sparse_block *p; struct tar* tar; tar = (struct tar *)(a->format->data); - bytes_skipped = __archive_read_consume(a, - tar->entry_bytes_remaining + tar->entry_padding + - tar->entry_bytes_unconsumed); + /* Do not consume the hole of a sparse file. */ + request = 0; + for (p = tar->sparse_list; p != NULL; p = p->next) { + if (!p->hole) + request += p->remaining; + } + if (request > tar->entry_bytes_remaining) + request = tar->entry_bytes_remaining; + request += tar->entry_padding + tar->entry_bytes_unconsumed; + + bytes_skipped = __archive_read_consume(a, request); if (bytes_skipped < 0) return (ARCHIVE_FATAL); diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt index d2eb2c2f39ef..ff73c770b554 100644 --- a/libarchive/test/CMakeLists.txt +++ b/libarchive/test/CMakeLists.txt @@ -110,6 +110,7 @@ IF(ENABLE_TEST) test_read_format_gtar_gz.c test_read_format_gtar_lzma.c test_read_format_gtar_sparse.c + test_read_format_gtar_sparse_skip_entry.c test_read_format_iso_Z.c test_read_format_iso_multi_extent.c test_read_format_iso_xorriso.c diff --git a/libarchive/test/test_read_format_gtar_sparse_skip_entry.c b/libarchive/test/test_read_format_gtar_sparse_skip_entry.c new file mode 100644 index 000000000000..813315b71fd7 --- /dev/null +++ b/libarchive/test/test_read_format_gtar_sparse_skip_entry.c @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 2014 Michihiro NAKAJIMA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 "test.h" +__FBSDID("$FreeBSD"); + +/* + * To test skip a sparse file entry, this test does not read file data. + */ +DEFINE_TEST(test_read_format_gtar_sparse_skip_entry) +{ + const char *refname = "test_read_format_gtar_sparse_skip_entry.tar.Z.uu"; + struct archive *a; + struct archive_entry *ae; + const void *p; + size_t s; + int64_t o; + + copy_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Verify regular first file. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("a", archive_entry_pathname(ae)); + assertEqualInt(10737418244, archive_entry_size(ae)); + assertEqualInt(archive_entry_is_encrypted(ae), 0); + assertEqualIntA(a, archive_read_has_encrypted_entries(a), + ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); + + /* Verify regular second file. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("b", archive_entry_pathname(ae)); + assertEqualInt(4, archive_entry_size(ae)); + assertEqualInt(archive_entry_is_encrypted(ae), 0); + assertEqualIntA(a, archive_read_has_encrypted_entries(a), + ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); + + + /* End of archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); + assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, + archive_format(a)); + + /* Close the archive. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + + + /* + * Read just one block of a sparse file and skip it. + */ + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Verify regular first file. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("a", archive_entry_pathname(ae)); + assertEqualInt(10737418244, archive_entry_size(ae)); + assertEqualInt(archive_entry_is_encrypted(ae), 0); + assertEqualIntA(a, archive_read_has_encrypted_entries(a), + ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); + assertEqualInt(0, archive_read_data_block(a, &p, &s, &o)); + assertEqualInt(4096, s); + assertEqualInt(0, o); + + + /* Verify regular second file. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("b", archive_entry_pathname(ae)); + assertEqualInt(4, archive_entry_size(ae)); + assertEqualInt(archive_entry_is_encrypted(ae), 0); + assertEqualIntA(a, archive_read_has_encrypted_entries(a), + ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); + + + /* End of archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); + assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, + archive_format(a)); + + /* Close the archive. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + diff --git a/libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu b/libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu new file mode 100644 index 000000000000..dc0daae9e1e2 --- /dev/null +++ b/libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu @@ -0,0 +1,15 @@ +begin 644 - +M'YV04,+@05(F#)DRBD:;,V!@T8-6)NE&'#10T<-#;>R(%CAEV28_3R9?LW\(P8-F[`<#%C +M)@T<->#6>`PBC.2^E07;J#'#Q>J-F5DJ<`GBB),J+N;`<3JGC(LV8=2\D<-V +M]DO;N'7S]MTFC9OA/6#,CE'[=N[=$V +M9]RY=212"9YD1EOO*&`DE!&*>645%9IY9589JGE +MEEQVZ>678(8IYIADEFGFF6BFJ>::;+;IYIMPQBGGG'36:>>=>.:IYYY\]NGG +MGX`&*NB@A!9JJ)YB](D@1PZ>U&B#*468484RT11###7<8!8(&-)4PX=^DN@4 +B5%*E6.J*746JTHN'2LFDDZW&*NNLM-9JZZVXYJKKKKR&!0`` +` +end From ab97207add168c4c49af857447682101524f9deb Mon Sep 17 00:00:00 2001 From: David C Somayajulu Date: Tue, 28 Jul 2015 19:15:44 +0000 Subject: [PATCH 024/314] - Avoid lock contention in the if_transmit callback by using trylock and enqueueing the frames when it fails. This way there is some latency removed from the transmitting path. - If IFF_DRV_OACTIVE is set (and also if IFF_DRV_RUNNING is not) just enqueue the desired frames and return successful transmit. This way we avoid to return errors on transmit side and resulting in possible out-of-order frames. Please note that IFF_DRV_OACTIVE is set everytime we get the threshold ring hit, so this can be happening quite often. Submitted by: Attilio.Rao@isilon.com MFC after:5 days --- sys/dev/bxe/bxe.c | 36 ++++++++++++++---------------------- sys/dev/bxe/bxe.h | 1 + 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c index f3e59640fb84..274cc5b4ca3e 100644 --- a/sys/dev/bxe/bxe.c +++ b/sys/dev/bxe/bxe.c @@ -5999,19 +5999,26 @@ bxe_tx_mq_start_locked(struct bxe_softc *sc, rc = tx_count = 0; + BXE_FP_TX_LOCK_ASSERT(fp); + if (!tx_br) { BLOGE(sc, "Multiqueue TX and no buf_ring!\n"); return (EINVAL); } + if (!sc->link_vars.link_up || + (ifp->if_drv_flags & + (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) { + rc = drbr_enqueue_drv(ifp, tx_br, m); + goto bxe_tx_mq_start_locked_exit; + } + /* fetch the depth of the driver queue */ depth = drbr_inuse_drv(ifp, tx_br); if (depth > fp->eth_q_stats.tx_max_drbr_queue_depth) { fp->eth_q_stats.tx_max_drbr_queue_depth = depth; } - BXE_FP_TX_LOCK_ASSERT(fp); - if (m == NULL) { /* no new work, check for pending frames */ next = drbr_dequeue_drv(ifp, tx_br); @@ -6103,26 +6110,11 @@ bxe_tx_mq_start(struct ifnet *ifp, fp = &sc->fp[fp_index]; - if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) { - BLOGW(sc, "Interface not running, ignoring transmit request\n"); - return (ENETDOWN); - } - - if (if_getdrvflags(ifp) & IFF_DRV_OACTIVE) { - BLOGW(sc, "Interface TX queue is full, ignoring transmit request\n"); - return (EBUSY); - } - - if (!sc->link_vars.link_up) { - BLOGW(sc, "Interface link is down, ignoring transmit request\n"); - return (ENETDOWN); - } - - /* XXX change to TRYLOCK here and if failed then schedule taskqueue */ - - BXE_FP_TX_LOCK(fp); - rc = bxe_tx_mq_start_locked(sc, ifp, fp, m); - BXE_FP_TX_UNLOCK(fp); + if (BXE_FP_TX_TRYLOCK(fp)) { + rc = bxe_tx_mq_start_locked(sc, ifp, fp, m); + BXE_FP_TX_UNLOCK(fp); + } else + rc = drbr_enqueue_drv(ifp, fp->tx_br, m); return (rc); } diff --git a/sys/dev/bxe/bxe.h b/sys/dev/bxe/bxe.h index 5fb31a32ba87..980a91fc759c 100644 --- a/sys/dev/bxe/bxe.h +++ b/sys/dev/bxe/bxe.h @@ -582,6 +582,7 @@ struct bxe_fastpath { #define BXE_FP_TX_LOCK(fp) mtx_lock(&fp->tx_mtx) #define BXE_FP_TX_UNLOCK(fp) mtx_unlock(&fp->tx_mtx) #define BXE_FP_TX_LOCK_ASSERT(fp) mtx_assert(&fp->tx_mtx, MA_OWNED) +#define BXE_FP_TX_TRYLOCK(fp) mtx_trylock(&fp->tx_mtx) #define BXE_FP_RX_LOCK(fp) mtx_lock(&fp->rx_mtx) #define BXE_FP_RX_UNLOCK(fp) mtx_unlock(&fp->rx_mtx) From 1e3e581593b6484569a2e6570329db4e2306f6cf Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 28 Jul 2015 19:58:36 +0000 Subject: [PATCH 025/314] Fix shell injection vulnerability in patch(1) and drop SCCS support by replacing system() with execve(). Future revisions may remove the functionality completely. Obtained from: Bitrig Security: CVE-2015-1416 --- usr.bin/patch/common.h | 6 +-- usr.bin/patch/inp.c | 100 ++++++++++++++++++++++++++--------------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/usr.bin/patch/common.h b/usr.bin/patch/common.h index 8963c8343a10..f33abcfd79e2 100644 --- a/usr.bin/patch/common.h +++ b/usr.bin/patch/common.h @@ -43,12 +43,10 @@ #define LINENUM_MAX LONG_MAX #define SCCSPREFIX "s." -#define GET "get -e %s" -#define SCCSDIFF "get -p %s | diff - %s >/dev/null" #define RCSSUFFIX ",v" -#define CHECKOUT "co -l %s" -#define RCSDIFF "rcsdiff %s > /dev/null" +#define CHECKOUT "/usr/bin/co" +#define RCSDIFF "/usr/bin/rcsdiff" #define ORIGEXT ".orig" #define REJEXT ".rej" diff --git a/usr.bin/patch/inp.c b/usr.bin/patch/inp.c index 826f85b40e9b..e7fa3515f66d 100644 --- a/usr.bin/patch/inp.c +++ b/usr.bin/patch/inp.c @@ -31,8 +31,10 @@ #include #include #include +#include #include +#include #include #include #include @@ -133,12 +135,14 @@ reallocate_lines(size_t *lines_allocated) static bool plan_a(const char *filename) { - int ifd, statfailed; + int ifd, statfailed, devnull, pstat; char *p, *s, lbuf[INITLINELEN]; struct stat filestat; ptrdiff_t sz; size_t i; size_t iline, lines_allocated; + pid_t pid; + char *argp[4] = {NULL}; #ifdef DEBUGGING if (debug & 8) @@ -166,13 +170,14 @@ plan_a(const char *filename) } if (statfailed && check_only) fatal("%s not found, -C mode, can't probe further\n", filename); - /* For nonexistent or read-only files, look for RCS or SCCS versions. */ + /* For nonexistent or read-only files, look for RCS versions. */ + if (statfailed || /* No one can write to it. */ (filestat.st_mode & 0222) == 0 || /* I can't write to it. */ ((filestat.st_mode & 0022) == 0 && filestat.st_uid != getuid())) { - const char *cs = NULL, *filebase, *filedir; + char *filebase, *filedir; struct stat cstat; char *tmp_filename1, *tmp_filename2; @@ -180,43 +185,26 @@ plan_a(const char *filename) tmp_filename2 = strdup(filename); if (tmp_filename1 == NULL || tmp_filename2 == NULL) fatal("strdupping filename"); + filebase = basename(tmp_filename1); filedir = dirname(tmp_filename2); - /* Leave room in lbuf for the diff command. */ - s = lbuf + 20; - #define try(f, a1, a2, a3) \ - (snprintf(s, buf_size - 20, f, a1, a2, a3), stat(s, &cstat) == 0) - - if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) || - try("%s/RCS/%s%s", filedir, filebase, "") || - try("%s/%s%s", filedir, filebase, RCSSUFFIX)) { - snprintf(buf, buf_size, CHECKOUT, filename); - snprintf(lbuf, sizeof lbuf, RCSDIFF, filename); - cs = "RCS"; - } else if (try("%s/SCCS/%s%s", filedir, SCCSPREFIX, filebase) || - try("%s/%s%s", filedir, SCCSPREFIX, filebase)) { - snprintf(buf, buf_size, GET, s); - snprintf(lbuf, sizeof lbuf, SCCSDIFF, s, filename); - cs = "SCCS"; - } else if (statfailed) - fatal("can't find %s\n", filename); - - free(tmp_filename1); - free(tmp_filename2); + (snprintf(lbuf, sizeof(lbuf), f, a1, a2, a3), stat(lbuf, &cstat) == 0) /* * else we can't write to it but it's not under a version * control system, so just proceed. */ - if (cs) { + if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) || + try("%s/RCS/%s%s", filedir, filebase, "") || + try("%s/%s%s", filedir, filebase, RCSSUFFIX)) { if (!statfailed) { if ((filestat.st_mode & 0222) != 0) /* The owner can write to it. */ fatal("file %s seems to be locked " - "by somebody else under %s\n", - filename, cs); + "by somebody else under RCS\n", + filename); /* * It might be checked out unlocked. See if * it's safe to check out the default version @@ -224,21 +212,59 @@ plan_a(const char *filename) */ if (verbose) say("Comparing file %s to default " - "%s version...\n", - filename, cs); - if (system(lbuf)) + "RCS version...\n", filename); + + switch (pid = fork()) { + case -1: + fatal("can't fork: %s\n", + strerror(errno)); + case 0: + devnull = open("/dev/null", O_RDONLY); + if (devnull == -1) { + fatal("can't open /dev/null: %s", + strerror(errno)); + } + (void)dup2(devnull, STDOUT_FILENO); + argp[0] = strdup(RCSDIFF); + argp[1] = strdup(filename); + execv(RCSDIFF, argp); + exit(127); + } + pid = waitpid(pid, &pstat, 0); + if (pid == -1 || WEXITSTATUS(pstat) != 0) { fatal("can't check out file %s: " - "differs from default %s version\n", - filename, cs); + "differs from default RCS version\n", + filename); + } } + if (verbose) - say("Checking out file %s from %s...\n", - filename, cs); - if (system(buf) || stat(filename, &filestat)) - fatal("can't check out file %s from %s\n", - filename, cs); + say("Checking out file %s from RCS...\n", + filename); + + switch (pid = fork()) { + case -1: + fatal("can't fork: %s\n", strerror(errno)); + case 0: + argp[0] = strdup(CHECKOUT); + argp[1] = strdup("-l"); + argp[2] = strdup(filename); + execv(CHECKOUT, argp); + exit(127); + } + pid = waitpid(pid, &pstat, 0); + if (pid == -1 || WEXITSTATUS(pstat) != 0 || + stat(filename, &filestat)) { + fatal("can't check out file %s from RCS\n", + filename); + } + } else if (statfailed) { + fatal("can't find %s\n", filename); } + free(tmp_filename1); + free(tmp_filename2); } + filemode = filestat.st_mode; if (!S_ISREG(filemode)) fatal("%s is not a normal file--can't patch\n", filename); From 3a0b9b773515a1bccb4cf483d9b98a1554c79b4a Mon Sep 17 00:00:00 2001 From: Xin LI Date: Tue, 28 Jul 2015 19:58:38 +0000 Subject: [PATCH 026/314] Fix multiple OpenSSH vulnerabilities. Security: CVE-2014-2653 Security: CVE-2015-5600 Security: FreeBSD-SA-15:16.openssh --- crypto/openssh/auth2-chall.c | 9 ++++++-- crypto/openssh/sshconnect.c | 42 ++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/crypto/openssh/auth2-chall.c b/crypto/openssh/auth2-chall.c index 980250a91c3e..791be5ca3c9f 100644 --- a/crypto/openssh/auth2-chall.c +++ b/crypto/openssh/auth2-chall.c @@ -82,6 +82,7 @@ struct KbdintAuthctxt void *ctxt; KbdintDevice *device; u_int nreq; + u_int devices_done; }; #ifdef USE_PAM @@ -168,11 +169,15 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt) if (len == 0) break; for (i = 0; devices[i]; i++) { - if (!auth2_method_allowed(authctxt, + if ((kbdintctxt->devices_done & (1 << i)) != 0 || + !auth2_method_allowed(authctxt, "keyboard-interactive", devices[i]->name)) continue; - if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) + if (strncmp(kbdintctxt->devices, devices[i]->name, + len) == 0) { kbdintctxt->device = devices[i]; + kbdintctxt->devices_done |= 1 << i; + } } t = kbdintctxt->devices; kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index fd8ad1dd3348..25ced5735dc6 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -1247,29 +1247,39 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) { int flags = 0; char *fp; + Key *plain = NULL; fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); debug("Server host key: %s %s", key_type(host_key), fp); free(fp); - /* XXX certs are not yet supported for DNS */ - if (!key_is_cert(host_key) && options.verify_host_key_dns && - verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { - if (flags & DNS_VERIFY_FOUND) { - - if (options.verify_host_key_dns == 1 && - flags & DNS_VERIFY_MATCH && - flags & DNS_VERIFY_SECURE) - return 0; - - if (flags & DNS_VERIFY_MATCH) { - matching_host_key_dns = 1; - } else { - warn_changed_key(host_key); - error("Update the SSHFP RR in DNS with the new " - "host key to get rid of this message."); + if (options.verify_host_key_dns) { + /* + * XXX certs are not yet supported for DNS, so downgrade + * them and try the plain key. + */ + plain = key_from_private(host_key); + if (key_is_cert(plain)) + key_drop_cert(plain); + if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { + if (flags & DNS_VERIFY_FOUND) { + if (options.verify_host_key_dns == 1 && + flags & DNS_VERIFY_MATCH && + flags & DNS_VERIFY_SECURE) { + key_free(plain); + return 0; + } + if (flags & DNS_VERIFY_MATCH) { + matching_host_key_dns = 1; + } else { + warn_changed_key(plain); + error("Update the SSHFP RR in DNS " + "with the new host key to get rid " + "of this message."); + } } } + key_free(plain); } return check_host_key(host, hostaddr, options.port, host_key, RDRW, From 38750ada8f6d4fe905b678f5552f995f3e42796b Mon Sep 17 00:00:00 2001 From: Jeff Roberson Date: Tue, 28 Jul 2015 20:24:09 +0000 Subject: [PATCH 027/314] - Eliminate the EMPTYKVA queue. It served as a cache of KVA allocations attached to bufs to avoid the overhead of the vm. This purposes is now better served by vmem. Freeing the kva immediately when a buf is destroyed leads to lower fragmentation and a much simpler scan algorithm. Reviewed by: kib Sponsored by: EMC / Isilon Storage Division --- sys/kern/vfs_bio.c | 105 ++++++++++----------------------------------- 1 file changed, 23 insertions(+), 82 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index d29c308d825b..01be712edaa4 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -309,13 +309,12 @@ static int bdirtywait; /* * Definitions for the buffer free lists. */ -#define BUFFER_QUEUES 5 /* number of free buffer queues */ +#define BUFFER_QUEUES 4 /* number of free buffer queues */ #define QUEUE_NONE 0 /* on no queue */ #define QUEUE_CLEAN 1 /* non-B_DELWRI buffers */ #define QUEUE_DIRTY 2 /* B_DELWRI buffers */ -#define QUEUE_EMPTYKVA 3 /* empty buffer headers w/KVA assignment */ -#define QUEUE_EMPTY 4 /* empty buffer headers */ +#define QUEUE_EMPTY 3 /* empty buffer headers */ #define QUEUE_SENTINEL 1024 /* not an queue index, but mark for sentinel */ /* Queues for free buffers with various properties */ @@ -1862,10 +1861,8 @@ brelse(struct buf *bp) bp->b_xflags &= ~(BX_BKGRDWRITE | BX_ALTDATA); if (bp->b_vflags & BV_BKGRDINPROG) panic("losing buffer 1"); - if (bp->b_kvasize) - qindex = QUEUE_EMPTYKVA; - else - qindex = QUEUE_EMPTY; + bufkvafree(bp); + qindex = QUEUE_EMPTY; bp->b_flags |= B_AGE; /* buffers with junk contents */ } else if (bp->b_flags & (B_INVAL | B_NOCACHE | B_RELBUF) || @@ -2251,8 +2248,6 @@ getnewbuf_reuse_bp(struct buf *bp, int qindex) LIST_INIT(&bp->b_dep); } -static int flushingbufs; - static struct buf * getnewbuf_scan(int maxsize, int defrag, int unmapped, int metadata) { @@ -2261,64 +2256,25 @@ getnewbuf_scan(int maxsize, int defrag, int unmapped, int metadata) KASSERT(!unmapped || !defrag, ("both unmapped and defrag")); - pass = 1; + pass = 0; restart: - atomic_add_int(&getnewbufrestarts, 1); + if (pass != 0) + atomic_add_int(&getnewbufrestarts, 1); - /* - * Setup for scan. If we do not have enough free buffers, - * we setup a degenerate case that immediately fails. Note - * that if we are specially marked process, we are allowed to - * dip into our reserves. - * - * The scanning sequence is nominally: EMPTY->EMPTYKVA->CLEAN - * for the allocation of the mapped buffer. For unmapped, the - * easiest is to start with EMPTY outright. - * - * We start with EMPTYKVA. If the list is empty we backup to EMPTY. - * However, there are a number of cases (defragging, reusing, ...) - * where we cannot backup. - */ nbp = NULL; mtx_lock(&bqclean); - if (!defrag && unmapped) { + /* + * If we're not defragging or low on bufspace attempt to make a new + * buf from a header. + */ + if (defrag == 0 && bufspace + maxsize < hibufspace) { nqindex = QUEUE_EMPTY; - nbp = TAILQ_FIRST(&bufqueues[QUEUE_EMPTY]); + nbp = TAILQ_FIRST(&bufqueues[nqindex]); } + /* + * All available buffers might be clean or we need to start recycling. + */ if (nbp == NULL) { - nqindex = QUEUE_EMPTYKVA; - nbp = TAILQ_FIRST(&bufqueues[QUEUE_EMPTYKVA]); - } - - /* - * If no EMPTYKVA buffers and we are either defragging or - * reusing, locate a CLEAN buffer to free or reuse. If - * bufspace useage is low skip this step so we can allocate a - * new buffer. - */ - if (nbp == NULL && (defrag || bufspace >= lobufspace)) { - nqindex = QUEUE_CLEAN; - nbp = TAILQ_FIRST(&bufqueues[QUEUE_CLEAN]); - } - - /* - * If we could not find or were not allowed to reuse a CLEAN - * buffer, check to see if it is ok to use an EMPTY buffer. - * We can only use an EMPTY buffer if allocating its KVA would - * not otherwise run us out of buffer space. No KVA is needed - * for the unmapped allocation. - */ - if (nbp == NULL && defrag == 0 && (bufspace + maxsize < hibufspace || - metadata)) { - nqindex = QUEUE_EMPTY; - nbp = TAILQ_FIRST(&bufqueues[QUEUE_EMPTY]); - } - - /* - * All available buffers might be clean, retry ignoring the - * lobufspace as the last resort. - */ - if (nbp == NULL && !TAILQ_EMPTY(&bufqueues[QUEUE_CLEAN])) { nqindex = QUEUE_CLEAN; nbp = TAILQ_FIRST(&bufqueues[QUEUE_CLEAN]); } @@ -2332,28 +2288,21 @@ getnewbuf_scan(int maxsize, int defrag, int unmapped, int metadata) /* * Calculate next bp (we can only use it if we do not - * block or do other fancy things). + * release the bqlock) */ if ((nbp = TAILQ_NEXT(bp, b_freelist)) == NULL) { switch (qindex) { case QUEUE_EMPTY: - nqindex = QUEUE_EMPTYKVA; - nbp = TAILQ_FIRST(&bufqueues[QUEUE_EMPTYKVA]); - if (nbp != NULL) - break; - /* FALLTHROUGH */ - case QUEUE_EMPTYKVA: nqindex = QUEUE_CLEAN; - nbp = TAILQ_FIRST(&bufqueues[QUEUE_CLEAN]); + nbp = TAILQ_FIRST(&bufqueues[nqindex]); if (nbp != NULL) break; /* FALLTHROUGH */ case QUEUE_CLEAN: - if (metadata && pass == 1) { - pass = 2; + if (metadata && pass == 0) { + pass = 1; nqindex = QUEUE_EMPTY; - nbp = TAILQ_FIRST( - &bufqueues[QUEUE_EMPTY]); + nbp = TAILQ_FIRST(&bufqueues[nqindex]); } /* * nbp is NULL. @@ -2399,11 +2348,11 @@ getnewbuf_scan(int maxsize, int defrag, int unmapped, int metadata) bremfreel(bp); mtx_unlock(&bqclean); + /* * NOTE: nbp is now entirely invalid. We can only restart * the scan from this point on. */ - getnewbuf_reuse_bp(bp, qindex); mtx_assert(&bqclean, MA_NOTOWNED); @@ -2412,7 +2361,6 @@ getnewbuf_scan(int maxsize, int defrag, int unmapped, int metadata) */ if (defrag) { bp->b_flags |= B_INVAL; - bufkvafree(bp); brelse(bp); defrag = 0; goto restart; @@ -2424,7 +2372,6 @@ getnewbuf_scan(int maxsize, int defrag, int unmapped, int metadata) */ if (qindex == QUEUE_CLEAN && BUF_LOCKWAITERS(bp)) { bp->b_flags |= B_INVAL; - bufkvafree(bp); brelse(bp); goto restart; } @@ -2437,16 +2384,11 @@ getnewbuf_scan(int maxsize, int defrag, int unmapped, int metadata) * KVM space. This occurs in rare situations when multiple * processes are blocked in getnewbuf() or allocbuf(). */ - if (bufspace >= hibufspace) - flushingbufs = 1; - if (flushingbufs && bp->b_kvasize != 0) { + if (bufspace >= hibufspace && bp->b_kvasize != 0) { bp->b_flags |= B_INVAL; - bufkvafree(bp); brelse(bp); goto restart; } - if (bufspace < lobufspace) - flushingbufs = 0; break; } return (bp); @@ -2492,7 +2434,6 @@ getnewbuf(struct vnode *vp, int slpflag, int slptimeo, int size, int maxsize, * async I/O rather then sync I/O. */ atomic_add_int(&getnewbufcalls, 1); - atomic_subtract_int(&getnewbufrestarts, 1); restart: bp = getnewbuf_scan(maxsize, defrag, (gbflags & (GB_UNMAPPED | GB_KVAALLOC)) == GB_UNMAPPED, metadata); From 81e2ba845c0062d44d3d35de2caae7a598c395fd Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Tue, 28 Jul 2015 20:52:10 +0000 Subject: [PATCH 028/314] Fix wrong warning printed after changing or updating NIS users PR: 37672 Submitted by: chris+freebsd@chrullrich.de --- usr.sbin/pw/pw_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index d6dad3f3c52b..aecc90aa174a 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -206,7 +206,7 @@ perform_chgpwent(const char *name, struct passwd *pwd) rc = chgnispwent(conf.userconf->nispasswd, name, pwd); if (rc == -1) warn("User '%s' not found in NIS passwd", pwd->pw_name); - else + else if (rc != 0) warn("NIS passwd update"); /* NOTE: NIS-only update errors are not fatal */ } @@ -678,7 +678,7 @@ pw_user(int mode, char *name, long id, struct cargs * args) rc = addnispwent(cnf->nispasswd, pwd); if (rc == -1) warnx("User '%s' already exists in NIS passwd", pwd->pw_name); - else + else if (rc != 0) warn("NIS passwd update"); /* NOTE: we treat NIS-only update errors as non-fatal */ } From 90a4edb58491b8048a6bdd7c885099629797558f Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Tue, 28 Jul 2015 21:10:58 +0000 Subject: [PATCH 029/314] Check uid/gid used when creating a user/group are not larger than UID_MAX/GID_MAX PR: 173977 Reported by: nvass@gmx.com --- usr.sbin/pw/pw.c | 4 ++-- usr.sbin/pw/tests/Makefile | 1 + usr.sbin/pw/tests/pw_groupadd.sh | 15 +++++++++++++++ usr.sbin/pw/tests/pw_useradd.sh | 8 ++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100755 usr.sbin/pw/tests/pw_groupadd.sh diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index 3db427afe44b..c1d9cd32a708 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -269,7 +269,7 @@ main(int argc, char *argv[]) } if (strspn(optarg, "0123456789") != strlen(optarg)) errx(EX_USAGE, "-g expects a number"); - id = strtonum(optarg, 0, LONG_MAX, &errstr); + id = strtonum(optarg, 0, GID_MAX, &errstr); if (errstr != NULL) errx(EX_USAGE, "Bad id '%s': %s", optarg, errstr); @@ -281,7 +281,7 @@ main(int argc, char *argv[]) addarg(&arglist, 'u', optarg); break; } - id = strtonum(optarg, 0, LONG_MAX, &errstr); + id = strtonum(optarg, 0, UID_MAX, &errstr); if (errstr != NULL) errx(EX_USAGE, "Bad id '%s': %s", optarg, errstr); diff --git a/usr.sbin/pw/tests/Makefile b/usr.sbin/pw/tests/Makefile index 193b8ab58530..c43285fa7fff 100644 --- a/usr.sbin/pw/tests/Makefile +++ b/usr.sbin/pw/tests/Makefile @@ -8,6 +8,7 @@ TESTSDIR= ${TESTSBASE}/usr.sbin/pw ATF_TESTS_SH= pw_etcdir \ pw_lock \ pw_config \ + pw_groupadd \ pw_groupdel \ pw_groupmod \ pw_useradd \ diff --git a/usr.sbin/pw/tests/pw_groupadd.sh b/usr.sbin/pw/tests/pw_groupadd.sh new file mode 100755 index 000000000000..9c8fdf12ebe8 --- /dev/null +++ b/usr.sbin/pw/tests/pw_groupadd.sh @@ -0,0 +1,15 @@ +# $FreeBSD$ + +# Import helper functions +. $(atf_get_srcdir)/helper_functions.shin + +atf_test_case group_add_gid_too_large +group_add_gid_too_large_body() { + populate_etc_skel + atf_check -s exit:64 -e inline:"pw: Bad id '9999999999999': too large\n" \ + ${PW} groupadd -n test1 -g 9999999999999 +} + +atf_init_test_cases() { + atf_add_test_case group_add_gid_too_large +} diff --git a/usr.sbin/pw/tests/pw_useradd.sh b/usr.sbin/pw/tests/pw_useradd.sh index 880dab5ca7bb..7306387bd194 100755 --- a/usr.sbin/pw/tests/pw_useradd.sh +++ b/usr.sbin/pw/tests/pw_useradd.sh @@ -289,6 +289,13 @@ user_add_uid0_body() { -s exit:0 ${PW} usershow foo } +atf_test_case user_add_uid_too_large +user_add_uid_too_large_body() { + populate_etc_skel + atf_check -s exit:64 -e inline:"pw: Bad id '9999999999999': too large\n" \ + ${PW} useradd -n test1 -u 9999999999999 +} + atf_init_test_cases() { atf_add_test_case user_add atf_add_test_case user_add_noupdate @@ -313,4 +320,5 @@ atf_init_test_cases() { atf_add_test_case user_add_R atf_add_test_case user_add_skel atf_add_test_case user_add_uid0 + atf_add_test_case user_add_uid_too_large } From b99a71b1da94c943c94610ccbd6d334284bf2abf Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Tue, 28 Jul 2015 21:39:58 +0000 Subject: [PATCH 030/314] Fix rescue build after r284356 with STRIP= by using proper STRIPBIN per build(7). This was causing the following error: rescue sh: rescue: not found *** [rescue] Error code 127 make[1]: stopped in /usr/obj/usr/src/rescue/rescue Sponsored by: EMC / Isilon Storage Division --- usr.sbin/crunch/crunchgen/crunchgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/crunch/crunchgen/crunchgen.c b/usr.sbin/crunch/crunchgen/crunchgen.c index 79b240f39704..8ace15add1f8 100644 --- a/usr.sbin/crunch/crunchgen/crunchgen.c +++ b/usr.sbin/crunch/crunchgen/crunchgen.c @@ -980,7 +980,7 @@ top_makefile_rules(FILE *outmk) prog_t *p; fprintf(outmk, "LD?= ld\n"); - fprintf(outmk, "STRIP?= strip\n"); + fprintf(outmk, "STRIPBIN?= strip\n"); if ( subtract_strlst(&libs, &libs_so) ) fprintf(outmk, "# NOTE: Some LIBS declarations below overridden by LIBS_SO\n"); @@ -1028,7 +1028,7 @@ top_makefile_rules(FILE *outmk) fprintf(outmk, "\t$(CC) -static -o %s %s.o $(CRUNCHED_OBJS) $(LIBS)\n", execfname, execfname); fprintf(outmk, ".endif\n"); - fprintf(outmk, "\t$(STRIP) %s\n", execfname); + fprintf(outmk, "\t$(STRIPBIN) %s\n", execfname); fprintf(outmk, "realclean: clean subclean\n"); fprintf(outmk, "clean:\n\trm -f %s *.lo *.o *_stub.c\n", execfname); fprintf(outmk, "subclean: $(SUBCLEAN_TARGETS)\n"); From 133362912cd8bf02029cfafef3249f1e0fdf4fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?= Date: Tue, 28 Jul 2015 21:47:37 +0000 Subject: [PATCH 031/314] drm/i915: Sort functions in i915_gem.c to match Linux 3.8's ordering While here, reduce the style diff with Linux. There is no functional change. The goal is to ease the future update to Linux 3.8's i915 driver. MFC after: 2 months --- sys/dev/drm2/i915/i915_drv.h | 3 - sys/dev/drm2/i915/i915_gem.c | 4324 +++++++++++++++--------------- sys/dev/drm2/i915/i915_gem_gtt.c | 55 + 3 files changed, 2259 insertions(+), 2123 deletions(-) diff --git a/sys/dev/drm2/i915/i915_drv.h b/sys/dev/drm2/i915/i915_drv.h index 0a79d3b5c467..fd1aa146e021 100644 --- a/sys/dev/drm2/i915/i915_drv.h +++ b/sys/dev/drm2/i915/i915_drv.h @@ -1151,8 +1151,6 @@ void i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); void i915_destroy_error_state(struct drm_device *dev); /* i915_gem.c */ -int i915_gem_create(struct drm_file *file, struct drm_device *dev, uint64_t size, - uint32_t *handle_p); int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_create_ioctl(struct drm_device *dev, void *data, @@ -1243,7 +1241,6 @@ int i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); int i915_gem_flush_ring(struct intel_ring_buffer *ring, uint32_t invalidate_domains, uint32_t flush_domains); void i915_gem_release_mmap(struct drm_i915_gem_object *obj); -int i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj); int i915_gem_object_sync(struct drm_i915_gem_object *obj, struct intel_ring_buffer *to); int i915_gem_object_put_fence(struct drm_i915_gem_object *obj); diff --git a/sys/dev/drm2/i915/i915_gem.c b/sys/dev/drm2/i915/i915_gem.c index 356ccc5d80da..1b4591722165 100644 --- a/sys/dev/drm2/i915/i915_gem.c +++ b/sys/dev/drm2/i915/i915_gem.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include #include + #include #include #include @@ -69,38 +70,40 @@ __FBSDID("$FreeBSD$"); #include -static void i915_gem_object_flush_cpu_write_domain( - struct drm_i915_gem_object *obj); -static uint32_t i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, - int tiling_mode); -static uint32_t i915_gem_get_gtt_alignment(struct drm_device *dev, - uint32_t size, int tiling_mode); -static int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, - unsigned alignment, bool map_and_fenceable); -static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, - int flags); -static void i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj); -static void i915_gem_object_put_pages_range(struct drm_i915_gem_object *obj, - off_t start, off_t end); +#define __user +#define __force +#define __iomem +#define __must_check +#define to_user_ptr(x) ((void *)(uintptr_t)(x)) +#define offset_in_page(x) ((x) & PAGE_MASK) +#define page_to_phys(x) VM_PAGE_TO_PHYS(x) + +static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); +static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); +static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + unsigned alignment, + bool map_and_fenceable); +static int i915_gem_phys_pwrite(struct drm_device *dev, + struct drm_i915_gem_object *obj, + struct drm_i915_gem_pwrite *args, + struct drm_file *file); + +static void i915_gem_write_fence(struct drm_device *dev, int reg, + struct drm_i915_gem_object *obj); +static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, + struct drm_i915_fence_reg *fence, + bool enable); + +static void i915_gem_lowmem(void *arg); +static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); + static int i915_gem_object_get_pages_range(struct drm_i915_gem_object *obj, off_t start, off_t end); -static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj); -static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); -static int i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj); -static bool i915_gem_object_is_inactive(struct drm_i915_gem_object *obj); -static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj); +static void i915_gem_object_put_pages_range(struct drm_i915_gem_object *obj, + off_t start, off_t end); + static vm_page_t i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, bool *fresh); -static void i915_gem_process_flushing_list(struct intel_ring_buffer *ring, - uint32_t flush_domains); -static void i915_gem_reset_fences(struct drm_device *dev); -static void i915_gem_retire_task_handler(void *arg, int pending); -static void i915_gem_lowmem(void *arg); -static void i915_gem_write_fence(struct drm_device *dev, int reg, - struct drm_i915_gem_object *obj); -static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, - bool interruptible); -static int i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno); MALLOC_DEFINE(DRM_I915_GEM, "i915gem", "Allocations from i915 gem"); long i915_gem_wired_pages_cnt; @@ -131,18 +134,17 @@ static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) obj->fence_reg = I915_FENCE_REG_NONE; } -static void -i915_gem_info_add_obj(struct drm_i915_private *dev_priv, size_t size) +/* some bookkeeping */ +static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, + size_t size) { - dev_priv->mm.object_count++; dev_priv->mm.object_memory += size; } -static void -i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, size_t size) +static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, + size_t size) { - dev_priv->mm.object_count--; dev_priv->mm.object_memory -= size; } @@ -150,10 +152,9 @@ i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, size_t size) static int i915_gem_wait_for_error(struct drm_device *dev) { - struct drm_i915_private *dev_priv; + struct drm_i915_private *dev_priv = dev->dev_private; int ret; - dev_priv = dev->dev_private; if (!atomic_load_acq_int(&dev_priv->mm.wedged)) return (0); @@ -171,150 +172,61 @@ i915_gem_wait_for_error(struct drm_device *dev) mtx_unlock(&dev_priv->error_completion_lock); if (atomic_load_acq_int(&dev_priv->mm.wedged)) { + /* GPU is hung, bump the completion count to account for + * the token we just consumed so that we never hit zero and + * end up waiting upon a subsequent completion event that + * will never happen. + */ mtx_lock(&dev_priv->error_completion_lock); dev_priv->error_completion++; mtx_unlock(&dev_priv->error_completion_lock); } - return (0); + return 0; } -int -i915_mutex_lock_interruptible(struct drm_device *dev) +int i915_mutex_lock_interruptible(struct drm_device *dev) { - struct drm_i915_private *dev_priv; int ret; - dev_priv = dev->dev_private; ret = i915_gem_wait_for_error(dev); - if (ret != 0) - return (ret); + if (ret) + return ret; /* * interruptible shall it be. might indeed be if dev_lock is * changed to sx */ - ret = sx_xlock_sig(&dev->dev_struct_lock); - if (ret != 0) - return (-ret); + ret = -sx_xlock_sig(&dev->dev_struct_lock); + if (ret) + return ret; - return (0); + return 0; } - -void -i915_gem_free_object(struct drm_gem_object *gem_obj) -{ - struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); - struct drm_device *dev; - drm_i915_private_t *dev_priv; - - dev = obj->base.dev; - dev_priv = dev->dev_private; - - CTR1(KTR_DRM, "object_destroy_tail %p", obj); - - if (obj->phys_obj) - i915_gem_detach_phys_object(dev, obj); - - obj->pin_count = 0; - if (i915_gem_object_unbind(obj) == -ERESTARTSYS) { - bool was_interruptible; - - was_interruptible = dev_priv->mm.interruptible; - dev_priv->mm.interruptible = false; - - if (i915_gem_object_unbind(obj)) - printf("i915_gem_free_object: unbind\n"); - - dev_priv->mm.interruptible = was_interruptible; - } - - drm_gem_free_mmap_offset(&obj->base); - drm_gem_object_release(&obj->base); - i915_gem_info_remove_obj(dev_priv, obj->base.size); - - free(obj->bit_17, DRM_I915_GEM); - free(obj, DRM_I915_GEM); -} - -static void -init_ring_lists(struct intel_ring_buffer *ring) +static bool +i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) { - INIT_LIST_HEAD(&ring->active_list); - INIT_LIST_HEAD(&ring->request_list); - INIT_LIST_HEAD(&ring->gpu_write_list); -} - -void -i915_gem_load(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv; - int i; - - dev_priv = dev->dev_private; - - INIT_LIST_HEAD(&dev_priv->mm.active_list); - INIT_LIST_HEAD(&dev_priv->mm.flushing_list); - INIT_LIST_HEAD(&dev_priv->mm.inactive_list); - INIT_LIST_HEAD(&dev_priv->mm.fence_list); - INIT_LIST_HEAD(&dev_priv->mm.gtt_list); - for (i = 0; i < I915_NUM_RINGS; i++) - init_ring_lists(&dev_priv->rings[i]); - for (i = 0; i < I915_MAX_NUM_FENCES; i++) - INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); - TIMEOUT_TASK_INIT(dev_priv->tq, &dev_priv->mm.retire_task, 0, - i915_gem_retire_task_handler, dev_priv); - dev_priv->error_completion = 0; - - /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ - if (IS_GEN3(dev)) { - I915_WRITE(MI_ARB_STATE, - _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); - } - - dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; - - /* Old X drivers will take 0-2 for front, back, depth buffers */ - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - dev_priv->fence_reg_start = 3; - - if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || - IS_G33(dev)) - dev_priv->num_fence_regs = 16; - else - dev_priv->num_fence_regs = 8; - - /* Initialize fence registers to zero */ - i915_gem_reset_fences(dev); - - i915_gem_detect_bit_6_swizzle(dev); - dev_priv->mm.interruptible = true; - - dev_priv->mm.i915_lowmem = EVENTHANDLER_REGISTER(vm_lowmem, - i915_gem_lowmem, dev, EVENTHANDLER_PRI_ANY); + return !obj->active; } int i915_gem_init_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) + struct drm_file *file) { - struct drm_i915_gem_init *args; - drm_i915_private_t *dev_priv; - int error; + struct drm_i915_gem_init *args = data; + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; if (drm_core_check_feature(dev, DRIVER_MODESET)) return -ENODEV; - dev_priv = dev->dev_private; - args = data; - if (args->gtt_start >= args->gtt_end || (args->gtt_end | args->gtt_start) & (PAGE_SIZE - 1)) - return (-EINVAL); + return -EINVAL; if (mtx_initialized(&dev_priv->mm.gtt_space.unused_lock)) - return (-EBUSY); + return -EBUSY; /* GEM with user mode setting was never supported on ilk and later. */ if (INTEL_INFO(dev)->gen >= 5) @@ -325,254 +237,22 @@ i915_gem_init_ioctl(struct drm_device *dev, void *data, * against. */ DRM_LOCK(dev); - error = i915_gem_init_global_gtt(dev, args->gtt_start, - args->gtt_end, args->gtt_end); - DRM_UNLOCK(dev); - return (error); -} - -int -i915_gem_idle(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv; - int ret; - - DRM_LOCK(dev); - - dev_priv = dev->dev_private; - if (dev_priv->mm.suspended) { - DRM_UNLOCK(dev); - return (0); - } - - ret = i915_gpu_idle(dev); - if (ret != 0) { - DRM_UNLOCK(dev); - return (ret); - } - i915_gem_retire_requests(dev); - - /* Under UMS, be paranoid and evict. */ - if (!drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = i915_gem_evict_everything(dev, false); - if (ret != 0) { - DRM_UNLOCK(dev); - return ret; - } - } - - i915_gem_reset_fences(dev); - - /* Hack! Don't let anybody do execbuf while we don't control the chip. - * We need to replace this with a semaphore, or something. - * And not confound mm.suspended! - */ - dev_priv->mm.suspended = 1; - callout_stop(&dev_priv->hangcheck_timer); - - i915_kernel_lost_context(dev); - i915_gem_cleanup_ringbuffer(dev); - + ret = i915_gem_init_global_gtt(dev, args->gtt_start, + args->gtt_end, args->gtt_end); DRM_UNLOCK(dev); - /* Cancel the retire work handler, which should be idle now. */ - taskqueue_cancel_timeout(dev_priv->tq, &dev_priv->mm.retire_task, NULL); - return (ret); -} - -void -i915_gem_init_swizzling(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv; - - dev_priv = dev->dev_private; - - if (INTEL_INFO(dev)->gen < 5 || - dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE) - return; - - I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | - DISP_TILE_SURFACE_SWIZZLING); - - if (IS_GEN5(dev)) - return; - - - I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); - if (IS_GEN6(dev)) - I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB)); - else - I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB)); -} - -void i915_gem_init_ppgtt(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv; - struct i915_hw_ppgtt *ppgtt; - uint32_t pd_offset, pd_entry; - vm_paddr_t pt_addr; - struct intel_ring_buffer *ring; - u_int first_pd_entry_in_global_pt, i; - - dev_priv = dev->dev_private; - ppgtt = dev_priv->mm.aliasing_ppgtt; - if (ppgtt == NULL) - return; - - first_pd_entry_in_global_pt = 512 * 1024 - I915_PPGTT_PD_ENTRIES; - for (i = 0; i < ppgtt->num_pd_entries; i++) { - pt_addr = VM_PAGE_TO_PHYS(ppgtt->pt_pages[i]); - pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); - pd_entry |= GEN6_PDE_VALID; - intel_gtt_write(first_pd_entry_in_global_pt + i, pd_entry); - } - intel_gtt_read_pte(first_pd_entry_in_global_pt); - - pd_offset = ppgtt->pd_offset; - pd_offset /= 64; /* in cachelines, */ - pd_offset <<= 16; - - if (INTEL_INFO(dev)->gen == 6) { - uint32_t ecochk, gab_ctl, ecobits; - - ecobits = I915_READ(GAC_ECO_BITS); - I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B); - - gab_ctl = I915_READ(GAB_CTL); - I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT); - - ecochk = I915_READ(GAM_ECOCHK); - I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | - ECOCHK_PPGTT_CACHE64B); - I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); - } else if (INTEL_INFO(dev)->gen >= 7) { - I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); - /* GFX_MODE is per-ring on gen7+ */ - } - - for_each_ring(ring, dev_priv, i) { - if (INTEL_INFO(dev)->gen >= 7) - I915_WRITE(RING_MODE_GEN7(ring), - _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); - - I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); - I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); - } -} - -int -i915_gem_init_hw(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv; - int ret; - - dev_priv = dev->dev_private; - - i915_gem_init_swizzling(dev); - - ret = intel_init_render_ring_buffer(dev); - if (ret != 0) - return (ret); - - if (HAS_BSD(dev)) { - ret = intel_init_bsd_ring_buffer(dev); - if (ret != 0) - goto cleanup_render_ring; - } - - if (HAS_BLT(dev)) { - ret = intel_init_blt_ring_buffer(dev); - if (ret != 0) - goto cleanup_bsd_ring; - } - - dev_priv->next_seqno = 1; - i915_gem_context_init(dev); - i915_gem_init_ppgtt(dev); - return (0); - -cleanup_bsd_ring: - intel_cleanup_ring_buffer(&dev_priv->rings[VCS]); -cleanup_render_ring: - intel_cleanup_ring_buffer(&dev_priv->rings[RCS]); - return (ret); -} - -static bool -intel_enable_ppgtt(struct drm_device *dev) -{ - if (i915_enable_ppgtt >= 0) - return i915_enable_ppgtt; - - /* Disable ppgtt on SNB if VT-d is on. */ - if (INTEL_INFO(dev)->gen == 6 && intel_iommu_enabled) - return false; - - return true; -} - -int i915_gem_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long gtt_size, mappable_size; - int ret; - - gtt_size = dev_priv->mm.gtt.gtt_total_entries << PAGE_SHIFT; - mappable_size = dev_priv->mm.gtt.gtt_mappable_entries << PAGE_SHIFT; - - DRM_LOCK(dev); - if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { - /* PPGTT pdes are stolen from global gtt ptes, so shrink the - * aperture accordingly when using aliasing ppgtt. */ - gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; - - i915_gem_init_global_gtt(dev, 0, mappable_size, gtt_size); - - ret = i915_gem_init_aliasing_ppgtt(dev); - if (ret) { - DRM_UNLOCK(dev); - return ret; - } - } else { - /* Let GEM Manage all of the aperture. - * - * However, leave one page at the end still bound to the scratch - * page. There are a number of places where the hardware - * apparently prefetches past the end of the object, and we've - * seen multiple hangs with the GPU head pointer stuck in a - * batchbuffer bound at the last page of the aperture. One page - * should be enough to keep any prefetching inside of the - * aperture. - */ - i915_gem_init_global_gtt(dev, 0, mappable_size, - gtt_size); - } - - ret = i915_gem_init_hw(dev); - DRM_UNLOCK(dev); - if (ret != 0) { - i915_gem_cleanup_aliasing_ppgtt(dev); - return (ret); - } - - /* Allow hardware batchbuffers unless told otherwise, but not for KMS. */ - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - dev_priv->dri1.allow_batchbuffer = 1; - return 0; + return ret; } int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) + struct drm_file *file) { - struct drm_i915_private *dev_priv; - struct drm_i915_gem_get_aperture *args; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_get_aperture *args = data; struct drm_i915_gem_object *obj; size_t pinned; - dev_priv = dev->dev_private; - args = data; - pinned = 0; DRM_LOCK(dev); list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) @@ -583,418 +263,84 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, args->aper_size = dev_priv->mm.gtt_total; args->aper_available_size = args->aper_size - pinned; - return (0); -} - -int -i915_gem_object_pin(struct drm_i915_gem_object *obj, uint32_t alignment, - bool map_and_fenceable) -{ - int ret; - - if (obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT) - return (-EBUSY); - - if (obj->gtt_space != NULL) { - if ((alignment && obj->gtt_offset & (alignment - 1)) || - (map_and_fenceable && !obj->map_and_fenceable)) { - DRM_DEBUG("bo is already pinned with incorrect alignment:" - " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," - " obj->map_and_fenceable=%d\n", - obj->gtt_offset, alignment, - map_and_fenceable, - obj->map_and_fenceable); - ret = i915_gem_object_unbind(obj); - if (ret != 0) - return (ret); - } - } - - if (obj->gtt_space == NULL) { - ret = i915_gem_object_bind_to_gtt(obj, alignment, - map_and_fenceable); - if (ret) - return (ret); - } - - if (!obj->has_global_gtt_mapping && map_and_fenceable) - i915_gem_gtt_bind_object(obj, obj->cache_level); - - obj->pin_count++; - obj->pin_mappable |= map_and_fenceable; - return 0; } -void -i915_gem_object_unpin(struct drm_i915_gem_object *obj) -{ - - KASSERT(obj->pin_count != 0, ("zero pin count")); - KASSERT(obj->gtt_space != NULL, ("No gtt mapping")); - - if (--obj->pin_count == 0) - obj->pin_mappable = false; -} - -int -i915_gem_pin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_pin *args; - struct drm_i915_gem_object *obj; - struct drm_gem_object *gobj; - int ret; - - args = data; - - ret = i915_mutex_lock_interruptible(dev); - if (ret != 0) - return ret; - - gobj = drm_gem_object_lookup(dev, file, args->handle); - if (gobj == NULL) { - ret = -ENOENT; - goto unlock; - } - obj = to_intel_bo(gobj); - - if (obj->madv != I915_MADV_WILLNEED) { - DRM_ERROR("Attempting to pin a purgeable buffer\n"); - ret = -EINVAL; - goto out; - } - - if (obj->pin_filp != NULL && obj->pin_filp != file) { - DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", - args->handle); - ret = -EINVAL; - goto out; - } - - obj->user_pin_count++; - obj->pin_filp = file; - if (obj->user_pin_count == 1) { - ret = i915_gem_object_pin(obj, args->alignment, true); - if (ret != 0) - goto out; - } - - /* XXX - flush the CPU caches for pinned objects - * as the X server doesn't manage domains yet - */ - i915_gem_object_flush_cpu_write_domain(obj); - args->offset = obj->gtt_offset; -out: - drm_gem_object_unreference(&obj->base); -unlock: - DRM_UNLOCK(dev); - return (ret); -} - -int -i915_gem_unpin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_pin *args; - struct drm_i915_gem_object *obj; - int ret; - - args = data; - ret = i915_mutex_lock_interruptible(dev); - if (ret != 0) - return (ret); - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - if (obj->pin_filp != file) { - DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", - args->handle); - ret = -EINVAL; - goto out; - } - obj->user_pin_count--; - if (obj->user_pin_count == 0) { - obj->pin_filp = NULL; - i915_gem_object_unpin(obj); - } - -out: - drm_gem_object_unreference(&obj->base); -unlock: - DRM_UNLOCK(dev); - return (ret); -} - -int -i915_gem_busy_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_busy *args; - struct drm_i915_gem_object *obj; - int ret; - - args = data; - - ret = i915_mutex_lock_interruptible(dev); - if (ret != 0) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - args->busy = obj->active; - if (args->busy) { - if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { - ret = i915_gem_flush_ring(obj->ring, - 0, obj->base.write_domain); - } else { - ret = i915_gem_check_olr(obj->ring, - obj->last_rendering_seqno); - } - - i915_gem_retire_requests_ring(obj->ring); - args->busy = obj->active; - } - - drm_gem_object_unreference(&obj->base); -unlock: - DRM_UNLOCK(dev); - return (ret); -} - static int -i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) -{ - struct drm_i915_private *dev_priv; - struct drm_i915_file_private *file_priv; - unsigned long recent_enough; - struct drm_i915_gem_request *request; - struct intel_ring_buffer *ring; - u32 seqno; - int ret; - - dev_priv = dev->dev_private; - if (atomic_load_acq_int(&dev_priv->mm.wedged)) - return (-EIO); - - file_priv = file->driver_priv; - recent_enough = ticks - (20 * hz / 1000); - ring = NULL; - seqno = 0; - - mtx_lock(&file_priv->mm.lck); - list_for_each_entry(request, &file_priv->mm.request_list, client_list) { - if (time_after_eq(request->emitted_jiffies, recent_enough)) - break; - ring = request->ring; - seqno = request->seqno; - } - mtx_unlock(&file_priv->mm.lck); - if (seqno == 0) - return (0); - - ret = __wait_seqno(ring, seqno, true); - if (ret == 0) - taskqueue_enqueue_timeout(dev_priv->tq, - &dev_priv->mm.retire_task, 0); - - return (ret); -} - -int -i915_gem_throttle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - - return (i915_gem_ring_throttle(dev, file_priv)); -} - -int -i915_gem_madvise_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_madvise *args; - struct drm_i915_gem_object *obj; - int ret; - - args = data; - switch (args->madv) { - case I915_MADV_DONTNEED: - case I915_MADV_WILLNEED: - break; - default: - return (-EINVAL); - } - - ret = i915_mutex_lock_interruptible(dev); - if (ret != 0) - return (ret); - - obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - if (obj->pin_count != 0) { - ret = -EINVAL; - goto out; - } - - if (obj->madv != I915_MADV_PURGED_INTERNAL) - obj->madv = args->madv; - if (i915_gem_object_is_purgeable(obj) && obj->gtt_space == NULL) - i915_gem_object_truncate(obj); - args->retained = obj->madv != I915_MADV_PURGED_INTERNAL; - -out: - drm_gem_object_unreference(&obj->base); -unlock: - DRM_UNLOCK(dev); - return (ret); -} - -void -i915_gem_cleanup_ringbuffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv; - struct intel_ring_buffer *ring; - int i; - - dev_priv = dev->dev_private; - for_each_ring(ring, dev_priv, i) - intel_cleanup_ring_buffer(ring); -} - -int -i915_gem_entervt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv; - int ret; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return (0); - dev_priv = dev->dev_private; - if (atomic_load_acq_int(&dev_priv->mm.wedged) != 0) { - DRM_ERROR("Reenabling wedged hardware, good luck\n"); - atomic_store_rel_int(&dev_priv->mm.wedged, 0); - } - - DRM_LOCK(dev); - dev_priv->mm.suspended = 0; - - ret = i915_gem_init_hw(dev); - if (ret != 0) { - DRM_UNLOCK(dev); - return (ret); - } - - KASSERT(list_empty(&dev_priv->mm.active_list), ("active list")); - KASSERT(list_empty(&dev_priv->mm.flushing_list), ("flushing list")); - KASSERT(list_empty(&dev_priv->mm.inactive_list), ("inactive list")); - DRM_UNLOCK(dev); - - ret = drm_irq_install(dev); - if (ret) - goto cleanup_ringbuffer; - - return (0); - -cleanup_ringbuffer: - DRM_LOCK(dev); - i915_gem_cleanup_ringbuffer(dev); - dev_priv->mm.suspended = 1; - DRM_UNLOCK(dev); - - return (ret); -} - -int -i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - - drm_irq_uninstall(dev); - return (i915_gem_idle(dev)); -} - -int -i915_gem_create(struct drm_file *file, struct drm_device *dev, uint64_t size, - uint32_t *handle_p) +i915_gem_create(struct drm_file *file, + struct drm_device *dev, + uint64_t size, + uint32_t *handle_p) { struct drm_i915_gem_object *obj; - uint32_t handle; int ret; + u32 handle; size = roundup(size, PAGE_SIZE); if (size == 0) - return (-EINVAL); + return -EINVAL; + /* Allocate the new object */ obj = i915_gem_alloc_object(dev, size); if (obj == NULL) - return (-ENOMEM); + return -ENOMEM; ret = drm_gem_handle_create(file, &obj->base, &handle); - if (ret != 0) { + if (ret) { drm_gem_object_release(&obj->base); i915_gem_info_remove_obj(dev->dev_private, obj->base.size); free(obj, DRM_I915_GEM); - return (ret); + return ret; } /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference(&obj->base); CTR2(KTR_DRM, "object_create %p %x", obj, size); + *handle_p = handle; - return (0); + return 0; } int -i915_gem_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args) +i915_gem_dumb_create(struct drm_file *file, + struct drm_device *dev, + struct drm_mode_create_dumb *args) { - /* have to work out size/pitch and return them */ args->pitch = roundup2(args->width * ((args->bpp + 7) / 8), 64); args->size = args->pitch * args->height; - return (i915_gem_create(file, dev, args->size, &args->handle)); + return i915_gem_create(file, dev, + args->size, &args->handle); } -int -i915_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, - uint32_t handle) +int i915_gem_dumb_destroy(struct drm_file *file, + struct drm_device *dev, + uint32_t handle) { - - return (drm_gem_handle_delete(file, handle)); + return drm_gem_handle_delete(file, handle); } +/** + * Creates a new mm object and returns a handle to it. + */ int i915_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) + struct drm_file *file) { struct drm_i915_gem_create *args = data; - return (i915_gem_create(file, dev, args->size, &args->handle)); + return i915_gem_create(file, dev, + args->size, &args->handle); +} + +static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) +{ + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; + + return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && + obj->tiling_mode != I915_TILING_NONE; } -#define __user -#define __force -#define __iomem -#define to_user_ptr(x) ((void *)(uintptr_t)(x)) -#define offset_in_page(x) ((x) & PAGE_MASK) -#define page_to_phys(x) VM_PAGE_TO_PHYS(x) static inline int __copy_to_user_inatomic(void __user *to, const void *from, unsigned n) { @@ -1120,33 +466,6 @@ __copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset, return 0; } -static int -i915_gem_phys_pwrite(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv) -{ - void *vaddr = (char *)obj->phys_obj->handle->vaddr + args->offset; - char __user *user_data = to_user_ptr(args->data_ptr); - - if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { - unsigned long unwritten; - - /* The physical object once assigned is fixed for the lifetime - * of the obj, so we can safely drop the lock and continue - * to access vaddr. - */ - DRM_UNLOCK(dev); - unwritten = copy_from_user(vaddr, user_data, args->size); - DRM_LOCK(dev); - if (unwritten) - return -EFAULT; - } - - i915_gem_chipset_flush(dev); - return 0; -} - /* Per-page copy function for the shmem pread fastpath. * Flushes invalid cachelines before reading the target if * needs_clflush is set. */ @@ -1411,7 +730,7 @@ fast_user_write(struct drm_device *dev, vaddr_atomic = pmap_mapdev_attr(dev->agp->base + page_base, length, PAT_WRITE_COMBINING); /* We can use the cpu mem copy function because this is X86. */ - vaddr = (char *)vaddr_atomic + page_offset; + vaddr = (char __force*)vaddr_atomic + page_offset; unwritten = __copy_from_user_inatomic_nocache(vaddr, user_data, length); pmap_unmapdev((vm_offset_t)vaddr_atomic, length); @@ -1435,7 +754,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, ret = i915_gem_object_pin(obj, 0, true); /* XXXKIB ret = i915_gem_obj_ggtt_pin(obj, 0, true, true); */ - if (ret != 0) + if (ret) goto out; ret = i915_gem_object_set_to_gtt_domain(obj, true); @@ -1678,7 +997,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev, if (!needs_clflush_after && obj->base.write_domain != I915_GEM_DOMAIN_CPU) { i915_gem_clflush_object(obj); - i915_gem_chipset_flush(dev); + i915_gem_chipset_flush(dev); } } @@ -1775,35 +1094,159 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, DRM_UNLOCK(dev); return ret; } -#undef __user -#undef __force -#undef __iomem -#undef to_user_ptr -#undef offset_in_page -#undef page_to_phys + +static int +i915_gem_check_wedge(struct drm_i915_private *dev_priv) +{ + DRM_LOCK_ASSERT(dev_priv->dev); + + if (atomic_load_acq_int(&dev_priv->mm.wedged) != 0) { + bool recovery_complete; + + /* Give the error handler a chance to run. */ + mtx_lock(&dev_priv->error_completion_lock); + recovery_complete = (&dev_priv->error_completion) > 0; + mtx_unlock(&dev_priv->error_completion_lock); + + return (recovery_complete ? -EIO : -EAGAIN); + } + + return 0; +} + +/* + * Compare seqno against outstanding lazy request. Emit a request if they are + * equal. + */ +static int +i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno) +{ + int ret; + + DRM_LOCK_ASSERT(ring->dev); + + ret = 0; + if (seqno == ring->outstanding_lazy_request) { + struct drm_i915_gem_request *request; + + request = malloc(sizeof(*request), DRM_I915_GEM, + M_WAITOK | M_ZERO); + + ret = i915_add_request(ring, NULL, request); + if (ret != 0) { + free(request, DRM_I915_GEM); + return ret; + } + + MPASS(seqno == request->seqno); + } + return ret; +} + +static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, + bool interruptible) +{ + drm_i915_private_t *dev_priv = ring->dev->dev_private; + int ret = 0, flags; + + if (i915_seqno_passed(ring->get_seqno(ring), seqno)) + return 0; + + CTR2(KTR_DRM, "request_wait_begin %s %d", ring->name, seqno); + + mtx_lock(&dev_priv->irq_lock); + if (!ring->irq_get(ring)) { + mtx_unlock(&dev_priv->irq_lock); + return -ENODEV; + } + + flags = interruptible ? PCATCH : 0; + while (!i915_seqno_passed(ring->get_seqno(ring), seqno) + && !atomic_load_acq_int(&dev_priv->mm.wedged) && + ret == 0) { + ret = -msleep(ring, &dev_priv->irq_lock, flags, "915gwr", 0); + if (ret == -ERESTART) + ret = -ERESTARTSYS; + } + ring->irq_put(ring); + mtx_unlock(&dev_priv->irq_lock); + + CTR3(KTR_DRM, "request_wait_end %s %d %d", ring->name, seqno, ret); + + return ret; +} + +/** + * Waits for a sequence number to be signaled, and cleans up the + * request and object lists appropriately for that event. + */ +int +i915_wait_request(struct intel_ring_buffer *ring, uint32_t seqno) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + KASSERT(seqno != 0, ("Zero seqno")); + + ret = i915_gem_check_wedge(dev_priv); + if (ret) + return ret; + + ret = i915_gem_check_olr(ring, seqno); + if (ret) + return ret; + + ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible); + if (atomic_load_acq_int(&dev_priv->mm.wedged)) + ret = -EAGAIN; + + return ret; +} + +/** + * Ensures that all rendering to the object has completed and the object is + * safe to unbind from the GTT or access from the CPU. + */ +static __must_check int +i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) +{ + int ret; + + KASSERT((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0, + ("In GPU write domain")); + + CTR5(KTR_DRM, "object_wait_rendering %p %s %x %d %d", obj, + obj->ring != NULL ? obj->ring->name : "none", obj->gtt_offset, + obj->active, obj->last_rendering_seqno); + if (obj->active) { + ret = i915_wait_request(obj->ring, obj->last_rendering_seqno); + if (ret != 0) + return (ret); + i915_gem_retire_requests_ring(obj->ring); + } + + return 0; +} int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) + struct drm_file *file) { - struct drm_i915_gem_set_domain *args; + struct drm_i915_gem_set_domain *args = data; struct drm_i915_gem_object *obj; - uint32_t read_domains; - uint32_t write_domain; + uint32_t read_domains = args->read_domains; + uint32_t write_domain = args->write_domain; int ret; - args = data; - read_domains = args->read_domains; - write_domain = args->write_domain; - if ((write_domain & I915_GEM_GPU_DOMAINS) != 0 || (read_domains & I915_GEM_GPU_DOMAINS) != 0 || (write_domain != 0 && read_domains != write_domain)) - return (-EINVAL); + return -EINVAL; ret = i915_mutex_lock_interruptible(dev); - if (ret != 0) - return (ret); + if (ret) + return ret; obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (&obj->base == NULL) { @@ -1811,50 +1254,68 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, goto unlock; } - if ((read_domains & I915_GEM_DOMAIN_GTT) != 0) { + if (read_domains & I915_GEM_DOMAIN_GTT) { ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); + + /* Silently promote "you're not bound, there was nothing to do" + * to success, since the client was just asking us to + * make sure everything was done. + */ if (ret == -EINVAL) ret = 0; - } else + } else { ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); + } drm_gem_object_unreference(&obj->base); unlock: DRM_UNLOCK(dev); - return (ret); + return ret; } +/** + * Called when user space has done writes to this buffer + */ int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) + struct drm_file *file) { - struct drm_i915_gem_sw_finish *args; + struct drm_i915_gem_sw_finish *args = data; struct drm_i915_gem_object *obj; - int ret; - - args = data; + int ret = 0; ret = i915_mutex_lock_interruptible(dev); - if (ret != 0) - return (ret); + if (ret) + return ret; + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (&obj->base == NULL) { ret = -ENOENT; goto unlock; } - if (obj->pin_count != 0) + + /* Pinned buffers may be scanout, so flush the cache */ + if (obj->pin_count) i915_gem_object_flush_cpu_write_domain(obj); + drm_gem_object_unreference(&obj->base); unlock: DRM_UNLOCK(dev); - return (ret); + return ret; } +/** + * Maps the contents of an object, returning the address it is mapped + * into. + * + * While the mapping holds a reference on the contents of the object, it doesn't + * imply a ref on the object itself. + */ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) + struct drm_file *file) { - struct drm_i915_gem_mmap *args; + struct drm_i915_gem_mmap *args = data; struct drm_gem_object *obj; struct proc *p; vm_map_t map; @@ -1862,11 +1323,10 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, vm_size_t size; int error, rv; - args = data; - obj = drm_gem_object_lookup(dev, file, args->handle); if (obj == NULL) - return (-ENOENT); + return -ENOENT; + error = 0; if (args->size == 0) goto out; @@ -1906,6 +1366,23 @@ i915_gem_pager_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot, return (0); } +/** + * i915_gem_fault - fault a page into the GTT + * vma: VMA in question + * vmf: fault info + * + * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped + * from userspace. The fault handler takes care of binding the object to + * the GTT (if needed), allocating and programming a fence register (again, + * only if needed based on whether the old reg is still valid or the object + * is tiled) and inserting a new PTE into the faulting process. + * + * Note that the faulting process may involve evicting existing objects + * from the GTT and/or fence registers to make room. So performance may + * suffer if the GTT working set is large or there are few fence registers + * left. + */ + int i915_intr_pf; static int @@ -1916,7 +1393,7 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot, struct drm_i915_gem_object *obj; struct drm_device *dev; drm_i915_private_t *dev_priv; - vm_page_t m, oldm; + vm_page_t page, oldpage; int cause, ret; bool write; @@ -1943,17 +1420,17 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot, * progress. */ if (*mres != NULL) { - oldm = *mres; - vm_page_lock(oldm); - vm_page_remove(oldm); - vm_page_unlock(oldm); + oldpage = *mres; + vm_page_lock(oldpage); + vm_page_remove(oldpage); + vm_page_unlock(oldpage); *mres = NULL; } else - oldm = NULL; + oldpage = NULL; VM_OBJECT_WUNLOCK(vm_obj); retry: cause = ret = 0; - m = NULL; + page = NULL; if (i915_intr_pf) { ret = i915_mutex_lock_interruptible(dev); @@ -1970,13 +1447,13 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot, * mapping for the page. Recheck. */ VM_OBJECT_WLOCK(vm_obj); - m = vm_page_lookup(vm_obj, OFF_TO_IDX(offset)); - if (m != NULL) { - if (vm_page_busied(m)) { + page = vm_page_lookup(vm_obj, OFF_TO_IDX(offset)); + if (page != NULL) { + if (vm_page_busied(page)) { DRM_UNLOCK(dev); - vm_page_lock(m); + vm_page_lock(page); VM_OBJECT_WUNLOCK(vm_obj); - vm_page_busy_sleep(m, "915pee"); + vm_page_busy_sleep(page, "915pee"); goto retry; } goto have_page; @@ -2019,45 +1496,45 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot, obj->fault_mappable = true; VM_OBJECT_WLOCK(vm_obj); - m = PHYS_TO_VM_PAGE(dev->agp->base + obj->gtt_offset + offset); - KASSERT((m->flags & PG_FICTITIOUS) != 0, + page = PHYS_TO_VM_PAGE(dev->agp->base + obj->gtt_offset + offset); + KASSERT((page->flags & PG_FICTITIOUS) != 0, ("physical address %#jx not fictitious", (uintmax_t)(dev->agp->base + obj->gtt_offset + offset))); - if (m == NULL) { + if (page == NULL) { VM_OBJECT_WUNLOCK(vm_obj); cause = 60; ret = -EFAULT; goto unlock; } - KASSERT((m->flags & PG_FICTITIOUS) != 0, - ("not fictitious %p", m)); - KASSERT(m->wire_count == 1, ("wire_count not 1 %p", m)); + KASSERT((page->flags & PG_FICTITIOUS) != 0, + ("not fictitious %p", page)); + KASSERT(page->wire_count == 1, ("wire_count not 1 %p", page)); - if (vm_page_busied(m)) { + if (vm_page_busied(page)) { DRM_UNLOCK(dev); - vm_page_lock(m); + vm_page_lock(page); VM_OBJECT_WUNLOCK(vm_obj); - vm_page_busy_sleep(m, "915pbs"); + vm_page_busy_sleep(page, "915pbs"); goto retry; } - if (vm_page_insert(m, vm_obj, OFF_TO_IDX(offset))) { + if (vm_page_insert(page, vm_obj, OFF_TO_IDX(offset))) { DRM_UNLOCK(dev); VM_OBJECT_WUNLOCK(vm_obj); VM_WAIT; goto retry; } - m->valid = VM_PAGE_BITS_ALL; + page->valid = VM_PAGE_BITS_ALL; have_page: - *mres = m; - vm_page_xbusy(m); + *mres = page; + vm_page_xbusy(page); CTR4(KTR_DRM, "fault %p %jx %x phys %x", gem_obj, offset, prot, - m->phys_addr); + page->phys_addr); DRM_UNLOCK(dev); - if (oldm != NULL) { - vm_page_lock(oldm); - vm_page_free(oldm); - vm_page_unlock(oldm); + if (oldpage != NULL) { + vm_page_lock(oldpage); + vm_page_free(oldpage); + vm_page_unlock(oldpage); } vm_object_pip_wakeup(vm_obj); return (VM_PAGER_OK); @@ -2099,19 +1576,145 @@ struct cdev_pager_ops i915_gem_pager_ops = { .cdev_pg_dtor = i915_gem_pager_dtor }; -int -i915_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset) +/** + * i915_gem_release_mmap - remove physical page mappings + * @obj: obj in question + * + * Preserve the reservation of the mmapping with the DRM core code, but + * relinquish ownership of the pages back to the system. + * + * It is vital that we remove the page mapping if we have mapped a tiled + * object through the GTT and then lose the fence register due to + * resource pressure. Similarly if the object has been moved out of the + * aperture, than pages mapped into userspace must be revoked. Removing the + * mapping will then trigger a page fault on the next user access, allowing + * fixup by i915_gem_fault(). + */ +void +i915_gem_release_mmap(struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv; + vm_object_t devobj; + vm_page_t page; + int i, page_count; + + if (!obj->fault_mappable) + return; + + CTR3(KTR_DRM, "release_mmap %p %x %x", obj, obj->gtt_offset, + OFF_TO_IDX(obj->base.size)); + devobj = cdev_pager_lookup(obj); + if (devobj != NULL) { + page_count = OFF_TO_IDX(obj->base.size); + + VM_OBJECT_WLOCK(devobj); +retry: + for (i = 0; i < page_count; i++) { + page = vm_page_lookup(devobj, i); + if (page == NULL) + continue; + if (vm_page_sleep_if_busy(page, "915unm")) + goto retry; + cdev_pager_free_page(devobj, page); + } + VM_OBJECT_WUNLOCK(devobj); + vm_object_deallocate(devobj); + } + + obj->fault_mappable = false; +} + +static uint32_t +i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) +{ + uint32_t gtt_size; + + if (INTEL_INFO(dev)->gen >= 4 || + tiling_mode == I915_TILING_NONE) + return size; + + /* Previous chips need a power-of-two fence region when tiling */ + if (INTEL_INFO(dev)->gen == 3) + gtt_size = 1024*1024; + else + gtt_size = 512*1024; + + while (gtt_size < size) + gtt_size <<= 1; + + return gtt_size; +} + +/** + * i915_gem_get_gtt_alignment - return required GTT alignment for an object + * @obj: object to check + * + * Return the required GTT alignment for an object, taking into account + * potential fence register mapping. + */ +static uint32_t +i915_gem_get_gtt_alignment(struct drm_device *dev, + uint32_t size, + int tiling_mode) +{ + /* + * Minimum alignment is 4k (GTT page size), but might be greater + * if a fence register is needed for the object. + */ + if (INTEL_INFO(dev)->gen >= 4 || + tiling_mode == I915_TILING_NONE) + return 4096; + + /* + * Previous chips need to be aligned to the size of the smallest + * fence register that can contain the object. + */ + return i915_gem_get_gtt_size(dev, size, tiling_mode); +} + +/** + * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an + * unfenced object + * @dev: the device + * @size: size of the object + * @tiling_mode: tiling mode of the object + * + * Return the required GTT alignment for an object, only taking into account + * unfenced tiled surface requirements. + */ +uint32_t +i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, + uint32_t size, + int tiling_mode) +{ + if (tiling_mode == I915_TILING_NONE) + return 4096; + + /* + * Minimum alignment is 4k (GTT page size) for sane hw. + */ + if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev)) + return 4096; + + /* Previous hardware however needs to be aligned to a power-of-two + * tile height. The simplest method for determining this is to reuse + * the power-of-tile object size. + */ + return i915_gem_get_gtt_size(dev, size, tiling_mode); +} + +int +i915_gem_mmap_gtt(struct drm_file *file, + struct drm_device *dev, + uint32_t handle, + uint64_t *offset) +{ + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; int ret; - dev_priv = dev->dev_private; - ret = i915_mutex_lock_interruptible(dev); - if (ret != 0) - return (ret); + if (ret) + return ret; obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); if (&obj->base == NULL) { @@ -2131,694 +1734,61 @@ i915_gem_mmap_gtt(struct drm_file *file, struct drm_device *dev, } ret = drm_gem_create_mmap_offset(&obj->base); - if (ret != 0) + if (ret) goto out; *offset = DRM_GEM_MAPPING_OFF(obj->base.map_list.key) | DRM_GEM_MAPPING_KEY; + out: drm_gem_object_unreference(&obj->base); unlock: DRM_UNLOCK(dev); - return (ret); -} - -int -i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_private *dev_priv; - struct drm_i915_gem_mmap_gtt *args; - - dev_priv = dev->dev_private; - args = data; - - return (i915_gem_mmap_gtt(file, dev, args->handle, &args->offset)); -} - -struct drm_i915_gem_object * -i915_gem_alloc_object(struct drm_device *dev, size_t size) -{ - struct drm_i915_private *dev_priv; - struct drm_i915_gem_object *obj; - - dev_priv = dev->dev_private; - - obj = malloc(sizeof(*obj), DRM_I915_GEM, M_WAITOK | M_ZERO); - - if (drm_gem_object_init(dev, &obj->base, size) != 0) { - free(obj, DRM_I915_GEM); - return (NULL); - } - - obj->base.write_domain = I915_GEM_DOMAIN_CPU; - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - - if (HAS_LLC(dev)) - obj->cache_level = I915_CACHE_LLC; - else - obj->cache_level = I915_CACHE_NONE; - obj->base.driver_private = NULL; - obj->fence_reg = I915_FENCE_REG_NONE; - INIT_LIST_HEAD(&obj->mm_list); - INIT_LIST_HEAD(&obj->gtt_list); - INIT_LIST_HEAD(&obj->ring_list); - INIT_LIST_HEAD(&obj->exec_list); - INIT_LIST_HEAD(&obj->gpu_write_list); - obj->madv = I915_MADV_WILLNEED; - /* Avoid an unnecessary call to unbind on the first bind. */ - obj->map_and_fenceable = true; - - i915_gem_info_add_obj(dev_priv, size); - - return (obj); -} - -void -i915_gem_clflush_object(struct drm_i915_gem_object *obj) -{ - - /* If we don't have a page list set up, then we're not pinned - * to GPU, and we can ignore the cache flush because it'll happen - * again at bind time. - */ - if (obj->pages == NULL) - return; - - /* If the GPU is snooping the contents of the CPU cache, - * we do not need to manually clear the CPU cache lines. However, - * the caches are only snooped when the render cache is - * flushed/invalidated. As we always have to emit invalidations - * and flushes when moving into and out of the RENDER domain, correct - * snooping behaviour occurs naturally as the result of our domain - * tracking. - */ - if (obj->cache_level != I915_CACHE_NONE) - return; - - CTR1(KTR_DRM, "object_clflush %p", obj); - drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE); -} - -static void -i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) -{ - uint32_t old_write_domain; - - if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) - return; - - i915_gem_clflush_object(obj); - intel_gtt_chipset_flush(); - old_write_domain = obj->base.write_domain; - obj->base.write_domain = 0; - - CTR3(KTR_DRM, "object_change_domain flush_cpu_write %p %x %x", obj, - obj->base.read_domains, old_write_domain); -} - -static int -i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj) -{ - - if ((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0) - return (0); - return (i915_gem_flush_ring(obj->ring, 0, obj->base.write_domain)); -} - -static void -i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) -{ - uint32_t old_write_domain; - - if (obj->base.write_domain != I915_GEM_DOMAIN_GTT) - return; - - wmb(); - - old_write_domain = obj->base.write_domain; - obj->base.write_domain = 0; - - CTR3(KTR_DRM, "object_change_domain flush gtt_write %p %x %x", obj, - obj->base.read_domains, old_write_domain); -} - -int -i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) -{ - drm_i915_private_t *dev_priv = obj->base.dev->dev_private; - uint32_t old_write_domain, old_read_domains; - int ret; - - if (obj->gtt_space == NULL) - return (-EINVAL); - - if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) - return 0; - - ret = i915_gem_object_flush_gpu_write_domain(obj); - if (ret != 0) - return (ret); - - if (obj->pending_gpu_write || write) { - ret = i915_gem_object_wait_rendering(obj); - if (ret != 0) - return (ret); - } - - i915_gem_object_flush_cpu_write_domain(obj); - - old_write_domain = obj->base.write_domain; - old_read_domains = obj->base.read_domains; - - KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) == 0, - ("In GTT write domain")); - obj->base.read_domains |= I915_GEM_DOMAIN_GTT; - if (write) { - obj->base.read_domains = I915_GEM_DOMAIN_GTT; - obj->base.write_domain = I915_GEM_DOMAIN_GTT; - obj->dirty = 1; - } - - /* And bump the LRU for this access */ - if (i915_gem_object_is_inactive(obj)) - list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - - CTR3(KTR_DRM, "object_change_domain set_to_gtt %p %x %x", obj, - old_read_domains, old_write_domain); - return (0); -} - -int -i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, - enum i915_cache_level cache_level) -{ - struct drm_device *dev; - drm_i915_private_t *dev_priv; - int ret; - - if (obj->cache_level == cache_level) - return 0; - - if (obj->pin_count) { - DRM_DEBUG("can not change the cache level of pinned objects\n"); - return (-EBUSY); - } - - dev = obj->base.dev; - dev_priv = dev->dev_private; - if (obj->gtt_space) { - ret = i915_gem_object_finish_gpu(obj); - if (ret != 0) - return (ret); - - i915_gem_object_finish_gtt(obj); - - /* Before SandyBridge, you could not use tiling or fence - * registers with snooped memory, so relinquish any fences - * currently pointing to our region in the aperture. - */ - if (INTEL_INFO(obj->base.dev)->gen < 6) { - ret = i915_gem_object_put_fence(obj); - if (ret != 0) - return (ret); - } - - if (obj->has_global_gtt_mapping) - i915_gem_gtt_bind_object(obj, cache_level); - if (obj->has_aliasing_ppgtt_mapping) - i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, - obj, cache_level); - } - - if (cache_level == I915_CACHE_NONE) { - u32 old_read_domains, old_write_domain; - - /* If we're coming from LLC cached, then we haven't - * actually been tracking whether the data is in the - * CPU cache or not, since we only allow one bit set - * in obj->write_domain and have been skipping the clflushes. - * Just set it to the CPU cache for now. - */ - KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) == 0, - ("obj %p in CPU write domain", obj)); - KASSERT((obj->base.read_domains & ~I915_GEM_DOMAIN_CPU) == 0, - ("obj %p in CPU read domain", obj)); - - old_read_domains = obj->base.read_domains; - old_write_domain = obj->base.write_domain; - - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - obj->base.write_domain = I915_GEM_DOMAIN_CPU; - - CTR3(KTR_DRM, "object_change_domain set_cache_level %p %x %x", - obj, old_read_domains, old_write_domain); - } - - obj->cache_level = cache_level; - return (0); -} - -static bool is_pin_display(struct drm_i915_gem_object *obj) -{ - /* There are 3 sources that pin objects: - * 1. The display engine (scanouts, sprites, cursors); - * 2. Reservations for execbuffer; - * 3. The user. - * - * We can ignore reservations as we hold the struct_mutex and - * are only called outside of the reservation path. The user - * can only increment pin_count once, and so if after - * subtracting the potential reference by the user, any pin_count - * remains, it must be due to another use by the display engine. - */ - return obj->pin_count - !!obj->user_pin_count; -} - -int -i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, - u32 alignment, struct intel_ring_buffer *pipelined) -{ - u32 old_read_domains, old_write_domain; - int ret; - - ret = i915_gem_object_flush_gpu_write_domain(obj); - if (ret != 0) - return (ret); - - if (pipelined != obj->ring) { - ret = i915_gem_object_sync(obj, pipelined); - if (ret) - return (ret); - } - - obj->pin_display = true; - ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE); - if (ret != 0) - goto err_unpin_display; - - ret = i915_gem_object_pin(obj, alignment, true); - if (ret != 0) - goto err_unpin_display; - - i915_gem_object_flush_cpu_write_domain(obj); - - old_write_domain = obj->base.write_domain; - old_read_domains = obj->base.read_domains; - - KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) == 0, - ("obj %p in GTT write domain", obj)); - obj->base.read_domains |= I915_GEM_DOMAIN_GTT; - - CTR3(KTR_DRM, "object_change_domain pin_to_display_plan %p %x %x", - obj, old_read_domains, obj->base.write_domain); - return (0); - -err_unpin_display: - obj->pin_display = is_pin_display(obj); return ret; } -void -i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj) -{ - i915_gem_object_unpin(obj); - obj->pin_display = is_pin_display(obj); -} - -int -i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) -{ - int ret; - - if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0) - return (0); - - if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { - ret = i915_gem_flush_ring(obj->ring, 0, obj->base.write_domain); - if (ret != 0) - return (ret); - } - - ret = i915_gem_object_wait_rendering(obj); - if (ret != 0) - return (ret); - - obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; - - return (0); -} - -int -i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) -{ - uint32_t old_write_domain, old_read_domains; - int ret; - - if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) - return 0; - - ret = i915_gem_object_flush_gpu_write_domain(obj); - if (ret != 0) - return (ret); - - if (write || obj->pending_gpu_write) { - ret = i915_gem_object_wait_rendering(obj); - if (ret != 0) - return (ret); - } - - i915_gem_object_flush_gtt_write_domain(obj); - - old_write_domain = obj->base.write_domain; - old_read_domains = obj->base.read_domains; - - if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { - i915_gem_clflush_object(obj); - obj->base.read_domains |= I915_GEM_DOMAIN_CPU; - } - - KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) == 0, - ("In cpu write domain")); - - if (write) { - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - obj->base.write_domain = I915_GEM_DOMAIN_CPU; - } - - CTR3(KTR_DRM, "object_change_domain set_to_cpu %p %x %x", obj, - old_read_domains, old_write_domain); - return (0); -} - -static uint32_t -i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) -{ - uint32_t gtt_size; - - if (INTEL_INFO(dev)->gen >= 4 || - tiling_mode == I915_TILING_NONE) - return (size); - - /* Previous chips need a power-of-two fence region when tiling */ - if (INTEL_INFO(dev)->gen == 3) - gtt_size = 1024*1024; - else - gtt_size = 512*1024; - - while (gtt_size < size) - gtt_size <<= 1; - - return (gtt_size); -} - /** - * i915_gem_get_gtt_alignment - return required GTT alignment for an object - * @obj: object to check + * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing + * @dev: DRM device + * @data: GTT mapping ioctl data + * @file: GEM object info * - * Return the required GTT alignment for an object, taking into account - * potential fence register mapping. + * Simply returns the fake offset to userspace so it can mmap it. + * The mmap call will end up in drm_gem_mmap(), which will set things + * up so we can get faults in the handler above. + * + * The fault handler will take care of binding the object into the GTT + * (since it may have been evicted to make room for something), allocating + * a fence register, and mapping the appropriate aperture address into + * userspace. */ -static uint32_t -i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size, - int tiling_mode) -{ - - /* - * Minimum alignment is 4k (GTT page size), but might be greater - * if a fence register is needed for the object. - */ - if (INTEL_INFO(dev)->gen >= 4 || - tiling_mode == I915_TILING_NONE) - return (4096); - - /* - * Previous chips need to be aligned to the size of the smallest - * fence register that can contain the object. - */ - return (i915_gem_get_gtt_size(dev, size, tiling_mode)); -} - -uint32_t -i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, uint32_t size, - int tiling_mode) -{ - - if (tiling_mode == I915_TILING_NONE) - return (4096); - - /* - * Minimum alignment is 4k (GTT page size) for sane hw. - */ - if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev)) - return (4096); - - /* - * Previous hardware however needs to be aligned to a power-of-two - * tile height. The simplest method for determining this is to reuse - * the power-of-tile object size. - */ - return (i915_gem_get_gtt_size(dev, size, tiling_mode)); -} - -static int -i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, - unsigned alignment, bool map_and_fenceable) -{ - struct drm_device *dev; - struct drm_i915_private *dev_priv; - struct drm_mm_node *free_space; - uint32_t size, fence_size, fence_alignment, unfenced_alignment; - bool mappable, fenceable; - int ret; - - dev = obj->base.dev; - dev_priv = dev->dev_private; - - if (obj->madv != I915_MADV_WILLNEED) { - DRM_ERROR("Attempting to bind a purgeable object\n"); - return (-EINVAL); - } - - fence_size = i915_gem_get_gtt_size(dev, obj->base.size, - obj->tiling_mode); - fence_alignment = i915_gem_get_gtt_alignment(dev, obj->base.size, - obj->tiling_mode); - unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(dev, - obj->base.size, obj->tiling_mode); - if (alignment == 0) - alignment = map_and_fenceable ? fence_alignment : - unfenced_alignment; - if (map_and_fenceable && (alignment & (fence_alignment - 1)) != 0) { - DRM_ERROR("Invalid object alignment requested %u\n", alignment); - return (-EINVAL); - } - - size = map_and_fenceable ? fence_size : obj->base.size; - - /* If the object is bigger than the entire aperture, reject it early - * before evicting everything in a vain attempt to find space. - */ - if (obj->base.size > (map_and_fenceable ? - dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { - DRM_ERROR( -"Attempting to bind an object larger than the aperture\n"); - return (-E2BIG); - } - - search_free: - if (map_and_fenceable) - free_space = drm_mm_search_free_in_range( - &dev_priv->mm.gtt_space, size, alignment, 0, - dev_priv->mm.gtt_mappable_end, 0); - else - free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, - size, alignment, 0); - if (free_space != NULL) { - if (map_and_fenceable) - obj->gtt_space = drm_mm_get_block_range_generic( - free_space, size, alignment, 0, 0, - dev_priv->mm.gtt_mappable_end, 1); - else - obj->gtt_space = drm_mm_get_block_generic(free_space, - size, alignment, 0, 1); - } - if (obj->gtt_space == NULL) { - ret = i915_gem_evict_something(dev, size, alignment, - map_and_fenceable); - if (ret != 0) - return (ret); - goto search_free; - } - ret = i915_gem_object_get_pages_gtt(obj, 0); - if (ret != 0) { - drm_mm_put_block(obj->gtt_space); - obj->gtt_space = NULL; - /* - * i915_gem_object_get_pages_gtt() cannot return - * ENOMEM, since we use vm_page_grab(). - */ - return (ret); - } - - ret = i915_gem_gtt_prepare_object(obj); - if (ret != 0) { - i915_gem_object_put_pages_gtt(obj); - drm_mm_put_block(obj->gtt_space); - obj->gtt_space = NULL; - if (i915_gem_evict_everything(dev, false)) - return (ret); - goto search_free; - } - - if (!dev_priv->mm.aliasing_ppgtt) - i915_gem_gtt_bind_object(obj, obj->cache_level); - - list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); - list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - - KASSERT((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0, - ("Object in gpu read domain")); - KASSERT((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0, - ("Object in gpu write domain")); - - obj->gtt_offset = obj->gtt_space->start; - - fenceable = - obj->gtt_space->size == fence_size && - (obj->gtt_space->start & (fence_alignment - 1)) == 0; - - mappable = - obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; - obj->map_and_fenceable = mappable && fenceable; - - CTR4(KTR_DRM, "object_bind %p %x %x %d", obj, obj->gtt_offset, - obj->base.size, map_and_fenceable); - return (0); -} - int -i915_gem_object_sync(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *to) +i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) { - struct intel_ring_buffer *from = obj->ring; - u32 seqno; - int ret, idx; + struct drm_i915_gem_mmap_gtt *args = data; - if (from == NULL || to == from) - return 0; - - if (to == NULL || !i915_semaphore_is_enabled(obj->base.dev)) - return i915_gem_object_wait_rendering(obj); - - idx = intel_ring_sync_index(from, to); - - seqno = obj->last_rendering_seqno; - if (seqno <= from->sync_seqno[idx]) - return 0; - - if (seqno == from->outstanding_lazy_request) { - struct drm_i915_gem_request *request; - - request = malloc(sizeof(*request), DRM_I915_GEM, - M_WAITOK | M_ZERO); - ret = i915_add_request(from, NULL, request); - if (ret) { - free(request, DRM_I915_GEM); - return ret; - } - seqno = request->seqno; - } - - - ret = to->sync_to(to, from, seqno); - if (!ret) - from->sync_seqno[idx] = seqno; - - return ret; + return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); } -static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) +/* Immediately discard the backing storage */ +static void +i915_gem_object_truncate(struct drm_i915_gem_object *obj) { - u32 old_write_domain, old_read_domains; + vm_object_t vm_obj; - /* Act a barrier for all accesses through the GTT */ - mb(); - - /* Force a pagefault for domain tracking on next user access */ - i915_gem_release_mmap(obj); - - if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0) - return; - - old_read_domains = obj->base.read_domains; - old_write_domain = obj->base.write_domain; - - obj->base.read_domains &= ~I915_GEM_DOMAIN_GTT; - obj->base.write_domain &= ~I915_GEM_DOMAIN_GTT; - - CTR3(KTR_DRM, "object_change_domain finish gtt %p %x %x", - obj, old_read_domains, old_write_domain); + vm_obj = obj->base.vm_obj; + VM_OBJECT_WLOCK(vm_obj); + vm_object_page_remove(vm_obj, 0, 0, false); + VM_OBJECT_WUNLOCK(vm_obj); + drm_gem_free_mmap_offset(&obj->base); + obj->madv = I915_MADV_PURGED_INTERNAL; } -int -i915_gem_object_unbind(struct drm_i915_gem_object *obj) +static inline int +i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) { - drm_i915_private_t *dev_priv; - int ret; - - dev_priv = obj->base.dev->dev_private; - ret = 0; - if (obj->gtt_space == NULL) - return (0); - if (obj->pin_count != 0) { - DRM_ERROR("Attempting to unbind pinned buffer\n"); - return (-EINVAL); - } - - ret = i915_gem_object_finish_gpu(obj); - if (ret == -ERESTARTSYS || ret == -EINTR) - return (ret); - - i915_gem_object_finish_gtt(obj); - - if (ret == 0) - ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret == -ERESTARTSYS || ret == -EINTR) - return (ret); - if (ret != 0) { - i915_gem_clflush_object(obj); - obj->base.read_domains = obj->base.write_domain = - I915_GEM_DOMAIN_CPU; - } - - ret = i915_gem_object_put_fence(obj); - if (ret) - return (ret); - - if (obj->has_global_gtt_mapping) - i915_gem_gtt_unbind_object(obj); - if (obj->has_aliasing_ppgtt_mapping) { - i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj); - obj->has_aliasing_ppgtt_mapping = 0; - } - i915_gem_gtt_finish_object(obj); - - i915_gem_object_put_pages_gtt(obj); - - list_del_init(&obj->gtt_list); - list_del_init(&obj->mm_list); - obj->map_and_fenceable = true; - - drm_mm_put_block(obj->gtt_space); - obj->gtt_space = NULL; - obj->gtt_offset = 0; - - if (i915_gem_object_is_purgeable(obj)) - i915_gem_object_truncate(obj); - CTR1(KTR_DRM, "object_unbind %p", obj); - - return (ret); + return obj->madv == I915_MADV_DONTNEED; } static void @@ -2826,98 +1796,23 @@ i915_gem_object_put_pages_range_locked(struct drm_i915_gem_object *obj, vm_pindex_t si, vm_pindex_t ei) { vm_object_t vm_obj; - vm_page_t m; + vm_page_t page; vm_pindex_t i; vm_obj = obj->base.vm_obj; VM_OBJECT_ASSERT_LOCKED(vm_obj); - for (i = si, m = vm_page_lookup(vm_obj, i); i < ei; - m = vm_page_next(m), i++) { - KASSERT(m->pindex == i, ("pindex %jx %jx", - (uintmax_t)m->pindex, (uintmax_t)i)); - vm_page_lock(m); - vm_page_unwire(m, PQ_INACTIVE); - if (m->wire_count == 0) + for (i = si, page = vm_page_lookup(vm_obj, i); i < ei; + page = vm_page_next(page), i++) { + KASSERT(page->pindex == i, ("pindex %jx %jx", + (uintmax_t)page->pindex, (uintmax_t)i)); + vm_page_lock(page); + vm_page_unwire(page, PQ_INACTIVE); + if (page->wire_count == 0) atomic_add_long(&i915_gem_wired_pages_cnt, -1); - vm_page_unlock(m); + vm_page_unlock(page); } } -static void -i915_gem_object_put_pages_range(struct drm_i915_gem_object *obj, - off_t start, off_t end) -{ - vm_object_t vm_obj; - - vm_obj = obj->base.vm_obj; - VM_OBJECT_WLOCK(vm_obj); - i915_gem_object_put_pages_range_locked(obj, - OFF_TO_IDX(trunc_page(start)), OFF_TO_IDX(round_page(end))); - VM_OBJECT_WUNLOCK(vm_obj); -} - -static int -i915_gem_object_get_pages_range(struct drm_i915_gem_object *obj, - off_t start, off_t end) -{ - vm_object_t vm_obj; - vm_page_t m; - vm_pindex_t si, ei, i; - bool need_swizzle, fresh; - - need_swizzle = i915_gem_object_needs_bit17_swizzle(obj) != 0; - vm_obj = obj->base.vm_obj; - si = OFF_TO_IDX(trunc_page(start)); - ei = OFF_TO_IDX(round_page(end)); - VM_OBJECT_WLOCK(vm_obj); - for (i = si; i < ei; i++) { - m = i915_gem_wire_page(vm_obj, i, &fresh); - if (m == NULL) - goto failed; - if (need_swizzle && fresh) - i915_gem_object_do_bit_17_swizzle_page(obj, m); - } - VM_OBJECT_WUNLOCK(vm_obj); - return (0); -failed: - i915_gem_object_put_pages_range_locked(obj, si, i); - VM_OBJECT_WUNLOCK(vm_obj); - return (-EIO); -} - -static int -i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, - int flags) -{ - struct drm_device *dev; - vm_object_t vm_obj; - vm_page_t m; - vm_pindex_t i, page_count; - int res; - - dev = obj->base.dev; - KASSERT(obj->pages == NULL, ("Obj already has pages")); - page_count = OFF_TO_IDX(obj->base.size); - obj->pages = malloc(page_count * sizeof(vm_page_t), DRM_I915_GEM, - M_WAITOK); - res = i915_gem_object_get_pages_range(obj, 0, obj->base.size); - if (res != 0) { - free(obj->pages, DRM_I915_GEM); - obj->pages = NULL; - return (res); - } - vm_obj = obj->base.vm_obj; - VM_OBJECT_WLOCK(vm_obj); - for (i = 0, m = vm_page_lookup(vm_obj, 0); i < page_count; - i++, m = vm_page_next(m)) { - KASSERT(m->pindex == i, ("pindex %jx %jx", - (uintmax_t)m->pindex, (uintmax_t)i)); - obj->pages[i] = m; - } - VM_OBJECT_WUNLOCK(vm_obj); - return (0); -} - #define GEM_PARANOID_CHECK_GTT 0 #if GEM_PARANOID_CHECK_GTT static void @@ -2945,10 +1840,23 @@ i915_gem_assert_pages_not_mapped(struct drm_device *dev, vm_page_t *ma, } #endif +static void +i915_gem_object_put_pages_range(struct drm_i915_gem_object *obj, + off_t start, off_t end) +{ + vm_object_t vm_obj; + + vm_obj = obj->base.vm_obj; + VM_OBJECT_WLOCK(vm_obj); + i915_gem_object_put_pages_range_locked(obj, + OFF_TO_IDX(trunc_page(start)), OFF_TO_IDX(round_page(end))); + VM_OBJECT_WUNLOCK(vm_obj); +} + static void i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) { - vm_page_t m; + vm_page_t page; int page_count, i; KASSERT(obj->madv != I915_MADV_PURGED_INTERNAL, ("Purged object")); @@ -2963,14 +1871,14 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) i915_gem_assert_pages_not_mapped(obj->base.dev, obj->pages, page_count); #endif for (i = 0; i < page_count; i++) { - m = obj->pages[i]; + page = obj->pages[i]; if (obj->dirty) - vm_page_dirty(m); + vm_page_dirty(page); if (obj->madv == I915_MADV_WILLNEED) - vm_page_reference(m); - vm_page_lock(m); + vm_page_reference(page); + vm_page_lock(page); vm_page_unwire(obj->pages[i], PQ_ACTIVE); - vm_page_unlock(m); + vm_page_unlock(page); atomic_add_long(&i915_gem_wired_pages_cnt, -1); } VM_OBJECT_WUNLOCK(obj->base.vm_obj); @@ -2979,69 +1887,139 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) obj->pages = NULL; } -void -i915_gem_release_mmap(struct drm_i915_gem_object *obj) +static int +i915_gpu_is_active(struct drm_device *dev) { - vm_object_t devobj; - vm_page_t m; - int i, page_count; + drm_i915_private_t *dev_priv = dev->dev_private; - if (!obj->fault_mappable) - return; - - CTR3(KTR_DRM, "release_mmap %p %x %x", obj, obj->gtt_offset, - OFF_TO_IDX(obj->base.size)); - devobj = cdev_pager_lookup(obj); - if (devobj != NULL) { - page_count = OFF_TO_IDX(obj->base.size); - - VM_OBJECT_WLOCK(devobj); -retry: - for (i = 0; i < page_count; i++) { - m = vm_page_lookup(devobj, i); - if (m == NULL) - continue; - if (vm_page_sleep_if_busy(m, "915unm")) - goto retry; - cdev_pager_free_page(devobj, m); - } - VM_OBJECT_WUNLOCK(devobj); - vm_object_deallocate(devobj); - } - - obj->fault_mappable = false; + return (!list_empty(&dev_priv->mm.flushing_list) || + !list_empty(&dev_priv->mm.active_list)); } -int -i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) +static void +i915_gem_lowmem(void *arg) { - int ret; + struct drm_device *dev; + struct drm_i915_private *dev_priv; + struct drm_i915_gem_object *obj, *next; + int cnt, cnt_fail, cnt_total; - KASSERT((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0, - ("In GPU write domain")); + dev = arg; + dev_priv = dev->dev_private; - CTR5(KTR_DRM, "object_wait_rendering %p %s %x %d %d", obj, - obj->ring != NULL ? obj->ring->name : "none", obj->gtt_offset, - obj->active, obj->last_rendering_seqno); - if (obj->active) { - ret = i915_wait_request(obj->ring, obj->last_rendering_seqno); - if (ret != 0) - return (ret); - i915_gem_retire_requests_ring(obj->ring); + if (!sx_try_xlock(&dev->dev_struct_lock)) + return; + + CTR0(KTR_DRM, "gem_lowmem"); + +rescan: + /* first scan for clean buffers */ + i915_gem_retire_requests(dev); + + cnt_total = cnt_fail = cnt = 0; + + list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, + mm_list) { + if (i915_gem_object_is_purgeable(obj)) { + if (i915_gem_object_unbind(obj) != 0) + cnt_total++; + } else + cnt_total++; } + + /* second pass, evict/count anything still on the inactive list */ + list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, + mm_list) { + if (i915_gem_object_unbind(obj) == 0) + cnt++; + else + cnt_fail++; + } + + if (cnt_fail > cnt_total / 100 && i915_gpu_is_active(dev)) { + /* + * We are desperate for pages, so as a last resort, wait + * for the GPU to finish and discard whatever we can. + * This has a dramatic impact to reduce the number of + * OOM-killer events whilst running the GPU aggressively. + */ + if (i915_gpu_idle(dev) == 0) + goto rescan; + } + DRM_UNLOCK(dev); +} + +static int +i915_gem_object_get_pages_range(struct drm_i915_gem_object *obj, + off_t start, off_t end) +{ + vm_object_t vm_obj; + vm_page_t page; + vm_pindex_t si, ei, i; + bool need_swizzle, fresh; + + need_swizzle = i915_gem_object_needs_bit17_swizzle(obj) != 0; + vm_obj = obj->base.vm_obj; + si = OFF_TO_IDX(trunc_page(start)); + ei = OFF_TO_IDX(round_page(end)); + VM_OBJECT_WLOCK(vm_obj); + for (i = si; i < ei; i++) { + page = i915_gem_wire_page(vm_obj, i, &fresh); + if (page == NULL) + goto failed; + if (need_swizzle && fresh) + i915_gem_object_do_bit_17_swizzle_page(obj, page); + } + VM_OBJECT_WUNLOCK(vm_obj); + return (0); +failed: + i915_gem_object_put_pages_range_locked(obj, si, i); + VM_OBJECT_WUNLOCK(vm_obj); + return (-EIO); +} + +static int +i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, + int flags) +{ + vm_object_t vm_obj; + vm_page_t page; + vm_pindex_t i, page_count; + int res; + + KASSERT(obj->pages == NULL, ("Obj already has pages")); + + page_count = OFF_TO_IDX(obj->base.size); + obj->pages = malloc(page_count * sizeof(vm_page_t), DRM_I915_GEM, + M_WAITOK); + res = i915_gem_object_get_pages_range(obj, 0, obj->base.size); + if (res != 0) { + free(obj->pages, DRM_I915_GEM); + obj->pages = NULL; + return (res); + } + vm_obj = obj->base.vm_obj; + VM_OBJECT_WLOCK(vm_obj); + for (i = 0, page = vm_page_lookup(vm_obj, 0); i < page_count; + i++, page = vm_page_next(page)) { + KASSERT(page->pindex == i, ("pindex %jx %jx", + (uintmax_t)page->pindex, (uintmax_t)i)); + obj->pages[i] = page; + } + VM_OBJECT_WUNLOCK(vm_obj); return (0); } void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *ring, uint32_t seqno) + struct intel_ring_buffer *ring, uint32_t seqno) { struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_fence_reg *reg; - obj->ring = ring; KASSERT(ring != NULL, ("NULL ring")); + obj->ring = ring; /* Add a reference if we're newly entering the active list. */ if (!obj->active) { @@ -3112,262 +2090,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) #endif } -static void -i915_gem_object_truncate(struct drm_i915_gem_object *obj) -{ - vm_object_t vm_obj; - - vm_obj = obj->base.vm_obj; - VM_OBJECT_WLOCK(vm_obj); - vm_object_page_remove(vm_obj, 0, 0, false); - VM_OBJECT_WUNLOCK(vm_obj); - drm_gem_free_mmap_offset(&obj->base); - obj->madv = I915_MADV_PURGED_INTERNAL; -} - -static inline int -i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) -{ - - return (obj->madv == I915_MADV_DONTNEED); -} - -static void -i915_gem_process_flushing_list(struct intel_ring_buffer *ring, - uint32_t flush_domains) -{ - struct drm_i915_gem_object *obj, *next; - uint32_t old_write_domain; - - list_for_each_entry_safe(obj, next, &ring->gpu_write_list, - gpu_write_list) { - if (obj->base.write_domain & flush_domains) { - old_write_domain = obj->base.write_domain; - obj->base.write_domain = 0; - list_del_init(&obj->gpu_write_list); - i915_gem_object_move_to_active(obj, ring, - i915_gem_next_request_seqno(ring)); - - CTR3(KTR_DRM, "object_change_domain process_flush %p %x %x", - obj, obj->base.read_domains, old_write_domain); - } - } -} - -static int -i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) -{ - drm_i915_private_t *dev_priv; - - dev_priv = obj->base.dev->dev_private; - return (dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && - obj->tiling_mode != I915_TILING_NONE); -} - -static vm_page_t -i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, bool *fresh) -{ - vm_page_t m; - int rv; - - VM_OBJECT_ASSERT_WLOCKED(object); - m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL); - if (m->valid != VM_PAGE_BITS_ALL) { - if (vm_pager_has_page(object, pindex, NULL, NULL)) { - rv = vm_pager_get_pages(object, &m, 1, 0); - if (rv != VM_PAGER_OK) { - vm_page_lock(m); - vm_page_free(m); - vm_page_unlock(m); - return (NULL); - } - if (fresh != NULL) - *fresh = true; - } else { - pmap_zero_page(m); - m->valid = VM_PAGE_BITS_ALL; - m->dirty = 0; - if (fresh != NULL) - *fresh = false; - } - } else if (fresh != NULL) { - *fresh = false; - } - vm_page_lock(m); - vm_page_wire(m); - vm_page_unlock(m); - vm_page_xunbusy(m); - atomic_add_long(&i915_gem_wired_pages_cnt, 1); - return (m); -} - -int -i915_gem_flush_ring(struct intel_ring_buffer *ring, uint32_t invalidate_domains, - uint32_t flush_domains) -{ - int ret; - - if (((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) == 0) - return 0; - - CTR3(KTR_DRM, "ring_flush %s %x %x", ring->name, invalidate_domains, - flush_domains); - ret = ring->flush(ring, invalidate_domains, flush_domains); - if (ret) - return ret; - - if (flush_domains & I915_GEM_GPU_DOMAINS) - i915_gem_process_flushing_list(ring, flush_domains); - return 0; -} - -static int -i915_ring_idle(struct intel_ring_buffer *ring) -{ - int ret; - - if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) - return 0; - - if (!list_empty(&ring->gpu_write_list)) { - ret = i915_gem_flush_ring(ring, I915_GEM_GPU_DOMAINS, - I915_GEM_GPU_DOMAINS); - if (ret != 0) - return ret; - } - - return (i915_wait_request(ring, i915_gem_next_request_seqno(ring))); -} - -int -i915_gpu_idle(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; - int ret, i; - - /* Flush everything onto the inactive list. */ - for_each_ring(ring, dev_priv, i) { - ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); - if (ret) - return ret; - - ret = i915_ring_idle(ring); - if (ret) - return ret; - - /* Is the device fubar? */ - if (!list_empty(&ring->gpu_write_list)) - return -EBUSY; - } - - return 0; -} - -static int -i915_gem_check_wedge(struct drm_i915_private *dev_priv) -{ - DRM_LOCK_ASSERT(dev_priv->dev); - - if (atomic_load_acq_int(&dev_priv->mm.wedged) != 0) { - bool recovery_complete; - /* Give the error handler a chance to run. */ - mtx_lock(&dev_priv->error_completion_lock); - recovery_complete = (&dev_priv->error_completion) > 0; - mtx_unlock(&dev_priv->error_completion_lock); - return (recovery_complete ? -EIO : -EAGAIN); - } - - return 0; -} - -/* - * Compare seqno against outstanding lazy request. Emit a request if they are - * equal. - */ -static int -i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno) -{ - int ret = 0; - - DRM_LOCK_ASSERT(ring->dev); - - if (seqno == ring->outstanding_lazy_request) { - struct drm_i915_gem_request *request; - - request = malloc(sizeof(*request), DRM_I915_GEM, - M_WAITOK | M_ZERO); - - ret = i915_add_request(ring, NULL, request); - if (ret != 0) { - free(request, DRM_I915_GEM); - return (ret); - } - - MPASS(seqno == request->seqno); - } - return ret; -} - -static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, - bool interruptible) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - int ret = 0, flags; - - if (i915_seqno_passed(ring->get_seqno(ring), seqno)) - return 0; - - CTR2(KTR_DRM, "request_wait_begin %s %d", ring->name, seqno); - - mtx_lock(&dev_priv->irq_lock); - if (!ring->irq_get(ring)) { - mtx_unlock(&dev_priv->irq_lock); - return (-ENODEV); - } - - flags = interruptible ? PCATCH : 0; - while (!i915_seqno_passed(ring->get_seqno(ring), seqno) - && !atomic_load_acq_int(&dev_priv->mm.wedged) && - ret == 0) { - ret = -msleep(ring, &dev_priv->irq_lock, flags, "915gwr", 0); - if (ret == -ERESTART) - ret = -ERESTARTSYS; - } - ring->irq_put(ring); - mtx_unlock(&dev_priv->irq_lock); - - CTR3(KTR_DRM, "request_wait_end %s %d %d", ring->name, seqno, ret); - - return ret; -} - -int -i915_wait_request(struct intel_ring_buffer *ring, uint32_t seqno) -{ - drm_i915_private_t *dev_priv; - int ret; - - KASSERT(seqno != 0, ("Zero seqno")); - - dev_priv = ring->dev->dev_private; - ret = 0; - - ret = i915_gem_check_wedge(dev_priv); - if (ret) - return ret; - - ret = i915_gem_check_olr(ring, seqno); - if (ret) - return ret; - - ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible); - if (atomic_load_acq_int(&dev_priv->mm.wedged)) - ret = -EAGAIN; - - return (ret); -} - static u32 i915_gem_get_seqno(struct drm_device *dev) { @@ -3391,10 +2113,11 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring) } int -i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, - struct drm_i915_gem_request *request) +i915_add_request(struct intel_ring_buffer *ring, + struct drm_file *file, + struct drm_i915_gem_request *request) { - drm_i915_private_t *dev_priv; + drm_i915_private_t *dev_priv = ring->dev->dev_private; struct drm_i915_file_private *file_priv; uint32_t seqno; u32 request_ring_position; @@ -3403,7 +2126,6 @@ i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, KASSERT(request != NULL, ("NULL request in add")); DRM_LOCK_ASSERT(ring->dev); - dev_priv = ring->dev->dev_private; seqno = i915_gem_next_request_seqno(ring); request_ring_position = intel_ring_get_tail(ring); @@ -3421,13 +2143,13 @@ i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, was_empty = list_empty(&ring->request_list); list_add_tail(&request->list, &ring->request_list); - if (file != NULL) { + if (file) { file_priv = file->driver_priv; mtx_lock(&file_priv->mm.lck); request->file_priv = file_priv; list_add_tail(&request->client_list, - &file_priv->mm.request_list); + &file_priv->mm.request_list); mtx_unlock(&file_priv->mm.lck); } @@ -3442,7 +2164,8 @@ i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, taskqueue_enqueue_timeout(dev_priv->tq, &dev_priv->mm.retire_task, hz); } - return (0); + + return 0; } static inline void @@ -3456,41 +2179,16 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request) DRM_LOCK_ASSERT(request->ring->dev); mtx_lock(&file_priv->mm.lck); - if (request->file_priv != NULL) { + if (request->file_priv) { list_del(&request->client_list); request->file_priv = NULL; } mtx_unlock(&file_priv->mm.lck); } -void -i915_gem_release(struct drm_device *dev, struct drm_file *file) +static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, + struct intel_ring_buffer *ring) { - struct drm_i915_file_private *file_priv; - struct drm_i915_gem_request *request; - - file_priv = file->driver_priv; - - /* Clean up our request list when the client is going away, so that - * later retire_requests won't dereference our soon-to-be-gone - * file_priv. - */ - mtx_lock(&file_priv->mm.lck); - while (!list_empty(&file_priv->mm.request_list)) { - request = list_first_entry(&file_priv->mm.request_list, - struct drm_i915_gem_request, - client_list); - list_del(&request->client_list); - request->file_priv = NULL; - } - mtx_unlock(&file_priv->mm.lck); -} - -static void -i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, - struct intel_ring_buffer *ring) -{ - if (ring->dev != NULL) DRM_LOCK_ASSERT(ring->dev); @@ -3498,7 +2196,8 @@ i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, struct drm_i915_gem_request *request; request = list_first_entry(&ring->request_list, - struct drm_i915_gem_request, list); + struct drm_i915_gem_request, + list); list_del(&request->list); i915_gem_request_remove_from_client(request); @@ -3509,7 +2208,8 @@ i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, struct drm_i915_gem_object *obj; obj = list_first_entry(&ring->active_list, - struct drm_i915_gem_object, ring_list); + struct drm_i915_gem_object, + ring_list); obj->base.write_domain = 0; list_del_init(&obj->gpu_write_list); @@ -3517,8 +2217,7 @@ i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, } } -static void -i915_gem_reset_fences(struct drm_device *dev) +static void i915_gem_reset_fences(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int i; @@ -3539,8 +2238,7 @@ i915_gem_reset_fences(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.fence_list); } -void -i915_gem_reset(struct drm_device *dev) +void i915_gem_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; @@ -3653,6 +2351,270 @@ i915_gem_retire_requests(struct drm_device *dev) i915_gem_retire_requests_ring(ring); } +static void +i915_gem_process_flushing_list(struct intel_ring_buffer *ring, + uint32_t flush_domains) +{ + struct drm_i915_gem_object *obj, *next; + uint32_t old_write_domain; + + list_for_each_entry_safe(obj, next, &ring->gpu_write_list, + gpu_write_list) { + if (obj->base.write_domain & flush_domains) { + old_write_domain = obj->base.write_domain; + obj->base.write_domain = 0; + list_del_init(&obj->gpu_write_list); + i915_gem_object_move_to_active(obj, ring, + i915_gem_next_request_seqno(ring)); + + CTR3(KTR_DRM, "object_change_domain process_flush %p %x %x", + obj, obj->base.read_domains, old_write_domain); + } + } +} + +int +i915_gem_flush_ring(struct intel_ring_buffer *ring, uint32_t invalidate_domains, + uint32_t flush_domains) +{ + int ret; + + if (((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) == 0) + return 0; + + CTR3(KTR_DRM, "ring_flush %s %x %x", ring->name, invalidate_domains, + flush_domains); + ret = ring->flush(ring, invalidate_domains, flush_domains); + if (ret) + return ret; + + if (flush_domains & I915_GEM_GPU_DOMAINS) + i915_gem_process_flushing_list(ring, flush_domains); + return 0; +} + +static void +i915_gem_retire_task_handler(void *arg, int pending) +{ + drm_i915_private_t *dev_priv; + struct drm_device *dev; + struct intel_ring_buffer *ring; + bool idle; + int i; + + dev_priv = arg; + dev = dev_priv->dev; + + /* Come back later if the device is busy... */ + if (!sx_try_xlock(&dev->dev_struct_lock)) { + taskqueue_enqueue_timeout(dev_priv->tq, + &dev_priv->mm.retire_task, hz); + return; + } + + CTR0(KTR_DRM, "retire_task"); + + i915_gem_retire_requests(dev); + + /* Send a periodic flush down the ring so we don't hold onto GEM + * objects indefinitely. + */ + idle = true; + for_each_ring(ring, dev_priv, i) { + struct intel_ring_buffer *ring = &dev_priv->rings[i]; + + if (!list_empty(&ring->gpu_write_list)) { + struct drm_i915_gem_request *request; + int ret; + + ret = i915_gem_flush_ring(ring, + 0, I915_GEM_GPU_DOMAINS); + request = malloc(sizeof(*request), DRM_I915_GEM, + M_WAITOK | M_ZERO); + if (ret || request == NULL || + i915_add_request(ring, NULL, request)) + free(request, DRM_I915_GEM); + } + + idle &= list_empty(&ring->request_list); + } + + if (!dev_priv->mm.suspended && !idle) + taskqueue_enqueue_timeout(dev_priv->tq, + &dev_priv->mm.retire_task, hz); + + DRM_UNLOCK(dev); +} + +int +i915_gem_object_sync(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *to) +{ + struct intel_ring_buffer *from = obj->ring; + u32 seqno; + int ret, idx; + + if (from == NULL || to == from) + return 0; + + if (to == NULL || !i915_semaphore_is_enabled(obj->base.dev)) + return i915_gem_object_wait_rendering(obj); + + idx = intel_ring_sync_index(from, to); + + seqno = obj->last_rendering_seqno; + if (seqno <= from->sync_seqno[idx]) + return 0; + + if (seqno == from->outstanding_lazy_request) { + struct drm_i915_gem_request *request; + + request = malloc(sizeof(*request), DRM_I915_GEM, + M_WAITOK | M_ZERO); + ret = i915_add_request(from, NULL, request); + if (ret) { + free(request, DRM_I915_GEM); + return ret; + } + seqno = request->seqno; + } + + + ret = to->sync_to(to, from, seqno); + if (!ret) + from->sync_seqno[idx] = seqno; + + return ret; +} + +static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) +{ + u32 old_write_domain, old_read_domains; + + /* Act a barrier for all accesses through the GTT */ + mb(); + + /* Force a pagefault for domain tracking on next user access */ + i915_gem_release_mmap(obj); + + if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0) + return; + + old_read_domains = obj->base.read_domains; + old_write_domain = obj->base.write_domain; + + obj->base.read_domains &= ~I915_GEM_DOMAIN_GTT; + obj->base.write_domain &= ~I915_GEM_DOMAIN_GTT; + + CTR3(KTR_DRM, "object_change_domain finish gtt %p %x %x", + obj, old_read_domains, old_write_domain); +} + +/** + * Unbinds an object from the GTT aperture. + */ +int +i915_gem_object_unbind(struct drm_i915_gem_object *obj) +{ + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; + int ret = 0; + + if (obj->gtt_space == NULL) + return 0; + + if (obj->pin_count) { + DRM_ERROR("Attempting to unbind pinned buffer\n"); + return -EINVAL; + } + + ret = i915_gem_object_finish_gpu(obj); + if (ret == -ERESTARTSYS || ret == -EINTR) + return ret; + + i915_gem_object_finish_gtt(obj); + + if (ret == 0) + ret = i915_gem_object_set_to_cpu_domain(obj, 1); + if (ret == -ERESTARTSYS || ret == -EINTR) + return ret; + if (ret != 0) { + i915_gem_clflush_object(obj); + obj->base.read_domains = obj->base.write_domain = + I915_GEM_DOMAIN_CPU; + } + + /* release the fence reg _after_ flushing */ + ret = i915_gem_object_put_fence(obj); + if (ret) + return ret; + + if (obj->has_global_gtt_mapping) + i915_gem_gtt_unbind_object(obj); + if (obj->has_aliasing_ppgtt_mapping) { + i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj); + obj->has_aliasing_ppgtt_mapping = 0; + } + i915_gem_gtt_finish_object(obj); + + i915_gem_object_put_pages_gtt(obj); + + list_del_init(&obj->gtt_list); + list_del_init(&obj->mm_list); + obj->map_and_fenceable = true; + + drm_mm_put_block(obj->gtt_space); + obj->gtt_space = NULL; + obj->gtt_offset = 0; + + if (i915_gem_object_is_purgeable(obj)) + i915_gem_object_truncate(obj); + CTR1(KTR_DRM, "object_unbind %p", obj); + + return ret; +} + +static int +i915_ring_idle(struct intel_ring_buffer *ring) +{ + int ret; + + if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) + return 0; + + if (!list_empty(&ring->gpu_write_list)) { + ret = i915_gem_flush_ring(ring, I915_GEM_GPU_DOMAINS, + I915_GEM_GPU_DOMAINS); + if (ret != 0) + return ret; + } + + return (i915_wait_request(ring, i915_gem_next_request_seqno(ring))); +} + +int i915_gpu_idle(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring; + int ret, i; + + /* Flush everything onto the inactive list. */ + for_each_ring(ring, dev_priv, i) { + ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); + if (ret) + return ret; + + ret = i915_ring_idle(ring); + if (ret) + return ret; + + /* Is the device fubar? */ + if (!list_empty(&ring->gpu_write_list)) + return -EBUSY; + } + + return 0; +} + static void sandybridge_write_fence_reg(struct drm_device *dev, int reg, struct drm_i915_gem_object *obj) { @@ -3803,13 +2765,14 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, struct drm_i915_fence_reg *fence, bool enable) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; - int reg = fence_number(dev_priv, fence); + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int fence_reg = fence_number(dev_priv, fence); - i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); + i915_gem_write_fence(dev, fence_reg, enable ? obj : NULL); if (enable) { - obj->fence_reg = reg; + obj->fence_reg = fence_reg; fence->obj = obj; list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); } else { @@ -3906,6 +2869,20 @@ i915_find_fence_reg(struct drm_device *dev) return NULL; } +/** + * i915_gem_object_get_fence - set up fencing for an object + * @obj: object to map through a fence reg + * + * When mapping objects through the GTT, userspace wants to be able to write + * to them without having to worry about swizzling if the object is tiled. + * This function walks the fence regs looking for a free one for @obj, + * stealing one if it can't find any. + * + * It then sets up the reg based on the object's properties: address, pitch + * and tiling format. + * + * For an untiled surface, this removes any existing fence. + */ int i915_gem_object_get_fence(struct drm_i915_gem_object *obj) { @@ -3924,8 +2901,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj) return ret; } - ret = 0; - + /* Just update our place in the LRU if our fence is getting reused. */ if (obj->fence_reg != I915_FENCE_REG_NONE) { reg = &dev_priv->fence_regs[obj->fence_reg]; if (!obj->fence_dirty) { @@ -3956,72 +2932,1097 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj) return 0; } -int -i915_gem_init_object(struct drm_gem_object *obj) +/** + * Finds free space in the GTT aperture and binds the object there. + */ +static int +i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, + unsigned alignment, + bool map_and_fenceable) +{ + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_mm_node *free_space; + u32 size, fence_size, fence_alignment, unfenced_alignment; + bool mappable, fenceable; + int ret; + + if (obj->madv != I915_MADV_WILLNEED) { + DRM_ERROR("Attempting to bind a purgeable object\n"); + return -EINVAL; + } + + fence_size = i915_gem_get_gtt_size(dev, + obj->base.size, + obj->tiling_mode); + fence_alignment = i915_gem_get_gtt_alignment(dev, + obj->base.size, + obj->tiling_mode); + unfenced_alignment = + i915_gem_get_unfenced_gtt_alignment(dev, + obj->base.size, + obj->tiling_mode); + + if (alignment == 0) + alignment = map_and_fenceable ? fence_alignment : + unfenced_alignment; + if (map_and_fenceable && alignment & (fence_alignment - 1)) { + DRM_ERROR("Invalid object alignment requested %u\n", alignment); + return -EINVAL; + } + + size = map_and_fenceable ? fence_size : obj->base.size; + + /* If the object is bigger than the entire aperture, reject it early + * before evicting everything in a vain attempt to find space. + */ + if (obj->base.size > + (map_and_fenceable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { + DRM_ERROR("Attempting to bind an object larger than the aperture\n"); + return -E2BIG; + } + + search_free: + if (map_and_fenceable) + free_space = drm_mm_search_free_in_range( + &dev_priv->mm.gtt_space, size, alignment, 0, + dev_priv->mm.gtt_mappable_end, 0); + else + free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, + size, alignment, 0); + if (free_space != NULL) { + if (map_and_fenceable) + obj->gtt_space = drm_mm_get_block_range_generic( + free_space, size, alignment, 0, 0, + dev_priv->mm.gtt_mappable_end, 1); + else + obj->gtt_space = drm_mm_get_block_generic(free_space, + size, alignment, 0, 1); + } + if (obj->gtt_space == NULL) { + ret = i915_gem_evict_something(dev, size, alignment, + map_and_fenceable); + if (ret != 0) + return ret; + goto search_free; + } + ret = i915_gem_object_get_pages_gtt(obj, 0); + if (ret) { + drm_mm_put_block(obj->gtt_space); + obj->gtt_space = NULL; + /* + * i915_gem_object_get_pages_gtt() cannot return + * ENOMEM, since we use vm_page_grab(). + */ + return ret; + } + + ret = i915_gem_gtt_prepare_object(obj); + if (ret) { + i915_gem_object_put_pages_gtt(obj); + drm_mm_put_block(obj->gtt_space); + obj->gtt_space = NULL; + if (i915_gem_evict_everything(dev, false)) + return ret; + goto search_free; + } + + if (!dev_priv->mm.aliasing_ppgtt) + i915_gem_gtt_bind_object(obj, obj->cache_level); + + list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); + list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + + KASSERT((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0, + ("Object in gpu read domain")); + KASSERT((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0, + ("Object in gpu write domain")); + + obj->gtt_offset = obj->gtt_space->start; + + fenceable = + obj->gtt_space->size == fence_size && + (obj->gtt_space->start & (fence_alignment - 1)) == 0; + + mappable = + obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; + + obj->map_and_fenceable = mappable && fenceable; + + CTR4(KTR_DRM, "object_bind %p %x %x %d", obj, obj->gtt_offset, + obj->base.size, map_and_fenceable); + return 0; +} + +void +i915_gem_clflush_object(struct drm_i915_gem_object *obj) +{ + /* If we don't have a page list set up, then we're not pinned + * to GPU, and we can ignore the cache flush because it'll happen + * again at bind time. + */ + if (obj->pages == NULL) + return; + + /* If the GPU is snooping the contents of the CPU cache, + * we do not need to manually clear the CPU cache lines. However, + * the caches are only snooped when the render cache is + * flushed/invalidated. As we always have to emit invalidations + * and flushes when moving into and out of the RENDER domain, correct + * snooping behaviour occurs naturally as the result of our domain + * tracking. + */ + if (obj->cache_level != I915_CACHE_NONE) + return; + + CTR1(KTR_DRM, "object_clflush %p", obj); + + drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE); +} + +/** Flushes the GTT write domain for the object if it's dirty. */ +static void +i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) +{ + uint32_t old_write_domain; + + if (obj->base.write_domain != I915_GEM_DOMAIN_GTT) + return; + + /* No actual flushing is required for the GTT write domain. Writes + * to it immediately go to main memory as far as we know, so there's + * no chipset flush. It also doesn't land in render cache. + * + * However, we do have to enforce the order so that all writes through + * the GTT land before any writes to the device, such as updates to + * the GATT itself. + */ + wmb(); + + old_write_domain = obj->base.write_domain; + obj->base.write_domain = 0; + + CTR3(KTR_DRM, "object_change_domain flush gtt_write %p %x %x", obj, + obj->base.read_domains, old_write_domain); +} + +/** Flushes the CPU write domain for the object if it's dirty. */ +static void +i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) +{ + uint32_t old_write_domain; + + if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) + return; + + i915_gem_clflush_object(obj); + intel_gtt_chipset_flush(); + old_write_domain = obj->base.write_domain; + obj->base.write_domain = 0; + + CTR3(KTR_DRM, "object_change_domain flush_cpu_write %p %x %x", obj, + obj->base.read_domains, old_write_domain); +} + +static int +i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj) { + if ((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0) + return (0); + return (i915_gem_flush_ring(obj->ring, 0, obj->base.write_domain)); +} + +/** + * Moves a single object to the GTT read, and possibly write domain. + * + * This function returns when the move is complete, including waiting on + * flushes to occur. + */ +int +i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) +{ + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; + uint32_t old_write_domain, old_read_domains; + int ret; + + /* Not valid to be called on unbound objects. */ + if (obj->gtt_space == NULL) + return -EINVAL; + + if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) + return 0; + + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret) + return (ret); + + if (obj->pending_gpu_write || write) { + ret = i915_gem_object_wait_rendering(obj); + if (ret) + return (ret); + } + + i915_gem_object_flush_cpu_write_domain(obj); + + old_write_domain = obj->base.write_domain; + old_read_domains = obj->base.read_domains; + + /* It should now be out of any other write domains, and we can update + * the domain values for our changes. + */ + KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) == 0, + ("In GTT write domain")); + obj->base.read_domains |= I915_GEM_DOMAIN_GTT; + if (write) { + obj->base.read_domains = I915_GEM_DOMAIN_GTT; + obj->base.write_domain = I915_GEM_DOMAIN_GTT; + obj->dirty = 1; + } + + CTR3(KTR_DRM, "object_change_domain set_to_gtt %p %x %x", obj, + old_read_domains, old_write_domain); + + /* And bump the LRU for this access */ + if (i915_gem_object_is_inactive(obj)) + list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + + return 0; +} + +int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, + enum i915_cache_level cache_level) +{ + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + + if (obj->cache_level == cache_level) + return 0; + + if (obj->pin_count) { + DRM_DEBUG("can not change the cache level of pinned objects\n"); + return -EBUSY; + } + + if (obj->gtt_space) { + ret = i915_gem_object_finish_gpu(obj); + if (ret) + return ret; + + i915_gem_object_finish_gtt(obj); + + /* Before SandyBridge, you could not use tiling or fence + * registers with snooped memory, so relinquish any fences + * currently pointing to our region in the aperture. + */ + if (INTEL_INFO(obj->base.dev)->gen < 6) { + ret = i915_gem_object_put_fence(obj); + if (ret) + return ret; + } + + if (obj->has_global_gtt_mapping) + i915_gem_gtt_bind_object(obj, cache_level); + if (obj->has_aliasing_ppgtt_mapping) + i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, + obj, cache_level); + } + + if (cache_level == I915_CACHE_NONE) { + u32 old_read_domains, old_write_domain; + + /* If we're coming from LLC cached, then we haven't + * actually been tracking whether the data is in the + * CPU cache or not, since we only allow one bit set + * in obj->write_domain and have been skipping the clflushes. + * Just set it to the CPU cache for now. + */ + KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) == 0, + ("obj %p in CPU write domain", obj)); + KASSERT((obj->base.read_domains & ~I915_GEM_DOMAIN_CPU) == 0, + ("obj %p in CPU read domain", obj)); + + old_read_domains = obj->base.read_domains; + old_write_domain = obj->base.write_domain; + + obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->base.write_domain = I915_GEM_DOMAIN_CPU; + + CTR3(KTR_DRM, "object_change_domain set_cache_level %p %x %x", + obj, old_read_domains, old_write_domain); + } + + obj->cache_level = cache_level; + return 0; +} + +static bool is_pin_display(struct drm_i915_gem_object *obj) +{ + /* There are 3 sources that pin objects: + * 1. The display engine (scanouts, sprites, cursors); + * 2. Reservations for execbuffer; + * 3. The user. + * + * We can ignore reservations as we hold the struct_mutex and + * are only called outside of the reservation path. The user + * can only increment pin_count once, and so if after + * subtracting the potential reference by the user, any pin_count + * remains, it must be due to another use by the display engine. + */ + return obj->pin_count - !!obj->user_pin_count; +} + +int +i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, + u32 alignment, + struct intel_ring_buffer *pipelined) +{ + u32 old_read_domains, old_write_domain; + int ret; + + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret) + return ret; + + if (pipelined != obj->ring) { + ret = i915_gem_object_sync(obj, pipelined); + if (ret) + return ret; + } + + /* Mark the pin_display early so that we account for the + * display coherency whilst setting up the cache domains. + */ + obj->pin_display = true; + + /* The display engine is not coherent with the LLC cache on gen6. As + * a result, we make sure that the pinning that is about to occur is + * done with uncached PTEs. This is lowest common denominator for all + * chipsets. + * + * However for gen6+, we could do better by using the GFDT bit instead + * of uncaching, which would allow us to flush all the LLC-cached data + * with that bit in the PTE to main memory with just one PIPE_CONTROL. + */ + ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE); + if (ret) + goto err_unpin_display; + + /* As the user may map the buffer once pinned in the display plane + * (e.g. libkms for the bootup splash), we have to ensure that we + * always use map_and_fenceable for all scanout buffers. + */ + ret = i915_gem_object_pin(obj, alignment, true); + if (ret) + goto err_unpin_display; + + i915_gem_object_flush_cpu_write_domain(obj); + + old_write_domain = obj->base.write_domain; + old_read_domains = obj->base.read_domains; + + KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) == 0, + ("obj %p in GTT write domain", obj)); + obj->base.read_domains |= I915_GEM_DOMAIN_GTT; + + CTR3(KTR_DRM, "object_change_domain pin_to_display_plan %p %x %x", + obj, old_read_domains, obj->base.write_domain); + + return 0; + +err_unpin_display: + obj->pin_display = is_pin_display(obj); + return ret; +} + +void +i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj) +{ + i915_gem_object_unpin(obj); + obj->pin_display = is_pin_display(obj); +} + +int +i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) +{ + int ret; + + if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0) + return 0; + + if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { + ret = i915_gem_flush_ring(obj->ring, 0, obj->base.write_domain); + if (ret) + return ret; + } + + ret = i915_gem_object_wait_rendering(obj); + if (ret) + return ret; + + /* Ensure that we invalidate the GPU's caches and TLBs. */ + obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; + return 0; +} + +int +i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) +{ + uint32_t old_write_domain, old_read_domains; + int ret; + + if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) + return 0; + + ret = i915_gem_object_flush_gpu_write_domain(obj); + if (ret) + return ret; + + if (write || obj->pending_gpu_write) { + ret = i915_gem_object_wait_rendering(obj); + if (ret) + return ret; + } + + i915_gem_object_flush_gtt_write_domain(obj); + + old_write_domain = obj->base.write_domain; + old_read_domains = obj->base.read_domains; + + /* Flush the CPU cache if it's still invalid. */ + if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { + i915_gem_clflush_object(obj); + + obj->base.read_domains |= I915_GEM_DOMAIN_CPU; + } + + /* It should now be out of any other write domains, and we can update + * the domain values for our changes. + */ + KASSERT((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) == 0, + ("In cpu write domain")); + + /* If we're writing through the CPU, then the GPU read domains will + * need to be invalidated at next use. + */ + if (write) { + obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->base.write_domain = I915_GEM_DOMAIN_CPU; + } + + CTR3(KTR_DRM, "object_change_domain set_to_cpu %p %x %x", obj, + old_read_domains, old_write_domain); + + return 0; +} + +/* Throttle our rendering by waiting until the ring has completed our requests + * emitted over 20 msec ago. + * + * Note that if we were to use the current jiffies each time around the loop, + * we wouldn't escape the function with any frames outstanding if the time to + * render a frame was over 20ms. + * + * This should get us reasonable parallelism between CPU and GPU but also + * relatively low latency when blocking on a particular request to finish. + */ +static int +i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_file_private *file_priv = file->driver_priv; + unsigned long recent_enough = ticks - (20 * hz / 1000); + struct drm_i915_gem_request *request; + struct intel_ring_buffer *ring = NULL; + u32 seqno = 0; + int ret; + + if (atomic_load_acq_int(&dev_priv->mm.wedged)) + return -EIO; + + mtx_lock(&file_priv->mm.lck); + list_for_each_entry(request, &file_priv->mm.request_list, client_list) { + if (time_after_eq(request->emitted_jiffies, recent_enough)) + break; + ring = request->ring; + seqno = request->seqno; + } + mtx_unlock(&file_priv->mm.lck); + if (seqno == 0) + return 0; + + ret = __wait_seqno(ring, seqno, true); + if (ret == 0) + taskqueue_enqueue_timeout(dev_priv->tq, + &dev_priv->mm.retire_task, 0); + + return ret; +} + +int +i915_gem_object_pin(struct drm_i915_gem_object *obj, + uint32_t alignment, + bool map_and_fenceable) +{ + int ret; + + if (obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT) + return -EBUSY; + + if (obj->gtt_space != NULL) { + if ((alignment && obj->gtt_offset & (alignment - 1)) || + (map_and_fenceable && !obj->map_and_fenceable)) { + DRM_DEBUG("bo is already pinned with incorrect alignment:" + " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," + " obj->map_and_fenceable=%d\n", + obj->gtt_offset, alignment, + map_and_fenceable, + obj->map_and_fenceable); + ret = i915_gem_object_unbind(obj); + if (ret) + return ret; + } + } + + if (obj->gtt_space == NULL) { + ret = i915_gem_object_bind_to_gtt(obj, alignment, + map_and_fenceable); + if (ret) + return ret; + } + + if (!obj->has_global_gtt_mapping && map_and_fenceable) + i915_gem_gtt_bind_object(obj, obj->cache_level); + + obj->pin_count++; + obj->pin_mappable |= map_and_fenceable; + + return 0; +} + +void +i915_gem_object_unpin(struct drm_i915_gem_object *obj) +{ + + KASSERT(obj->pin_count != 0, ("zero pin count")); + KASSERT(obj->gtt_space != NULL, ("No gtt mapping")); + + if (--obj->pin_count == 0) + obj->pin_mappable = false; +} + +int +i915_gem_pin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_gem_pin *args = data; + struct drm_i915_gem_object *obj; + struct drm_gem_object *gobj; + int ret; + + ret = i915_mutex_lock_interruptible(dev); + if (ret) + return ret; + + gobj = drm_gem_object_lookup(dev, file, args->handle); + if (gobj == NULL) { + ret = -ENOENT; + goto unlock; + } + obj = to_intel_bo(gobj); + + if (obj->madv != I915_MADV_WILLNEED) { + DRM_ERROR("Attempting to pin a purgeable buffer\n"); + ret = -EINVAL; + goto out; + } + + if (obj->pin_filp != NULL && obj->pin_filp != file) { + DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", + args->handle); + ret = -EINVAL; + goto out; + } + + obj->user_pin_count++; + obj->pin_filp = file; + if (obj->user_pin_count == 1) { + ret = i915_gem_object_pin(obj, args->alignment, true); + if (ret) + goto out; + } + + /* XXX - flush the CPU caches for pinned objects + * as the X server doesn't manage domains yet + */ + i915_gem_object_flush_cpu_write_domain(obj); + args->offset = obj->gtt_offset; +out: + drm_gem_object_unreference(&obj->base); +unlock: + DRM_UNLOCK(dev); + return ret; +} + +int +i915_gem_unpin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_gem_pin *args = data; + struct drm_i915_gem_object *obj; + int ret; + + ret = i915_mutex_lock_interruptible(dev); + if (ret) + return ret; + + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + if (&obj->base == NULL) { + ret = -ENOENT; + goto unlock; + } + + if (obj->pin_filp != file) { + DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", + args->handle); + ret = -EINVAL; + goto out; + } + obj->user_pin_count--; + if (obj->user_pin_count == 0) { + obj->pin_filp = NULL; + i915_gem_object_unpin(obj); + } + +out: + drm_gem_object_unreference(&obj->base); +unlock: + DRM_UNLOCK(dev); + return ret; +} + +int +i915_gem_busy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_gem_busy *args = data; + struct drm_i915_gem_object *obj; + int ret; + + ret = i915_mutex_lock_interruptible(dev); + if (ret) + return ret; + + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); + if (&obj->base == NULL) { + ret = -ENOENT; + goto unlock; + } + + args->busy = obj->active; + if (args->busy) { + if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { + ret = i915_gem_flush_ring(obj->ring, + 0, obj->base.write_domain); + } else { + ret = i915_gem_check_olr(obj->ring, + obj->last_rendering_seqno); + } + + i915_gem_retire_requests_ring(obj->ring); + args->busy = obj->active; + } + + drm_gem_object_unreference(&obj->base); +unlock: + DRM_UNLOCK(dev); + return ret; +} + +int +i915_gem_throttle_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + + return i915_gem_ring_throttle(dev, file_priv); +} + +int +i915_gem_madvise_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_i915_gem_madvise *args = data; + struct drm_i915_gem_object *obj; + int ret; + + switch (args->madv) { + case I915_MADV_DONTNEED: + case I915_MADV_WILLNEED: + break; + default: + return -EINVAL; + } + + ret = i915_mutex_lock_interruptible(dev); + if (ret) + return ret; + + obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle)); + if (&obj->base == NULL) { + ret = -ENOENT; + goto unlock; + } + + if (obj->pin_count) { + ret = -EINVAL; + goto out; + } + + if (obj->madv != I915_MADV_PURGED_INTERNAL) + obj->madv = args->madv; + + /* if the object is no longer attached, discard its backing storage */ + if (i915_gem_object_is_purgeable(obj) && obj->gtt_space == NULL) + i915_gem_object_truncate(obj); + + args->retained = obj->madv != I915_MADV_PURGED_INTERNAL; + +out: + drm_gem_object_unreference(&obj->base); +unlock: + DRM_UNLOCK(dev); + return ret; +} + +struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, + size_t size) +{ + struct drm_i915_private *dev_priv; + struct drm_i915_gem_object *obj; + + dev_priv = dev->dev_private; + + obj = malloc(sizeof(*obj), DRM_I915_GEM, M_WAITOK | M_ZERO); + + if (drm_gem_object_init(dev, &obj->base, size) != 0) { + free(obj, DRM_I915_GEM); + return NULL; + } + + obj->base.write_domain = I915_GEM_DOMAIN_CPU; + obj->base.read_domains = I915_GEM_DOMAIN_CPU; + + if (HAS_LLC(dev)) { + /* On some devices, we can have the GPU use the LLC (the CPU + * cache) for about a 10% performance improvement + * compared to uncached. Graphics requests other than + * display scanout are coherent with the CPU in + * accessing this cache. This means in this mode we + * don't need to clflush on the CPU side, and on the + * GPU side we only need to flush internal caches to + * get data visible to the CPU. + * + * However, we maintain the display planes as UC, and so + * need to rebind when first used as such. + */ + obj->cache_level = I915_CACHE_LLC; + } else + obj->cache_level = I915_CACHE_NONE; + obj->base.driver_private = NULL; + obj->fence_reg = I915_FENCE_REG_NONE; + INIT_LIST_HEAD(&obj->mm_list); + INIT_LIST_HEAD(&obj->gtt_list); + INIT_LIST_HEAD(&obj->ring_list); + INIT_LIST_HEAD(&obj->exec_list); + INIT_LIST_HEAD(&obj->gpu_write_list); + obj->madv = I915_MADV_WILLNEED; + /* Avoid an unnecessary call to unbind on the first bind. */ + obj->map_and_fenceable = true; + + i915_gem_info_add_obj(dev_priv, size); + + return obj; +} + +int i915_gem_init_object(struct drm_gem_object *obj) +{ printf("i915_gem_init_object called\n"); - return (0); + + return 0; +} + +void i915_gem_free_object(struct drm_gem_object *gem_obj) +{ + struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + CTR1(KTR_DRM, "object_destroy_tail %p", obj); + + if (obj->phys_obj) + i915_gem_detach_phys_object(dev, obj); + + obj->pin_count = 0; + if (i915_gem_object_unbind(obj) == -ERESTARTSYS) { + bool was_interruptible; + + was_interruptible = dev_priv->mm.interruptible; + dev_priv->mm.interruptible = false; + + if (i915_gem_object_unbind(obj)) + printf("i915_gem_free_object: unbind\n"); + + dev_priv->mm.interruptible = was_interruptible; + } + + drm_gem_free_mmap_offset(&obj->base); + drm_gem_object_release(&obj->base); + i915_gem_info_remove_obj(dev_priv, obj->base.size); + + free(obj->bit_17, DRM_I915_GEM); + free(obj, DRM_I915_GEM); +} + +int +i915_gem_idle(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + + DRM_LOCK(dev); + + if (dev_priv->mm.suspended) { + DRM_UNLOCK(dev); + return 0; + } + + ret = i915_gpu_idle(dev); + if (ret) { + DRM_UNLOCK(dev); + return ret; + } + i915_gem_retire_requests(dev); + + /* Under UMS, be paranoid and evict. */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = i915_gem_evict_everything(dev, false); + if (ret) { + DRM_UNLOCK(dev); + return ret; + } + } + + i915_gem_reset_fences(dev); + + /* Hack! Don't let anybody do execbuf while we don't control the chip. + * We need to replace this with a semaphore, or something. + * And not confound mm.suspended! + */ + dev_priv->mm.suspended = 1; + callout_stop(&dev_priv->hangcheck_timer); + + i915_kernel_lost_context(dev); + i915_gem_cleanup_ringbuffer(dev); + + DRM_UNLOCK(dev); + + /* Cancel the retire work handler, which should be idle now. */ + taskqueue_cancel_timeout(dev_priv->tq, &dev_priv->mm.retire_task, NULL); + + return ret; +} + +void i915_gem_init_swizzling(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + if (INTEL_INFO(dev)->gen < 5 || + dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE) + return; + + I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | + DISP_TILE_SURFACE_SWIZZLING); + + if (IS_GEN5(dev)) + return; + + I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); + if (IS_GEN6(dev)) + I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB)); + else + I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB)); +} + +int +i915_gem_init_hw(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + + i915_gem_init_swizzling(dev); + + ret = intel_init_render_ring_buffer(dev); + if (ret) + return ret; + + if (HAS_BSD(dev)) { + ret = intel_init_bsd_ring_buffer(dev); + if (ret) + goto cleanup_render_ring; + } + + if (HAS_BLT(dev)) { + ret = intel_init_blt_ring_buffer(dev); + if (ret) + goto cleanup_bsd_ring; + } + + dev_priv->next_seqno = 1; + + /* + * XXX: There was some w/a described somewhere suggesting loading + * contexts before PPGTT. + */ + i915_gem_context_init(dev); + i915_gem_init_ppgtt(dev); + + return 0; + +cleanup_bsd_ring: + intel_cleanup_ring_buffer(&dev_priv->rings[VCS]); +cleanup_render_ring: + intel_cleanup_ring_buffer(&dev_priv->rings[RCS]); + return ret; } static bool -i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) +intel_enable_ppgtt(struct drm_device *dev) { + if (i915_enable_ppgtt >= 0) + return i915_enable_ppgtt; - return !obj->active; + /* Disable ppgtt on SNB if VT-d is on. */ + if (INTEL_INFO(dev)->gen == 6 && intel_iommu_enabled) + return false; + + return true; } -static void -i915_gem_retire_task_handler(void *arg, int pending) +int i915_gem_init(struct drm_device *dev) { - drm_i915_private_t *dev_priv; - struct drm_device *dev; + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long gtt_size, mappable_size; + int ret; + + gtt_size = dev_priv->mm.gtt.gtt_total_entries << PAGE_SHIFT; + mappable_size = dev_priv->mm.gtt.gtt_mappable_entries << PAGE_SHIFT; + + DRM_LOCK(dev); + if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { + /* PPGTT pdes are stolen from global gtt ptes, so shrink the + * aperture accordingly when using aliasing ppgtt. */ + gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; + + i915_gem_init_global_gtt(dev, 0, mappable_size, gtt_size); + + ret = i915_gem_init_aliasing_ppgtt(dev); + if (ret) { + DRM_UNLOCK(dev); + return ret; + } + } else { + /* Let GEM Manage all of the aperture. + * + * However, leave one page at the end still bound to the scratch + * page. There are a number of places where the hardware + * apparently prefetches past the end of the object, and we've + * seen multiple hangs with the GPU head pointer stuck in a + * batchbuffer bound at the last page of the aperture. One page + * should be enough to keep any prefetching inside of the + * aperture. + */ + i915_gem_init_global_gtt(dev, 0, mappable_size, + gtt_size); + } + + ret = i915_gem_init_hw(dev); + DRM_UNLOCK(dev); + if (ret) { + i915_gem_cleanup_aliasing_ppgtt(dev); + return ret; + } + + /* Allow hardware batchbuffers unless told otherwise, but not for KMS. */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + dev_priv->dri1.allow_batchbuffer = 1; + return 0; +} + +void +i915_gem_cleanup_ringbuffer(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring; - bool idle; int i; - dev_priv = arg; - dev = dev_priv->dev; + for_each_ring(ring, dev_priv, i) + intel_cleanup_ring_buffer(ring); +} - /* Come back later if the device is busy... */ - if (!sx_try_xlock(&dev->dev_struct_lock)) { - taskqueue_enqueue_timeout(dev_priv->tq, - &dev_priv->mm.retire_task, hz); - return; +int +i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + + if (atomic_load_acq_int(&dev_priv->mm.wedged) != 0) { + DRM_ERROR("Reenabling wedged hardware, good luck\n"); + atomic_store_rel_int(&dev_priv->mm.wedged, 0); } - CTR0(KTR_DRM, "retire_task"); + DRM_LOCK(dev); + dev_priv->mm.suspended = 0; - i915_gem_retire_requests(dev); - - /* Send a periodic flush down the ring so we don't hold onto GEM - * objects indefinitely. - */ - idle = true; - for_each_ring(ring, dev_priv, i) { - struct intel_ring_buffer *ring = &dev_priv->rings[i]; - - if (!list_empty(&ring->gpu_write_list)) { - struct drm_i915_gem_request *request; - int ret; - - ret = i915_gem_flush_ring(ring, - 0, I915_GEM_GPU_DOMAINS); - request = malloc(sizeof(*request), DRM_I915_GEM, - M_WAITOK | M_ZERO); - if (ret || request == NULL || - i915_add_request(ring, NULL, request)) - free(request, DRM_I915_GEM); - } - - idle &= list_empty(&ring->request_list); + ret = i915_gem_init_hw(dev); + if (ret != 0) { + DRM_UNLOCK(dev); + return ret; } - if (!dev_priv->mm.suspended && !idle) - taskqueue_enqueue_timeout(dev_priv->tq, - &dev_priv->mm.retire_task, hz); - + KASSERT(list_empty(&dev_priv->mm.active_list), ("active list")); + KASSERT(list_empty(&dev_priv->mm.flushing_list), ("flushing list")); + KASSERT(list_empty(&dev_priv->mm.inactive_list), ("inactive list")); DRM_UNLOCK(dev); + + ret = drm_irq_install(dev); + if (ret) + goto cleanup_ringbuffer; + + return 0; + +cleanup_ringbuffer: + DRM_LOCK(dev); + i915_gem_cleanup_ringbuffer(dev); + dev_priv->mm.suspended = 1; + DRM_UNLOCK(dev); + + return ret; +} + +int +i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + + drm_irq_uninstall(dev); + return i915_gem_idle(dev); } void @@ -4033,64 +4034,123 @@ i915_gem_lastclose(struct drm_device *dev) return; ret = i915_gem_idle(dev); - if (ret != 0) + if (ret) DRM_ERROR("failed to idle hardware: %d\n", ret); } -static int -i915_gem_init_phys_object(struct drm_device *dev, int id, int size, int align) +static void +init_ring_lists(struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv; + INIT_LIST_HEAD(&ring->active_list); + INIT_LIST_HEAD(&ring->request_list); + INIT_LIST_HEAD(&ring->gpu_write_list); +} + +void +i915_gem_load(struct drm_device *dev) +{ + int i; + drm_i915_private_t *dev_priv = dev->dev_private; + + INIT_LIST_HEAD(&dev_priv->mm.active_list); + INIT_LIST_HEAD(&dev_priv->mm.flushing_list); + INIT_LIST_HEAD(&dev_priv->mm.inactive_list); + INIT_LIST_HEAD(&dev_priv->mm.fence_list); + INIT_LIST_HEAD(&dev_priv->mm.gtt_list); + for (i = 0; i < I915_NUM_RINGS; i++) + init_ring_lists(&dev_priv->rings[i]); + for (i = 0; i < I915_MAX_NUM_FENCES; i++) + INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); + TIMEOUT_TASK_INIT(dev_priv->tq, &dev_priv->mm.retire_task, 0, + i915_gem_retire_task_handler, dev_priv); + dev_priv->error_completion = 0; + + /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ + if (IS_GEN3(dev)) { + I915_WRITE(MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); + } + + dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; + + /* Old X drivers will take 0-2 for front, back, depth buffers */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + dev_priv->fence_reg_start = 3; + + if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) + dev_priv->num_fence_regs = 16; + else + dev_priv->num_fence_regs = 8; + + /* Initialize fence registers to zero */ + i915_gem_reset_fences(dev); + + i915_gem_detect_bit_6_swizzle(dev); + dev_priv->mm.interruptible = true; + + dev_priv->mm.i915_lowmem = EVENTHANDLER_REGISTER(vm_lowmem, + i915_gem_lowmem, dev, EVENTHANDLER_PRI_ANY); +} + +void +i915_gem_unload(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv; + + dev_priv = dev->dev_private; + EVENTHANDLER_DEREGISTER(vm_lowmem, dev_priv->mm.i915_lowmem); +} + +static int i915_gem_init_phys_object(struct drm_device *dev, + int id, int size, int align) +{ + drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_phys_object *phys_obj; int ret; - dev_priv = dev->dev_private; - if (dev_priv->mm.phys_objs[id - 1] != NULL || size == 0) - return (0); + if (dev_priv->mm.phys_objs[id - 1] || !size) + return 0; - phys_obj = malloc(sizeof(struct drm_i915_gem_phys_object), DRM_I915_GEM, - M_WAITOK | M_ZERO); + phys_obj = malloc(sizeof(struct drm_i915_gem_phys_object), + DRM_I915_GEM, M_WAITOK | M_ZERO); phys_obj->id = id; phys_obj->handle = drm_pci_alloc(dev, size, align, BUS_SPACE_MAXADDR); - if (phys_obj->handle == NULL) { + if (!phys_obj->handle) { ret = -ENOMEM; - goto free_obj; + goto kfree_obj; } pmap_change_attr((vm_offset_t)phys_obj->handle->vaddr, size / PAGE_SIZE, PAT_WRITE_COMBINING); dev_priv->mm.phys_objs[id - 1] = phys_obj; - return (0); - -free_obj: + return 0; +kfree_obj: free(phys_obj, DRM_I915_GEM); - return (ret); + return ret; } -static void -i915_gem_free_phys_object(struct drm_device *dev, int id) +static void i915_gem_free_phys_object(struct drm_device *dev, int id) { - drm_i915_private_t *dev_priv; + drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_phys_object *phys_obj; - dev_priv = dev->dev_private; - if (dev_priv->mm.phys_objs[id - 1] == NULL) + if (!dev_priv->mm.phys_objs[id - 1]) return; phys_obj = dev_priv->mm.phys_objs[id - 1]; - if (phys_obj->cur_obj != NULL) + if (phys_obj->cur_obj) { i915_gem_detach_phys_object(dev, phys_obj->cur_obj); + } drm_pci_free(dev, phys_obj->handle); free(phys_obj, DRM_I915_GEM); dev_priv->mm.phys_objs[id - 1] = NULL; } -void -i915_gem_free_all_phys_object(struct drm_device *dev) +void i915_gem_free_all_phys_object(struct drm_device *dev) { int i; @@ -4098,41 +4158,40 @@ i915_gem_free_all_phys_object(struct drm_device *dev) i915_gem_free_phys_object(dev, i); } -void -i915_gem_detach_phys_object(struct drm_device *dev, - struct drm_i915_gem_object *obj) +void i915_gem_detach_phys_object(struct drm_device *dev, + struct drm_i915_gem_object *obj) { - vm_page_t m; + vm_page_t page; struct sf_buf *sf; char *vaddr, *dst; int i, page_count; - if (obj->phys_obj == NULL) + if (!obj->phys_obj) return; vaddr = obj->phys_obj->handle->vaddr; page_count = obj->base.size / PAGE_SIZE; VM_OBJECT_WLOCK(obj->base.vm_obj); for (i = 0; i < page_count; i++) { - m = i915_gem_wire_page(obj->base.vm_obj, i, NULL); - if (m == NULL) + page = i915_gem_wire_page(obj->base.vm_obj, i, NULL); + if (page == NULL) continue; /* XXX */ VM_OBJECT_WUNLOCK(obj->base.vm_obj); - sf = sf_buf_alloc(m, 0); + sf = sf_buf_alloc(page, 0); if (sf != NULL) { dst = (char *)sf_buf_kva(sf); memcpy(dst, vaddr + IDX_TO_OFF(i), PAGE_SIZE); sf_buf_free(sf); } - drm_clflush_pages(&m, 1); + drm_clflush_pages(&page, 1); VM_OBJECT_WLOCK(obj->base.vm_obj); - vm_page_reference(m); - vm_page_lock(m); - vm_page_dirty(m); - vm_page_unwire(m, PQ_INACTIVE); - vm_page_unlock(m); + vm_page_reference(page); + vm_page_lock(page); + vm_page_dirty(page); + vm_page_unwire(page, PQ_INACTIVE); + vm_page_unlock(page); atomic_add_long(&i915_gem_wired_pages_cnt, -1); } VM_OBJECT_WUNLOCK(obj->base.vm_obj); @@ -4144,30 +4203,35 @@ i915_gem_detach_phys_object(struct drm_device *dev, int i915_gem_attach_phys_object(struct drm_device *dev, - struct drm_i915_gem_object *obj, int id, int align) + struct drm_i915_gem_object *obj, + int id, + int align) { - drm_i915_private_t *dev_priv; - vm_page_t m; + drm_i915_private_t *dev_priv = dev->dev_private; + vm_page_t page; struct sf_buf *sf; char *dst, *src; - int i, page_count, ret; + int ret = 0; + int page_count; + int i; if (id > I915_MAX_PHYS_OBJECT) - return (-EINVAL); + return -EINVAL; - if (obj->phys_obj != NULL) { + if (obj->phys_obj) { if (obj->phys_obj->id == id) - return (0); + return 0; i915_gem_detach_phys_object(dev, obj); } - dev_priv = dev->dev_private; - if (dev_priv->mm.phys_objs[id - 1] == NULL) { - ret = i915_gem_init_phys_object(dev, id, obj->base.size, align); - if (ret != 0) { + /* create a new object */ + if (!dev_priv->mm.phys_objs[id - 1]) { + ret = i915_gem_init_phys_object(dev, id, + obj->base.size, align); + if (ret) { DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->base.size); - return (ret); + return ret; } } @@ -4178,15 +4242,14 @@ i915_gem_attach_phys_object(struct drm_device *dev, page_count = obj->base.size / PAGE_SIZE; VM_OBJECT_WLOCK(obj->base.vm_obj); - ret = 0; for (i = 0; i < page_count; i++) { - m = i915_gem_wire_page(obj->base.vm_obj, i, NULL); - if (m == NULL) { + page = i915_gem_wire_page(obj->base.vm_obj, i, NULL); + if (page == NULL) { ret = -EIO; break; } VM_OBJECT_WUNLOCK(obj->base.vm_obj); - sf = sf_buf_alloc(m, 0); + sf = sf_buf_alloc(page, 0); src = (char *)sf_buf_kva(sf); dst = (char *)obj->phys_obj->handle->vaddr + IDX_TO_OFF(i); memcpy(dst, src, PAGE_SIZE); @@ -4194,85 +4257,106 @@ i915_gem_attach_phys_object(struct drm_device *dev, VM_OBJECT_WLOCK(obj->base.vm_obj); - vm_page_reference(m); - vm_page_lock(m); - vm_page_unwire(m, PQ_INACTIVE); - vm_page_unlock(m); + vm_page_reference(page); + vm_page_lock(page); + vm_page_unwire(page, PQ_INACTIVE); + vm_page_unlock(page); atomic_add_long(&i915_gem_wired_pages_cnt, -1); } VM_OBJECT_WUNLOCK(obj->base.vm_obj); - return (ret); + return ret; } static int -i915_gpu_is_active(struct drm_device *dev) +i915_gem_phys_pwrite(struct drm_device *dev, + struct drm_i915_gem_object *obj, + struct drm_i915_gem_pwrite *args, + struct drm_file *file_priv) { - drm_i915_private_t *dev_priv; + void *vaddr = (char *)obj->phys_obj->handle->vaddr + args->offset; + char __user *user_data = to_user_ptr(args->data_ptr); - dev_priv = dev->dev_private; - return (!list_empty(&dev_priv->mm.flushing_list) || - !list_empty(&dev_priv->mm.active_list)); -} + if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { + unsigned long unwritten; -static void -i915_gem_lowmem(void *arg) -{ - struct drm_device *dev; - struct drm_i915_private *dev_priv; - struct drm_i915_gem_object *obj, *next; - int cnt, cnt_fail, cnt_total; - - dev = arg; - dev_priv = dev->dev_private; - - if (!sx_try_xlock(&dev->dev_struct_lock)) - return; - - CTR0(KTR_DRM, "gem_lowmem"); - -rescan: - /* first scan for clean buffers */ - i915_gem_retire_requests(dev); - - cnt_total = cnt_fail = cnt = 0; - - list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, - mm_list) { - if (i915_gem_object_is_purgeable(obj)) { - if (i915_gem_object_unbind(obj) != 0) - cnt_total++; - } else - cnt_total++; - } - - /* second pass, evict/count anything still on the inactive list */ - list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, - mm_list) { - if (i915_gem_object_unbind(obj) == 0) - cnt++; - else - cnt_fail++; - } - - if (cnt_fail > cnt_total / 100 && i915_gpu_is_active(dev)) { - /* - * We are desperate for pages, so as a last resort, wait - * for the GPU to finish and discard whatever we can. - * This has a dramatic impact to reduce the number of - * OOM-killer events whilst running the GPU aggressively. + /* The physical object once assigned is fixed for the lifetime + * of the obj, so we can safely drop the lock and continue + * to access vaddr. */ - if (i915_gpu_idle(dev) == 0) - goto rescan; + DRM_UNLOCK(dev); + unwritten = copy_from_user(vaddr, user_data, args->size); + DRM_LOCK(dev); + if (unwritten) + return -EFAULT; } - DRM_UNLOCK(dev); + + i915_gem_chipset_flush(dev); + return 0; } -void -i915_gem_unload(struct drm_device *dev) +void i915_gem_release(struct drm_device *dev, struct drm_file *file) { - struct drm_i915_private *dev_priv; + struct drm_i915_file_private *file_priv = file->driver_priv; - dev_priv = dev->dev_private; - EVENTHANDLER_DEREGISTER(vm_lowmem, dev_priv->mm.i915_lowmem); + /* Clean up our request list when the client is going away, so that + * later retire_requests won't dereference our soon-to-be-gone + * file_priv. + */ + mtx_lock(&file_priv->mm.lck); + while (!list_empty(&file_priv->mm.request_list)) { + struct drm_i915_gem_request *request; + + request = list_first_entry(&file_priv->mm.request_list, + struct drm_i915_gem_request, + client_list); + list_del(&request->client_list); + request->file_priv = NULL; + } + mtx_unlock(&file_priv->mm.lck); } + +static vm_page_t +i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, bool *fresh) +{ + vm_page_t page; + int rv; + + VM_OBJECT_ASSERT_WLOCKED(object); + page = vm_page_grab(object, pindex, VM_ALLOC_NORMAL); + if (page->valid != VM_PAGE_BITS_ALL) { + if (vm_pager_has_page(object, pindex, NULL, NULL)) { + rv = vm_pager_get_pages(object, &page, 1, 0); + if (rv != VM_PAGER_OK) { + vm_page_lock(page); + vm_page_free(page); + vm_page_unlock(page); + return (NULL); + } + if (fresh != NULL) + *fresh = true; + } else { + pmap_zero_page(page); + page->valid = VM_PAGE_BITS_ALL; + page->dirty = 0; + if (fresh != NULL) + *fresh = false; + } + } else if (fresh != NULL) { + *fresh = false; + } + vm_page_lock(page); + vm_page_wire(page); + vm_page_unlock(page); + vm_page_xunbusy(page); + atomic_add_long(&i915_gem_wired_pages_cnt, 1); + return (page); +} + +#undef __user +#undef __force +#undef __iomem +#undef __must_check +#undef to_user_ptr +#undef offset_in_page +#undef page_to_phys diff --git a/sys/dev/drm2/i915/i915_gem_gtt.c b/sys/dev/drm2/i915/i915_gem_gtt.c index 89c8060fd3cb..117c07cc3f7c 100644 --- a/sys/dev/drm2/i915/i915_gem_gtt.c +++ b/sys/dev/drm2/i915/i915_gem_gtt.c @@ -189,6 +189,61 @@ void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, obj->base.size >> PAGE_SHIFT); } +void i915_gem_init_ppgtt(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv; + struct i915_hw_ppgtt *ppgtt; + uint32_t pd_offset, pd_entry; + vm_paddr_t pt_addr; + struct intel_ring_buffer *ring; + u_int first_pd_entry_in_global_pt, i; + + dev_priv = dev->dev_private; + ppgtt = dev_priv->mm.aliasing_ppgtt; + if (ppgtt == NULL) + return; + + first_pd_entry_in_global_pt = 512 * 1024 - I915_PPGTT_PD_ENTRIES; + for (i = 0; i < ppgtt->num_pd_entries; i++) { + pt_addr = VM_PAGE_TO_PHYS(ppgtt->pt_pages[i]); + pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); + pd_entry |= GEN6_PDE_VALID; + intel_gtt_write(first_pd_entry_in_global_pt + i, pd_entry); + } + intel_gtt_read_pte(first_pd_entry_in_global_pt); + + pd_offset = ppgtt->pd_offset; + pd_offset /= 64; /* in cachelines, */ + pd_offset <<= 16; + + if (INTEL_INFO(dev)->gen == 6) { + uint32_t ecochk, gab_ctl, ecobits; + + ecobits = I915_READ(GAC_ECO_BITS); + I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B); + + gab_ctl = I915_READ(GAB_CTL); + I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT); + + ecochk = I915_READ(GAM_ECOCHK); + I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | + ECOCHK_PPGTT_CACHE64B); + I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); + } else if (INTEL_INFO(dev)->gen >= 7) { + I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); + /* GFX_MODE is per-ring on gen7+ */ + } + + for_each_ring(ring, dev_priv, i) { + if (INTEL_INFO(dev)->gen >= 7) + I915_WRITE(RING_MODE_GEN7(ring), + _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); + + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); + } +} + void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) { From bbdee3ebde9fa64a814fa235fb577dbbc2e499b1 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Tue, 28 Jul 2015 21:49:38 +0000 Subject: [PATCH 032/314] Reject usermod and userdel if the user concerned is not on the user database supposed to be manipulated This prevent pw usermod creating a new local user when requesting to usermod on a username is defined in LDAP. This issue only happens when modifying the local user database (not inpacting commands when -V or -R are used). PR: 187653 Submitted by: tmwalaszek@gmail.com --- usr.sbin/pw/pw_user.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index aecc90aa174a..cd9c23c3676c 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -310,6 +310,7 @@ pw_user(int mode, char *name, long id, struct cargs * args) FILE *fp; char *dmode_c; void *set = NULL; + int valid_type = _PWF_FILES; static struct passwd fakeuser = { @@ -505,6 +506,14 @@ pw_user(int mode, char *name, long id, struct cargs * args) errx(EX_NOUSER, "no such user `%s'", name); } + if (conf.userconf->nispasswd && *conf.userconf->nispasswd == '/') + valid_type = _PWF_NIS; + + if (PWF._altdir == PWF_REGULAR && + ((pwd->pw_fields & _PWF_SOURCE) != valid_type)) + errx(EX_NOUSER, "no such %s user `%s'", + valid_type == _PWF_FILES ? "local" : "NIS" , name); + if (name == NULL) name = pwd->pw_name; @@ -1076,6 +1085,7 @@ pw_userdel(char *name, long id) char grname[LOGNAMESIZE]; int rc; struct stat st; + int valid_type = _PWF_FILES; if (id < 0 && name == NULL) errx(EX_DATAERR, "username or id required"); @@ -1086,6 +1096,15 @@ pw_userdel(char *name, long id) errx(EX_NOUSER, "no such uid `%ld'", id); errx(EX_NOUSER, "no such user `%s'", name); } + + if (conf.userconf->nispasswd && *conf.userconf->nispasswd == '/') + valid_type = _PWF_NIS; + + if (PWF._altdir == PWF_REGULAR && + ((pwd->pw_fields & _PWF_SOURCE) != valid_type)) + errx(EX_NOUSER, "no such %s user `%s'", + valid_type == _PWF_FILES ? "local" : "NIS" , name); + uid = pwd->pw_uid; if (name == NULL) name = pwd->pw_name; From b7551bceebaa972dcfa72abb4eb0dae4f4fe91d7 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Tue, 28 Jul 2015 22:48:58 +0000 Subject: [PATCH 033/314] unlink(2): Note the possibility for ENOSPC to be returned on ZFS. PR: 154930 --- lib/libc/sys/unlink.2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/libc/sys/unlink.2 b/lib/libc/sys/unlink.2 index 406c77c24752..e59ecf8b2a93 100644 --- a/lib/libc/sys/unlink.2 +++ b/lib/libc/sys/unlink.2 @@ -28,7 +28,7 @@ .\" @(#)unlink.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd April 25, 2010 +.Dd July 28, 2015 .Dt UNLINK 2 .Os .Sh NAME @@ -151,6 +151,9 @@ The .Fa path argument points outside the process's allocated address space. +.It Bq Er ENOSPC +On file systems supporting copy-on-write or snapshots, there was not enough +free space to record metadata for the delete operation of the file. .El .Pp In addition to the errors returned by the From 006a388bb64106d24d6e8065b8547ff6ec3c06f0 Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Wed, 29 Jul 2015 02:21:35 +0000 Subject: [PATCH 034/314] Compilers will complain the usage of obsolescent variable declarations. Also it will fix the build problem with sparc64. Submitted by: ed@ --- usr.bin/ypcat/ypcat.c | 4 ++-- usr.bin/ypmatch/ypmatch.c | 4 ++-- usr.bin/ypwhich/ypwhich.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/usr.bin/ypcat/ypcat.c b/usr.bin/ypcat/ypcat.c index b3d90336c61a..d3a7f4177997 100644 --- a/usr.bin/ypcat/ypcat.c +++ b/usr.bin/ypcat/ypcat.c @@ -47,9 +47,9 @@ __FBSDID("$FreeBSD$"); #include #include -const struct ypalias { +static const struct ypalias { char *alias, *name; -} static ypaliases[] = { +} ypaliases[] = { { "passwd", "passwd.byname" }, { "master.passwd", "master.passwd.byname" }, { "shadow", "shadow.byname" }, diff --git a/usr.bin/ypmatch/ypmatch.c b/usr.bin/ypmatch/ypmatch.c index d6b58c2c5d31..ff4253fbaf0c 100644 --- a/usr.bin/ypmatch/ypmatch.c +++ b/usr.bin/ypmatch/ypmatch.c @@ -47,9 +47,9 @@ __FBSDID("$FreeBSD$"); #include #include -const struct ypalias { +static const struct ypalias { char *alias, *name; -} static ypaliases[] = { +} ypaliases[] = { { "passwd", "passwd.byname" }, { "master.passwd", "master.passwd.byname" }, { "shadow", "shadow.byname" }, diff --git a/usr.bin/ypwhich/ypwhich.c b/usr.bin/ypwhich/ypwhich.c index d02461ebafb9..14fc1b344125 100644 --- a/usr.bin/ypwhich/ypwhich.c +++ b/usr.bin/ypwhich/ypwhich.c @@ -59,9 +59,9 @@ __FBSDID("$FreeBSD$"); extern bool_t xdr_domainname(); -const struct ypalias { +static const struct ypalias { char *alias, *name; -} static ypaliases[] = { +} ypaliases[] = { { "passwd", "passwd.byname" }, { "master.passwd", "master.passwd.byname" }, { "shadow", "shadow.byname" }, From 98082691bbd38c008e72e5fefe0a6ffde24af09f Mon Sep 17 00:00:00 2001 From: Jeff Roberson Date: Wed, 29 Jul 2015 02:26:57 +0000 Subject: [PATCH 035/314] - Make 'struct buf *buf' private to vfs_bio.c. Having a global variable 'buf' is inconvenient and has lead me to some irritating to discover bugs over the years. It also makes it more challenging to refactor the buf allocation system. - Move swbuf and declare it as an extern in vfs_bio.c. This is still not perfect but better than it was before. - Eliminate the unused ffs function that relied on knowledge of the buf array. - Move the shutdown code that iterates over the buf array into vfs_bio.c. Reviewed by: kib Sponsored by: EMC / Isilon Storage Division --- sys/kern/kern_shutdown.c | 126 ++--------------------------------- sys/kern/subr_param.c | 7 -- sys/kern/vfs_bio.c | 138 +++++++++++++++++++++++++++++++++++++-- sys/sys/buf.h | 3 +- sys/ufs/ffs/ffs_subr.c | 35 ---------- sys/vm/vm_pager.c | 2 + 6 files changed, 140 insertions(+), 171 deletions(-) diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 4d57fd3f3fcf..3a91673bab11 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -275,24 +275,13 @@ doadump(boolean_t textdump) return (error); } -static int -isbufbusy(struct buf *bp) -{ - if (((bp->b_flags & (B_INVAL | B_PERSISTENT)) == 0 && - BUF_ISLOCKED(bp)) || - ((bp->b_flags & (B_DELWRI | B_INVAL)) == B_DELWRI)) - return (1); - return (0); -} - /* * Shutdown the system cleanly to prepare for reboot, halt, or power off. */ void kern_reboot(int howto) { - static int first_buf_printf = 1; - static int waittime = -1; + static int once = 0; #if defined(SMP) /* @@ -321,116 +310,9 @@ kern_reboot(int howto) /* * Now sync filesystems */ - if (!cold && (howto & RB_NOSYNC) == 0 && waittime < 0) { - register struct buf *bp; - int iter, nbusy, pbusy; -#ifndef PREEMPTION - int subiter; -#endif - - waittime = 0; - - wdog_kern_pat(WD_LASTVAL); - sys_sync(curthread, NULL); - - /* - * With soft updates, some buffers that are - * written will be remarked as dirty until other - * buffers are written. - */ - for (iter = pbusy = 0; iter < 20; iter++) { - nbusy = 0; - for (bp = &buf[nbuf]; --bp >= buf; ) - if (isbufbusy(bp)) - nbusy++; - if (nbusy == 0) { - if (first_buf_printf) - printf("All buffers synced."); - break; - } - if (first_buf_printf) { - printf("Syncing disks, buffers remaining... "); - first_buf_printf = 0; - } - printf("%d ", nbusy); - if (nbusy < pbusy) - iter = 0; - pbusy = nbusy; - - wdog_kern_pat(WD_LASTVAL); - sys_sync(curthread, NULL); - -#ifdef PREEMPTION - /* - * Drop Giant and spin for a while to allow - * interrupt threads to run. - */ - DROP_GIANT(); - DELAY(50000 * iter); - PICKUP_GIANT(); -#else - /* - * Drop Giant and context switch several times to - * allow interrupt threads to run. - */ - DROP_GIANT(); - for (subiter = 0; subiter < 50 * iter; subiter++) { - thread_lock(curthread); - mi_switch(SW_VOL, NULL); - thread_unlock(curthread); - DELAY(1000); - } - PICKUP_GIANT(); -#endif - } - printf("\n"); - /* - * Count only busy local buffers to prevent forcing - * a fsck if we're just a client of a wedged NFS server - */ - nbusy = 0; - for (bp = &buf[nbuf]; --bp >= buf; ) { - if (isbufbusy(bp)) { -#if 0 -/* XXX: This is bogus. We should probably have a BO_REMOTE flag instead */ - if (bp->b_dev == NULL) { - TAILQ_REMOVE(&mountlist, - bp->b_vp->v_mount, mnt_list); - continue; - } -#endif - nbusy++; - if (show_busybufs > 0) { - printf( - "%d: buf:%p, vnode:%p, flags:%0x, blkno:%jd, lblkno:%jd, buflock:", - nbusy, bp, bp->b_vp, bp->b_flags, - (intmax_t)bp->b_blkno, - (intmax_t)bp->b_lblkno); - BUF_LOCKPRINTINFO(bp); - if (show_busybufs > 1) - vn_printf(bp->b_vp, - "vnode content: "); - } - } - } - if (nbusy) { - /* - * Failed to sync all blocks. Indicate this and don't - * unmount filesystems (thus forcing an fsck on reboot). - */ - printf("Giving up on %d buffers\n", nbusy); - DELAY(5000000); /* 5 seconds */ - } else { - if (!first_buf_printf) - printf("Final sync complete\n"); - /* - * Unmount filesystems - */ - if (panicstr == 0) - vfs_unmountall(); - } - swapoff_all(); - DELAY(100000); /* wait for console output to finish */ + if (!cold && (howto & RB_NOSYNC) == 0 && once == 0) { + once = 1; + bufshutdown(show_busybufs); } print_uptime(); diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c index cba656aa1884..5043a57bfefb 100644 --- a/sys/kern/subr_param.c +++ b/sys/kern/subr_param.c @@ -138,13 +138,6 @@ SYSCTL_PROC(_kern, OID_AUTO, vm_guest, CTLFLAG_RD | CTLTYPE_STRING, NULL, 0, sysctl_kern_vm_guest, "A", "Virtual machine guest detected?"); -/* - * These have to be allocated somewhere; allocating - * them here forces loader errors if this file is omitted - * (if they've been externed everywhere else; hah!). - */ -struct buf *swbuf; - /* * The elements of this array are ordered based upon the values of the * corresponding enum VM_GUEST members. diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 01be712edaa4..ac6c61813e69 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -64,9 +64,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#include #include #include #include @@ -76,6 +78,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "opt_compat.h" #include "opt_swap.h" @@ -91,11 +94,8 @@ struct buf_ops buf_ops_bio = { .bop_bdflush = bufbdflush, }; -/* - * XXX buf is global because kern_shutdown.c and ffs_checkoverlap has - * carnal knowledge of buffers. This knowledge should be moved to vfs_bio.c. - */ -struct buf *buf; /* buffer header pool */ +static struct buf *buf; /* buffer header pool */ +extern struct buf *swbuf; /* Swap buffer header pool. */ caddr_t unmapped_buf; /* Used below and for softdep flushing threads in ufs/ffs/ffs_softdep.c */ @@ -958,6 +958,134 @@ vfs_buf_check_mapped(struct buf *bp) KASSERT(bp->b_data < unmapped_buf || bp->b_data > unmapped_buf + MAXPHYS, ("b_data + b_offset unmapped %p", bp)); } +static int +isbufbusy(struct buf *bp) +{ + if (((bp->b_flags & (B_INVAL | B_PERSISTENT)) == 0 && + BUF_ISLOCKED(bp)) || + ((bp->b_flags & (B_DELWRI | B_INVAL)) == B_DELWRI)) + return (1); + return (0); +} + +/* + * Shutdown the system cleanly to prepare for reboot, halt, or power off. + */ +void +bufshutdown(int show_busybufs) +{ + static int first_buf_printf = 1; + struct buf *bp; + int iter, nbusy, pbusy; +#ifndef PREEMPTION + int subiter; +#endif + + /* + * Sync filesystems for shutdown + */ + wdog_kern_pat(WD_LASTVAL); + sys_sync(curthread, NULL); + + /* + * With soft updates, some buffers that are + * written will be remarked as dirty until other + * buffers are written. + */ + for (iter = pbusy = 0; iter < 20; iter++) { + nbusy = 0; + for (bp = &buf[nbuf]; --bp >= buf; ) + if (isbufbusy(bp)) + nbusy++; + if (nbusy == 0) { + if (first_buf_printf) + printf("All buffers synced."); + break; + } + if (first_buf_printf) { + printf("Syncing disks, buffers remaining... "); + first_buf_printf = 0; + } + printf("%d ", nbusy); + if (nbusy < pbusy) + iter = 0; + pbusy = nbusy; + + wdog_kern_pat(WD_LASTVAL); + sys_sync(curthread, NULL); + +#ifdef PREEMPTION + /* + * Drop Giant and spin for a while to allow + * interrupt threads to run. + */ + DROP_GIANT(); + DELAY(50000 * iter); + PICKUP_GIANT(); +#else + /* + * Drop Giant and context switch several times to + * allow interrupt threads to run. + */ + DROP_GIANT(); + for (subiter = 0; subiter < 50 * iter; subiter++) { + thread_lock(curthread); + mi_switch(SW_VOL, NULL); + thread_unlock(curthread); + DELAY(1000); + } + PICKUP_GIANT(); +#endif + } + printf("\n"); + /* + * Count only busy local buffers to prevent forcing + * a fsck if we're just a client of a wedged NFS server + */ + nbusy = 0; + for (bp = &buf[nbuf]; --bp >= buf; ) { + if (isbufbusy(bp)) { +#if 0 +/* XXX: This is bogus. We should probably have a BO_REMOTE flag instead */ + if (bp->b_dev == NULL) { + TAILQ_REMOVE(&mountlist, + bp->b_vp->v_mount, mnt_list); + continue; + } +#endif + nbusy++; + if (show_busybufs > 0) { + printf( + "%d: buf:%p, vnode:%p, flags:%0x, blkno:%jd, lblkno:%jd, buflock:", + nbusy, bp, bp->b_vp, bp->b_flags, + (intmax_t)bp->b_blkno, + (intmax_t)bp->b_lblkno); + BUF_LOCKPRINTINFO(bp); + if (show_busybufs > 1) + vn_printf(bp->b_vp, + "vnode content: "); + } + } + } + if (nbusy) { + /* + * Failed to sync all blocks. Indicate this and don't + * unmount filesystems (thus forcing an fsck on reboot). + */ + printf("Giving up on %d buffers\n", nbusy); + DELAY(5000000); /* 5 seconds */ + } else { + if (!first_buf_printf) + printf("Final sync complete\n"); + /* + * Unmount filesystems + */ + if (panicstr == 0) + vfs_unmountall(); + } + swapoff_all(); + DELAY(100000); /* wait for console output to finish */ +} static inline void vfs_buf_check_unmapped(struct buf *bp) diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 2ffa4f5b27fb..d5ce0e51d87a 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -465,8 +465,6 @@ extern int dirtybufthresh; extern int bdwriteskip; extern int dirtybufferflushes; extern int altbufferflushes; -extern struct buf *buf; /* The buffer headers. */ -extern struct buf *swbuf; /* Swap I/O buffer headers. */ extern int nswbuf; /* Number of swap I/O buffer headers. */ extern int cluster_pbuf_freecnt; /* Number of pbufs for clusters */ extern int vnode_pbuf_freecnt; /* Number of pbufs for vnode pager */ @@ -485,6 +483,7 @@ void runningbufwakeup(struct buf *); void waitrunningbufspace(void); caddr_t kern_vfs_bio_buffer_alloc(caddr_t v, long physmem_est); void bufinit(void); +void bufshutdown(int); void bdata2bio(struct buf *bp, struct bio *bip); void bwillwrite(void); int buf_dirty_count_severe(void); diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c index e2460a36be2d..67f7e5ceebc2 100644 --- a/sys/ufs/ffs/ffs_subr.c +++ b/sys/ufs/ffs/ffs_subr.c @@ -55,10 +55,6 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef KDB -void ffs_checkoverlap(struct buf *, struct inode *); -#endif - /* * Return buffer with the contents of block "offset" from the beginning of * directory "ip". If "res" is non-zero, fill it in with a pointer to the @@ -165,37 +161,6 @@ ffs_fragacct(fs, fragmap, fraglist, cnt) } } -#ifdef KDB -void -ffs_checkoverlap(bp, ip) - struct buf *bp; - struct inode *ip; -{ - struct buf *ebp, *ep; - ufs2_daddr_t start, last; - struct vnode *vp; - - ebp = &buf[nbuf]; - start = bp->b_blkno; - last = start + btodb(bp->b_bcount) - 1; - for (ep = buf; ep < ebp; ep++) { - if (ep == bp || (ep->b_flags & B_INVAL) || - ep->b_vp == NULLVP) - continue; - vp = ip->i_devvp; - /* look for overlap */ - if (ep->b_bcount == 0 || ep->b_blkno > last || - ep->b_blkno + btodb(ep->b_bcount) <= start) - continue; - vprint("Disk overlap", vp); - printf("\tstart %jd, end %jd overlap start %jd, end %jd\n", - (intmax_t)start, (intmax_t)last, (intmax_t)ep->b_blkno, - (intmax_t)(ep->b_blkno + btodb(ep->b_bcount) - 1)); - panic("ffs_checkoverlap: Disk buffer overlap"); - } -} -#endif /* KDB */ - /* * block operations * diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c index a42061c0417b..40d7d4e43ac7 100644 --- a/sys/vm/vm_pager.c +++ b/sys/vm/vm_pager.c @@ -86,6 +86,8 @@ __FBSDID("$FreeBSD$"); int cluster_pbuf_freecnt = -1; /* unlimited to begin with */ +struct buf *swbuf; + static int dead_pager_getpages(vm_object_t, vm_page_t *, int, int); static vm_object_t dead_pager_alloc(void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t, struct ucred *); From aa255ef6dd5e11952d36d2f7963a596155a8454b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 29 Jul 2015 02:34:25 +0000 Subject: [PATCH 036/314] Teach sysctl about the new optional suffix after IK to specify precision. Update input as well. Add IK to the manual (it was missing completely). Differential Revision: https://reviews.freebsd.org/D3181 --- sbin/sysctl/sysctl.c | 50 ++++++++++++++++++++++++++++++++------- share/man/man9/sysctl.9 | 52 ++++++++++++++++++++--------------------- 2 files changed, 67 insertions(+), 35 deletions(-) diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c index f32112013610..d740778cf0c8 100644 --- a/sbin/sysctl/sysctl.c +++ b/sbin/sysctl/sysctl.c @@ -81,7 +81,7 @@ static int show_var(int *, int); static int sysctl_all(int *oid, int len); static int name2oid(const char *, int *); -static int strIKtoi(const char *, char **); +static int strIKtoi(const char *, char **, const char *); static int ctl_sign[CTLTYPE+1] = { [CTLTYPE_INT] = 1, @@ -336,8 +336,8 @@ parse(const char *string, int lineno) switch (kind & CTLTYPE) { case CTLTYPE_INT: - if (strcmp(fmt, "IK") == 0) - intval = strIKtoi(newvalstr, &endptr); + if (strncmp(fmt, "IK", 2) == 0) + intval = strIKtoi(newvalstr, &endptr, fmt); else intval = (int)strtol(newvalstr, &endptr, 0); @@ -666,12 +666,13 @@ S_bios_smap_xattr(size_t l2, void *p) #endif static int -strIKtoi(const char *str, char **endptrp) +strIKtoi(const char *str, char **endptrp, const char *fmt) { int kelv; float temp; size_t len; const char *p; + int prec, i; assert(errno == 0); @@ -679,16 +680,36 @@ strIKtoi(const char *str, char **endptrp) /* caller already checked this */ assert(len > 0); + /* + * A format of "IK" is in deciKelvin. A format of "IK3" is in + * milliKelvin. The single digit following IK is log10 of the + * multiplying factor to convert Kelvin into the untis of this sysctl, + * or the dividing factor to convert the sysctl value to Kelvin. Numbers + * larger than 6 will run into precision issues with 32-bit integers. + * Characters that aren't ASCII digits after the 'K' are ignored. No + * localization is present because this is an interface from the kernel + * to this program (eg not an end-user interface), so isdigit() isn't + * used here. + */ + if (fmt[2] != '\0' && fmt[2] >= '0' && fmt[2] <= '9') + prec = fmt[2] - '0'; + else + prec = 1; p = &str[len - 1]; - if (*p == 'C' || *p == 'F') { + if (*p == 'C' || *p == 'F' || *p == 'K') { temp = strtof(str, endptrp); if (*endptrp != str && *endptrp == p && errno == 0) { if (*p == 'F') temp = (temp - 32) * 5 / 9; *endptrp = NULL; - return (temp * 10 + 2732); + if (*p != 'K') + temp += 273.15; + for (i = 0; i < prec; i++) + temp *= 10.0; + return ((int)(temp + 0.5)); } } else { + /* No unit specified -> treat it as a raw number */ kelv = (int)strtol(str, endptrp, 10); if (*endptrp != str && *endptrp == p && errno == 0) { *endptrp = NULL; @@ -772,7 +793,9 @@ show_var(int *oid, int nlen) size_t intlen; size_t j, len; u_int kind; + float base; int (*func)(size_t, void *); + int prec; /* Silence GCC. */ umv = mv = intlen = 0; @@ -893,8 +916,19 @@ show_var(int *oid, int nlen) else if (fmt[1] == 'K') { if (mv < 0) printf("%jd", mv); - else - printf("%.1fC", (mv - 2732.0) / 10); + else { + /* + * See strIKtoi for details on fmt. + */ + prec = 1; + if (fmt[2] != '\0') + prec = fmt[2] - '0'; + base = 1.0; + for (int i = 0; i < prec; i++) + base *= 10.0; + printf("%.*fC", prec, + (float)mv / base - 273.15); + } } else printf(hflag ? "%'jd" : "%jd", mv); sep1 = " "; diff --git a/share/man/man9/sysctl.9 b/share/man/man9/sysctl.9 index cdf05921d269..51ab5d7ab747 100644 --- a/share/man/man9/sysctl.9 +++ b/share/man/man9/sysctl.9 @@ -318,35 +318,33 @@ which specifies the format of the OID in a symbolic way. This format is used as a hint by .Xr sysctl 8 to apply proper data formatting for display purposes. -Currently used format names are: -.Dq N -for node, -.Dq A -for -.Li "char *" , -.Dq I -for -.Li "int" , -.Dq IU -for -.Li "unsigned int" , -.Dq L -for -.Li "long" , -.Dq LU -for -.Li "unsigned long" , -.Dq Q -for -.Li "quad_t" , -.Dq QU -for +.Pp +Current formats: +.Bl -tag -width "S,TYPE" -compact -offset indent +.It Cm N +node +.It Cm A +.Li "char *" +.It Cm I +.Li "int" +.It Cm IK Ns Op Ar n +temperature in Kelvin, multiplied by an optional single digit +power of ten scaling factor: 1 (default) gives deciKelvin, 0 gives Kelvin, 3 +gives milliKelvin +.It Cm IU +.Li "unsigned int" +.It Cm L +.Li "long" +.It Cm LU +.Li "unsigned long" +.It Cm Q +.Li "quad_t" +.It Cm QU .Li "u_quad_t" -and -.Dq S,TYPE -for +.It Cm "S,TYPE" .Li "struct TYPE" -structures. +structures +.El .It Fa descr A pointer to a textual description of the OID. .El From 7d07bfd8a39e6aaea81cd608eb1bd7f472fa8cbc Mon Sep 17 00:00:00 2001 From: Jeff Roberson Date: Wed, 29 Jul 2015 03:06:08 +0000 Subject: [PATCH 037/314] - Remove some dead code copied from ffs. --- sys/fs/ext2fs/ext2_subr.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/sys/fs/ext2fs/ext2_subr.c b/sys/fs/ext2fs/ext2_subr.c index 6b9041d6e4a8..1c5c3bb9b8c9 100644 --- a/sys/fs/ext2fs/ext2_subr.c +++ b/sys/fs/ext2fs/ext2_subr.c @@ -54,10 +54,6 @@ #include #include -#ifdef KDB -void ext2_checkoverlap(struct buf *, struct inode *); -#endif - /* * Return buffer with the contents of block "offset" from the beginning of * directory "ip". If "res" is non-zero, fill it in with a pointer to the @@ -130,34 +126,6 @@ ext2_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) return (0); } -#ifdef KDB -void -ext2_checkoverlap(struct buf *bp, struct inode *ip) -{ - struct buf *ebp, *ep; - e4fs_daddr_t start, last; - struct vnode *vp; - - ebp = &buf[nbuf]; - start = bp->b_blkno; - last = start + btodb(bp->b_bcount) - 1; - for (ep = buf; ep < ebp; ep++) { - if (ep == bp || (ep->b_flags & B_INVAL)) - continue; - vp = ip->i_ump->um_devvp; - /* look for overlap */ - if (ep->b_bcount == 0 || ep->b_blkno > last || - ep->b_blkno + btodb(ep->b_bcount) <= start) - continue; - vprint("Disk overlap", vp); - printf("\tstart %jd, end %jd overlap start %jd, end %jd\n", - (intmax_t)start, (intmax_t)last, (intmax_t)ep->b_blkno, - (intmax_t)(ep->b_blkno + btodb(ep->b_bcount) - 1)); - panic("ext2_checkoverlap: Disk buffer overlap"); - } -} -#endif /* KDB */ - /* * Update the cluster map because of an allocation of free like ffs. * From 8411215a807ac7948df16e12df0b1e878d368b2f Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 29 Jul 2015 06:22:41 +0000 Subject: [PATCH 038/314] Create a strtounum function using the same API as strtonum This function returns uintmax_t Use this function to convert to gid_t/uid_t --- usr.sbin/pw/Makefile | 2 +- usr.sbin/pw/pw.c | 6 +++--- usr.sbin/pw/pw.h | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/usr.sbin/pw/Makefile b/usr.sbin/pw/Makefile index c265399730c7..87bb5f68e3d6 100644 --- a/usr.sbin/pw/Makefile +++ b/usr.sbin/pw/Makefile @@ -3,7 +3,7 @@ PROG= pw MAN= pw.conf.5 pw.8 SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \ - grupd.c pwupd.c psdate.c bitmap.c cpdir.c rm_r.c + grupd.c pwupd.c psdate.c bitmap.c cpdir.c rm_r.c strtounum.c WARNS?= 3 diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index c1d9cd32a708..88c83dbfa125 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -199,7 +199,7 @@ main(int argc, char *argv[]) cmdhelp(mode, which); else if (which != -1 && mode != -1) { if (strspn(argv[1], "0123456789") == strlen(argv[1])) { - id = strtonum(argv[1], 0, LONG_MAX, &errstr); + id = strtounum(argv[1], 0, UID_MAX, &errstr); if (errstr != NULL) errx(EX_USAGE, "Bad id '%s': %s", argv[1], errstr); @@ -269,7 +269,7 @@ main(int argc, char *argv[]) } if (strspn(optarg, "0123456789") != strlen(optarg)) errx(EX_USAGE, "-g expects a number"); - id = strtonum(optarg, 0, GID_MAX, &errstr); + id = strtounum(optarg, 0, GID_MAX, &errstr); if (errstr != NULL) errx(EX_USAGE, "Bad id '%s': %s", optarg, errstr); @@ -281,7 +281,7 @@ main(int argc, char *argv[]) addarg(&arglist, 'u', optarg); break; } - id = strtonum(optarg, 0, UID_MAX, &errstr); + id = strtounum(optarg, 0, UID_MAX, &errstr); if (errstr != NULL) errx(EX_USAGE, "Bad id '%s': %s", optarg, errstr); diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h index ed3b7158e907..3ab3c74a9537 100644 --- a/usr.sbin/pw/pw.h +++ b/usr.sbin/pw/pw.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -101,3 +102,6 @@ char *pw_pwcrypt(char *password); extern const char *Modes[]; extern const char *Which[]; + +uintmax_t strtounum(const char *numstr, uintmax_t minval, uintmax_t maxval, + const char **errmsg); From 22665b2563f06782cf46e6c42a64dc0d2093480a Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 29 Jul 2015 06:23:06 +0000 Subject: [PATCH 039/314] Actually add the new code --- usr.sbin/pw/strtounum.c | 73 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 usr.sbin/pw/strtounum.c diff --git a/usr.sbin/pw/strtounum.c b/usr.sbin/pw/strtounum.c new file mode 100644 index 000000000000..968779539c27 --- /dev/null +++ b/usr.sbin/pw/strtounum.c @@ -0,0 +1,73 @@ +/*- + * Copyright (C) Baptiste Daroussin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT 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 DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include "pw.h" + +#define INVALID "invalid" +#define TOOSMALL "too small" +#define TOOLARGE "too large" + +uintmax_t +strtounum(const char *numstr, uintmax_t minval, uintmax_t maxval, + const char **errstrp) +{ + uintmax_t ret = 0; + char *ep; + + if (minval > maxval) { + errno = EINVAL; + if (errstrp != NULL) + *errstrp = INVALID; + return (0); + } + + ret = strtoumax(numstr, &ep, 10); + if (errno == EINVAL || numstr == ep || *ep != '\0') { + errno = EINVAL; + if (errstrp != NULL) + *errstrp = INVALID; + return (0); + } else if ((ret == 0 && errno == ERANGE) || ret < minval) { + errno = ERANGE; + if (errstrp != NULL) + *errstrp = TOOSMALL; + return (0); + } else if ((ret == UINTMAX_MAX && errno == ERANGE) || ret > maxval) { + errno = ERANGE; + if (errstrp != NULL) + *errstrp = TOOLARGE; + return (0); + } + + return (ret); +} From 3720b82fa855d19d07a7d1ea9ec7eb01a320a866 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 29 Jul 2015 06:31:44 +0000 Subject: [PATCH 040/314] Implement CloudABI's readdir(). Summary: CloudABI's readdir() system call could be thought of as a mixture between FreeBSD's getdents(2) and pread(). Instead of using the file descriptor offset, userspace provides a 64-bit cloudabi_dircookie_t continue reading at a given point. CLOUDABI_DIRCOOKIE_START, having value 0, can be used to return entries at the start of the directory. The file descriptor offset is not used to store the cookie for the reason that in a file descriptor centric environment, it would make sense to allow concurrent use of a single file descriptor. The remaining space returned by the system call should be filled with a partially truncated copy of the next entry. The advantage of doing this is that it gracefully deals with long filenames. If the C library provides a buffer that is too small to hold a single entry, it can still extract the directory entry header, meaning that it can retry the read with a larger buffer or skip it using the cookie. Test Plan: This implementation passes the cloudlibc unit tests at: https://github.com/NuxiNL/cloudlibc/tree/master/src/libc/dirent Reviewers: marcel, kib Reviewed By: kib Subscribers: imp Differential Revision: https://reviews.freebsd.org/D3226 --- sys/compat/cloudabi/cloudabi_file.c | 176 +++++++++++++++++++++++++++- 1 file changed, 174 insertions(+), 2 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_file.c b/sys/compat/cloudabi/cloudabi_file.c index 45f658367485..cdec170e96d1 100644 --- a/sys/compat/cloudabi/cloudabi_file.c +++ b/sys/compat/cloudabi/cloudabi_file.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -35,11 +36,15 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include +#include + static MALLOC_DEFINE(M_CLOUDABI_PATH, "cloudabipath", "CloudABI pathnames"); /* @@ -197,13 +202,180 @@ cloudabi_sys_file_open(struct thread *td, return (ENOSYS); } +/* Converts a FreeBSD directory entry structure and writes it to userspace. */ +static int +write_dirent(struct dirent *bde, cloudabi_dircookie_t cookie, struct uio *uio) +{ + cloudabi_dirent_t cde = { + .d_next = cookie, + .d_ino = bde->d_fileno, + .d_namlen = bde->d_namlen, + }; + size_t len; + int error; + + /* Convert file type. */ + switch (bde->d_type) { + case DT_BLK: + cde.d_type = CLOUDABI_FILETYPE_BLOCK_DEVICE; + break; + case DT_CHR: + cde.d_type = CLOUDABI_FILETYPE_CHARACTER_DEVICE; + break; + case DT_DIR: + cde.d_type = CLOUDABI_FILETYPE_DIRECTORY; + break; + case DT_FIFO: + cde.d_type = CLOUDABI_FILETYPE_FIFO; + break; + case DT_LNK: + cde.d_type = CLOUDABI_FILETYPE_SYMBOLIC_LINK; + break; + case DT_REG: + cde.d_type = CLOUDABI_FILETYPE_REGULAR_FILE; + break; + case DT_SOCK: + /* The exact socket type cannot be derived. */ + cde.d_type = CLOUDABI_FILETYPE_SOCKET_STREAM; + break; + default: + cde.d_type = CLOUDABI_FILETYPE_UNKNOWN; + break; + } + + /* Write directory entry structure. */ + len = sizeof(cde) < uio->uio_resid ? sizeof(cde) : uio->uio_resid; + error = uiomove(&cde, len, uio); + if (error != 0) + return (error); + + /* Write filename. */ + len = bde->d_namlen < uio->uio_resid ? bde->d_namlen : uio->uio_resid; + return (uiomove(bde->d_name, len, uio)); +} + int cloudabi_sys_file_readdir(struct thread *td, struct cloudabi_sys_file_readdir_args *uap) { + struct iovec iov = { + .iov_base = uap->buf, + .iov_len = uap->nbyte + }; + struct uio uio = { + .uio_iov = &iov, + .uio_iovcnt = 1, + .uio_resid = iov.iov_len, + .uio_segflg = UIO_USERSPACE, + .uio_rw = UIO_READ, + .uio_td = td + }; + struct file *fp; + struct vnode *vp; + void *readbuf; + cap_rights_t rights; + cloudabi_dircookie_t offset; + int error; - /* Not implemented. */ - return (ENOSYS); + /* Obtain directory vnode. */ + error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) { + if (error == EINVAL) + return (ENOTDIR); + return (error); + } + if ((fp->f_flag & FREAD) == 0) { + fdrop(fp, td); + return (EBADF); + } + + /* + * Call VOP_READDIR() and convert resulting data until the user + * provided buffer is filled. + */ + readbuf = malloc(MAXBSIZE, M_TEMP, M_WAITOK); + offset = uap->cookie; + vp = fp->f_vnode; + while (uio.uio_resid > 0) { + struct iovec readiov = { + .iov_base = readbuf, + .iov_len = MAXBSIZE + }; + struct uio readuio = { + .uio_iov = &readiov, + .uio_iovcnt = 1, + .uio_rw = UIO_READ, + .uio_segflg = UIO_SYSSPACE, + .uio_td = td, + .uio_resid = MAXBSIZE, + .uio_offset = offset + }; + struct dirent *bde; + unsigned long *cookies, *cookie; + size_t readbuflen; + int eof, ncookies; + + /* Validate file type. */ + vn_lock(vp, LK_SHARED | LK_RETRY); + if (vp->v_type != VDIR) { + VOP_UNLOCK(vp, 0); + error = ENOTDIR; + goto done; + } +#ifdef MAC + error = mac_vnode_check_readdir(td->td_ucred, vp); + if (error != 0) { + VOP_UNLOCK(vp, 0); + goto done; + } +#endif /* MAC */ + + /* Read new directory entries. */ + cookies = NULL; + ncookies = 0; + error = VOP_READDIR(vp, &readuio, fp->f_cred, &eof, + &ncookies, &cookies); + VOP_UNLOCK(vp, 0); + if (error != 0) + goto done; + + /* Convert entries to CloudABI's format. */ + readbuflen = MAXBSIZE - readuio.uio_resid; + bde = readbuf; + cookie = cookies; + while (readbuflen >= offsetof(struct dirent, d_name) && + uio.uio_resid > 0 && ncookies > 0) { + /* Ensure that the returned offset always increases. */ + if (readbuflen >= bde->d_reclen && bde->d_fileno != 0 && + *cookie > offset) { + error = write_dirent(bde, *cookie, &uio); + if (error != 0) { + free(cookies, M_TEMP); + goto done; + } + } + + if (offset < *cookie) + offset = *cookie; + ++cookie; + --ncookies; + readbuflen -= bde->d_reclen; + bde = (struct dirent *)((char *)bde + bde->d_reclen); + } + free(cookies, M_TEMP); + if (eof) + break; + } + +done: + fdrop(fp, td); + free(readbuf, M_TEMP); + if (error != 0) + return (error); + + /* Return number of bytes copied to userspace. */ + td->td_retval[0] = uap->nbyte - uio.uio_resid; + return (0); } int From 48c29b118e8229f19397bb8e205a086fdf0ed468 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Wed, 29 Jul 2015 06:35:36 +0000 Subject: [PATCH 041/314] pf: Always initialise pf_fragment.fr_flags When we allocate the struct pf_fragment in pf_fillup_fragment() we forgot to initialise the fr_flags field. As a result we sometimes mistakenly thought the fragment to not be a buffered fragment. This resulted in panics because we'd end up freeing the pf_fragment but not removing it from V_pf_fragqueue (believing it to be part of V_pf_cachequeue). The next time we iterated V_pf_fragqueue we'd use a freed object and panic. While here also fix a pf_fragment use after free in pf_normalize_ip(). pf_reassemble() frees the pf_fragment, so we can't use it any more. PR: 201879, 201932 MFC after: 5 days --- sys/netpfil/pf/pf_norm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index 384f5653bdec..497f0ed41fc7 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -431,6 +431,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, } *(struct pf_fragment_cmp *)frag = *key; + frag->fr_flags = 0; frag->fr_timeout = time_second; frag->fr_maxlen = frent->fe_len; TAILQ_INIT(&frag->fr_queue); @@ -1284,9 +1285,6 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason, if (m == NULL) return (PF_DROP); - if (frag != NULL && (frag->fr_flags & PFFRAG_DROP)) - goto drop; - h = mtod(m, struct ip *); } else { /* non-buffering fragment cache (drops or masks overlaps) */ From a09a7146a7529191aa94022e8c2e7a175e41b5d8 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Wed, 29 Jul 2015 07:15:16 +0000 Subject: [PATCH 042/314] RFC4868 section 2.3 requires that the output be half... This fixes problems that was introduced in r285336... I have verified that HMAC-SHA2-256 both ah only and w/ AES-CBC interoperate w/ a NetBSD 6.1.5 vm... Reviewed by: gnn --- sys/netipsec/xform.h | 1 + sys/netipsec/xform_ah.c | 33 +++++++++++++++++++++++++++++++-- sys/netipsec/xform_esp.c | 30 ++++++------------------------ 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/sys/netipsec/xform.h b/sys/netipsec/xform.h index 132717fa839e..fee457be8794 100644 --- a/sys/netipsec/xform.h +++ b/sys/netipsec/xform.h @@ -105,6 +105,7 @@ struct xformsw { #ifdef _KERNEL extern void xform_register(struct xformsw*); extern int xform_init(struct secasvar *sav, int xftype); +extern int xform_ah_authsize(struct auth_hash *esph); struct cryptoini; diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c index 0710578a0345..ae0feb9f627a 100644 --- a/sys/netipsec/xform_ah.c +++ b/sys/netipsec/xform_ah.c @@ -85,8 +85,8 @@ * Return authenticator size in bytes, based on a field in the * algorithm descriptor. */ -#define AUTHSIZE(sav) \ - ((sav->flags & SADB_X_EXT_OLD) ? 16 : (sav)->tdb_authalgxform->hashsize) +#define AUTHSIZE(sav) ((sav->flags & SADB_X_EXT_OLD) ? 16 : \ + xform_ah_authsize((sav)->tdb_authalgxform)) VNET_DEFINE(int, ah_enable) = 1; /* control flow of packets with AH */ VNET_DEFINE(int, ah_cleartos) = 1; /* clear ip_tos when doing AH calc */ @@ -112,6 +112,35 @@ static unsigned char ipseczeroes[256]; /* larger than an ip6 extension hdr */ static int ah_input_cb(struct cryptop*); static int ah_output_cb(struct cryptop*); +int +xform_ah_authsize(struct auth_hash *esph) +{ + int alen; + + if (esph == NULL) + return 0; + + switch (esph->type) { + case CRYPTO_SHA2_256_HMAC: + case CRYPTO_SHA2_384_HMAC: + case CRYPTO_SHA2_512_HMAC: + alen = esph->hashsize / 2; /* RFC4868 2.3 */ + break; + + case CRYPTO_AES_128_NIST_GMAC: + case CRYPTO_AES_192_NIST_GMAC: + case CRYPTO_AES_256_NIST_GMAC: + alen = esph->hashsize; + break; + + default: + alen = AH_HMAC_HASHLEN; + break; + } + + return alen; +} + /* * NB: this is public for use by the PF_KEY support. */ diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index e0dc2b2728e6..dbb1a274c885 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -320,7 +320,6 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) IPSEC_ASSERT(sav != NULL, ("null SA")); IPSEC_ASSERT(sav->tdb_encalgxform != NULL, ("null encoding xform")); - alen = 0; /* Valid IP Packet length ? */ if ( (skip&3) || (m->m_pkthdr.len&3) ){ DPRINTF(("%s: misaligned packet, skip %u pkt len %u", @@ -335,13 +334,13 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) esph = sav->tdb_authalgxform; espx = sav->tdb_encalgxform; - /* Determine the ESP header length */ + /* Determine the ESP header and auth length */ if (sav->flags & SADB_X_EXT_OLD) hlen = sizeof (struct esp) + sav->ivlen; else hlen = sizeof (struct newesp) + sav->ivlen; - /* Authenticator hash size */ - alen = esph ? esph->hashsize : 0; + + alen = xform_ah_authsize(esph); /* * Verify payload length is multiple of encryption algorithm @@ -530,7 +529,7 @@ esp_input_cb(struct cryptop *crp) /* If authentication was performed, check now. */ if (esph != NULL) { - alen = esph->hashsize; + alen = xform_ah_authsize(esph); AHSTAT_INC(ahs_hist[sav->alg_auth]); /* Copy the authenticator from the packet */ m_copydata(m, m->m_pkthdr.len - alen, alen, aalg); @@ -700,10 +699,7 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, /* XXX clamp padding length a la KAME??? */ padding = ((blks - ((rlen + 2) % blks)) % blks) + 2; - if (esph) - alen = esph->hashsize; - else - alen = 0; + alen = xform_ah_authsize(esph); ESPSTAT_INC(esps_output); @@ -983,21 +979,7 @@ esp_output_cb(struct cryptop *crp) if (esph != NULL) { int alen; - switch (esph->type) { - case CRYPTO_SHA2_256_HMAC: - case CRYPTO_SHA2_384_HMAC: - case CRYPTO_SHA2_512_HMAC: - alen = esph->hashsize/2; - break; - case CRYPTO_AES_128_NIST_GMAC: - case CRYPTO_AES_192_NIST_GMAC: - case CRYPTO_AES_256_NIST_GMAC: - alen = esph->hashsize; - break; - default: - alen = AH_HMAC_HASHLEN; - break; - } + alen = xform_ah_authsize(esph); m_copyback(m, m->m_pkthdr.len - alen, alen, ipseczeroes); } From cc0a3c8ca4561297b4df88fec347ba004d04277c Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 29 Jul 2015 08:12:05 +0000 Subject: [PATCH 043/314] Convert in_ifaddr_lock and in6_ifaddr_lock to rmlock. Both are used to protect access to IP addresses lists and they can be acquired for reading several times per packet. To reduce lock contention it is better to use rmlock here. Reviewed by: gnn (previous version) Obtained from: Yandex LLC Sponsored by: Yandex LLC Differential Revision: https://reviews.freebsd.org/D3149 --- sys/dev/cxgbe/tom/t4_tom.c | 7 +++++-- sys/net/if_spppsubr.c | 2 ++ sys/net/if_stf.c | 9 +++++--- sys/netinet/if_ether.c | 19 +++++++++-------- sys/netinet/igmp.c | 11 +++++++--- sys/netinet/in.c | 41 ++++++++++++++++++++++--------------- sys/netinet/in_mcast.c | 10 ++++++--- sys/netinet/in_pcb.c | 15 ++++++++------ sys/netinet/in_var.h | 23 +++++++++++---------- sys/netinet/ip_icmp.c | 9 +++++--- sys/netinet/ip_input.c | 5 +++-- sys/netinet/ip_output.c | 5 ++++- sys/netinet/raw_ip.c | 14 +++++++------ sys/netinet6/in6.c | 28 +++++++++++++++---------- sys/netinet6/in6_ifattach.c | 2 ++ sys/netinet6/in6_src.c | 10 +++++---- sys/netinet6/in6_var.h | 16 +++++++-------- sys/netinet6/ip6_input.c | 6 ++++-- 18 files changed, 142 insertions(+), 90 deletions(-) diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c index a980fba80a77..d0a248892e4f 100644 --- a/sys/dev/cxgbe/tom/t4_tom.c +++ b/sys/dev/cxgbe/tom/t4_tom.c @@ -36,9 +36,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#include #include #include #include @@ -762,6 +764,7 @@ t4_clip_task(void *arg, int count) static void update_clip_table(struct adapter *sc, struct tom_data *td) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; struct in6_addr *lip, tlip; struct clip_head stale; @@ -770,7 +773,7 @@ update_clip_table(struct adapter *sc, struct tom_data *td) ASSERT_SYNCHRONIZED_OP(sc); - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); mtx_lock(&td->clip_table_lock); if (gen == td->clip_gen) @@ -862,7 +865,7 @@ update_clip_table(struct adapter *sc, struct tom_data *td) td->clip_gen = gen; done: mtx_unlock(&td->clip_table_lock); - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); } static void diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 6743981c9009..841a0f20741e 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -28,7 +28,9 @@ #include #include +#include #include +#include #include #include #include diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index aed2a37379d6..23905783d0db 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -84,10 +84,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -530,6 +532,7 @@ stf_checkaddr4(sc, in, inifp) struct in_addr *in; struct ifnet *inifp; /* incoming interface */ { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia4; /* @@ -553,16 +556,16 @@ stf_checkaddr4(sc, in, inifp) /* * reject packets with broadcast */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia4, &V_in_ifaddrhead, ia_link) { if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0) continue; if (in->s_addr == ia4->ia_broadaddr.sin_addr.s_addr) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return -1; } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * perform ingress filter diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index aa370d6f904d..1012e93c2863 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -42,12 +42,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -563,6 +565,7 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_log_per_second, static void in_arpinput(struct mbuf *m) { + struct rm_priotracker in_ifa_tracker; struct arphdr *ah; struct ifnet *ifp = m->m_pkthdr.rcvif; struct llentry *la = NULL; @@ -621,7 +624,7 @@ in_arpinput(struct mbuf *m) * of the receive interface. (This will change slightly * when we have clusters of interfaces). */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) { if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) || ia->ia_ifp == ifp) && @@ -629,7 +632,7 @@ in_arpinput(struct mbuf *m) (ia->ia_ifa.ifa_carp == NULL || (*carp_iamatch_p)(&ia->ia_ifa, &enaddr))) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } } @@ -638,7 +641,7 @@ in_arpinput(struct mbuf *m) ia->ia_ifp == ifp) && isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } @@ -657,13 +660,13 @@ in_arpinput(struct mbuf *m) if (BDG_MEMBER_MATCHES_ARP(itaddr.s_addr, ifp, ia)) { ifa_ref(&ia->ia_ifa); ifp = ia->ia_ifp; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } } } #undef BDG_MEMBER_MATCHES_ARP - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * No match, use the first inet address on the receive interface @@ -684,13 +687,13 @@ in_arpinput(struct mbuf *m) /* * If bridging, fall back to using any inet address. */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); if (!bridged || (ia = TAILQ_FIRST(&V_in_ifaddrhead)) == NULL) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto drop; } ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); match: if (!enaddr) enaddr = (u_int8_t *)IF_LLADDR(ifp); diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index a094a499f7bf..185f5c2b5a04 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -58,6 +58,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include @@ -1215,6 +1217,7 @@ static int igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip, /*const*/ struct igmp *igmp) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_multi *inm; @@ -1237,7 +1240,7 @@ igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip, * Replace 0.0.0.0 with the subnet address if told to do so. */ if (V_igmp_recvifkludge && in_nullhost(ip->ip_src)) { - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL) { ip->ip_src.s_addr = htonl(ia->ia_subnet); ifa_free(&ia->ia_ifa); @@ -1323,6 +1326,7 @@ static int igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip, /*const*/ struct igmp *igmp) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_multi *inm; @@ -1331,7 +1335,7 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip, * leave requires knowing that we are the only member of a * group. */ - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL && in_hosteq(ip->ip_src, IA_SIN(ia)->sin_addr)) { ifa_free(&ia->ia_ifa); return (0); @@ -3487,6 +3491,7 @@ igmp_intr(struct mbuf *m) static struct mbuf * igmp_v3_encap_report(struct ifnet *ifp, struct mbuf *m) { + struct rm_priotracker in_ifa_tracker; struct igmp_report *igmp; struct ip *ip; int hdrlen, igmpreclen; @@ -3535,7 +3540,7 @@ igmp_v3_encap_report(struct ifnet *ifp, struct mbuf *m) if (m->m_flags & M_IGMP_LOOP) { struct in_ifaddr *ia; - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL) { ip->ip_src = ia->ia_addr.sin_addr; ifa_free(&ia->ia_ifa); diff --git a/sys/netinet/in.c b/sys/netinet/in.c index f47492ddaf1a..c2c7ce089c22 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -44,7 +44,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include @@ -93,17 +95,18 @@ SX_SYSINIT(in_control_sx, &in_control_sx, "in_control"); int in_localaddr(struct in_addr in) { + struct rm_priotracker in_ifa_tracker; register u_long i = ntohl(in.s_addr); register struct in_ifaddr *ia; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if ((i & ia->ia_subnetmask) == ia->ia_subnet) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (1); } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (0); } @@ -114,16 +117,17 @@ in_localaddr(struct in_addr in) int in_localip(struct in_addr in) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(ia, INADDR_HASH(in.s_addr), ia_hash) { if (IA_SIN(ia)->sin_addr.s_addr == in.s_addr) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (1); } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (0); } @@ -158,18 +162,19 @@ in_ifhasaddr(struct ifnet *ifp, struct in_addr in) static struct in_ifaddr * in_localip_more(struct in_ifaddr *ia) { + struct rm_priotracker in_ifa_tracker; in_addr_t in = IA_SIN(ia)->sin_addr.s_addr; struct in_ifaddr *it; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(it, INADDR_HASH(in), ia_hash) { if (it != ia && IA_SIN(it)->sin_addr.s_addr == in) { ifa_ref(&it->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (it); } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (NULL); } @@ -646,6 +651,7 @@ in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, struct thread *td) int in_addprefix(struct in_ifaddr *target, int flags) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; int error; @@ -659,7 +665,7 @@ in_addprefix(struct in_ifaddr *target, int flags) prefix.s_addr &= mask.s_addr; } - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); /* Look for an existing address with the same prefix, mask, and fib */ TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (rtinitflags(ia)) { @@ -687,13 +693,13 @@ in_addprefix(struct in_ifaddr *target, int flags) #ifdef RADIX_MPATH if (ia->ia_addr.sin_addr.s_addr == target->ia_addr.sin_addr.s_addr) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (EEXIST); } else break; #endif if (V_nosameprefix) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (EEXIST); } else { int fibnum; @@ -701,12 +707,12 @@ in_addprefix(struct in_ifaddr *target, int flags) fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (0); } } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * No-one seem to have this prefix route, so we try to insert it. @@ -725,6 +731,7 @@ in_addprefix(struct in_ifaddr *target, int flags) int in_scrubprefix(struct in_ifaddr *target, u_int flags) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; int error = 0; @@ -775,7 +782,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) return (0); } - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (rtinitflags(ia)) { p = ia->ia_dstaddr.sin_addr; @@ -802,7 +809,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) */ if ((ia->ia_flags & IFA_ROUTE) == 0) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); error = rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target)); if (error == 0) @@ -821,7 +828,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) return (error); } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * remove all L2 entries on the given prefix diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c index 93557f8f335b..c168780c7283 100644 --- a/sys/netinet/in_mcast.c +++ b/sys/netinet/in_mcast.c @@ -38,9 +38,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#include #include #include #include @@ -1748,6 +1750,7 @@ inp_get_source_filters(struct inpcb *inp, struct sockopt *sopt) int inp_getmoptions(struct inpcb *inp, struct sockopt *sopt) { + struct rm_priotracker in_ifa_tracker; struct ip_mreqn mreqn; struct ip_moptions *imo; struct ifnet *ifp; @@ -1787,7 +1790,7 @@ inp_getmoptions(struct inpcb *inp, struct sockopt *sopt) mreqn.imr_address = imo->imo_multicast_addr; } else if (ifp != NULL) { mreqn.imr_ifindex = ifp->if_index; - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL) { mreqn.imr_address = IA_SIN(ia)->sin_addr; @@ -1878,6 +1881,7 @@ static struct ifnet * inp_lookup_mcast_ifp(const struct inpcb *inp, const struct sockaddr_in *gsin, const struct in_addr ina) { + struct rm_priotracker in_ifa_tracker; struct ifnet *ifp; KASSERT(gsin->sin_family == AF_INET, ("%s: not AF_INET", __func__)); @@ -1902,7 +1906,7 @@ inp_lookup_mcast_ifp(const struct inpcb *inp, struct ifnet *mifp; mifp = NULL; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { mifp = ia->ia_ifp; if (!(mifp->if_flags & IFF_LOOPBACK) && @@ -1911,7 +1915,7 @@ inp_lookup_mcast_ifp(const struct inpcb *inp, break; } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); } } diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index bc48e105f69b..965932486db3 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -47,11 +47,13 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -992,6 +994,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, u_short *lportp, in_addr_t *faddrp, u_short *fportp, struct inpcb **oinpp, struct ucred *cred) { + struct rm_priotracker in_ifa_tracker; struct sockaddr_in *sin = (struct sockaddr_in *)nam; struct in_ifaddr *ia; struct inpcb *oinp; @@ -1028,20 +1031,20 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, * choose the broadcast address for that interface. */ if (faddr.s_addr == INADDR_ANY) { - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); faddr = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); if (cred != NULL && (error = prison_get_ip4(cred, &faddr)) != 0) return (error); } else if (faddr.s_addr == (u_long)INADDR_BROADCAST) { - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); if (TAILQ_FIRST(&V_in_ifaddrhead)->ia_ifp->if_flags & IFF_BROADCAST) faddr = satosin(&TAILQ_FIRST( &V_in_ifaddrhead)->ia_broadaddr)->sin_addr; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); } } if (laddr.s_addr == INADDR_ANY) { @@ -1059,7 +1062,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, imo = inp->inp_moptions; if (imo->imo_multicast_ifp != NULL) { ifp = imo->imo_multicast_ifp; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if ((ia->ia_ifp == ifp) && (cred == NULL || @@ -1073,7 +1076,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, laddr = ia->ia_addr.sin_addr; error = 0; } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); } } if (error) diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 0318fb2ff9a2..f9e98128bc1c 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -119,15 +119,15 @@ VNET_DECLARE(u_long, in_ifaddrhmask); /* mask for hash table */ #define INADDR_HASH(x) \ (&V_in_ifaddrhashtbl[INADDR_HASHVAL(x) & V_in_ifaddrhmask]) -extern struct rwlock in_ifaddr_lock; +extern struct rmlock in_ifaddr_lock; -#define IN_IFADDR_LOCK_ASSERT() rw_assert(&in_ifaddr_lock, RA_LOCKED) -#define IN_IFADDR_RLOCK() rw_rlock(&in_ifaddr_lock) -#define IN_IFADDR_RLOCK_ASSERT() rw_assert(&in_ifaddr_lock, RA_RLOCKED) -#define IN_IFADDR_RUNLOCK() rw_runlock(&in_ifaddr_lock) -#define IN_IFADDR_WLOCK() rw_wlock(&in_ifaddr_lock) -#define IN_IFADDR_WLOCK_ASSERT() rw_assert(&in_ifaddr_lock, RA_WLOCKED) -#define IN_IFADDR_WUNLOCK() rw_wunlock(&in_ifaddr_lock) +#define IN_IFADDR_LOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_LOCKED) +#define IN_IFADDR_RLOCK(t) rm_rlock(&in_ifaddr_lock, (t)) +#define IN_IFADDR_RLOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_RLOCKED) +#define IN_IFADDR_RUNLOCK(t) rm_runlock(&in_ifaddr_lock, (t)) +#define IN_IFADDR_WLOCK() rm_wlock(&in_ifaddr_lock) +#define IN_IFADDR_WLOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_WLOCKED) +#define IN_IFADDR_WUNLOCK() rm_wunlock(&in_ifaddr_lock) /* * Macro for finding the internet address structure (in_ifaddr) @@ -161,18 +161,19 @@ do { \ * Macro for finding the internet address structure (in_ifaddr) corresponding * to a given interface (ifnet structure). */ -#define IFP_TO_IA(ifp, ia) \ +#define IFP_TO_IA(ifp, ia, t) \ /* struct ifnet *ifp; */ \ /* struct in_ifaddr *ia; */ \ + /* struct rm_priotracker *t; */ \ do { \ - IN_IFADDR_RLOCK(); \ + IN_IFADDR_RLOCK((t)); \ for ((ia) = TAILQ_FIRST(&V_in_ifaddrhead); \ (ia) != NULL && (ia)->ia_ifp != (ifp); \ (ia) = TAILQ_NEXT((ia), ia_link)) \ continue; \ if ((ia) != NULL) \ ifa_ref(&(ia)->ia_ifa); \ - IN_IFADDR_RUNLOCK(); \ + IN_IFADDR_RUNLOCK((t)); \ } while (0) /* diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index b6b967f6d59c..57553f547f75 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -647,6 +649,7 @@ icmp_input(struct mbuf **mp, int *offp, int proto) static void icmp_reflect(struct mbuf *m) { + struct rm_priotracker in_ifa_tracker; struct ip *ip = mtod(m, struct ip *); struct ifaddr *ifa; struct ifnet *ifp; @@ -672,15 +675,15 @@ icmp_reflect(struct mbuf *m) * If the incoming packet was addressed directly to one of our * own addresses, use dst as the src for the reply. */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash) { if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr) { t = IA_SIN(ia)->sin_addr; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * If the incoming packet was addressed to one of our broadcast diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 4140edac5460..e1cbb43c87f7 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -97,8 +98,8 @@ extern void ipreass_slowtimo(void); extern void ipreass_destroy(void); #endif -struct rwlock in_ifaddr_lock; -RW_SYSINIT(in_ifaddr_lock, &in_ifaddr_lock, "in_ifaddr_lock"); +struct rmlock in_ifaddr_lock; +RM_SYSINIT(in_ifaddr_lock, &in_ifaddr_lock, "in_ifaddr_lock"); VNET_DEFINE(int, rsvp_on); diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 588bc0542a31..c75698113290 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -44,11 +44,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -120,6 +122,7 @@ int ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct inpcb *inp) { + struct rm_priotracker in_ifa_tracker; struct ip *ip; struct ifnet *ifp = NULL; /* keep compiler happy */ struct mbuf *m0; @@ -258,7 +261,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, * packets if the interface is specified. */ ifp = imo->imo_multicast_ifp; - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia) have_ia_ref = 1; isbroadcast = 0; /* fool gcc */ diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index a71d8ec86f71..4e9fedaac817 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -724,6 +725,7 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) void rip_ctlinput(int cmd, struct sockaddr *sa, void *vip) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct ifnet *ifp; int err; @@ -731,12 +733,12 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip) switch (cmd) { case PRC_IFDOWN: - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (ia->ia_ifa.ifa_addr == sa && (ia->ia_flags & IFA_ROUTE)) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * in_scrubprefix() kills the interface route. */ @@ -753,21 +755,21 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip) } } if (ia == NULL) /* If ia matched, already unlocked. */ - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); break; case PRC_IFUP: - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (ia->ia_ifa.ifa_addr == sa) break; } if (ia == NULL || (ia->ia_flags & IFA_ROUTE)) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return; } ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); flags = RTF_UP; ifp = ia->ia_ifa.ifa_ifp; diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 4340150a7f14..754a5f334231 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -80,6 +80,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -1499,9 +1501,10 @@ in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags) struct in6_ifaddr * in6ifa_ifwithaddr(const struct in6_addr *addr, uint32_t zoneid) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); LIST_FOREACH(ia, IN6ADDR_HASH(addr), ia6_hash) { if (IN6_ARE_ADDR_EQUAL(IA6_IN6(ia), addr)) { if (zoneid != 0 && @@ -1511,7 +1514,7 @@ in6ifa_ifwithaddr(const struct in6_addr *addr, uint32_t zoneid) break; } } - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (ia); } @@ -1649,20 +1652,21 @@ ip6_sprintf(char *ip6buf, const struct in6_addr *addr) int in6_localaddr(struct in6_addr *in6) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6)) return 1; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr, &ia->ia_prefixmask.sin6_addr)) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return 1; } } - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (0); } @@ -1674,16 +1678,17 @@ in6_localaddr(struct in6_addr *in6) int in6_localip(struct in6_addr *in6) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); LIST_FOREACH(ia, IN6ADDR_HASH(in6), ia6_hash) { if (IN6_ARE_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr)) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (1); } } - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (0); } @@ -1720,19 +1725,20 @@ in6_ifhasaddr(struct ifnet *ifp, struct in6_addr *addr) int in6_is_addr_deprecated(struct sockaddr_in6 *sa6) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); LIST_FOREACH(ia, IN6ADDR_HASH(&sa6->sin6_addr), ia6_hash) { if (IN6_ARE_ADDR_EQUAL(IA6_IN6(ia), &sa6->sin6_addr)) { if (ia->ia6_flags & IN6_IFF_DEPRECATED) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (1); /* true */ } break; } } - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (0); /* false */ } diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 8c25e982cdeb..d8a32d504aa4 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -39,7 +39,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index 227f234206a8..d77324ff6538 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -178,6 +179,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, struct inpcb *inp, struct route_in6 *ro, struct ucred *cred, struct ifnet **ifpp, struct in6_addr *srcp) { + struct rm_priotracker in6_ifa_tracker; struct in6_addr dst, tmp; struct ifnet *ifp = NULL, *oifp = NULL; struct in6_ifaddr *ia = NULL, *ia_best = NULL; @@ -303,7 +305,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, return (error); rule = 0; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { int new_scope = -1, new_matchlen = -1; struct in6_addrpolicy *new_policy = NULL; @@ -501,7 +503,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, } if ((ia = ia_best) == NULL) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); IP6STAT_INC(ip6s_sources_none); return (EADDRNOTAVAIL); } @@ -518,7 +520,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, tmp = ia->ia_addr.sin6_addr; if (cred != NULL && prison_local_ip6(cred, &tmp, (inp != NULL && (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); IP6STAT_INC(ip6s_sources_none); return (EADDRNOTAVAIL); } @@ -537,7 +539,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, IP6STAT_INC(ip6s_sources_otherscope[best_scope]); if (IFA6_IS_DEPRECATED(ia)) IP6STAT_INC(ip6s_sources_deprecated[best_scope]); - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (0); } diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index a486ce188287..81ca8396da6e 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -535,14 +535,14 @@ in6_addrhash(const struct in6_addr *in6) return (fnv_32_buf(&x, sizeof(x), FNV1_32_INIT)); } -extern struct rwlock in6_ifaddr_lock; -#define IN6_IFADDR_LOCK_ASSERT( ) rw_assert(&in6_ifaddr_lock, RA_LOCKED) -#define IN6_IFADDR_RLOCK() rw_rlock(&in6_ifaddr_lock) -#define IN6_IFADDR_RLOCK_ASSERT() rw_assert(&in6_ifaddr_lock, RA_RLOCKED) -#define IN6_IFADDR_RUNLOCK() rw_runlock(&in6_ifaddr_lock) -#define IN6_IFADDR_WLOCK() rw_wlock(&in6_ifaddr_lock) -#define IN6_IFADDR_WLOCK_ASSERT() rw_assert(&in6_ifaddr_lock, RA_WLOCKED) -#define IN6_IFADDR_WUNLOCK() rw_wunlock(&in6_ifaddr_lock) +extern struct rmlock in6_ifaddr_lock; +#define IN6_IFADDR_LOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_LOCKED) +#define IN6_IFADDR_RLOCK(t) rm_rlock(&in6_ifaddr_lock, (t)) +#define IN6_IFADDR_RLOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_RLOCKED) +#define IN6_IFADDR_RUNLOCK(t) rm_runlock(&in6_ifaddr_lock, (t)) +#define IN6_IFADDR_WLOCK() rm_wlock(&in6_ifaddr_lock) +#define IN6_IFADDR_WLOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_WLOCKED) +#define IN6_IFADDR_WUNLOCK() rm_wunlock(&in6_ifaddr_lock) #define in6_ifstat_inc(ifp, tag) \ do { \ diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 78e8ef3b6b39..e4e388f3712c 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -82,6 +82,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -144,8 +146,8 @@ VNET_PCPUSTAT_SYSINIT(ip6stat); VNET_PCPUSTAT_SYSUNINIT(ip6stat); #endif /* VIMAGE */ -struct rwlock in6_ifaddr_lock; -RW_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); +struct rmlock in6_ifaddr_lock; +RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); static void ip6_init2(void *); static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); From 6cebf7e2be8f098e055ebb5b9305cd7ead7033fd Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 29 Jul 2015 09:57:34 +0000 Subject: [PATCH 044/314] Move bufshutdown() out of the #ifdef INVARIANTS block. --- sys/kern/vfs_bio.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index ac6c61813e69..d46432d0b16e 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -958,6 +958,22 @@ vfs_buf_check_mapped(struct buf *bp) KASSERT(bp->b_data < unmapped_buf || bp->b_data > unmapped_buf + MAXPHYS, ("b_data + b_offset unmapped %p", bp)); } + +static inline void +vfs_buf_check_unmapped(struct buf *bp) +{ + + KASSERT(bp->b_data == unmapped_buf, + ("unmapped buf: corrupted b_data %p", bp)); +} + +#define BUF_CHECK_MAPPED(bp) vfs_buf_check_mapped(bp) +#define BUF_CHECK_UNMAPPED(bp) vfs_buf_check_unmapped(bp) +#else +#define BUF_CHECK_MAPPED(bp) do {} while (0) +#define BUF_CHECK_UNMAPPED(bp) do {} while (0) +#endif + static int isbufbusy(struct buf *bp) { @@ -1087,21 +1103,6 @@ bufshutdown(int show_busybufs) DELAY(100000); /* wait for console output to finish */ } -static inline void -vfs_buf_check_unmapped(struct buf *bp) -{ - - KASSERT(bp->b_data == unmapped_buf, - ("unmapped buf: corrupted b_data %p", bp)); -} - -#define BUF_CHECK_MAPPED(bp) vfs_buf_check_mapped(bp) -#define BUF_CHECK_UNMAPPED(bp) vfs_buf_check_unmapped(bp) -#else -#define BUF_CHECK_MAPPED(bp) do {} while (0) -#define BUF_CHECK_UNMAPPED(bp) do {} while (0) -#endif - static void bpmap_qenter(struct buf *bp) { From b13653baf9e68fe9d64387c22fef6405d5d0418e Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 29 Jul 2015 10:53:42 +0000 Subject: [PATCH 045/314] Reduce overhead of ipfw's me6 opcode. Skip checks for IPv6 multicast addresses. Use in6_localip() for global unicast. And for IPv6 link-local addresses do search in the IPv6 addresses list. Since LLA are stored in the kernel internal form, use IN6_ARE_MASKED_ADDR_EQUAL() macro with lla_mask for addresses comparison. lla_mask has zero bits in the second word, where we keep sin6_scope_id. Obtained from: Yandex LLC Sponsored by: Yandex LLC --- sys/netpfil/ipfw/ip_fw2.c | 52 +++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index afa3944244a6..e32c7cc7a26c 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -503,31 +503,35 @@ flow6id_match( int curr_flow, ipfw_insn_u32 *cmd ) } /* support for IP6_*_ME opcodes */ -static int -search_ip6_addr_net (struct in6_addr * ip6_addr) -{ - struct ifnet *mdc; - struct ifaddr *mdc2; - struct in6_ifaddr *fdm; - struct in6_addr copia; +static const struct in6_addr lla_mask = {{{ + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}}}; - TAILQ_FOREACH(mdc, &V_ifnet, if_link) { - if_addr_rlock(mdc); - TAILQ_FOREACH(mdc2, &mdc->if_addrhead, ifa_link) { - if (mdc2->ifa_addr->sa_family == AF_INET6) { - fdm = (struct in6_ifaddr *)mdc2; - copia = fdm->ia_addr.sin6_addr; - /* need for leaving scope_id in the sock_addr */ - in6_clearscope(&copia); - if (IN6_ARE_ADDR_EQUAL(ip6_addr, &copia)) { - if_addr_runlock(mdc); - return 1; - } - } +static int +ipfw_localip6(struct in6_addr *in6) +{ + struct rm_priotracker in6_ifa_tracker; + struct in6_ifaddr *ia; + + if (IN6_IS_ADDR_MULTICAST(in6)) + return (0); + + if (!IN6_IS_ADDR_LINKLOCAL(in6)) + return (in6_localip(in6)); + + IN6_IFADDR_RLOCK(&in6_ifa_tracker); + TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { + if (!IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) + continue; + if (IN6_ARE_MASKED_ADDR_EQUAL(&ia->ia_addr.sin6_addr, + in6, &lla_mask)) { + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); + return (1); } - if_addr_runlock(mdc); } - return 0; + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); + return (0); } static int @@ -1597,7 +1601,7 @@ do { \ #ifdef INET6 /* FALLTHROUGH */ case O_IP6_SRC_ME: - match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6); + match= is_ipv6 && ipfw_localip6(&args->f_id.src_ip6); #endif break; @@ -1636,7 +1640,7 @@ do { \ #ifdef INET6 /* FALLTHROUGH */ case O_IP6_DST_ME: - match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6); + match= is_ipv6 && ipfw_localip6(&args->f_id.dst_ip6); #endif break; From cf89e8c9190d82dcfc2371baad65b029e7b9fd88 Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Wed, 29 Jul 2015 11:22:19 +0000 Subject: [PATCH 046/314] Add quirk for ThunderX ITS device table size Limit the number of supported device IDs to 0x100000 in order to decrease the size of the ITS device table so that it matches with the HW capabilities. Obtained from: Semihalf Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3131 --- sys/arm64/arm64/gic_v3_its.c | 76 +++++++++++++++++++++++++++++++++--- sys/arm64/arm64/gic_v3_var.h | 2 + 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/sys/arm64/arm64/gic_v3_its.c b/sys/arm64/arm64/gic_v3_its.c index 274a6aa2c230..fb4b8681483e 100644 --- a/sys/arm64/arm64/gic_v3_its.c +++ b/sys/arm64/arm64/gic_v3_its.c @@ -101,6 +101,8 @@ static void its_cmd_mapi(struct gic_v3_its_softc *, struct its_dev *, uint32_t); static void its_cmd_inv(struct gic_v3_its_softc *, struct its_dev *, uint32_t); static void its_cmd_invall(struct gic_v3_its_softc *, struct its_col *); +static uint32_t its_get_devbits(device_t); + static void lpi_init_conftable(struct gic_v3_its_softc *); static void lpi_bitmap_init(struct gic_v3_its_softc *); static void lpi_init_cpu(struct gic_v3_its_softc *); @@ -142,13 +144,19 @@ const char *its_ptab_type[] = { */ /* Cavium ThunderX PCI devid acquire function */ +static uint32_t its_get_devbits_thunder(device_t); static uint32_t its_get_devid_thunder(device_t); static const struct its_quirks its_quirks[] = { { + /* + * Hardware: Cavium ThunderX + * Chip revision: Pass 1.0, Pass 1.1 + */ .cpuid = CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0), .cpuid_mask = CPU_IMPL_MASK | CPU_PART_MASK, .devid_func = its_get_devid_thunder, + .devbits_func = its_get_devbits_thunder, }, }; @@ -299,7 +307,6 @@ its_alloc_tables(struct gic_v3_its_softc *sc) { uint64_t gits_baser, gits_tmp; uint64_t type, esize, cache, share, psz; - uint64_t gits_typer; size_t page_size, npages, nitspages, nidents, tn; size_t its_tbl_size; vm_offset_t ptab_vaddr; @@ -308,9 +315,6 @@ its_alloc_tables(struct gic_v3_its_softc *sc) page_size = PAGE_SIZE_64K; - /* Read features first */ - gits_typer = gic_its_read(sc, 8, GITS_TYPER); - for (tn = 0; tn < GITS_BASER_NUM; tn++) { gits_baser = gic_its_read(sc, 8, GITS_BASER(tn)); type = GITS_BASER_TYPE(gits_baser); @@ -324,7 +328,7 @@ its_alloc_tables(struct gic_v3_its_softc *sc) case GITS_BASER_TYPE_RES7: continue; case GITS_BASER_TYPE_DEV: - nidents = (1 << GITS_TYPER_DEVB(gits_typer)); + nidents = (1 << its_get_devbits(sc->dev)); its_tbl_size = esize * nidents; its_tbl_size = roundup2(its_tbl_size, page_size); npages = howmany(its_tbl_size, PAGE_SIZE); @@ -1447,6 +1451,68 @@ its_get_devid_thunder(device_t pci_dev) return (0); } +static uint32_t +its_get_devbits_thunder(device_t dev) +{ + uint32_t devid_bits; + + /* + * GITS_TYPER[17:13] of ThunderX reports that device IDs + * are to be 21 bits in length. + * The entry size of the ITS table can be read from GITS_BASERn[52:48] + * and on ThunderX is supposed to be 8 bytes in length (for device + * table). Finally the page size that is to be used by ITS to access + * this table will be set to 64KB. + * + * This gives 0x200000 entries of size 0x8 bytes covered by 256 pages + * each of which 64KB in size. The number of pages (minus 1) should + * then be written to GITS_BASERn[7:0]. In that case this value would + * be 0xFF but on ThunderX the maximum value that HW accepts is 0xFD. + * + * Set arbitrary number of device ID bits to 20 in order to limit + * the number of entries in ITS device table to 0x100000 and hence + * the table size to 8MB. + */ + devid_bits = 20; + if (bootverbose) { + device_printf(dev, + "Limiting number of Device ID bits implemented to %d\n", + devid_bits); + } + + return (devid_bits); +} + +static __inline uint32_t +its_get_devbits_default(device_t dev) +{ + uint64_t gits_typer; + struct gic_v3_its_softc *sc; + + sc = device_get_softc(dev); + + gits_typer = gic_its_read(sc, 8, GITS_TYPER); + + return (GITS_TYPER_DEVB(gits_typer)); +} + +static uint32_t +its_get_devbits(device_t dev) +{ + const struct its_quirks *quirk; + size_t i; + + for (i = 0; i < nitems(its_quirks); i++) { + quirk = &its_quirks[i]; + if (CPU_MATCH_RAW(quirk->cpuid_mask, quirk->cpuid)) { + if (quirk->devbits_func != NULL) + return ((*quirk->devbits_func)(dev)); + } + } + + return (its_get_devbits_default(dev)); +} + static __inline uint32_t its_get_devid_default(device_t pci_dev) { diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h index 1621c0cfdffe..8bfce9b1ed13 100644 --- a/sys/arm64/arm64/gic_v3_var.h +++ b/sys/arm64/arm64/gic_v3_var.h @@ -235,12 +235,14 @@ struct gic_v3_its_softc { }; /* Stuff that is specific to the vendor's implementation */ +typedef uint32_t (*its_devbits_func_t)(device_t); typedef uint32_t (*its_devid_func_t)(device_t); struct its_quirks { uint64_t cpuid; uint64_t cpuid_mask; its_devid_func_t devid_func; + its_devbits_func_t devbits_func; }; extern devclass_t gic_v3_its_devclass; From 9d2332c9ee9e6895f7da22fdc81b42a1c7fa4c66 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 29 Jul 2015 12:42:45 +0000 Subject: [PATCH 047/314] Split up Capsicum to CloudABI rights conversion into two separate routines. CloudABI's openat() ensures that files are opened with the smallest set of relevant rights. For example, when opening a FIFO, unrelated rights like CAP_RECV are automatically removed. To remove unrelated rights, we can just reuse the code for this that was already present in the rights conversion function. --- sys/compat/cloudabi/cloudabi_fd.c | 115 ++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 30 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index 23eb78b844d8..1b3aa0f0ce09 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -266,24 +266,11 @@ cloudabi_convert_filetype(const struct file *fp) } } -/* - * Converts FreeBSD's Capsicum rights to CloudABI's set of rights. - */ +/* Removes rights that conflict with the file descriptor type. */ static void -convert_capabilities(const cap_rights_t *capabilities, - cloudabi_filetype_t filetype, cloudabi_rights_t *base, - cloudabi_rights_t *inheriting) +cloudabi_remove_conflicting_rights(cloudabi_filetype_t filetype, + cloudabi_rights_t *base, cloudabi_rights_t *inheriting) { - cloudabi_rights_t rights; - - /* Convert FreeBSD bits to CloudABI bits. */ - rights = 0; -#define MAPPING(cloudabi, ...) do { \ - if (cap_rights_is_set(capabilities, ##__VA_ARGS__)) \ - rights |= (cloudabi); \ -} while (0); - RIGHTS_MAPPINGS -#undef MAPPING /* * CloudABI has a small number of additional rights bits to @@ -303,7 +290,7 @@ convert_capabilities(const cap_rights_t *capabilities, */ switch (filetype) { case CLOUDABI_FILETYPE_DIRECTORY: - *base = rights & (CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS | + *base &= CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS | CLOUDABI_RIGHT_FD_SYNC | CLOUDABI_RIGHT_FILE_ADVISE | CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY | CLOUDABI_RIGHT_FILE_CREATE_FILE | @@ -323,29 +310,77 @@ convert_capabilities(const cap_rights_t *capabilities, CLOUDABI_RIGHT_FILE_UNLINK | CLOUDABI_RIGHT_POLL_FD_READWRITE | CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY | - CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY); - *inheriting = rights; + CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY; + *inheriting &= CLOUDABI_RIGHT_FD_DATASYNC | + CLOUDABI_RIGHT_FD_READ | + CLOUDABI_RIGHT_FD_SEEK | + CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS | + CLOUDABI_RIGHT_FD_SYNC | + CLOUDABI_RIGHT_FD_TELL | + CLOUDABI_RIGHT_FD_WRITE | + CLOUDABI_RIGHT_FILE_ADVISE | + CLOUDABI_RIGHT_FILE_ALLOCATE | + CLOUDABI_RIGHT_FILE_CREATE_DIRECTORY | + CLOUDABI_RIGHT_FILE_CREATE_FILE | + CLOUDABI_RIGHT_FILE_CREATE_FIFO | + CLOUDABI_RIGHT_FILE_LINK_SOURCE | + CLOUDABI_RIGHT_FILE_LINK_TARGET | + CLOUDABI_RIGHT_FILE_OPEN | + CLOUDABI_RIGHT_FILE_READDIR | + CLOUDABI_RIGHT_FILE_READLINK | + CLOUDABI_RIGHT_FILE_RENAME_SOURCE | + CLOUDABI_RIGHT_FILE_RENAME_TARGET | + CLOUDABI_RIGHT_FILE_STAT_FGET | + CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE | + CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES | + CLOUDABI_RIGHT_FILE_STAT_GET | + CLOUDABI_RIGHT_FILE_STAT_PUT_TIMES | + CLOUDABI_RIGHT_FILE_SYMLINK | + CLOUDABI_RIGHT_FILE_UNLINK | + CLOUDABI_RIGHT_MEM_MAP | + CLOUDABI_RIGHT_MEM_MAP_EXEC | + CLOUDABI_RIGHT_POLL_FD_READWRITE | + CLOUDABI_RIGHT_PROC_EXEC | + CLOUDABI_RIGHT_SOCK_BIND_DIRECTORY | + CLOUDABI_RIGHT_SOCK_CONNECT_DIRECTORY; break; case CLOUDABI_FILETYPE_FIFO: - *base = rights & ~(CLOUDABI_RIGHT_FILE_ADVISE | - CLOUDABI_RIGHT_FILE_ALLOCATE | - CLOUDABI_RIGHT_FILE_READDIR); + *base &= CLOUDABI_RIGHT_FD_READ | + CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS | + CLOUDABI_RIGHT_FD_WRITE | + CLOUDABI_RIGHT_FILE_STAT_FGET | + CLOUDABI_RIGHT_POLL_FD_READWRITE; *inheriting = 0; break; case CLOUDABI_FILETYPE_POLL: - *base = rights & ~CLOUDABI_RIGHT_FILE_ADVISE; + *base &= ~CLOUDABI_RIGHT_FILE_ADVISE; *inheriting = 0; break; case CLOUDABI_FILETYPE_PROCESS: - *base = rights & ~CLOUDABI_RIGHT_FILE_ADVISE; + *base &= ~CLOUDABI_RIGHT_FILE_ADVISE; *inheriting = 0; break; case CLOUDABI_FILETYPE_REGULAR_FILE: - *base = rights & ~CLOUDABI_RIGHT_FILE_READDIR; + *base &= CLOUDABI_RIGHT_FD_DATASYNC | + CLOUDABI_RIGHT_FD_READ | + CLOUDABI_RIGHT_FD_SEEK | + CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS | + CLOUDABI_RIGHT_FD_SYNC | + CLOUDABI_RIGHT_FD_TELL | + CLOUDABI_RIGHT_FD_WRITE | + CLOUDABI_RIGHT_FILE_ADVISE | + CLOUDABI_RIGHT_FILE_ALLOCATE | + CLOUDABI_RIGHT_FILE_STAT_FGET | + CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE | + CLOUDABI_RIGHT_FILE_STAT_FPUT_TIMES | + CLOUDABI_RIGHT_MEM_MAP | + CLOUDABI_RIGHT_MEM_MAP_EXEC | + CLOUDABI_RIGHT_POLL_FD_READWRITE | + CLOUDABI_RIGHT_PROC_EXEC; *inheriting = 0; break; case CLOUDABI_FILETYPE_SHARED_MEMORY: - *base = rights & ~(CLOUDABI_RIGHT_FD_SEEK | + *base &= ~(CLOUDABI_RIGHT_FD_SEEK | CLOUDABI_RIGHT_FD_TELL | CLOUDABI_RIGHT_FILE_ADVISE | CLOUDABI_RIGHT_FILE_ALLOCATE | @@ -355,7 +390,7 @@ convert_capabilities(const cap_rights_t *capabilities, case CLOUDABI_FILETYPE_SOCKET_DGRAM: case CLOUDABI_FILETYPE_SOCKET_SEQPACKET: case CLOUDABI_FILETYPE_SOCKET_STREAM: - *base = rights & (CLOUDABI_RIGHT_FD_READ | + *base &= CLOUDABI_RIGHT_FD_READ | CLOUDABI_RIGHT_FD_STAT_PUT_FLAGS | CLOUDABI_RIGHT_FD_WRITE | CLOUDABI_RIGHT_FILE_STAT_FGET | @@ -365,16 +400,36 @@ convert_capabilities(const cap_rights_t *capabilities, CLOUDABI_RIGHT_SOCK_CONNECT_SOCKET | CLOUDABI_RIGHT_SOCK_LISTEN | CLOUDABI_RIGHT_SOCK_SHUTDOWN | - CLOUDABI_RIGHT_SOCK_STAT_GET); - *inheriting = rights; + CLOUDABI_RIGHT_SOCK_STAT_GET; break; default: - *base = rights; *inheriting = 0; break; } } +/* Converts FreeBSD's Capsicum rights to CloudABI's set of rights. */ +static void +convert_capabilities(const cap_rights_t *capabilities, + cloudabi_filetype_t filetype, cloudabi_rights_t *base, + cloudabi_rights_t *inheriting) +{ + cloudabi_rights_t rights; + + /* Convert FreeBSD bits to CloudABI bits. */ + rights = 0; +#define MAPPING(cloudabi, ...) do { \ + if (cap_rights_is_set(capabilities, ##__VA_ARGS__)) \ + rights |= (cloudabi); \ +} while (0); + RIGHTS_MAPPINGS +#undef MAPPING + + *base = rights; + *inheriting = rights; + cloudabi_remove_conflicting_rights(filetype, base, inheriting); +} + int cloudabi_sys_fd_stat_get(struct thread *td, struct cloudabi_sys_fd_stat_get_args *uap) From fc964cbf4e295b98ab5ebb6cbfb00743cdee0489 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 13:36:17 +0000 Subject: [PATCH 048/314] ar: enable deterministic mode by default Ar cannot handle UIDs with more than 6 digits, and storing the mtime, uid, gid and mode provides little to negative value anyhow for ar's uses. Turn on deterministic (-D) mode by default; it can be disabled by the user with -U. PR: 196929 Relnotes: Yes Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3190 --- usr.bin/ar/ar.1 | 1 + usr.bin/ar/ar.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/usr.bin/ar/ar.1 b/usr.bin/ar/ar.1 index 02e99f1a92c9..6998c04e0d9c 100644 --- a/usr.bin/ar/ar.1 +++ b/usr.bin/ar/ar.1 @@ -210,6 +210,7 @@ and 0644 instead of file mode from the members named by arguments .Ar . This ensures that checksums on the resulting archives are reproducible when member contents are identical. +This option is enabled by default. If multiple .Fl D and diff --git a/usr.bin/ar/ar.c b/usr.bin/ar/ar.c index 3d5e2b87667b..104d55ce85ca 100644 --- a/usr.bin/ar/ar.c +++ b/usr.bin/ar/ar.c @@ -104,6 +104,8 @@ main(int argc, char **argv) bsdar = &bsdar_storage; memset(bsdar, 0, sizeof(*bsdar)); + /* Enable deterministic mode by default. */ + bsdar->options |= AR_D; if ((bsdar->progname = getprogname()) == NULL) bsdar->progname = "ar"; From 4446a47a6f0fdff4ac678d816a1638702fd4970d Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Wed, 29 Jul 2015 13:49:34 +0000 Subject: [PATCH 049/314] Fixed shutdown(2) unix(4) tests for SOCK_SEQPACKET after r285910 (by ed). --- tests/sys/kern/unix_seqpacket_test.c | 60 ++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/tests/sys/kern/unix_seqpacket_test.c b/tests/sys/kern/unix_seqpacket_test.c index ccbacafbd7a1..986b70eeb459 100644 --- a/tests/sys/kern/unix_seqpacket_test.c +++ b/tests/sys/kern/unix_seqpacket_test.c @@ -751,35 +751,79 @@ ATF_TC_BODY(send_recv_with_connect, tc) ATF_TC_WITHOUT_HEAD(shutdown_send); ATF_TC_BODY(shutdown_send, tc) { - int s; - const char data[] = "data"; + struct sockaddr_un sun; + /* ATF's isolation mechanisms will guarantee uniqueness of this file */ + const char *path = "sock"; + const char *data = "data"; ssize_t ssize; + int s, err, s2; s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); ATF_REQUIRE(s >= 0); - ATF_CHECK_EQ(0, shutdown(s, SHUT_RDWR)); + + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_LOCAL; + sun.sun_len = sizeof(sun); + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + err = bind(s, (struct sockaddr *)&sun, sizeof(sun)); + err = listen(s, -1); + ATF_CHECK_EQ(0, err); + + /* Create the other socket */ + s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + ATF_REQUIRE(s2 >= 0); + err = connect(s2, (struct sockaddr*)&sun, sizeof(sun)); + if (err != 0) { + perror("connect"); + atf_tc_fail("connect(2) failed"); + } + + ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); /* USE MSG_NOSIGNAL so we don't get SIGPIPE */ - ssize = send(s, data, sizeof(data), MSG_EOR | MSG_NOSIGNAL); + ssize = send(s2, data, sizeof(data), MSG_EOR | MSG_NOSIGNAL); ATF_CHECK_EQ(EPIPE, errno); ATF_CHECK_EQ(-1, ssize); close(s); + close(s2); } /* send(2) should cause SIGPIPE on a shutdown socket */ ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe); ATF_TC_BODY(shutdown_send_sigpipe, tc) { - int s; - const char data[] = "data"; + struct sockaddr_un sun; + /* ATF's isolation mechanisms will guarantee uniqueness of this file */ + const char *path = "sock"; + const char *data = "data"; ssize_t ssize; + int s, err, s2; s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); ATF_REQUIRE(s >= 0); - ATF_CHECK_EQ(0, shutdown(s, SHUT_RDWR)); + + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_LOCAL; + sun.sun_len = sizeof(sun); + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + err = bind(s, (struct sockaddr *)&sun, sizeof(sun)); + err = listen(s, -1); + ATF_CHECK_EQ(0, err); + + /* Create the other socket */ + s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); + ATF_REQUIRE(s2 >= 0); + err = connect(s2, (struct sockaddr*)&sun, sizeof(sun)); + if (err != 0) { + perror("connect"); + atf_tc_fail("connect(2) failed"); + } + + ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); - ssize = send(s, data, sizeof(data), MSG_EOR); + ssize = send(s2, data, sizeof(data), MSG_EOR); ATF_CHECK_EQ(1, got_sigpipe); close(s); + close(s2); } /* nonblocking send(2) and recv(2) a single short record */ From 10a0e0bf0a5ee749abbdc29555147b75d0746b81 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 29 Jul 2015 14:07:43 +0000 Subject: [PATCH 050/314] Eliminate the use of m_copydata() in gif_encapcheck(). ip_encap already has inspected mbuf's data, at least an IP header. And it is safe to use mtod() and do direct access to needed fields. Add M_ASSERTPKTHDR() to gif_encapcheck(), since the code expects that mbuf has a packet header. Move the code from gif_validate[46] into in[6]_gif_encapcheck(), also remove "martian filters" checks. According to RFC 4213 it is enough to verify that the source address is the address of the encapsulator, as configured on the decapsulator. Reviewed by: melifaro Obtained from: Yandex LLC Sponsored by: Yandex LLC --- sys/net/if_gif.c | 7 +++--- sys/netinet/in_gif.c | 50 ++++++++++-------------------------------- sys/netinet6/in6_gif.c | 45 +++++++++++-------------------------- 3 files changed, 29 insertions(+), 73 deletions(-) diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 48a842a9dd93..78b4d9da4430 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -280,9 +280,9 @@ int gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg) { GIF_RLOCK_TRACKER; + const struct ip *ip; struct gif_softc *sc; int ret; - uint8_t ver; sc = (struct gif_softc *)arg; if (sc == NULL || (GIF2IFP(sc)->if_flags & IFF_UP) == 0) @@ -309,11 +309,12 @@ gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg) } /* Bail on short packets */ + M_ASSERTPKTHDR(m); if (m->m_pkthdr.len < sizeof(struct ip)) goto done; - m_copydata(m, 0, 1, &ver); - switch (ver >> 4) { + ip = mtod(m, const struct ip *); + switch (ip->ip_v) { #ifdef INET case 4: if (sc->gif_family != AF_INET) diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index e634987cf4c9..0afdea278c39 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -67,8 +67,6 @@ __FBSDID("$FreeBSD$"); #include -static int gif_validate4(const struct ip *, struct gif_softc *, - struct ifnet *); static int in_gif_input(struct mbuf **, int *, int); extern struct domain inetdomain; @@ -163,16 +161,22 @@ in_gif_input(struct mbuf **mp, int *offp, int proto) } /* - * validate outer address. + * we know that we are in IFF_UP, outer address available, and outer family + * matched the physical addr family. see gif_encapcheck(). */ -static int -gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp) +int +in_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg) { + const struct ip *ip; + struct gif_softc *sc; int ret; + /* sanity check done in caller */ + sc = (struct gif_softc *)arg; GIF_RLOCK_ASSERT(sc); /* check for address match */ + ip = mtod(m, const struct ip *); if (sc->gif_iphdr->ip_src.s_addr != ip->ip_dst.s_addr) return (0); ret = 32; @@ -182,18 +186,8 @@ gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp) } else ret += 32; - /* martian filters on outer source - NOT done in ip_input! */ - if (IN_MULTICAST(ntohl(ip->ip_src.s_addr))) - return (0); - switch ((ntohl(ip->ip_src.s_addr) & 0xff000000) >> 24) { - case 0: - case 127: - case 255: - return (0); - } - /* ingress filters on outer source */ - if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0 && ifp) { + if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0) { struct sockaddr_in sin; struct rtentry *rt; @@ -204,8 +198,8 @@ gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp) /* XXX MRT check for the interface we would use on output */ rt = in_rtalloc1((struct sockaddr *)&sin, 0, 0UL, sc->gif_fibnum); - if (!rt || rt->rt_ifp != ifp) { - if (rt) + if (rt == NULL || rt->rt_ifp != m->m_pkthdr.rcvif) { + if (rt != NULL) RTFREE_LOCKED(rt); return (0); } @@ -214,26 +208,6 @@ gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp) return (ret); } -/* - * we know that we are in IFF_UP, outer address available, and outer family - * matched the physical addr family. see gif_encapcheck(). - */ -int -in_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg) -{ - struct ip ip; - struct gif_softc *sc; - struct ifnet *ifp; - - /* sanity check done in caller */ - sc = (struct gif_softc *)arg; - GIF_RLOCK_ASSERT(sc); - - m_copydata(m, 0, sizeof(ip), (caddr_t)&ip); - ifp = ((m->m_flags & M_PKTHDR) != 0) ? m->m_pkthdr.rcvif : NULL; - return (gif_validate4(&ip, sc, ifp)); -} - int in_gif_attach(struct gif_softc *sc) { diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c index 126890f73077..d714f236384e 100644 --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -81,8 +81,6 @@ SYSCTL_DECL(_net_inet6_ip6); SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, gifhlim, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_gif_hlim), 0, ""); -static int gif_validate6(const struct ip6_hdr *, struct gif_softc *, - struct ifnet *); static int in6_gif_input(struct mbuf **, int *, int); extern struct domain inet6domain; @@ -174,20 +172,26 @@ in6_gif_input(struct mbuf **mp, int *offp, int proto) } /* - * validate outer address. + * we know that we are in IFF_UP, outer address available, and outer family + * matched the physical addr family. see gif_encapcheck(). */ -static int -gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc, - struct ifnet *ifp) +int +in6_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg) { + const struct ip6_hdr *ip6; + struct gif_softc *sc; int ret; + /* sanity check done in caller */ + sc = (struct gif_softc *)arg; GIF_RLOCK_ASSERT(sc); + /* * Check for address match. Note that the check is for an incoming * packet. We should compare the *source* address in our configuration * and the *destination* address of the packet, and vice versa. */ + ip6 = mtod(m, const struct ip6_hdr *); if (!IN6_ARE_ADDR_EQUAL(&sc->gif_ip6hdr->ip6_src, &ip6->ip6_dst)) return (0); ret = 128; @@ -197,10 +201,8 @@ gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc, } else ret += 128; - /* martian filters on outer source - done in ip6_input */ - /* ingress filters on outer source */ - if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0 && ifp) { + if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0) { struct sockaddr_in6 sin6; struct rtentry *rt; @@ -212,37 +214,16 @@ gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc, rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL, sc->gif_fibnum); - if (!rt || rt->rt_ifp != ifp) { - if (rt) + if (rt == NULL || rt->rt_ifp != m->m_pkthdr.rcvif) { + if (rt != NULL) RTFREE_LOCKED(rt); return (0); } RTFREE_LOCKED(rt); } - return (ret); } -/* - * we know that we are in IFF_UP, outer address available, and outer family - * matched the physical addr family. see gif_encapcheck(). - */ -int -in6_gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg) -{ - struct ip6_hdr ip6; - struct gif_softc *sc; - struct ifnet *ifp; - - /* sanity check done in caller */ - sc = (struct gif_softc *)arg; - GIF_RLOCK_ASSERT(sc); - - m_copydata(m, 0, sizeof(ip6), (caddr_t)&ip6); - ifp = ((m->m_flags & M_PKTHDR) != 0) ? m->m_pkthdr.rcvif : NULL; - return (gif_validate6(&ip6, sc, ifp)); -} - int in6_gif_attach(struct gif_softc *sc) { From 1f6aae90ad33ff1495f63137ce3e87824c0a7ee9 Mon Sep 17 00:00:00 2001 From: Sean Bruno Date: Wed, 29 Jul 2015 15:32:59 +0000 Subject: [PATCH 051/314] Make Broadcom XLR use shared ds1374 RTC driver. Remove its identical and redundant ds1374u version. Differential Revision: D3225 Submitted by: kevin.bowling@kev009.com --- sys/mips/conf/XLR | 2 +- sys/mips/conf/XLR64 | 2 +- sys/mips/conf/XLRN32 | 2 +- sys/mips/rmi/dev/iic/ds1374u.c | 147 --------------------------------- sys/mips/rmi/files.xlr | 1 - sys/mips/rmi/xlr_i2c.c | 2 +- 6 files changed, 4 insertions(+), 152 deletions(-) delete mode 100644 sys/mips/rmi/dev/iic/ds1374u.c diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR index d1e0da0efa95..0133fada2343 100644 --- a/sys/mips/conf/XLR +++ b/sys/mips/conf/XLR @@ -135,7 +135,7 @@ device ic device iic device iicbb device iicbus -device ds1374u # RTC on XLR boards +device ds1374 # RTC on XLR boards device max6657 # Temparature sensor on XLR boards device at24co2n # EEPROM on XLR boards diff --git a/sys/mips/conf/XLR64 b/sys/mips/conf/XLR64 index 1db8d857bf67..c8b1dfbb433c 100644 --- a/sys/mips/conf/XLR64 +++ b/sys/mips/conf/XLR64 @@ -109,7 +109,7 @@ device ic device iic device iicbb device iicbus -device ds1374u # RTC on XLR boards +device ds1374 # RTC on XLR boards device max6657 # Temparature sensor on XLR boards device at24co2n # EEPROM on XLR boards diff --git a/sys/mips/conf/XLRN32 b/sys/mips/conf/XLRN32 index c23b4515bdd4..e2f44687d411 100644 --- a/sys/mips/conf/XLRN32 +++ b/sys/mips/conf/XLRN32 @@ -113,7 +113,7 @@ device ic device iic device iicbb device iicbus -device ds1374u # RTC on XLR boards +device ds1374 # RTC on XLR boards device max6657 # Temparature sensor on XLR boards device at24co2n # EEPROM on XLR boards diff --git a/sys/mips/rmi/dev/iic/ds1374u.c b/sys/mips/rmi/dev/iic/ds1374u.c deleted file mode 100644 index 0c0b8236b170..000000000000 --- a/sys/mips/rmi/dev/iic/ds1374u.c +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright (c) 2003-2009 RMI Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of RMI 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 AUTHOR 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 AUTHOR 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. - * - * RMI_BSD */ - -#include -__FBSDID("$FreeBSD$"); -/* - * RTC chip sitting on the I2C bus. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "iicbus_if.h" -#include "clock_if.h" - -#define DS1374_RTC_COUNTER 0 /* counter (bytes 0-3) */ - -struct ds1374u_softc { - uint32_t sc_addr; - device_t sc_dev; -}; - -static int -ds1374u_probe(device_t dev) -{ - device_set_desc(dev, "DS1374U-33 RTC"); - return (0); -} - -static int -ds1374u_attach(device_t dev) -{ - struct ds1374u_softc *sc = device_get_softc(dev); - - if(sc==NULL) { - printf("ds1374u_attach device_get_softc failed\n"); - return (0); - } - sc->sc_dev = dev; - sc->sc_addr = iicbus_get_addr(dev); - - clock_register(dev, 1000); - return (0); -} - -static int -ds1374u_settime(device_t dev, struct timespec *ts) -{ - /* NB: register pointer precedes actual data */ - uint8_t data[5] = { DS1374_RTC_COUNTER }; - struct ds1374u_softc *sc = device_get_softc(dev); - struct iic_msg msgs[1] = { - { sc->sc_addr, IIC_M_WR, 5, data }, - }; - - data[1] = (ts->tv_sec >> 0) & 0xff; - data[2] = (ts->tv_sec >> 8) & 0xff; - data[3] = (ts->tv_sec >> 16) & 0xff; - data[4] = (ts->tv_sec >> 24) & 0xff; - - return iicbus_transfer(dev, msgs, 1); -} - -static int -ds1374u_gettime(device_t dev, struct timespec *ts) -{ - struct ds1374u_softc *sc = device_get_softc(dev); - uint8_t addr[1] = { DS1374_RTC_COUNTER }; - uint8_t secs[4]; - struct iic_msg msgs[2] = { - { sc->sc_addr, IIC_M_WR, 1, addr }, - { sc->sc_addr, IIC_M_RD, 4, secs }, - }; - int error; - - error = iicbus_transfer(dev, msgs, 2); - if (error == 0) { - /* counter has seconds since epoch */ - ts->tv_sec = (secs[3] << 24) | (secs[2] << 16) - | (secs[1] << 8) | (secs[0] << 0); - ts->tv_nsec = 0; - } - return error; -} - -static device_method_t ds1374u_methods[] = { - DEVMETHOD(device_probe, ds1374u_probe), - DEVMETHOD(device_attach, ds1374u_attach), - - DEVMETHOD(clock_gettime, ds1374u_gettime), - DEVMETHOD(clock_settime, ds1374u_settime), - - {0, 0}, -}; - -static driver_t ds1374u_driver = { - "ds1374u", - ds1374u_methods, - sizeof(struct ds1374u_softc), -}; -static devclass_t ds1374u_devclass; - -DRIVER_MODULE(ds1374u, iicbus, ds1374u_driver, ds1374u_devclass, 0, 0); -MODULE_VERSION(ds1374u, 1); -MODULE_DEPEND(ds1374u, iicbus, 1, 1, 1); diff --git a/sys/mips/rmi/files.xlr b/sys/mips/rmi/files.xlr index 0827ca7ce84b..ed85a1b9c47a 100644 --- a/sys/mips/rmi/files.xlr +++ b/sys/mips/rmi/files.xlr @@ -22,6 +22,5 @@ mips/rmi/dev/sec/rmisec.c optional rmisec mips/rmi/dev/sec/rmilib.c optional rmisec mips/rmi/dev/xlr/rge.c optional rge mips/rmi/dev/nlge/if_nlge.c optional nlge -mips/rmi/dev/iic/ds1374u.c optional ds1374u mips/rmi/dev/iic/max6657.c optional max6657 mips/rmi/dev/iic/at24co2n.c optional at24co2n diff --git a/sys/mips/rmi/xlr_i2c.c b/sys/mips/rmi/xlr_i2c.c index 96f982066702..2605887d6048 100644 --- a/sys/mips/rmi/xlr_i2c.c +++ b/sys/mips/rmi/xlr_i2c.c @@ -187,7 +187,7 @@ xlr_i2c_attach(device_t dev) return -1; } if(xlr_board_info.xlr_i2c_device[I2C_RTC].enabled == 1) { - tmpd = device_add_child(sc->iicbus, "ds1374u", 0); + tmpd = device_add_child(sc->iicbus, "ds1374_rtc", 0); device_set_ivars(tmpd, &xlr_board_info.xlr_i2c_device[I2C_RTC]); } if(xlr_board_info.xlr_i2c_device[I2C_THERMAL].enabled == 1) { From 8cdcc73cfa580635932e18c60ef3198ccd0ae8e8 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 15:42:22 +0000 Subject: [PATCH 052/314] Include c++filt and readelf in WITHOUT_ELFTOOLCHAIN_TOOLS --- tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS b/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS index e4780582c860..7871e86369d5 100644 --- a/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS +++ b/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS @@ -1,7 +1,9 @@ .\" $FreeBSD$ Set to use .Xr addr2line 1 , +.Xr c++filt 1 , .Xr nm 1 , +.Xr readelf 1 , .Xr size 1 , .Xr strings 1 , and From 8843746ab4cf9818ef5bf400f6f5045297a42c78 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Wed, 29 Jul 2015 16:37:36 +0000 Subject: [PATCH 053/314] Remove the AUTHORS section until it's clear who exactly wrote the driver. --- share/man/man4/pms.4 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/share/man/man4/pms.4 b/share/man/man4/pms.4 index 7684051213c5..e4986c90c98c 100644 --- a/share/man/man4/pms.4 +++ b/share/man/man4/pms.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 23, 2015 +.Dd July 29, 2015 .Dt PMS 4 .Os .Sh NAME @@ -124,5 +124,3 @@ The .Nm device driver first appeared in .Fx 10.2 . -.Sh AUTHORS -.An Achim Leubner Aq Mt Achim.Leubner@pmcs.com From e555b4309c337304587b7fda6ebda106d6854758 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 29 Jul 2015 17:16:53 +0000 Subject: [PATCH 054/314] Introduce falloc_caps() to create descriptors with capabilties in place. falloc_noinstall() followed by finstall() allows you to create and install file descriptors with custom capabilities. Add falloc_caps() that can do both of these actions in one go. This will be used by CloudABI to create pipes with custom capabilities. Reviewed by: mjg --- sys/kern/kern_descrip.c | 5 +++-- sys/sys/filedesc.h | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 933e4cc5cc81..dc0ee49c3851 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1707,7 +1707,8 @@ fdallocn(struct thread *td, int minfd, int *fds, int n) * release the FILEDESC lock. */ int -falloc(struct thread *td, struct file **resultfp, int *resultfd, int flags) +falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, int flags, + struct filecaps *fcaps) { struct file *fp; int error, fd; @@ -1716,7 +1717,7 @@ falloc(struct thread *td, struct file **resultfp, int *resultfd, int flags) if (error) return (error); /* no reference held on error */ - error = finstall(td, fp, &fd, flags, NULL); + error = finstall(td, fp, &fd, flags, fcaps); if (error) { fdrop(fp, td); /* one reference (fp only) */ return (error); diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index b557706bb04e..f75927b86b72 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -146,6 +146,10 @@ enum { /* Flags for kern_dup(). */ #define FDDUP_FLAG_CLOEXEC 0x1 /* Atomically set UF_EXCLOSE. */ +/* For backward compatibility. */ +#define falloc(td, resultfp, resultfd, flags) \ + falloc_caps(td, resultfp, resultfd, flags, NULL) + struct thread; void filecaps_init(struct filecaps *fcaps); @@ -156,8 +160,8 @@ void filecaps_free(struct filecaps *fcaps); int closef(struct file *fp, struct thread *td); int dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode, int openerror, int *indxp); -int falloc(struct thread *td, struct file **resultfp, int *resultfd, - int flags); +int falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, + int flags, struct filecaps *fcaps); int falloc_noinstall(struct thread *td, struct file **resultfp); void _finstall(struct filedesc *fdp, struct file *fp, int fd, int flags, struct filecaps *fcaps); From 8328babdd0716967a63a23af9dee2e122bb291dc Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 29 Jul 2015 17:18:27 +0000 Subject: [PATCH 055/314] Make pipes in CloudABI work. Summary: Pipes in CloudABI are unidirectional. The reason for this is that CloudABI attempts to provide a uniform runtime environment across different flavours of UNIX. Instead of implementing a custom pipe that is unidirectional, we can simply reuse Capsicum permission bits to support this. This is nice, because CloudABI already attempts to restrict permission bits to correspond with the operations that apply to a certain file descriptor. Replace kern_pipe() and kern_pipe2() by a single kern_pipe() that takes a pair of filecaps. These filecaps are passed to the newly introduced falloc_caps() function that creates the descriptors with rights in place. Test Plan: CloudABI pipes seem to be created with proper rights in place: https://github.com/NuxiNL/cloudlibc/blob/master/src/libc/unistd/pipe_test.c#L44 Reviewers: jilles, mjg Reviewed By: mjg Subscribers: imp Differential Revision: https://reviews.freebsd.org/D3236 --- sys/compat/cloudabi/cloudabi_fd.c | 14 ++++++++++++++ sys/compat/linux/linux_file.c | 4 ++-- sys/kern/sys_pipe.c | 22 ++++++++-------------- sys/sys/syscallsubr.h | 5 +++-- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index 1b3aa0f0ce09..5a58cb312d98 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -120,10 +120,24 @@ int cloudabi_sys_fd_create2(struct thread *td, struct cloudabi_sys_fd_create2_args *uap) { + struct filecaps fcaps1 = {}, fcaps2 = {}; int fds[2]; int error; switch (uap->type) { + case CLOUDABI_FILETYPE_FIFO: + /* + * CloudABI pipes are unidirectional. Restrict rights on + * the pipe to simulate this. + */ + cap_rights_init(&fcaps1.fc_rights, CAP_EVENT, CAP_FCNTL, + CAP_FSTAT, CAP_READ); + fcaps1.fc_fcntls = CAP_FCNTL_SETFL; + cap_rights_init(&fcaps2.fc_rights, CAP_EVENT, CAP_FCNTL, + CAP_FSTAT, CAP_WRITE); + fcaps2.fc_fcntls = CAP_FCNTL_SETFL; + error = kern_pipe(td, fds, 0, &fcaps1, &fcaps2); + break; case CLOUDABI_FILETYPE_SOCKET_DGRAM: error = kern_socketpair(td, AF_UNIX, SOCK_DGRAM, 0, fds); break; diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 1e5e37a2db76..489dc1e458dc 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -1582,7 +1582,7 @@ linux_pipe(struct thread *td, struct linux_pipe_args *args) printf(ARGS(pipe, "*")); #endif - error = kern_pipe2(td, fildes, 0); + error = kern_pipe(td, fildes, 0, NULL, NULL); if (error) return (error); @@ -1609,7 +1609,7 @@ linux_pipe2(struct thread *td, struct linux_pipe2_args *args) flags |= O_NONBLOCK; if ((args->flags & LINUX_O_CLOEXEC) != 0) flags |= O_CLOEXEC; - error = kern_pipe2(td, fildes, flags); + error = kern_pipe(td, fildes, flags, NULL, NULL); if (error) return (error); diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 70e76ad39952..a81c9dee055f 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -397,14 +397,8 @@ pipe_dtor(struct pipe *dpipe) * the zone pick up the pieces via pipeclose(). */ int -kern_pipe(struct thread *td, int fildes[2]) -{ - - return (kern_pipe2(td, fildes, 0)); -} - -int -kern_pipe2(struct thread *td, int fildes[2], int flags) +kern_pipe(struct thread *td, int fildes[2], int flags, struct filecaps *fcaps1, + struct filecaps *fcaps2) { struct file *rf, *wf; struct pipe *rpipe, *wpipe; @@ -414,13 +408,13 @@ kern_pipe2(struct thread *td, int fildes[2], int flags) pipe_paircreate(td, &pp); rpipe = &pp->pp_rpipe; wpipe = &pp->pp_wpipe; - error = falloc(td, &rf, &fd, flags); + error = falloc_caps(td, &rf, &fd, flags, fcaps1); if (error) { pipeclose(rpipe); pipeclose(wpipe); return (error); } - /* An extra reference on `rf' has been held for us by falloc(). */ + /* An extra reference on `rf' has been held for us by falloc_caps(). */ fildes[0] = fd; fflags = FREAD | FWRITE; @@ -434,7 +428,7 @@ kern_pipe2(struct thread *td, int fildes[2], int flags) * side while we are blocked trying to allocate the write side. */ finit(rf, fflags, DTYPE_PIPE, rpipe, &pipeops); - error = falloc(td, &wf, &fd, flags); + error = falloc_caps(td, &wf, &fd, flags, fcaps2); if (error) { fdclose(td, rf, fildes[0]); fdrop(rf, td); @@ -442,7 +436,7 @@ kern_pipe2(struct thread *td, int fildes[2], int flags) pipeclose(wpipe); return (error); } - /* An extra reference on `wf' has been held for us by falloc(). */ + /* An extra reference on `wf' has been held for us by falloc_caps(). */ finit(wf, fflags, DTYPE_PIPE, wpipe, &pipeops); fdrop(wf, td); fildes[1] = fd; @@ -458,7 +452,7 @@ sys_pipe(struct thread *td, struct pipe_args *uap) int error; int fildes[2]; - error = kern_pipe(td, fildes); + error = kern_pipe(td, fildes, 0, NULL, NULL); if (error) return (error); @@ -475,7 +469,7 @@ sys_pipe2(struct thread *td, struct pipe2_args *uap) if (uap->flags & ~(O_CLOEXEC | O_NONBLOCK)) return (EINVAL); - error = kern_pipe2(td, fildes, uap->flags); + error = kern_pipe(td, fildes, uap->flags, NULL, NULL); if (error) return (error); error = copyout(fildes, uap->fildes, 2 * sizeof(int)); diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index d22c349bb678..f6f851b60a52 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -35,6 +35,7 @@ #include struct file; +struct filecaps; enum idtype; struct itimerval; struct image_args; @@ -150,8 +151,8 @@ int kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int flags, int mode); int kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name, u_long flags); -int kern_pipe(struct thread *td, int fildes[2]); -int kern_pipe2(struct thread *td, int fildes[2], int flags); +int kern_pipe(struct thread *td, int fildes[2], int flags, + struct filecaps *fcaps1, struct filecaps *fcaps2); int kern_poll(struct thread *td, struct pollfd *fds, u_int nfds, struct timespec *tsp, sigset_t *uset); int kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, From a80ac30b2df8e89e46c3d1bb1e375b25c618e24c Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 17:34:26 +0000 Subject: [PATCH 056/314] ar: Fix deterministic mode default with options other than -q or -r Reported by: jhibbits Reviewed by: jhibbits Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3237 --- usr.bin/ar/ar.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/usr.bin/ar/ar.c b/usr.bin/ar/ar.c index 104d55ce85ca..4dee029b96aa 100644 --- a/usr.bin/ar/ar.c +++ b/usr.bin/ar/ar.c @@ -100,12 +100,12 @@ main(int argc, char **argv) struct bsdar *bsdar, bsdar_storage; char *p; size_t len; - int i, opt; + int i, opt, Dflag, Uflag; bsdar = &bsdar_storage; memset(bsdar, 0, sizeof(*bsdar)); - /* Enable deterministic mode by default. */ - bsdar->options |= AR_D; + Dflag = 0; + Uflag = 0; if ((bsdar->progname = getprogname()) == NULL) bsdar->progname = "ar"; @@ -122,10 +122,12 @@ main(int argc, char **argv) /* Ignored. */ break; case 'D': - bsdar->options |= AR_D; + Dflag = 1; + Uflag = 0; break; case 'U': - bsdar->options &= ~AR_D; + Uflag = 1; + Dflag = 0; break; case 'V': ranlib_version(); @@ -182,7 +184,8 @@ main(int argc, char **argv) set_mode(bsdar, opt); break; case 'D': - bsdar->options |= AR_D; + Dflag = 1; + Uflag = 0; break; case 'f': case 'T': @@ -222,7 +225,8 @@ main(int argc, char **argv) set_mode(bsdar, opt); break; case 'U': - bsdar->options &= ~AR_D; + Uflag = 1; + Dflag = 0; break; case 'u': bsdar->options |= AR_U; @@ -275,6 +279,10 @@ main(int argc, char **argv) argv++; } + /* Set determinstic mode for -D, and by default without -U. */ + if (Dflag || (Uflag == 0 && (bsdar->mode == 'q' || bsdar->mode == 'r'))) + bsdar->options |= AR_D; + if (bsdar->options & AR_A) only_mode(bsdar, "-a", "mqr"); if (bsdar->options & AR_B) @@ -283,8 +291,10 @@ main(int argc, char **argv) only_mode(bsdar, "-c", "qr"); if (bsdar->options & AR_CC) only_mode(bsdar, "-C", "x"); - if (bsdar->options & AR_D) + if (Dflag) only_mode(bsdar, "-D", "qr"); + if (Uflag) + only_mode(bsdar, "-U", "qr"); if (bsdar->options & AR_O) only_mode(bsdar, "-o", "x"); if (bsdar->options & AR_SS) From 4741bfcb57776df8564c3e4b865e5a54cda4800e Mon Sep 17 00:00:00 2001 From: Patrick Kelsey Date: Wed, 29 Jul 2015 17:59:13 +0000 Subject: [PATCH 057/314] Revert r265338, r271089 and r271123 as those changes do not handle non-inline urgent data and introduce an mbuf exhaustion attack vector similar to FreeBSD-SA-15:15.tcp, but not requiring VNETs. Address the issue described in FreeBSD-SA-15:15.tcp. Reviewed by: glebius Approved by: so Approved by: jmallett (mentor) Security: FreeBSD-SA-15:15.tcp Sponsored by: Norse Corp, Inc. --- sys/netinet/tcp_input.c | 6 +- sys/netinet/tcp_reass.c | 232 ++++++++++++++++++++++++--------------- sys/netinet/tcp_subr.c | 2 + sys/netinet/tcp_usrreq.c | 2 +- sys/netinet/tcp_var.h | 12 +- sys/sys/mbuf.h | 1 - 6 files changed, 163 insertions(+), 92 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 9454a6565b03..3ca37b549129 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1665,7 +1665,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tp->snd_nxt == tp->snd_max && tiwin && tiwin == tp->snd_wnd && ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && - tp->t_segq == NULL && ((to.to_flags & TOF_TS) == 0 || + LIST_EMPTY(&tp->t_segq) && + ((to.to_flags & TOF_TS) == 0 || TSTMP_GEQ(to.to_tsval, tp->ts_recent)) ) { /* @@ -2903,7 +2904,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * immediately when segments are out of order (so * fast retransmit can work). */ - if (th->th_seq == tp->rcv_nxt && tp->t_segq == NULL && + if (th->th_seq == tp->rcv_nxt && + LIST_EMPTY(&tp->t_segq) && TCPS_HAVEESTABLISHED(tp->t_state)) { if (DELAY_ACK(tp, tlen)) tp->t_flags |= TF_DELACK; diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 17d9a79eb50d..77d8940a0d92 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -71,33 +71,80 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef TCPDEBUG +#include +#endif /* TCPDEBUG */ + +static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0, + "TCP Segment Reassembly Queue"); + +static int tcp_reass_maxseg = 0; +SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN, + &tcp_reass_maxseg, 0, + "Global maximum number of TCP Segments in Reassembly Queue"); + +static uma_zone_t tcp_reass_zone; +SYSCTL_UMA_CUR(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLFLAG_VNET, + &tcp_reass_zone, + "Global number of TCP Segments currently in Reassembly Queue"); + +/* Initialize TCP reassembly queue */ +static void +tcp_reass_zone_change(void *tag) +{ + + /* Set the zone limit and read back the effective value. */ + tcp_reass_maxseg = nmbclusters / 16; + tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, + tcp_reass_maxseg); +} + +void +tcp_reass_global_init(void) +{ + + tcp_reass_maxseg = nmbclusters / 16; + TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments", + &tcp_reass_maxseg); + tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), + NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); + /* Set the zone limit and read back the effective value. */ + tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, + tcp_reass_maxseg); + EVENTHANDLER_REGISTER(nmbclusters_change, + tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY); +} void tcp_reass_flush(struct tcpcb *tp) { - struct mbuf *m; + struct tseg_qent *qe; INP_WLOCK_ASSERT(tp->t_inpcb); - while ((m = tp->t_segq) != NULL) { - tp->t_segq = m->m_nextpkt; - tp->t_segqlen -= m->m_pkthdr.len; - m_freem(m); + while ((qe = LIST_FIRST(&tp->t_segq)) != NULL) { + LIST_REMOVE(qe, tqe_q); + m_freem(qe->tqe_m); + uma_zfree(tcp_reass_zone, qe); + tp->t_segqlen--; } KASSERT((tp->t_segqlen == 0), - ("TCP reass queue %p length is %d instead of 0 after flush.", + ("TCP reass queue %p segment count is %d instead of 0 after flush.", tp, tp->t_segqlen)); } -#define M_TCPHDR(m) ((struct tcphdr *)((m)->m_pkthdr.pkt_tcphdr)) - int tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) { + struct tseg_qent *q; + struct tseg_qent *p = NULL; + struct tseg_qent *nq; + struct tseg_qent *te = NULL; struct socket *so = tp->t_inpcb->inp_socket; - struct mbuf *mq, *mp; - int flags, wakeup; + char *s = NULL; + int flags; + struct tseg_qent tqs; INP_WLOCK_ASSERT(tp->t_inpcb); @@ -113,10 +160,6 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) if (th == NULL) goto present; - M_ASSERTPKTHDR(m); - KASSERT(*tlenp == m->m_pkthdr.len, ("%s: tlenp %u len %u", __func__, - *tlenp, m->m_pkthdr.len)); - /* * Limit the number of segments that can be queued to reduce the * potential for mbuf exhaustion. For best performance, we want to be @@ -127,15 +170,17 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) * Always let the missing segment through which caused this queue. * NB: Access to the socket buffer is left intentionally unlocked as we * can tolerate stale information here. + * + * XXXLAS: Using sbspace(so->so_rcv) instead of so->so_rcv.sb_hiwat + * should work but causes packets to be dropped when they shouldn't. + * Investigate why and re-evaluate the below limit after the behaviour + * is understood. */ if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && - tp->t_segqlen + m->m_pkthdr.len >= sbspace(&so->so_rcv)) { - char *s; - + tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { TCPSTAT_INC(tcps_rcvreassfull); *tlenp = 0; - if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, - NULL))) { + if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: queue limit reached, " "segment dropped\n", s, __func__); free(s, M_TCPLOG); @@ -144,14 +189,47 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) return (0); } + /* + * Allocate a new queue entry. If we can't, or hit the zone limit + * just drop the pkt. + * + * Use a temporary structure on the stack for the missing segment + * when the zone is exhausted. Otherwise we may get stuck. + */ + te = uma_zalloc(tcp_reass_zone, M_NOWAIT); + if (te == NULL) { + if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { + TCPSTAT_INC(tcps_rcvmemdrop); + m_freem(m); + *tlenp = 0; + if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, + NULL))) { + log(LOG_DEBUG, "%s; %s: global zone limit " + "reached, segment dropped\n", s, __func__); + free(s, M_TCPLOG); + } + return (0); + } else { + bzero(&tqs, sizeof(struct tseg_qent)); + te = &tqs; + if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, + NULL))) { + log(LOG_DEBUG, + "%s; %s: global zone limit reached, using " + "stack for missing segment\n", s, __func__); + free(s, M_TCPLOG); + } + } + } + tp->t_segqlen++; + /* * Find a segment which begins after this one does. */ - mp = NULL; - for (mq = tp->t_segq; mq != NULL; mq = mq->m_nextpkt) { - if (SEQ_GT(M_TCPHDR(mq)->th_seq, th->th_seq)) + LIST_FOREACH(q, &tp->t_segq, tqe_q) { + if (SEQ_GT(q->tqe_th->th_seq, th->th_seq)) break; - mp = mq; + p = q; } /* @@ -159,16 +237,18 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) * our data already. If so, drop the data from the incoming * segment. If it provides all of our data, drop us. */ - if (mp != NULL) { + if (p != NULL) { int i; - /* conversion to int (in i) handles seq wraparound */ - i = M_TCPHDR(mp)->th_seq + mp->m_pkthdr.len - th->th_seq; + i = p->tqe_th->th_seq + p->tqe_len - th->th_seq; if (i > 0) { if (i >= *tlenp) { TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); + if (te != &tqs) + uma_zfree(tcp_reass_zone, te); + tp->t_segqlen--; /* * Try to present any queued data * at the left window edge to the user. @@ -190,54 +270,37 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - while (mq) { - struct mbuf *nq; - int i; - - i = (th->th_seq + *tlenp) - M_TCPHDR(mq)->th_seq; + while (q) { + int i = (th->th_seq + *tlenp) - q->tqe_th->th_seq; if (i <= 0) break; - if (i < mq->m_pkthdr.len) { - M_TCPHDR(mq)->th_seq += i; - m_adj(mq, i); - tp->t_segqlen -= i; + if (i < q->tqe_len) { + q->tqe_th->th_seq += i; + q->tqe_len -= i; + m_adj(q->tqe_m, i); break; } - nq = mq->m_nextpkt; - tp->t_segqlen -= mq->m_pkthdr.len; - m_freem(mq); - if (mp) - mp->m_nextpkt = nq; - else - tp->t_segq = nq; - mq = nq; + nq = LIST_NEXT(q, tqe_q); + LIST_REMOVE(q, tqe_q); + m_freem(q->tqe_m); + uma_zfree(tcp_reass_zone, q); + tp->t_segqlen--; + q = nq; } - /* - * Insert the new segment queue entry into place. Try to collapse - * mbuf chains if segments are adjacent. - */ - if (mp) { - if (M_TCPHDR(mp)->th_seq + mp->m_pkthdr.len == th->th_seq) - m_catpkt(mp, m); - else { - m->m_nextpkt = mp->m_nextpkt; - mp->m_nextpkt = m; - m->m_pkthdr.pkt_tcphdr = th; - } + /* Insert the new segment queue entry into place. */ + te->tqe_m = m; + te->tqe_th = th; + te->tqe_len = *tlenp; + + if (p == NULL) { + LIST_INSERT_HEAD(&tp->t_segq, te, tqe_q); } else { - mq = tp->t_segq; - tp->t_segq = m; - if (mq && th->th_seq + *tlenp == M_TCPHDR(mq)->th_seq) { - m->m_nextpkt = mq->m_nextpkt; - mq->m_nextpkt = NULL; - m_catpkt(m, mq); - } else - m->m_nextpkt = mq; - m->m_pkthdr.pkt_tcphdr = th; + KASSERT(te != &tqs, ("%s: temporary stack based entry not " + "first element in queue", __func__)); + LIST_INSERT_AFTER(p, te, tqe_q); } - tp->t_segqlen += *tlenp; present: /* @@ -246,30 +309,25 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) */ if (!TCPS_HAVEESTABLISHED(tp->t_state)) return (0); - - flags = 0; - wakeup = 0; + q = LIST_FIRST(&tp->t_segq); + if (!q || q->tqe_th->th_seq != tp->rcv_nxt) + return (0); SOCKBUF_LOCK(&so->so_rcv); - while ((mq = tp->t_segq) != NULL && - M_TCPHDR(mq)->th_seq == tp->rcv_nxt) { - tp->t_segq = mq->m_nextpkt; - - tp->rcv_nxt += mq->m_pkthdr.len; - tp->t_segqlen -= mq->m_pkthdr.len; - flags = M_TCPHDR(mq)->th_flags & TH_FIN; - + do { + tp->rcv_nxt += q->tqe_len; + flags = q->tqe_th->th_flags & TH_FIN; + nq = LIST_NEXT(q, tqe_q); + LIST_REMOVE(q, tqe_q); if (so->so_rcv.sb_state & SBS_CANTRCVMORE) - m_freem(mq); - else { - mq->m_nextpkt = NULL; - sbappendstream_locked(&so->so_rcv, mq, 0); - wakeup = 1; - } - } + m_freem(q->tqe_m); + else + sbappendstream_locked(&so->so_rcv, q->tqe_m, 0); + if (q != &tqs) + uma_zfree(tcp_reass_zone, q); + tp->t_segqlen--; + q = nq; + } while (q && q->tqe_th->th_seq == tp->rcv_nxt); ND6_HINT(tp); - if (wakeup) - sorwakeup_locked(so); - else - SOCKBUF_UNLOCK(&so->so_rcv); + sorwakeup_locked(so); return (flags); } diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 757bcf2e43db..7fe0eba0a310 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -385,6 +385,8 @@ tcp_init(void) if (!IS_DEFAULT_VNET(curvnet)) return; + tcp_reass_global_init(); + /* XXX virtualize those bellow? */ tcp_delacktime = TCPTV_DELACK; tcp_keepinit = TCPTV_KEEP_INIT; diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 4ea39e300cff..de2de94e18e1 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1977,7 +1977,7 @@ db_print_tcpcb(struct tcpcb *tp, const char *name, int indent) db_print_indent(indent); db_printf("t_segq first: %p t_segqlen: %d t_dupacks: %d\n", - tp->t_segq, tp->t_segqlen, tp->t_dupacks); + LIST_FIRST(&tp->t_segq), tp->t_segqlen, tp->t_dupacks); db_print_indent(indent); db_printf("tt_rexmt: %p tt_persist: %p tt_keep: %p\n", diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index df01735c5e5d..e8b6670cebb6 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -46,6 +46,15 @@ VNET_DECLARE(int, tcp_do_rfc1323); #endif /* _KERNEL */ +/* TCP segment queue entry */ +struct tseg_qent { + LIST_ENTRY(tseg_qent) tqe_q; + int tqe_len; /* TCP segment data length */ + struct tcphdr *tqe_th; /* a pointer to tcp header */ + struct mbuf *tqe_m; /* mbuf contains packet */ +}; +LIST_HEAD(tsegqe_head, tseg_qent); + struct sackblk { tcp_seq start; /* start seq no. of sack block */ tcp_seq end; /* end seq no. */ @@ -91,7 +100,7 @@ do { \ * Organized for 16 byte cacheline efficiency. */ struct tcpcb { - struct mbuf *t_segq; /* segment reassembly queue */ + struct tsegqe_head t_segq; /* segment reassembly queue */ void *t_pspare[2]; /* new reassembly queue */ int t_segqlen; /* segment reassembly queue length */ int t_dupacks; /* consecutive dup acks recd */ @@ -667,6 +676,7 @@ char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *, char *tcp_log_vain(struct in_conninfo *, struct tcphdr *, void *, const void *); int tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *); +void tcp_reass_global_init(void); void tcp_reass_flush(struct tcpcb *); int tcp_input(struct mbuf **, int *, int); u_long tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *); diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 3d5a7c1c4428..39a41d3a40d7 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -150,7 +150,6 @@ struct pkthdr { #define tso_segsz PH_per.sixteen[1] #define csum_phsum PH_per.sixteen[2] #define csum_data PH_per.thirtytwo[1] -#define pkt_tcphdr PH_loc.ptr /* * Description of external storage mapped into mbuf; valid only if M_EXT is From d9f2a782491ca34d4939659f89b50786da5be1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ermal=20Lu=C3=A7i?= Date: Wed, 29 Jul 2015 18:04:01 +0000 Subject: [PATCH 058/314] ip_output normalization and fixes ip_output has a big chunk of code used to handle special cases with pfil consumers which also forces a reloop on it. Gather all this code together to make it readable and properly handle the reloop cases. Some of the issues identified: M_IP_NEXTHOP is not handled properly in existing code. route reference leaking is possible with in FIB number change route flags checking is not consistent in the function Differential Revision: https://reviews.freebsd.org/D3022 Reviewed by: gnn Approved by: gnn(mentor) MFC after: 4 weeks --- sys/netinet/ip_output.c | 208 ++++++++++++++++++++++------------------ 1 file changed, 113 insertions(+), 95 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index c75698113290..d36548aa7e66 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -106,6 +106,94 @@ static void ip_mloopback extern int in_mcast_loop; extern struct protosw inetsw[]; +static inline int +ip_output_pfil(struct mbuf *m, struct ifnet *ifp, struct inpcb *inp, + struct sockaddr_in *dst, int *fibnum, int *error) +{ + struct m_tag *fwd_tag = NULL; + struct in_addr odst; + struct ip *ip; + + ip = mtod(m, struct ip *); + + /* Run through list of hooks for output packets. */ + odst.s_addr = ip->ip_dst.s_addr; + *error = pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, inp); + if ((*error) != 0 || m == NULL) + return 1; /* Finished */ + + ip = mtod(m, struct ip *); + + /* See if destination IP address was changed by packet filter. */ + if (odst.s_addr != ip->ip_dst.s_addr) { + m->m_flags |= M_SKIP_FIREWALL; + /* If destination is now ourself drop to ip_input(). */ + if (in_localip(ip->ip_dst)) { + m->m_flags |= M_FASTFWD_OURS; + if (m->m_pkthdr.rcvif == NULL) + m->m_pkthdr.rcvif = V_loif; + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + m->m_pkthdr.csum_flags |= + CSUM_IP_CHECKED | CSUM_IP_VALID; +#ifdef SCTP + if (m->m_pkthdr.csum_flags & CSUM_SCTP) + m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; +#endif + *error = netisr_queue(NETISR_IP, m); + return 1; /* Finished */ + } + + bzero(dst, sizeof(*dst)); + dst->sin_family = AF_INET; + dst->sin_len = sizeof(*dst); + dst->sin_addr = ip->ip_dst; + + return -1; /* Reloop */ + } + /* See if fib was changed by packet filter. */ + if ((*fibnum) != M_GETFIB(m)) { + m->m_flags |= M_SKIP_FIREWALL; + *fibnum = M_GETFIB(m); + return -1; /* Reloop for FIB change */ + } + + /* See if local, if yes, send it to netisr with IP_FASTFWD_OURS. */ + if (m->m_flags & M_FASTFWD_OURS) { + if (m->m_pkthdr.rcvif == NULL) + m->m_pkthdr.rcvif = V_loif; + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } +#ifdef SCTP + if (m->m_pkthdr.csum_flags & CSUM_SCTP) + m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; +#endif + m->m_pkthdr.csum_flags |= + CSUM_IP_CHECKED | CSUM_IP_VALID; + + *error = netisr_queue(NETISR_IP, m); + return 1; /* Finished */ + } + /* Or forward to some other address? */ + if ((m->m_flags & M_IP_NEXTHOP) && + ((fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL)) { + bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in)); + m->m_flags |= M_SKIP_FIREWALL; + m->m_flags &= ~M_IP_NEXTHOP; + m_tag_delete(m, fwd_tag); + + return -1; /* Reloop for CHANGE of dst */ + } + + return 0; +} + /* * IP output. The packet in mbuf chain m contains a skeletal IP * header (with len, off, ttl, proto, tos, src, dst). @@ -136,11 +224,8 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, uint16_t ip_len, ip_off; struct route iproute; struct rtentry *rte; /* cache for ro->ro_rt */ - struct in_addr odst; - struct m_tag *fwd_tag = NULL; uint32_t fibnum; int have_ia_ref; - int needfiblookup; #ifdef IPSEC int no_route_but_check_spd = 0; #endif @@ -194,32 +279,20 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, */ gw = dst = (struct sockaddr_in *)&ro->ro_dst; fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : M_GETFIB(m); -again: - ia = NULL; - have_ia_ref = 0; + rte = ro->ro_rt; /* - * If there is a cached route, check that it is to the same - * destination and is still up. If not, free it and try again. * The address family should also be checked in case of sharing * the cache with IPv6. */ - rte = ro->ro_rt; - if (rte && ((rte->rt_flags & RTF_UP) == 0 || - rte->rt_ifp == NULL || - !RT_LINK_IS_UP(rte->rt_ifp) || - dst->sin_family != AF_INET || - dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { - RO_RTFREE(ro); - ro->ro_lle = NULL; - rte = NULL; - gw = dst; - } - if (rte == NULL && fwd_tag == NULL) { + if (rte == NULL || dst->sin_family != AF_INET) { bzero(dst, sizeof(*dst)); dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst); dst->sin_addr = ip->ip_dst; } +again: + ia = NULL; + have_ia_ref = 0; /* * If routing to interface only, short circuit routing lookup. * The use of an all-ones broadcast address implies this; an @@ -282,6 +355,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, rte = ro->ro_rt; } if (rte == NULL || + (rte->rt_flags & RTF_UP) == 0 || rte->rt_ifp == NULL || !RT_LINK_IS_UP(rte->rt_ifp)) { #ifdef IPSEC @@ -307,6 +381,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, else isbroadcast = in_broadcast(gw->sin_addr, ifp); } + /* * Calculate MTU. If we have a route that is up, use that, * otherwise use the interface's MTU. @@ -318,6 +393,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, /* Catch a possible divide by zero later. */ KASSERT(mtu > 0, ("%s: mtu %d <= 0, rte=%p (rt_flags=0x%08x) ifp=%p", __func__, mtu, rte, (rte != NULL) ? rte->rt_flags : 0, ifp)); + if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { m->m_flags |= M_MCAST; /* @@ -475,87 +551,29 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, #endif /* IPSEC */ /* Jump over all PFIL processing if hooks are not active. */ - if (!PFIL_HOOKED(&V_inet_pfil_hook)) - goto passout; - - /* Run through list of hooks for output packets. */ - odst.s_addr = ip->ip_dst.s_addr; - error = pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, inp); - if (error != 0 || m == NULL) - goto done; - - ip = mtod(m, struct ip *); - needfiblookup = 0; - - /* See if destination IP address was changed by packet filter. */ - if (odst.s_addr != ip->ip_dst.s_addr) { - m->m_flags |= M_SKIP_FIREWALL; - /* If destination is now ourself drop to ip_input(). */ - if (in_localip(ip->ip_dst)) { - m->m_flags |= M_FASTFWD_OURS; - if (m->m_pkthdr.rcvif == NULL) - m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { - m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; - m->m_pkthdr.csum_data = 0xffff; - } - m->m_pkthdr.csum_flags |= - CSUM_IP_CHECKED | CSUM_IP_VALID; -#ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP) - m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; -#endif - error = netisr_queue(NETISR_IP, m); + if (PFIL_HOOKED(&V_inet_pfil_hook)) { + switch (ip_output_pfil(m, ifp, inp, dst, &fibnum, &error)) { + case 1: /* Finished */ goto done; - } else { + + case 0: /* Continue normally */ + ip = mtod(m, struct ip *); + break; + + case -1: /* Need to try again */ + /* Reset everything for a new round */ + RO_RTFREE(ro); if (have_ia_ref) ifa_free(&ia->ia_ifa); - needfiblookup = 1; /* Redo the routing table lookup. */ + ro->ro_lle = NULL; + rte = NULL; + gw = dst; + ip = mtod(m, struct ip *); + goto again; + } } - /* See if fib was changed by packet filter. */ - if (fibnum != M_GETFIB(m)) { - m->m_flags |= M_SKIP_FIREWALL; - fibnum = M_GETFIB(m); - RO_RTFREE(ro); - needfiblookup = 1; - } - if (needfiblookup) - goto again; - /* See if local, if yes, send it to netisr with IP_FASTFWD_OURS. */ - if (m->m_flags & M_FASTFWD_OURS) { - if (m->m_pkthdr.rcvif == NULL) - m->m_pkthdr.rcvif = V_loif; - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { - m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID | CSUM_PSEUDO_HDR; - m->m_pkthdr.csum_data = 0xffff; - } -#ifdef SCTP - if (m->m_pkthdr.csum_flags & CSUM_SCTP) - m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; -#endif - m->m_pkthdr.csum_flags |= - CSUM_IP_CHECKED | CSUM_IP_VALID; - - error = netisr_queue(NETISR_IP, m); - goto done; - } - /* Or forward to some other address? */ - if ((m->m_flags & M_IP_NEXTHOP) && - (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) { - bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in)); - m->m_flags |= M_SKIP_FIREWALL; - m->m_flags &= ~M_IP_NEXTHOP; - m_tag_delete(m, fwd_tag); - if (have_ia_ref) - ifa_free(&ia->ia_ifa); - goto again; - } - -passout: /* 127/8 must not appear on wire - RFC1122. */ if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) { From 2d83b16bd4943160895436ad7576260d73245dbd Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 18:33:11 +0000 Subject: [PATCH 059/314] Update OLD_FILES for tools provided by ELF Tool Chain or Binutils Sponsored by: The FreeBSD Foundation --- tools/build/mk/OptionalObsoleteFiles.inc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index bcee64f870cd..55631e73cc7b 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -186,7 +186,6 @@ OLD_FILES+=usr/bin/as OLD_FILES+=usr/bin/ld OLD_FILES+=usr/bin/objcopy OLD_FILES+=usr/bin/objdump -OLD_FILES+=usr/bin/readelf OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xbn OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xc @@ -204,7 +203,6 @@ OLD_FILES+=usr/share/man/man1/as.1.gz OLD_FILES+=usr/share/man/man1/ld.1.gz OLD_FILES+=usr/share/man/man1/objcopy.1.gz OLD_FILES+=usr/share/man/man1/objdump.1.gz -OLD_FILES+=usr/share/man/man1/readelf.1.gz OLD_FILES+=usr/share/man/man7/as.7.gz OLD_FILES+=usr/share/man/man7/ld.7.gz OLD_FILES+=usr/share/man/man7/ldint.7.gz @@ -1653,6 +1651,21 @@ OLD_FILES+=usr/bin/elfcopy OLD_FILES+=usr/share/man/man1/elfcopy.1.gz .endif +.if ${MK_ELFTOOLCHAIN_TOOLS} == no && ${MK_BINUTILS} == no +OLD_FILES+=usr/bin/addr2line +OLD_FILES+=usr/bin/nm +OLD_FILES+=usr/bin/readelf +OLD_FILES+=usr/bin/size +OLD_FILES+=usr/bin/strings +OLD_FILES+=usr/bin/strip +OLD_FILES+=usr/share/man/man1/addr2line.1.gz +OLD_FILES+=usr/share/man/man1/nm.1.gz +OLD_FILES+=usr/share/man/man1/readelf.1.gz +OLD_FILES+=usr/share/man/man1/size.1.gz +OLD_FILES+=usr/share/man/man1/strings.1.gz +OLD_FILES+=usr/share/man/man1/strip.1.gz +.endif + #.if ${MK_EXAMPLES} == no # to be filled in #.endif From 5ea9e83e2fd22c8a26b9acd2f32c0941bc12aa30 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 18:45:38 +0000 Subject: [PATCH 060/314] Allow ELF Tool Chain elfcopy to be installed as objcopy ELF Tool Chain elfcopy is nearly a drop-in replacement for GNU objcopy, but does not currently support PE output which is needed for building x86 UEFI bits. Add a src.conf knob to allow installing it as objcopy and set it by default for aarch64 only, where we don't have a native binutils. Reviewed by: bapt Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D2887 --- gnu/usr.bin/binutils/Makefile | 5 ++++- share/mk/src.opts.mk | 3 +++ tools/build/mk/OptionalObsoleteFiles.inc | 7 ++++++- tools/build/options/WITHOUT_ELFCOPY_AS_OBJCOPY | 4 ++++ tools/build/options/WITH_ELFCOPY_AS_OBJCOPY | 4 ++++ usr.bin/elfcopy/Makefile | 12 ++++++++++-- 6 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 tools/build/options/WITHOUT_ELFCOPY_AS_OBJCOPY create mode 100644 tools/build/options/WITH_ELFCOPY_AS_OBJCOPY diff --git a/gnu/usr.bin/binutils/Makefile b/gnu/usr.bin/binutils/Makefile index 1c863dfa7a33..d1241486b46d 100644 --- a/gnu/usr.bin/binutils/Makefile +++ b/gnu/usr.bin/binutils/Makefile @@ -11,7 +11,7 @@ SUBDIR= doc\ as \ ld \ ${_nm} \ - objcopy \ + ${_objcopy} \ objdump \ ${_readelf} \ ${_size} \ @@ -26,5 +26,8 @@ _size= size _strings= strings _strip= strip .endif +.if ${MK_ELFTOOLCHAIN_TOOLS} == "no" || ${MK_ELFCOPY_AS_OBJCOPY} == "no" +_objcopy= objcopy +.endif .include diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 3331f6f47966..fb2e1c20e24d 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -234,6 +234,9 @@ __DEFAULT_NO_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_FULL CLANG_IS_CC .endif .if ${__T} == "aarch64" BROKEN_OPTIONS+=BINUTILS BINUTILS_BOOTSTRAP GCC GCC_BOOTSTRAP GDB +__DEFAULT_YES_OPTIONS+=ELFCOPY_AS_OBJCOPY +.else +__DEFAULT_NO_OPTIONS+=ELFCOPY_AS_OBJCOPY .endif # LLVM lacks support for FreeBSD 64-bit atomic operations for ARMv4/ARMv5 .if ${__T} == "arm" || ${__T} == "armeb" diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 55631e73cc7b..48dbdf595a46 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -184,7 +184,9 @@ OLD_DIRS+=usr/share/examples/bhyve .if ${MK_BINUTILS} == no OLD_FILES+=usr/bin/as OLD_FILES+=usr/bin/ld +.if ${MK_ELFTOOLCHAIN_TOOLS} != no && ${MK_ELFCOPY_AS_OBJCOPY} == no OLD_FILES+=usr/bin/objcopy +.endif OLD_FILES+=usr/bin/objdump OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.x OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xbn @@ -201,7 +203,9 @@ OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xw OLD_FILES+=usr/share/man/man1/as.1.gz OLD_FILES+=usr/share/man/man1/ld.1.gz +.if ${MK_ELFTOOLCHAIN_TOOLS} != no && ${MK_ELFCOPY_AS_OBJCOPY} == no OLD_FILES+=usr/share/man/man1/objcopy.1.gz +.endif OLD_FILES+=usr/share/man/man1/objdump.1.gz OLD_FILES+=usr/share/man/man7/as.7.gz OLD_FILES+=usr/share/man/man7/ld.7.gz @@ -1646,7 +1650,8 @@ OLD_FILES+=usr/share/nls/ru_RU.KOI8-R/ee.cat OLD_FILES+=usr/share/nls/uk_UA.KOI8-U/ee.cat .endif -.if ${MK_ELFTOOLCHAIN_TOOLS} == no +.if ${MK_ELFTOOLCHAIN_TOOLS} == no || \ + (${MK_ELFTOOLCHAIN_TOOLS} != no && MK_ELFCOPY_AS_OBJCOPY != no) OLD_FILES+=usr/bin/elfcopy OLD_FILES+=usr/share/man/man1/elfcopy.1.gz .endif diff --git a/tools/build/options/WITHOUT_ELFCOPY_AS_OBJCOPY b/tools/build/options/WITHOUT_ELFCOPY_AS_OBJCOPY new file mode 100644 index 000000000000..f06a60692344 --- /dev/null +++ b/tools/build/options/WITHOUT_ELFCOPY_AS_OBJCOPY @@ -0,0 +1,4 @@ +.\" $FreeBSD$ +Set to build and install +.Xr objcopy 1 +from GNU Binutils, instead of the one from ELF Tool Chain. diff --git a/tools/build/options/WITH_ELFCOPY_AS_OBJCOPY b/tools/build/options/WITH_ELFCOPY_AS_OBJCOPY new file mode 100644 index 000000000000..eabaac375142 --- /dev/null +++ b/tools/build/options/WITH_ELFCOPY_AS_OBJCOPY @@ -0,0 +1,4 @@ +.\" $FreeBSD$ +Set to build and install ELF Tool Chain's elfcopy as +.Xr objcopy 1 , +instead of the one from GNU Binutils. diff --git a/usr.bin/elfcopy/Makefile b/usr.bin/elfcopy/Makefile index 8e7f31d2b9bd..dc6dd47be719 100644 --- a/usr.bin/elfcopy/Makefile +++ b/usr.bin/elfcopy/Makefile @@ -7,7 +7,15 @@ ELFCOPYDIR= ${ELFTCDIR}/elfcopy .PATH: ${ELFCOPYDIR} +.if ${MK_ELFCOPY_AS_OBJCOPY} != "no" +PROG= objcopy +objcopy.1: elfcopy.1 + sed -e 's/\.Dt ELFCOPY 1/.Dt OBJCOPY 1/' \ + -e 's/\.Nm elfcopy/.Nm objcopy/' < ${.ALLSRC} > ${.TARGET} +CLEANFILES+= objcopy.1 +.else PROG= elfcopy +.endif SRCS= archive.c ascii.c binary.c main.c sections.c segments.c symbols.c @@ -17,8 +25,8 @@ LIBADD= archive elftc elf CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common -MAN= elfcopy.1 strip.1 +MAN= ${PROG}.1 strip.1 -LINKS= ${BINDIR}/elfcopy ${BINDIR}/strip +LINKS= ${BINDIR}/${PROG} ${BINDIR}/strip .include From 5be09b1082553692a86bb017231abbe8033f4356 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 18:55:51 +0000 Subject: [PATCH 061/314] Regenerate src.conf(5) after r286016 and r286030 --- share/man/man5/src.conf.5 | 70 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 90885e76a6af..e236ce27955b 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,7 +1,7 @@ .\" DO NOT EDIT-- this file is automatically generated. -.\" from FreeBSD: head/tools/build/options/makeman 255964 2013-10-01 07:22:04Z des +.\" from FreeBSD: head/tools/build/options/makeman 284708 2015-06-22 20:21:57Z sjg .\" $FreeBSD$ -.Dd June 22, 2015 +.Dd July 29, 2015 .Dt SRC.CONF 5 .Os .Sh NAME @@ -127,7 +127,7 @@ Set to not build .Xr autofs 4 related programs, libraries, and kernel modules. .It Va WITH_AUTO_OBJ -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_AUTO_OBJ 284708 2015-06-22 20:21:57Z sjg Enable automatic creation of objdirs. .It Va WITHOUT_BHYVE .\" from FreeBSD: head/tools/build/options/WITHOUT_BHYVE 277727 2015-01-26 06:44:48Z ngie @@ -142,6 +142,9 @@ Set to not build or install binutils (as, c++-filt, gconv, ld, nm, objcopy, objdump, readelf, size and strip) as part of the normal system build. The resulting system cannot build programs from source. +.Pp +It is a default setting on +arm64/aarch64. .It Va WITHOUT_BINUTILS_BOOTSTRAP .\" from FreeBSD: head/tools/build/options/WITHOUT_BINUTILS_BOOTSTRAP 264660 2014-04-18 17:03:58Z imp Set to not build binutils (as, c++-filt, gconv, @@ -151,6 +154,9 @@ as part of the bootstrap process. The option does not work for build targets unless some alternative toolchain is provided. .Ef +.Pp +It is a default setting on +arm64/aarch64. .It Va WITHOUT_BLUETOOTH .\" from FreeBSD: head/tools/build/options/WITHOUT_BLUETOOTH 156932 2006-03-21 07:50:50Z ru Set to not build Bluetooth related kernel modules, programs and libraries. @@ -243,7 +249,7 @@ When set, it also enforces the following options: Set to build the Clang C/C++ compiler during the normal phase of the build. .Pp It is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386, pc98/i386, powerpc/powerpc and powerpc/powerpc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, arm64/aarch64, i386/i386, pc98/i386, powerpc/powerpc and powerpc/powerpc64. .It Va WITHOUT_CLANG_BOOTSTRAP .\" from FreeBSD: head/tools/build/options/WITHOUT_CLANG_BOOTSTRAP 273177 2014-10-16 18:28:11Z skreuzer Set to not build the Clang C/C++ compiler during the bootstrap phase of the build. @@ -258,7 +264,7 @@ mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, powerpc/powerp Set to build the Clang C/C++ compiler during the bootstrap phase of the build. .Pp It is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386 and pc98/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, arm64/aarch64, i386/i386 and pc98/i386. .It Va WITH_CLANG_EXTRAS .\" from FreeBSD: head/tools/build/options/WITH_CLANG_EXTRAS 231057 2012-02-05 23:56:22Z dim Set to build additional clang and llvm tools, such as bugpoint. @@ -275,7 +281,7 @@ Set to build the ARCMigrate, Rewriter and StaticAnalyzer components of the Clang C/C++ compiler. .Pp It is a default setting on -amd64/amd64, i386/i386, pc98/i386, powerpc/powerpc and powerpc/powerpc64. +amd64/amd64, arm64/aarch64, i386/i386, pc98/i386, powerpc/powerpc and powerpc/powerpc64. .It Va WITHOUT_CLANG_IS_CC .\" from FreeBSD: head/tools/build/options/WITHOUT_CLANG_IS_CC 242629 2012-11-05 21:53:23Z brooks Set to install the GCC compiler as @@ -295,7 +301,7 @@ and .Pa /usr/bin/cpp . .Pp It is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386 and pc98/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, arm64/aarch64, i386/i386 and pc98/i386. .It Va WITHOUT_CPP .\" from FreeBSD: head/tools/build/options/WITHOUT_CPP 156932 2006-03-21 07:50:50Z ru Set to not build @@ -396,7 +402,7 @@ and are located automatically by .\" from FreeBSD: head/tools/build/options/WITHOUT_DICT 156932 2006-03-21 07:50:50Z ru Set to not build the Webster dictionary files. .It Va WITH_DIRDEPS_CACHE -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_DIRDEPS_CACHE 284708 2015-06-22 20:21:57Z sjg Cache result of dirdeps.mk which can save significant time for subsequent builds. Depends on @@ -429,11 +435,29 @@ and related programs. .It Va WITH_EISA .\" from FreeBSD: head/tools/build/options/WITH_EISA 264654 2014-04-18 16:53:06Z imp Set to build EISA kernel modules. +.It Va WITHOUT_ELFCOPY_AS_OBJCOPY +.\" from FreeBSD: head/tools/build/options/WITHOUT_ELFCOPY_AS_OBJCOPY 286030 2015-07-29 18:45:38Z emaste +Set to build and install +.Xr objcopy 1 +from GNU Binutils, instead of the one from ELF Tool Chain. +.Pp +It is a default setting on +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, pc98/i386, powerpc/powerpc, powerpc/powerpc64 and sparc64/sparc64. +.It Va WITH_ELFCOPY_AS_OBJCOPY +.\" from FreeBSD: head/tools/build/options/WITH_ELFCOPY_AS_OBJCOPY 286030 2015-07-29 18:45:38Z emaste +Set to build and install ELF Tool Chain's elfcopy as +.Xr objcopy 1 , +instead of the one from GNU Binutils. +.Pp +It is a default setting on +arm64/aarch64. .It Va WITHOUT_ELFTOOLCHAIN_TOOLS -.\" from FreeBSD: head/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS 276796 2015-01-07 22:02:37Z emaste +.\" from FreeBSD: head/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS 286016 2015-07-29 15:42:22Z emaste Set to use .Xr addr2line 1 , +.Xr c++filt 1 , .Xr nm 1 , +.Xr readelf 1 , .Xr size 1 , .Xr strings 1 , and @@ -462,11 +486,6 @@ and .\" from FreeBSD: head/tools/build/options/WITHOUT_FLOPPY 221540 2011-05-06 19:13:03Z ru Set to not build or install programs for operating floppy disk driver. -.It Va WITH_FMAKE -.\" from FreeBSD: head/tools/build/options/WITH_FMAKE 275138 2014-11-26 20:43:09Z gjb -Causes the old FreeBSD -.Xr make 1 -program to be built and installed as fmake. .It Va WITHOUT_FMTREE .\" from FreeBSD: head/tools/build/options/WITHOUT_FMTREE 261299 2014-01-30 21:37:43Z brooks Set to not build and install @@ -503,7 +522,7 @@ Set to not build games. Set to not build and install gcc and g++ as part of the normal build process. .Pp It is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386 and pc98/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, arm64/aarch64, i386/i386 and pc98/i386. .It Va WITH_GCC .\" from FreeBSD: head/tools/build/options/WITH_GCC 255326 2013-09-06 20:49:48Z zeising Set to build and install gcc and g++. @@ -518,7 +537,7 @@ unless an alternative compiler is provided via XCC. .Pp It is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386 and pc98/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, arm64/aarch64, i386/i386 and pc98/i386. .It Va WITH_GCC_BOOTSTRAP .\" from FreeBSD: head/tools/build/options/WITH_GCC_BOOTSTRAP 264660 2014-04-18 17:03:58Z imp Set to build gcc and g++ as part of the bootstrap process. @@ -534,6 +553,9 @@ tool. .\" from FreeBSD: head/tools/build/options/WITHOUT_GDB 156932 2006-03-21 07:50:50Z ru Set to not build .Xr gdb 1 . +.Pp +It is a default setting on +arm64/aarch64. .It Va WITHOUT_GNU .\" from FreeBSD: head/tools/build/options/WITHOUT_GNU 174550 2007-12-12 16:43:17Z ru Set to not build contributed GNU software as a part of the base system. @@ -554,7 +576,7 @@ Do not build the GNU C++ stack (g++, libstdc++). This is the default on platforms where clang is the system compiler. .Pp It is a default setting on -amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386 and pc98/i386. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, arm64/aarch64, i386/i386 and pc98/i386. .It Va WITH_GNUCXX .\" from FreeBSD: head/tools/build/options/WITH_GNUCXX 255321 2013-09-06 20:08:03Z theraven Build the GNU C++ stack (g++, libstdc++). @@ -861,11 +883,11 @@ Set to not build utilities for manual pages, .Xr manctl 8 , and related support files. .It Va WITH_META_FILES -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_META_FILES 284708 2015-06-22 20:21:57Z sjg Create meta files during non META_MODE build. The meta files can be useful for debugging. .It Va WITH_META_MODE -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_META_MODE 284708 2015-06-22 20:21:57Z sjg Enable building in meta mode. .Pp The build is driven by dirdeps.mk using DIRDEPS stored in @@ -1153,7 +1175,7 @@ Set to not build kernel modules that include sourceless microcode. .\" from FreeBSD: head/tools/build/options/WITHOUT_SSP 180012 2008-06-25 21:33:28Z ru Set to not build world with propolice stack smashing protection. .It Va WITH_STAGING -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_STAGING 284708 2015-06-22 20:21:57Z sjg Enable staging of files to a stage tree. This can be best thought of as auto-install to .Va DESTDIR @@ -1173,13 +1195,13 @@ is set explicitly) is set explicitly) .El .It Va WITH_STAGING_MAN -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_STAGING_MAN 284708 2015-06-22 20:21:57Z sjg Enable staging of MAN pages to stage tree. .It Va WITH_STAGING_PROG -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_STAGING_PROG 284708 2015-06-22 20:21:57Z sjg Enable staging of PROGs to stage tree. .It Va WITH_STALE_STAGED -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_STALE_STAGED 284708 2015-06-22 20:21:57Z sjg Check staged files are not stale. .It Va WITH_SVN .\" from FreeBSD: head/tools/build/options/WITH_SVN 252561 2013-07-03 12:36:47Z zeising @@ -1206,7 +1228,7 @@ Set to not build .Xr sysinstall 8 and related programs. .It Va WITH_SYSROOT -.\" $FreeBSD$ +.\" from FreeBSD: head/tools/build/options/WITH_SYSROOT 284708 2015-06-22 20:21:57Z sjg Enable use of sysroot during build. Depends on .Va WITH_META_MODE . From 6974dd6f4bdee418d58754a0d8b0f3261c2583b2 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 19:06:53 +0000 Subject: [PATCH 062/314] Use default CLANG build options for ARM We previously disabled CLANG_FULL on (little-endian) ARM because the build failed. This is no longer the case and as of Clang 3.5 we cannot build any part of the in-tree Clang with in-tree GCC, so it's no longer necessary to disable CLANG_FULL. Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D2525 --- share/mk/src.opts.mk | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index fb2e1c20e24d..48c51fa575da 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -214,15 +214,11 @@ __TT=${MACHINE} # If the compiler is not C++11 capable, disable clang and use gcc instead. __DEFAULT_YES_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX __DEFAULT_NO_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_FULL CLANG_IS_CC -.elif ${__T} == "aarch64" || ${__T} == "amd64" || ${__T} == "i386" -# On x86 and arm64, clang is enabled, and will be installed as the default cc. +.elif ${__T} == "aarch64" || ${__T} == "amd64" || ${__TT} == "arm" || \ + ${__T} == "i386" +# On x86 and arm, clang is enabled, and will be installed as the default cc. __DEFAULT_YES_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_FULL CLANG_IS_CC __DEFAULT_NO_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX -.elif ${__TT} == "arm" -# On arm, clang is enabled, and it is installed as the default cc, but -# since gcc is unable to build the full clang, disable it by default. -__DEFAULT_YES_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_IS_CC -__DEFAULT_NO_OPTIONS+=CLANG_FULL GCC GCC_BOOTSTRAP GNUCXX .elif ${__T:Mpowerpc*} # On powerpc, clang is enabled, but gcc is installed as the default cc. __DEFAULT_YES_OPTIONS+=CLANG CLANG_FULL GCC GCC_BOOTSTRAP GNUCXX From c67acb750885dce4e47cdff3f110fd79f491254c Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 20:02:20 +0000 Subject: [PATCH 063/314] Remove mention of non-existent gconv tool I believe this is a typo of gcov, but gcov is not controlled by WITHOUT_BINUTILS anyhow. Sponsored by: The FreeBSD Foundation --- tools/build/options/WITHOUT_BINUTILS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build/options/WITHOUT_BINUTILS b/tools/build/options/WITHOUT_BINUTILS index dd95162591e5..014f4b3a8620 100644 --- a/tools/build/options/WITHOUT_BINUTILS +++ b/tools/build/options/WITHOUT_BINUTILS @@ -1,5 +1,5 @@ .\" $FreeBSD$ -Set to not build or install binutils (as, c++-filt, gconv, +Set to not build or install binutils (as, c++-filt, ld, nm, objcopy, objdump, readelf, size and strip) as part of the normal system build. The resulting system cannot build programs from source. From 3c40232395dbe672151c48bf8c907ef250db35b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ermal=20Lu=C3=A7i?= Date: Wed, 29 Jul 2015 20:10:36 +0000 Subject: [PATCH 064/314] Avoid double reference decrement when firewalls force relooping of packets When firewalls force a reloop of packets and the caller supplied a route the reference to the route might be reduced twice creating issues. This is especially the scenario when a packet is looped because of operation in the firewall but the new route lookup gives a down route. Differential Revision: https://reviews.freebsd.org/D3037 Reviewed by: gnn Approved by: gnn(mentor) --- sys/netinet/ip_output.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index d36548aa7e66..079077745e13 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -681,6 +681,13 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, done: if (ro == &iproute) RO_RTFREE(ro); + else if (rte == NULL) + /* + * If the caller supplied a route but somehow the reference + * to it has been released need to prevent the caller + * calling RTFREE on it again. + */ + ro->ro_rt = NULL; if (have_ia_ref) ifa_free(&ia->ia_ifa); return (error); From 79855a57e2a5e1ca5c9767ec3bd53f0c0e3d9116 Mon Sep 17 00:00:00 2001 From: Sean Bruno Date: Wed, 29 Jul 2015 20:47:27 +0000 Subject: [PATCH 065/314] Remove dead functions pmap_pvdump and pads. Differential Revision: D3206 Submitted by: kevin.bowling@kev009.com Reviewed by: alc --- sys/arm/arm/pmap-v6-new.c | 57 --------------------------------------- sys/i386/i386/pmap.c | 48 --------------------------------- sys/mips/mips/pmap.c | 50 ---------------------------------- 3 files changed, 155 deletions(-) diff --git a/sys/arm/arm/pmap-v6-new.c b/sys/arm/arm/pmap-v6-new.c index 13a97dea5186..1549cc1e1851 100644 --- a/sys/arm/arm/pmap-v6-new.c +++ b/sys/arm/arm/pmap-v6-new.c @@ -162,7 +162,6 @@ __FBSDID("$FreeBSD$"); static void pmap_zero_page_check(vm_page_t m); void pmap_debug(int level); int pmap_pid_dump(int pid); -void pmap_pvdump(vm_paddr_t pa); #define PDEBUG(_lev_,_stat_) \ if (pmap_debug_level >= (_lev_)) \ @@ -6345,62 +6344,6 @@ pmap_pid_dump(int pid) return (npte2); } -/* - * Print address space of pmap. - */ -static void -pads(pmap_t pmap) -{ - int i, j; - vm_paddr_t va; - pt1_entry_t pte1; - pt2_entry_t *pte2p, pte2; - - if (pmap == kernel_pmap) - return; - for (i = 0; i < NPTE1_IN_PT1; i++) { - pte1 = pte1_load(&pmap->pm_pt1[i]); - if (pte1_is_section(pte1)) { - /* - * QQQ: Do something here! - */ - } else if (pte1_is_link(pte1)) { - for (j = 0; j < NPTE2_IN_PT2; j++) { - va = (i << PTE1_SHIFT) + (j << PAGE_SHIFT); - if (pmap == kernel_pmap && va < KERNBASE) - continue; - if (pmap != kernel_pmap && va >= KERNBASE && - (va < UPT2V_MIN_ADDRESS || - va >= UPT2V_MAX_ADDRESS)) - continue; - - pte2p = pmap_pte2(pmap, va); - pte2 = pte2_load(pte2p); - pmap_pte2_release(pte2p); - if (!pte2_is_valid(pte2)) - continue; - printf("%x:%x ", va, pte2); - } - } - } -} - -void -pmap_pvdump(vm_paddr_t pa) -{ - pv_entry_t pv; - pmap_t pmap; - vm_page_t m; - - printf("pa %x", pa); - m = PHYS_TO_VM_PAGE(pa); - TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { - pmap = PV_PMAP(pv); - printf(" -> pmap %p, va %x", (void *)pmap, pv->pv_va); - pads(pmap); - } - printf(" "); -} #endif #ifdef DDB diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index a642d10088f7..b02311eae8cb 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -5461,51 +5461,3 @@ pmap_pid_dump(int pid) return (npte); } #endif - -#if defined(DEBUG) - -static void pads(pmap_t pm); -void pmap_pvdump(vm_paddr_t pa); - -/* print address space of pmap*/ -static void -pads(pmap_t pm) -{ - int i, j; - vm_paddr_t va; - pt_entry_t *ptep; - - if (pm == kernel_pmap) - return; - for (i = 0; i < NPDEPTD; i++) - if (pm->pm_pdir[i]) - for (j = 0; j < NPTEPG; j++) { - va = (i << PDRSHIFT) + (j << PAGE_SHIFT); - if (pm == kernel_pmap && va < KERNBASE) - continue; - if (pm != kernel_pmap && va > UPT_MAX_ADDRESS) - continue; - ptep = pmap_pte(pm, va); - if (pmap_pte_v(ptep)) - printf("%x:%x ", va, *ptep); - }; - -} - -void -pmap_pvdump(vm_paddr_t pa) -{ - pv_entry_t pv; - pmap_t pmap; - vm_page_t m; - - printf("pa %x", pa); - m = PHYS_TO_VM_PAGE(pa); - TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { - pmap = PV_PMAP(pv); - printf(" -> pmap %p, va %x", (void *)pmap, pv->pv_va); - pads(pmap); - } - printf(" "); -} -#endif diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 7ab4244d9685..50b57d22329d 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -3294,56 +3294,6 @@ DB_SHOW_COMMAND(ptable, ddb_pid_dump) } #endif -#if defined(DEBUG) - -static void pads(pmap_t pm); -void pmap_pvdump(vm_offset_t pa); - -/* print address space of pmap*/ -static void -pads(pmap_t pm) -{ - unsigned va, i, j; - pt_entry_t *ptep; - - if (pm == kernel_pmap) - return; - for (i = 0; i < NPTEPG; i++) - if (pm->pm_segtab[i]) - for (j = 0; j < NPTEPG; j++) { - va = (i << SEGSHIFT) + (j << PAGE_SHIFT); - if (pm == kernel_pmap && va < KERNBASE) - continue; - if (pm != kernel_pmap && - va >= VM_MAXUSER_ADDRESS) - continue; - ptep = pmap_pte(pm, va); - if (pte_test(ptep, PTE_V)) - printf("%x:%x ", va, *(int *)ptep); - } - -} - -void -pmap_pvdump(vm_offset_t pa) -{ - register pv_entry_t pv; - vm_page_t m; - - printf("pa %x", pa); - m = PHYS_TO_VM_PAGE(pa); - for (pv = TAILQ_FIRST(&m->md.pv_list); pv; - pv = TAILQ_NEXT(pv, pv_list)) { - printf(" -> pmap %p, va %x", (void *)pv->pv_pmap, pv->pv_va); - pads(pv->pv_pmap); - } - printf(" "); -} - -/* N/C */ -#endif - - /* * Allocate TLB address space tag (called ASID or TLBPID) and return it. * It takes almost as much or more time to search the TLB for a From e0fe6b48352d5c67b5f933946b2c3cdd9085bba5 Mon Sep 17 00:00:00 2001 From: Sean Bruno Date: Wed, 29 Jul 2015 20:50:48 +0000 Subject: [PATCH 066/314] Add support for BCM5466 PHY Differential Revision: D3232 Submitted by: kevin.bowling@kev009.com --- sys/dev/mii/brgphy.c | 1 + sys/dev/mii/miidevs | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c index 32914a386484..373b7097eaf4 100644 --- a/sys/dev/mii/brgphy.c +++ b/sys/dev/mii/brgphy.c @@ -131,6 +131,7 @@ static const struct mii_phydesc brgphys[] = { MII_PHY_DESC(BROADCOM, BCM5752), MII_PHY_DESC(BROADCOM, BCM5780), MII_PHY_DESC(BROADCOM, BCM5708C), + MII_PHY_DESC(BROADCOM, BCM5466), MII_PHY_DESC(BROADCOM2, BCM5482), MII_PHY_DESC(BROADCOM2, BCM5708S), MII_PHY_DESC(BROADCOM2, BCM5709C), diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs index 2d3a5bef613e..04452f2fbe8a 100644 --- a/sys/dev/mii/miidevs +++ b/sys/dev/mii/miidevs @@ -170,6 +170,7 @@ model BROADCOM BCM54K2 0x002e BCM54K2 1000BASE-T media interface model BROADCOM BCM5714 0x0034 BCM5714 1000BASE-T media interface model BROADCOM BCM5780 0x0035 BCM5780 1000BASE-T media interface model BROADCOM BCM5708C 0x0036 BCM5708C 1000BASE-T media interface +model BROADCOM BCM5466 0x003b BCM5466 1000BASE-T media interface model BROADCOM2 BCM5325 0x0003 BCM5325 10/100 5-port PHY switch model BROADCOM2 BCM5906 0x0004 BCM5906 10/100baseTX media interface model BROADCOM2 BCM5481 0x000a BCM5481 1000BASE-T media interface From 9c80b8aa0f7d20ac97957bb40f3de1486f7aac29 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 29 Jul 2015 21:15:50 +0000 Subject: [PATCH 067/314] Clarify historical practice of not removing old entries. Add entry for stable/10 branch that was forgotten when it was created. Update end date to be correct. --- UPDATING | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/UPDATING b/UPDATING index ce3b74a354a6..d032144b4e25 100644 --- a/UPDATING +++ b/UPDATING @@ -577,6 +577,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: or # pkg install pkg; ldd /usr/local/sbin/pkg | grep bsdyml +20131010: + The stable/10 branch has been created in subversion from head + revision r256279. + 20131010: The rc.d/jail script has been updated to support jail(8) configuration file. The "jail__*" rc.conf(5) variables @@ -1120,6 +1124,13 @@ COMMON ITEMS: around can lead to problems if pam has changed too much from your starting point to allow continued authentication after the upgrade. + This file should be read as a log of events. When a later event changes + information of a prior event, the prior event should not be deleted. + Instead, a pointer to the entry with the new information should be + placed in the old entry. Readers of this file should also sanity check + older entries before relying on them blindly. Authors of new entries + should write them with this in mind. + ZFS notes --------- When upgrading the boot ZFS pool to a new version, always follow @@ -1290,7 +1301,7 @@ FORMAT: This file contains a list, in reverse chronological order, of major breakages in tracking -current. It is not guaranteed to be a complete -list of such breakages, and only contains entries since October 10, 2007. +list of such breakages, and only contains entries since September 23, 2011. If you need to see UPDATING entries from before that date, you will need to fetch an UPDATING file from an older FreeBSD release. From 0e1fd2dda37b48356f49e0486b350adc987ccf20 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Wed, 29 Jul 2015 21:29:50 +0000 Subject: [PATCH 068/314] nvme: do not notify a consumer about failures that occur during initialization MFC after: 3 days Sponsored by: Intel --- sys/dev/nvme/nvme.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/dev/nvme/nvme.c b/sys/dev/nvme/nvme.c index 329c5e56e82d..cc14d34afbc4 100644 --- a/sys/dev/nvme/nvme.c +++ b/sys/dev/nvme/nvme.c @@ -390,6 +390,15 @@ nvme_notify_fail_consumers(struct nvme_controller *ctrlr) struct nvme_consumer *cons; uint32_t i; + /* + * This controller failed during initialization (i.e. IDENTIFY + * command failed or timed out). Do not notify any nvme + * consumers of the failure here, since the consumer does not + * even know about the controller yet. + */ + if (!ctrlr->is_initialized) + return; + for (i = 0; i < NVME_MAX_CONSUMERS; i++) { cons = &nvme_consumer[i]; if (cons->id != INVALID_CONSUMER_ID && cons->fail_fn != NULL) From b43cca137bde684208a3a403440ffa8e182825dd Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 29 Jul 2015 21:41:15 +0000 Subject: [PATCH 069/314] MK_ELFCOPY_AS_OBJCOPY should be a variable PR: 201978 Submitted by: O. Hartmann Differential Revision: https://reviews.freebsd.org/D2887 --- tools/build/mk/OptionalObsoleteFiles.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 48dbdf595a46..cc0ccf67cf3e 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1651,7 +1651,7 @@ OLD_FILES+=usr/share/nls/uk_UA.KOI8-U/ee.cat .endif .if ${MK_ELFTOOLCHAIN_TOOLS} == no || \ - (${MK_ELFTOOLCHAIN_TOOLS} != no && MK_ELFCOPY_AS_OBJCOPY != no) + (${MK_ELFTOOLCHAIN_TOOLS} != no && ${MK_ELFCOPY_AS_OBJCOPY} != no) OLD_FILES+=usr/bin/elfcopy OLD_FILES+=usr/share/man/man1/elfcopy.1.gz .endif From c308ef6fd2bebab6e032c560c7ea3d95313fbab1 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 29 Jul 2015 22:51:54 +0000 Subject: [PATCH 070/314] Actually set the proper license Reported by: trasz --- usr.sbin/pw/strtounum.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/usr.sbin/pw/strtounum.c b/usr.sbin/pw/strtounum.c index 968779539c27..b3944865346c 100644 --- a/usr.sbin/pw/strtounum.c +++ b/usr.sbin/pw/strtounum.c @@ -1,26 +1,27 @@ /*- * Copyright (C) Baptiste Daroussin + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. * 2. 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. * - * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT 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 DAVID L. NUGENT 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. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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 From 25f37276e54c50d2cf477eddcd3bb6d23c1b0708 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 29 Jul 2015 23:06:30 +0000 Subject: [PATCH 071/314] This patch fixes a problem where, if the NFSv4 server has a previous unconfirmed clientid structure for the same client on the last hash list, this old entry would not be removed/deleted. I do not think this bug would have caused serious problems, since the new entry would have been before the old one on the list. This old entry would have eventually been scavenged/removed. Detected while reading the code looking for another bug. MFC after: 3 days --- sys/fs/nfsserver/nfs_nfsdstate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 15f5243717cf..d1ade4aaf153 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -220,7 +220,8 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, break; } } - i++; + if (gotit == 0) + i++; } if (!gotit || (clp->lc_flags & (LCL_NEEDSCONFIRM | LCL_ADMINREVOKED))) { From 796ba6fcc2bb4305a6faa0029da6f413293b4d9c Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 29 Jul 2015 23:26:14 +0000 Subject: [PATCH 072/314] Cleanup includes --- usr.sbin/pw/rm_r.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/usr.sbin/pw/rm_r.c b/usr.sbin/pw/rm_r.c index 65a63e6e0cbe..172c7b02e1db 100644 --- a/usr.sbin/pw/rm_r.c +++ b/usr.sbin/pw/rm_r.c @@ -29,15 +29,12 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include -#include -#include -#include #include -#include -#include + #include #include +#include +#include #include "pwupd.h" From e381fd293d6d0424a73fc828f56cb82abdd991c1 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Wed, 29 Jul 2015 23:37:15 +0000 Subject: [PATCH 073/314] const'ify an arg that we don't update... --- sys/crypto/aesni/aesni.h | 2 +- sys/crypto/aesni/aesni_ghash.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/crypto/aesni/aesni.h b/sys/crypto/aesni/aesni.h index 0594176a4522..3d5adec79eed 100644 --- a/sys/crypto/aesni/aesni.h +++ b/sys/crypto/aesni/aesni.h @@ -104,7 +104,7 @@ void AES_GCM_encrypt(const unsigned char *in, unsigned char *out, const unsigned char *key, int nr); int AES_GCM_decrypt(const unsigned char *in, unsigned char *out, const unsigned char *addt, const unsigned char *ivec, - unsigned char *tag, uint32_t nbytes, uint32_t abytes, int ibytes, + const unsigned char *tag, uint32_t nbytes, uint32_t abytes, int ibytes, const unsigned char *key, int nr); int aesni_cipher_setup_common(struct aesni_session *ses, const uint8_t *key, diff --git a/sys/crypto/aesni/aesni_ghash.c b/sys/crypto/aesni/aesni_ghash.c index f7be6c089754..54c8815ce01f 100644 --- a/sys/crypto/aesni/aesni_ghash.c +++ b/sys/crypto/aesni/aesni_ghash.c @@ -528,7 +528,7 @@ AES_GCM_encrypt(const unsigned char *in, unsigned char *out, int AES_GCM_decrypt(const unsigned char *in, unsigned char *out, const unsigned char *addt, const unsigned char *ivec, - unsigned char *tag, uint32_t nbytes, uint32_t abytes, int ibytes, + const unsigned char *tag, uint32_t nbytes, uint32_t abytes, int ibytes, const unsigned char *key, int nr) { int i, j ,k; @@ -677,7 +677,7 @@ AES_GCM_decrypt(const unsigned char *in, unsigned char *out, X = _mm_shuffle_epi8(X, BSWAP_MASK); T = _mm_xor_si128(X, T); - if (!m128icmp(T, _mm_loadu_si128((__m128i*)tag))) + if (!m128icmp(T, _mm_loadu_si128((const __m128i*)tag))) return 0; //in case the authentication failed ctr1 = _mm_shuffle_epi8(Y, BSWAP_EPI64); From dd5b64258f6d85a771ac71e215d8490bf80a2044 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 29 Jul 2015 23:59:17 +0000 Subject: [PATCH 074/314] MFamd64 r285934: Remove store/load (= full) barrier from the i386 atomic_load_acq_*(). Noted by: alc (long time ago) Reviewed by: alc, bde Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/i386/include/atomic.h | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h index adc86cac623a..35919666c35c 100644 --- a/sys/i386/include/atomic.h +++ b/sys/i386/include/atomic.h @@ -233,13 +233,13 @@ atomic_testandset_int(volatile u_int *p, u_int v) * IA32 memory model, a simple store guarantees release semantics. * * However, a load may pass a store if they are performed on distinct - * addresses, so for atomic_load_acq we introduce a Store/Load barrier - * before the load in SMP kernels. We use "lock addl $0,mem", as - * recommended by the AMD Software Optimization Guide, and not mfence. - * In the kernel, we use a private per-cpu cache line as the target - * for the locked addition, to avoid introducing false data - * dependencies. In userspace, a word at the top of the stack is - * utilized. + * addresses, so we need Store/Load barrier for sequentially + * consistent fences in SMP kernels. We use "lock addl $0,mem" for a + * Store/Load barrier, as recommended by the AMD Software Optimization + * Guide, and not mfence. In the kernel, we use a private per-cpu + * cache line as the target for the locked addition, to avoid + * introducing false data dependencies. In userspace, a word at the + * top of the stack is utilized. * * For UP kernels, however, the memory of the single processor is * always consistent, so we only need to stop the compiler from @@ -282,22 +282,12 @@ __storeload_barrier(void) } #endif /* _KERNEL*/ -/* - * C11-standard acq/rel semantics only apply when the variable in the - * call is the same for acq as it is for rel. However, our previous - * (x86) implementations provided much stronger ordering than required - * (essentially what is called seq_cst order in C11). This - * implementation provides the historical strong ordering since some - * callers depend on it. - */ - #define ATOMIC_LOAD(TYPE) \ static __inline u_##TYPE \ atomic_load_acq_##TYPE(volatile u_##TYPE *p) \ { \ u_##TYPE res; \ \ - __storeload_barrier(); \ res = *p; \ __compiler_membar(); \ return (res); \ From 48cae112b516ce625d38f22fdc07a29d509de845 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 30 Jul 2015 00:13:20 +0000 Subject: [PATCH 075/314] Use private cache line for the locked nop in *mb() on i386. Suggested by: alc Reviewed by: alc, bde Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/i386/i386/vm_machdep.c | 4 +-- sys/i386/include/atomic.h | 71 +++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index f67b279e4393..62e99aa7f2c9 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -111,8 +111,8 @@ _Static_assert(OFFSETOF_CURTHREAD == offsetof(struct pcpu, pc_curthread), "OFFSETOF_CURTHREAD does not correspond with offset of pc_curthread."); _Static_assert(OFFSETOF_CURPCB == offsetof(struct pcpu, pc_curpcb), "OFFSETOF_CURPCB does not correspond with offset of pc_curpcb."); -_Static_assert(OFFSETOF_MONITORBUF == offsetof(struct pcpu, pc_monitorbuf), - "OFFSETOF_MONINORBUF does not correspond with offset of pc_monitorbuf."); +_Static_assert(__OFFSETOF_MONITORBUF == offsetof(struct pcpu, pc_monitorbuf), + "__OFFSETOF_MONINORBUF does not correspond with offset of pc_monitorbuf."); static void cpu_reset_real(void); #ifdef SMP diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h index 35919666c35c..15742a51d2a9 100644 --- a/sys/i386/include/atomic.h +++ b/sys/i386/include/atomic.h @@ -37,9 +37,31 @@ #include #endif -#define mb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc") -#define wmb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc") -#define rmb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc") +#ifndef __OFFSETOF_MONITORBUF +/* + * __OFFSETOF_MONITORBUF == __pcpu_offset(pc_monitorbuf). + * + * The open-coded number is used instead of the symbolic expression to + * avoid a dependency on sys/pcpu.h in machine/atomic.h consumers. + * An assertion in i386/vm_machdep.c ensures that the value is correct. + */ +#define __OFFSETOF_MONITORBUF 0x180 + +static __inline void +__mbk(void) +{ + + __asm __volatile("lock; addl $0,%%fs:%0" + : "+m" (*(u_int *)__OFFSETOF_MONITORBUF) : : "memory", "cc"); +} + +static __inline void +__mbu(void) +{ + + __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc"); +} +#endif /* * Various simple operations on memory, each of which is atomic in the @@ -246,40 +268,15 @@ atomic_testandset_int(volatile u_int *p, u_int v) * reordering accesses in a way that violates the semantics of acquire * and release. */ + #if defined(_KERNEL) - -/* - * OFFSETOF_MONITORBUF == __pcpu_offset(pc_monitorbuf). - * - * The open-coded number is used instead of the symbolic expression to - * avoid a dependency on sys/pcpu.h in machine/atomic.h consumers. - * An assertion in i386/vm_machdep.c ensures that the value is correct. - */ -#define OFFSETOF_MONITORBUF 0x180 - #if defined(SMP) -static __inline void -__storeload_barrier(void) -{ - - __asm __volatile("lock; addl $0,%%fs:%0" - : "+m" (*(u_int *)OFFSETOF_MONITORBUF) : : "memory", "cc"); -} +#define __storeload_barrier() __mbk() #else /* _KERNEL && UP */ -static __inline void -__storeload_barrier(void) -{ - - __compiler_membar(); -} +#define __storeload_barrier() __compiler_membar() #endif /* SMP */ #else /* !_KERNEL */ -static __inline void -__storeload_barrier(void) -{ - - __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc"); -} +#define __storeload_barrier() __mbu() #endif /* _KERNEL*/ #define ATOMIC_LOAD(TYPE) \ @@ -776,4 +773,14 @@ u_long atomic_swap_long(volatile u_long *p, u_long v); #endif /* !WANT_FUNCTIONS */ +#if defined(_KERNEL) +#define mb() __mbk() +#define wmb() __mbk() +#define rmb() __mbk() +#else +#define mb() __mbu() +#define wmb() __mbu() +#define rmb() __mbu() +#endif + #endif /* !_MACHINE_ATOMIC_H_ */ From 8b15f615e03e05781e90e8def1cb585a43b16664 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Thu, 30 Jul 2015 02:09:03 +0000 Subject: [PATCH 076/314] Follow r256586 and rename the kernel version of the Free() macro to R_Free(). This matches the other macros and reduces the chances to clash with other headers. This also fixes the build of radix.c outside of the kernel environment. Reviewed by: glebius --- sys/net/radix.c | 10 +++++----- sys/net/radix.h | 2 +- sys/net/route.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sys/net/radix.c b/sys/net/radix.c index d16c92490729..d6db35ea3a94 100644 --- a/sys/net/radix.c +++ b/sys/net/radix.c @@ -533,7 +533,7 @@ rn_addmask(void *n_arg, struct radix_node_head *maskhead, int search, int skip) x = rn_insert(cp, maskhead, &maskduplicated, x); if (maskduplicated) { log(LOG_ERR, "rn_addmask: mask impossibly already in tree"); - Free(saved_x); + R_Free(saved_x); return (x); } /* @@ -829,7 +829,7 @@ rn_delete(void *v_arg, void *netmask_arg, struct radix_node_head *head) for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) if (m == saved_m) { *mp = m->rm_mklist; - Free(m); + R_Free(m); break; } if (m == 0) { @@ -920,7 +920,7 @@ rn_delete(void *v_arg, void *netmask_arg, struct radix_node_head *head) struct radix_mask *mm = m->rm_mklist; x->rn_mklist = 0; if (--(m->rm_refs) < 0) - Free(m); + R_Free(m); m = mm; } if (m) @@ -1152,7 +1152,7 @@ rn_detachhead_internal(void **head) rnh = *head; /* Free nodes. */ - Free(rnh); + R_Free(rnh); *head = NULL; } @@ -1186,7 +1186,7 @@ rn_freeentry(struct radix_node *rn, void *arg) x = (struct radix_node *)rn_delete(rn + 2, NULL, rnh); if (x != NULL) - Free(x); + R_Free(x); return (0); } diff --git a/sys/net/radix.h b/sys/net/radix.h index cc262fa745eb..d4bb58a47ed4 100644 --- a/sys/net/radix.h +++ b/sys/net/radix.h @@ -137,7 +137,7 @@ struct radix_node_head { #else #define R_Malloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_NOWAIT)) #define R_Zalloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_NOWAIT | M_ZERO)) -#define Free(p) free((caddr_t)p, M_RTABLE); +#define R_Free(p) free((caddr_t)p, M_RTABLE); #define RADIX_NODE_HEAD_LOCK_INIT(rnh) \ rw_init_flags(&(rnh)->rnh_lock, "radix node head", 0) diff --git a/sys/net/route.c b/sys/net/route.c index 992cf8e72b0f..a88742267ccf 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -519,7 +519,7 @@ rtfree(struct rtentry *rt) * This also frees the gateway, as they are always malloc'd * together. */ - Free(rt_key(rt)); + R_Free(rt_key(rt)); /* * and the rtentry itself of course @@ -1352,7 +1352,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, if (rn_mpath_capable(rnh) && rt_mpath_conflict(rnh, rt, netmask)) { ifa_free(rt->rt_ifa); - Free(rt_key(rt)); + R_Free(rt_key(rt)); uma_zfree(V_rtzone, rt); senderr(EEXIST); } @@ -1419,7 +1419,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, */ if (rn == NULL) { ifa_free(rt->rt_ifa); - Free(rt_key(rt)); + R_Free(rt_key(rt)); uma_zfree(V_rtzone, rt); #ifdef FLOWTABLE if (rt0 != NULL) @@ -1641,7 +1641,7 @@ rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate) * Free()/free() handle a NULL argument just fine. */ bcopy(dst, new, dlen); - Free(rt_key(rt)); /* free old block, if any */ + R_Free(rt_key(rt)); /* free old block, if any */ rt_key(rt) = (struct sockaddr *)new; rt->rt_gateway = (struct sockaddr *)(new + dlen); } From aaebf690629431093f467ed6c2ddd181a4336749 Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Thu, 30 Jul 2015 03:50:01 +0000 Subject: [PATCH 077/314] Add support for Xen blkif indirect segment I/Os. This makes it possible for the blkfront driver to perform I/Os of up to 2 MB, subject to support from the blkback to which it is connected and the initiation of such large I/Os by the rest of the kernel. In practice, the I/O size is increased from 40 kB to 128 kB. The changes to xen/interface/io/blkif.h consist merely of merging updates from the upstream Xen repository. In dev/xen/blkfront/block.h we add some convenience macros and structure fields used for indirect-page I/Os: The device records its negotiated limit on the number of indirect pages used, while each I/O command structure gains permanently allocated page(s) for indirect page references and the Xen grant references for those pages. In dev/xen/blkfront/blkfront.c we now check in xbd_queue_cb whether a request is small enough to handle without an indirection page, and either follow the previous behaviour or use new code for issuing an indirect segment I/O. In xbd_connect we read the size of indirect segment I/Os supported by the backend and select the maximum size we will use; then allocate the pages and Xen grant references for each I/O command structure. In xbd_free those grants and pages are released. A new loader tunable, hw.xbd.xbd_enable_indirect, can be set to 0 in order to disable this functionality; it works by pretending that the backend does not support this feature. Some backends exhibit a loss of performance with large I/Os, so users may wish to test with and without this functionality enabled. Reviewed by: royger MFC after: 3 days Relnotes: yes --- sys/dev/xen/blkfront/blkfront.c | 109 ++++++++++++++++---- sys/dev/xen/blkfront/block.h | 25 ++++- sys/xen/interface/io/blkif.h | 171 ++++++++++++++++++++++++++++++-- 3 files changed, 271 insertions(+), 34 deletions(-) diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c index 0610732bfb98..312a0771a9e4 100644 --- a/sys/dev/xen/blkfront/blkfront.c +++ b/sys/dev/xen/blkfront/blkfront.c @@ -84,6 +84,11 @@ static void xbd_startio(struct xbd_softc *sc); /*---------------------------- Global Static Data ----------------------------*/ static MALLOC_DEFINE(M_XENBLOCKFRONT, "xbd", "Xen Block Front driver data"); +static int xbd_enable_indirect = 1; +SYSCTL_NODE(_hw, OID_AUTO, xbd, CTLFLAG_RD, 0, "xbd driver parameters"); +SYSCTL_INT(_hw_xbd, OID_AUTO, xbd_enable_indirect, CTLFLAG_RDTUN, + &xbd_enable_indirect, 0, "Enable xbd indirect segments"); + /*---------------------------- Command Processing ----------------------------*/ static void xbd_freeze(struct xbd_softc *sc, xbd_flag_t xbd_flag) @@ -205,7 +210,6 @@ xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) { struct xbd_softc *sc; struct xbd_command *cm; - blkif_request_t *ring_req; int op; cm = arg; @@ -218,22 +222,47 @@ xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) return; } - KASSERT(nsegs <= BLKIF_MAX_SEGMENTS_PER_REQUEST, + KASSERT(nsegs <= sc->xbd_max_request_segments, ("Too many segments in a blkfront I/O")); - /* Fill out a communications ring structure. */ - ring_req = RING_GET_REQUEST(&sc->xbd_ring, sc->xbd_ring.req_prod_pvt); - sc->xbd_ring.req_prod_pvt++; - ring_req->id = cm->cm_id; - ring_req->operation = cm->cm_operation; - ring_req->sector_number = cm->cm_sector_number; - ring_req->handle = (blkif_vdev_t)(uintptr_t)sc->xbd_disk; - ring_req->nr_segments = nsegs; - cm->cm_nseg = nsegs; - xbd_mksegarray(segs, nsegs, &cm->cm_gref_head, - xenbus_get_otherend_id(sc->xbd_dev), - cm->cm_operation == BLKIF_OP_WRITE, - cm->cm_sg_refs, ring_req->seg); + if (nsegs <= BLKIF_MAX_SEGMENTS_PER_REQUEST) { + blkif_request_t *ring_req; + + /* Fill out a blkif_request_t structure. */ + ring_req = (blkif_request_t *) + RING_GET_REQUEST(&sc->xbd_ring, sc->xbd_ring.req_prod_pvt); + sc->xbd_ring.req_prod_pvt++; + ring_req->id = cm->cm_id; + ring_req->operation = cm->cm_operation; + ring_req->sector_number = cm->cm_sector_number; + ring_req->handle = (blkif_vdev_t)(uintptr_t)sc->xbd_disk; + ring_req->nr_segments = nsegs; + cm->cm_nseg = nsegs; + xbd_mksegarray(segs, nsegs, &cm->cm_gref_head, + xenbus_get_otherend_id(sc->xbd_dev), + cm->cm_operation == BLKIF_OP_WRITE, + cm->cm_sg_refs, ring_req->seg); + } else { + blkif_request_indirect_t *ring_req; + + /* Fill out a blkif_request_indirect_t structure. */ + ring_req = (blkif_request_indirect_t *) + RING_GET_REQUEST(&sc->xbd_ring, sc->xbd_ring.req_prod_pvt); + sc->xbd_ring.req_prod_pvt++; + ring_req->id = cm->cm_id; + ring_req->operation = BLKIF_OP_INDIRECT; + ring_req->indirect_op = cm->cm_operation; + ring_req->sector_number = cm->cm_sector_number; + ring_req->handle = (blkif_vdev_t)(uintptr_t)sc->xbd_disk; + ring_req->nr_segments = nsegs; + cm->cm_nseg = nsegs; + xbd_mksegarray(segs, nsegs, &cm->cm_gref_head, + xenbus_get_otherend_id(sc->xbd_dev), + cm->cm_operation == BLKIF_OP_WRITE, + cm->cm_sg_refs, cm->cm_indirectionpages); + memcpy(ring_req->indirect_grefs, &cm->cm_indirectionrefs, + sizeof(grant_ref_t) * sc->xbd_max_request_indirectpages); + } if (cm->cm_operation == BLKIF_OP_READ) op = BUS_DMASYNC_PREREAD; @@ -1015,6 +1044,16 @@ xbd_free(struct xbd_softc *sc) cm->cm_sg_refs = NULL; } + if (cm->cm_indirectionpages != NULL) { + gnttab_end_foreign_access_references( + sc->xbd_max_request_indirectpages, + &cm->cm_indirectionrefs[0]); + contigfree(cm->cm_indirectionpages, PAGE_SIZE * + sc->xbd_max_request_indirectpages, + M_XENBLOCKFRONT); + cm->cm_indirectionpages = NULL; + } + bus_dmamap_destroy(sc->xbd_io_dmat, cm->cm_map); } free(sc->xbd_shadow, M_XENBLOCKFRONT); @@ -1051,9 +1090,6 @@ xbd_initialize(struct xbd_softc *sc) */ max_ring_page_order = 0; sc->xbd_ring_pages = 1; - sc->xbd_max_request_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST; - sc->xbd_max_request_size = - XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments); /* * Protocol negotiation. @@ -1167,7 +1203,7 @@ xbd_connect(struct xbd_softc *sc) unsigned long sectors, sector_size; unsigned int binfo; int err, feature_barrier, feature_flush; - int i; + int i, j; if (sc->xbd_state == XBD_STATE_CONNECTED || sc->xbd_state == XBD_STATE_SUSPENDED) @@ -1198,6 +1234,22 @@ xbd_connect(struct xbd_softc *sc) if (err == 0 && feature_flush != 0) sc->xbd_flags |= XBDF_FLUSH; + err = xs_gather(XST_NIL, xenbus_get_otherend_path(dev), + "feature-max-indirect-segments", "%" PRIu32, + &sc->xbd_max_request_segments, NULL); + if ((err != 0) || (xbd_enable_indirect == 0)) + sc->xbd_max_request_segments = 0; + if (sc->xbd_max_request_segments > XBD_MAX_INDIRECT_SEGMENTS) + sc->xbd_max_request_segments = XBD_MAX_INDIRECT_SEGMENTS; + if (sc->xbd_max_request_segments > XBD_SIZE_TO_SEGS(MAXPHYS)) + sc->xbd_max_request_segments = XBD_SIZE_TO_SEGS(MAXPHYS); + sc->xbd_max_request_indirectpages = + XBD_INDIRECT_SEGS_TO_PAGES(sc->xbd_max_request_segments); + if (sc->xbd_max_request_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST) + sc->xbd_max_request_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST; + sc->xbd_max_request_size = + XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments); + /* Allocate datastructures based on negotiated values. */ err = bus_dma_tag_create( bus_get_dma_tag(sc->xbd_dev), /* parent */ @@ -1230,6 +1282,7 @@ xbd_connect(struct xbd_softc *sc) for (i = 0; i < sc->xbd_max_requests; i++) { struct xbd_command *cm; + void * indirectpages; cm = &sc->xbd_shadow[i]; cm->cm_sg_refs = malloc( @@ -1242,6 +1295,24 @@ xbd_connect(struct xbd_softc *sc) cm->cm_sc = sc; if (bus_dmamap_create(sc->xbd_io_dmat, 0, &cm->cm_map) != 0) break; + if (sc->xbd_max_request_indirectpages > 0) { + indirectpages = contigmalloc( + PAGE_SIZE * sc->xbd_max_request_indirectpages, + M_XENBLOCKFRONT, M_ZERO, 0, ~0, PAGE_SIZE, 0); + } else { + indirectpages = NULL; + } + for (j = 0; j < sc->xbd_max_request_indirectpages; j++) { + if (gnttab_grant_foreign_access( + xenbus_get_otherend_id(sc->xbd_dev), + (vtomach(indirectpages) >> PAGE_SHIFT) + j, + 1 /* grant read-only access */, + &cm->cm_indirectionrefs[j])) + break; + } + if (j < sc->xbd_max_request_indirectpages) + break; + cm->cm_indirectionpages = indirectpages; xbd_free_command(cm); } diff --git a/sys/dev/xen/blkfront/block.h b/sys/dev/xen/blkfront/block.h index 8dcd322b12b3..28c6ff2b48de 100644 --- a/sys/dev/xen/blkfront/block.h +++ b/sys/dev/xen/blkfront/block.h @@ -75,11 +75,25 @@ __CONST_RING_SIZE(blkif, PAGE_SIZE * XBD_MAX_RING_PAGES) /** - * The maximum mapped region size per request we will allow in a negotiated - * block-front/back communication channel. + * The maximum number of blkif segments which can be provided per indirect + * page in an indirect request. */ -#define XBD_MAX_REQUEST_SIZE \ - MIN(MAXPHYS, XBD_SEGS_TO_SIZE(BLKIF_MAX_SEGMENTS_PER_REQUEST)) +#define XBD_MAX_SEGMENTS_PER_PAGE \ + (PAGE_SIZE / sizeof(struct blkif_request_segment)) + +/** + * The maximum number of blkif segments which can be provided in an indirect + * request. + */ +#define XBD_MAX_INDIRECT_SEGMENTS \ + (BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST * XBD_MAX_SEGMENTS_PER_PAGE) + +/** + * Compute the number of indirect segment pages required for an I/O with the + * specified number of indirect segments. + */ +#define XBD_INDIRECT_SEGS_TO_PAGES(segs) \ + ((segs + XBD_MAX_SEGMENTS_PER_PAGE - 1) / XBD_MAX_SEGMENTS_PER_PAGE) typedef enum { XBDCF_Q_MASK = 0xFF, @@ -111,6 +125,8 @@ struct xbd_command { blkif_sector_t cm_sector_number; int cm_status; xbd_cbcf_t *cm_complete; + void *cm_indirectionpages; + grant_ref_t cm_indirectionrefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST]; }; typedef enum { @@ -165,6 +181,7 @@ struct xbd_softc { uint32_t xbd_max_requests; uint32_t xbd_max_request_segments; uint32_t xbd_max_request_size; + uint32_t xbd_max_request_indirectpages; grant_ref_t xbd_ring_ref[XBD_MAX_RING_PAGES]; blkif_front_ring_t xbd_ring; xen_intr_handle_t xen_intr_handle; diff --git a/sys/xen/interface/io/blkif.h b/sys/xen/interface/io/blkif.h index 160547a27502..9c73ae7e863c 100644 --- a/sys/xen/interface/io/blkif.h +++ b/sys/xen/interface/io/blkif.h @@ -97,6 +97,28 @@ * * The type of the backing device/object. * + * + * direct-io-safe + * Values: 0/1 (boolean) + * Default Value: 0 + * + * The underlying storage is not affected by the direct IO memory + * lifetime bug. See: + * http://lists.xen.org/archives/html/xen-devel/2012-12/msg01154.html + * + * Therefore this option gives the backend permission to use + * O_DIRECT, notwithstanding that bug. + * + * That is, if this option is enabled, use of O_DIRECT is safe, + * in circumstances where we would normally have avoided it as a + * workaround for that bug. This option is not relevant for all + * backends, and even not necessarily supported for those for + * which it is relevant. A backend which knows that it is not + * affected by the bug can ignore this option. + * + * This option doesn't require a backend to use O_DIRECT, so it + * should not be used to try to control the caching behaviour. + * *--------------------------------- Features --------------------------------- * * feature-barrier @@ -126,6 +148,34 @@ * of this type may still be returned at any time with the * BLKIF_RSP_EOPNOTSUPP result code. * + * feature-persistent + * Values: 0/1 (boolean) + * Default Value: 0 + * Notes: 7 + * + * A value of "1" indicates that the backend can keep the grants used + * by the frontend driver mapped, so the same set of grants should be + * used in all transactions. The maximum number of grants the backend + * can map persistently depends on the implementation, but ideally it + * should be RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. Using this + * feature the backend doesn't need to unmap each grant, preventing + * costly TLB flushes. The backend driver should only map grants + * persistently if the frontend supports it. If a backend driver chooses + * to use the persistent protocol when the frontend doesn't support it, + * it will probably hit the maximum number of persistently mapped grants + * (due to the fact that the frontend won't be reusing the same grants), + * and fall back to non-persistent mode. Backend implementations may + * shrink or expand the number of persistently mapped grants without + * notifying the frontend depending on memory constraints (this might + * cause a performance degradation). + * + * If a backend driver wants to limit the maximum number of persistently + * mapped grants to a value less than RING_SIZE * + * BLKIF_MAX_SEGMENTS_PER_REQUEST a LRU strategy should be used to + * discard the grants that are less commonly used. Using a LRU in the + * backend driver paired with a LIFO queue in the frontend will + * allow us to have better performance in this scenario. + * *----------------------- Request Transport Parameters ------------------------ * * max-ring-page-order @@ -147,6 +197,16 @@ * *------------------------- Backend Device Properties ------------------------- * + * discard-enable + * Values: 0/1 (boolean) + * Default Value: 1 + * + * This optional property, set by the toolstack, instructs the backend + * to offer discard to the frontend. If the property is missing the + * backend should offer discard if the backing storage actually supports + * it. This optional property, set by the toolstack, requests that the + * backend offer, or not offer, discard to the frontend. + * * discard-alignment * Values: * Default Value: 0 @@ -166,6 +226,7 @@ * discard-secure * Values: 0/1 (boolean) * Default Value: 0 + * Notes: 10 * * A value of "1" indicates that the backend can process BLKIF_OP_DISCARD * requests with the BLKIF_DISCARD_SECURE flag set. @@ -180,13 +241,17 @@ * sector-size * Values: * - * The size, in bytes, of the individually addressible data blocks - * on the backend device. + * The logical sector size, in bytes, of the backend device. + * + * physical-sector-size + * Values: + * + * The physical sector size, in bytes, of the backend device. * * sectors * Values: * - * The size of the backend device, expressed in units of its native + * The size of the backend device, expressed in units of its logical * sector size ("sector-size"). * ***************************************************************************** @@ -243,6 +308,27 @@ * The size of the frontend allocated request ring buffer in units of * machine pages. The value must be a power of 2. * + * feature-persistent + * Values: 0/1 (boolean) + * Default Value: 0 + * Notes: 7, 8, 9 + * + * A value of "1" indicates that the frontend will reuse the same grants + * for all transactions, allowing the backend to map them with write + * access (even when it should be read-only). If the frontend hits the + * maximum number of allowed persistently mapped grants, it can fallback + * to non persistent mode. This will cause a performance degradation, + * since the the backend driver will still try to map those grants + * persistently. Since the persistent grants protocol is compatible with + * the previous protocol, a frontend driver can choose to work in + * persistent mode even when the backend doesn't support it. + * + * It is recommended that the frontend driver stores the persistently + * mapped grants in a LIFO queue, so a subset of all persistently mapped + * grants gets used commonly. This is done in case the backend driver + * decides to limit the maximum number of persistently mapped grants + * to a value less than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. + * *------------------------- Virtual Device Properties ------------------------- * * device-type @@ -262,17 +348,23 @@ * ----- * (1) Multi-page ring buffer scheme first developed in the Citrix XenServer * PV drivers. - * (2) Multi-page ring buffer scheme first used in some Red Hat distributions + * (2) Multi-page ring buffer scheme first used in some RedHat distributions * including a distribution deployed on certain nodes of the Amazon * EC2 cluster. * (3) Support for multi-page ring buffers was implemented independently, - * in slightly different forms, by both Citrix and Red Hat/Amazon. + * in slightly different forms, by both Citrix and RedHat/Amazon. * For full interoperability, block front and backends should publish * identical ring parameters, adjusted for unit differences, to the * XenStore nodes used in both schemes. - * (4) Devices that support discard functionality may internally allocate - * space (discardable extents) in units that are larger than the - * exported logical block size. + * (4) Devices that support discard functionality may internally allocate space + * (discardable extents) in units that are larger than the exported logical + * block size. If the backing device has such discardable extents the + * backend should provide both discard-granularity and discard-alignment. + * Providing just one of the two may be considered an error by the frontend. + * Backends supporting discard should include discard-granularity and + * discard-alignment even if it supports discarding individual sectors. + * Frontends should assume discard-alignment == 0 and discard-granularity + * == sector size if these keys are missing. * (5) The discard-alignment parameter allows a physical device to be * partitioned into virtual devices that do not necessarily begin or * end on a discardable extent boundary. @@ -280,6 +372,19 @@ * 'ring-ref' is used to communicate the grant reference for this * page to the backend. When using a multi-page ring, the 'ring-ref' * node is not created. Instead 'ring-ref0' - 'ring-refN' are used. + * (7) When using persistent grants data has to be copied from/to the page + * where the grant is currently mapped. The overhead of doing this copy + * however doesn't suppress the speed improvement of not having to unmap + * the grants. + * (8) The frontend driver has to allow the backend driver to map all grants + * with write access, even when they should be mapped read-only, since + * further requests may reuse these grants and require write permissions. + * (9) Linux implementation doesn't have a limit on the maximum number of + * grants that can be persistently mapped in the frontend driver, but + * due to the frontent driver implementation it should never be bigger + * than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. + *(10) The discard-secure property may be present and will be set to 1 if the + * backing device supports secure discard. */ /* @@ -403,6 +508,30 @@ */ #define BLKIF_OP_DISCARD 5 +/* + * Recognized if "feature-max-indirect-segments" in present in the backend + * xenbus info. The "feature-max-indirect-segments" node contains the maximum + * number of segments allowed by the backend per request. If the node is + * present, the frontend might use blkif_request_indirect structs in order to + * issue requests with more than BLKIF_MAX_SEGMENTS_PER_REQUEST (11). The + * maximum number of indirect segments is fixed by the backend, but the + * frontend can issue requests with any number of indirect segments as long as + * it's less than the number provided by the backend. The indirect_grefs field + * in blkif_request_indirect should be filled by the frontend with the + * grant references of the pages that are holding the indirect segments. + * These pages are filled with an array of blkif_request_segment that hold the + * information about the segments. The number of indirect pages to use is + * determined by the number of segments an indirect request contains. Every + * indirect page can contain a maximum of + * (PAGE_SIZE / sizeof(struct blkif_request_segment)) segments, so to + * calculate the number of indirect pages to use we have to do + * ceil(indirect_segments / (PAGE_SIZE / sizeof(struct blkif_request_segment))). + * + * If a backend does not recognize BLKIF_OP_INDIRECT, it should *not* + * create the "feature-max-indirect-segments" node! + */ +#define BLKIF_OP_INDIRECT 6 + /* * Maximum scatter/gather segments per request. * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE. @@ -410,12 +539,18 @@ */ #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11 +/* + * Maximum number of indirect pages to use per request. + */ +#define BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST 8 + /* * NB. first_sect and last_sect in blkif_request_segment, as well as * sector_number in blkif_request, are always expressed in 512-byte units. * However they must be properly aligned to the real sector size of the - * physical disk, which is reported in the "sector-size" node in the backend - * xenbus info. Also the xenbus "sectors" node is expressed in 512-byte units. + * physical disk, which is reported in the "physical-sector-size" node in + * the backend xenbus info. Also the xenbus "sectors" node is expressed in + * 512-byte units. */ struct blkif_request_segment { grant_ref_t gref; /* reference to I/O buffer frame */ @@ -453,6 +588,20 @@ struct blkif_request_discard { }; typedef struct blkif_request_discard blkif_request_discard_t; +struct blkif_request_indirect { + uint8_t operation; /* BLKIF_OP_INDIRECT */ + uint8_t indirect_op; /* BLKIF_OP_{READ/WRITE} */ + uint16_t nr_segments; /* number of segments */ + uint64_t id; /* private guest value, echoed in resp */ + blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ + blkif_vdev_t handle; /* same as for read/write requests */ + grant_ref_t indirect_grefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST]; +#ifdef __i386__ + uint64_t pad; /* Make it 64 byte aligned on i386 */ +#endif +}; +typedef struct blkif_request_indirect blkif_request_indirect_t; + struct blkif_response { uint64_t id; /* copied from request */ uint8_t operation; /* copied from request */ @@ -484,7 +633,7 @@ DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response); /* * Local variables: * mode: C - * c-set-style: "BSD" + * c-file-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil From a5c1653b5c48a9d59acc372d500d6a79abec019d Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Thu, 30 Jul 2015 04:01:00 +0000 Subject: [PATCH 078/314] Disable blkif indirect segment I/Os in EC2 by default due to performance issues on some EC2 instance types. Users may want to experiment with removing this from loader.conf and measuring the performance impact on the EC2 instances they are using. --- release/tools/ec2.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf index 9472ec59d89f..557e60260dbf 100644 --- a/release/tools/ec2.conf +++ b/release/tools/ec2.conf @@ -70,6 +70,11 @@ vm_extra_pre_umount() { # nodes, but apply the workaround just in case. echo 'hw.broken_txfifo="1"' >> ${DESTDIR}/boot/loader.conf + # Some EC2 instances suffer a significant (~40%) reduction in + # throughput when using blkif indirect segment I/Os. Disable this + # by default for now. + echo 'hw.xbd.xbd_enable_indirect="0"' >> ${DESTDIR}/boot/loader.conf + # The first time the AMI boots, the installed "first boot" scripts # should be allowed to run: # * ec2_configinit (download and process EC2 user-data) From a86e343db61f1af0b001f7d4766debd7fb14e581 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 30 Jul 2015 06:14:47 +0000 Subject: [PATCH 079/314] Improve strtounum Fix many style bugs Better variable naming Use C99 'restrict' were apropriate Fix potential errno race Submitted by: bde --- usr.sbin/pw/pw.h | 4 ++-- usr.sbin/pw/strtounum.c | 49 +++++++++++++++++++---------------------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h index 3ab3c74a9537..a22572e57cab 100644 --- a/usr.sbin/pw/pw.h +++ b/usr.sbin/pw/pw.h @@ -103,5 +103,5 @@ char *pw_pwcrypt(char *password); extern const char *Modes[]; extern const char *Which[]; -uintmax_t strtounum(const char *numstr, uintmax_t minval, uintmax_t maxval, - const char **errmsg); +uintmax_t strtounum(const char * __restrict, uintmax_t, uintmax_t, + const char ** __restrict); diff --git a/usr.sbin/pw/strtounum.c b/usr.sbin/pw/strtounum.c index b3944865346c..8d8347080ac2 100644 --- a/usr.sbin/pw/strtounum.c +++ b/usr.sbin/pw/strtounum.c @@ -34,41 +34,38 @@ __FBSDID("$FreeBSD$"); #include "pw.h" -#define INVALID "invalid" -#define TOOSMALL "too small" -#define TOOLARGE "too large" - uintmax_t -strtounum(const char *numstr, uintmax_t minval, uintmax_t maxval, - const char **errstrp) +strtounum(const char * __restrict np, uintmax_t minval, uintmax_t maxval, + const char ** __restrict errpp) { - uintmax_t ret = 0; - char *ep; + char *endp; + uintmax_t ret; if (minval > maxval) { errno = EINVAL; - if (errstrp != NULL) - *errstrp = INVALID; + if (errpp != NULL) + *errpp = "invalid"; return (0); } - - ret = strtoumax(numstr, &ep, 10); - if (errno == EINVAL || numstr == ep || *ep != '\0') { + errno = 0; + ret = strtoumax(np, &endp, 10); + if (endp == np || *endp != '\0') { errno = EINVAL; - if (errstrp != NULL) - *errstrp = INVALID; - return (0); - } else if ((ret == 0 && errno == ERANGE) || ret < minval) { - errno = ERANGE; - if (errstrp != NULL) - *errstrp = TOOSMALL; - return (0); - } else if ((ret == UINTMAX_MAX && errno == ERANGE) || ret > maxval) { - errno = ERANGE; - if (errstrp != NULL) - *errstrp = TOOLARGE; + if (errpp != NULL) + *errpp = "invalid"; + return (0); + } + if (ret < minval) { + errno = ERANGE; + if (errpp != NULL) + *errpp = "too small"; + return (0); + } + if (errno == ERANGE || ret > maxval) { + errno = ERANGE; + if (errpp != NULL) + *errpp = "too large"; return (0); } - return (ret); } From a5965d1513c55154c0d02ab3ff720af962bd5ae5 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Thu, 30 Jul 2015 10:26:43 +0000 Subject: [PATCH 080/314] Build if_stf(4) module only when both INET and INET6 support are enabled. --- sys/modules/Makefile | 7 ++++++- sys/modules/if_stf/Makefile | 2 +- sys/net/if_stf.c | 3 --- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 508488414136..7b0e286c9fea 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -149,7 +149,7 @@ SUBDIR= \ ${_if_me} \ if_lagg \ ${_if_ndis} \ - if_stf \ + ${_if_stf} \ if_tap \ if_tun \ if_vlan \ @@ -411,6 +411,11 @@ _if_gif= if_gif _if_gre= if_gre .endif +.if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ + defined(ALL_MODULES) +_if_stf= if_stf +.endif + .if ${MK_INET_SUPPORT} != "no" || defined(ALL_MODULES) _if_me= if_me _ipdivert= ipdivert diff --git a/sys/modules/if_stf/Makefile b/sys/modules/if_stf/Makefile index 709c2555132b..4eb2f01df560 100644 --- a/sys/modules/if_stf/Makefile +++ b/sys/modules/if_stf/Makefile @@ -3,6 +3,6 @@ .PATH: ${.CURDIR}/../../net KMOD= if_stf -SRCS= if_stf.c opt_inet.h opt_inet6.h +SRCS= if_stf.c .include diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index 23905783d0db..6d7eeb8e33de 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -74,9 +74,6 @@ * Note that there is no way to be 100% secure. */ -#include "opt_inet.h" -#include "opt_inet6.h" - #include #include #include From 4d3523c2f73f9437ce40c53cd7394e871b98cd3d Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 30 Jul 2015 13:45:34 +0000 Subject: [PATCH 081/314] Remove obsolete vendor code from Alpine platform support This is a clean-up patch from a serie delivering support for Annapurna Labs Alpine PoC. The HAL files have already been added to sys/contrib/alpine-hal so there is no need for them in the platform directory. This patch removes obsolete files. Reviewed by: andrew Obtained from: Semihalf Sponsored by: Annapurna Labs Differential Revision: https://reviews.freebsd.org/D3248 --- sys/arm/annapurna/alpine/hal/al_hal_common.h | 70 - sys/arm/annapurna/alpine/hal/al_hal_iofic.h | 222 -- .../annapurna/alpine/hal/al_hal_iofic_regs.h | 127 - sys/arm/annapurna/alpine/hal/al_hal_nb_regs.h | 1823 ----------- .../annapurna/alpine/hal/al_hal_pbs_regs.h | 2751 ---------------- sys/arm/annapurna/alpine/hal/al_hal_pcie.c | 2788 ----------------- sys/arm/annapurna/alpine/hal/al_hal_pcie.h | 1157 ------- .../alpine/hal/al_hal_pcie_axi_reg.h | 1501 --------- .../alpine/hal/al_hal_pcie_interrupts.h | 271 -- .../annapurna/alpine/hal/al_hal_pcie_regs.h | 594 ---- .../annapurna/alpine/hal/al_hal_pcie_w_reg.h | 1505 --------- .../alpine/hal/al_hal_plat_services.h | 419 --- .../annapurna/alpine/hal/al_hal_plat_types.h | 94 - .../annapurna/alpine/hal/al_hal_reg_utils.h | 188 -- sys/arm/annapurna/alpine/hal/al_hal_types.h | 117 - .../alpine/hal/al_hal_unit_adapter_regs.h | 314 -- 16 files changed, 13941 deletions(-) delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_common.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_iofic.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_iofic_regs.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_nb_regs.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_pbs_regs.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_pcie.c delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_pcie.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_pcie_axi_reg.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_pcie_interrupts.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_pcie_regs.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_pcie_w_reg.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_plat_services.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_plat_types.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_reg_utils.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_types.h delete mode 100644 sys/arm/annapurna/alpine/hal/al_hal_unit_adapter_regs.h diff --git a/sys/arm/annapurna/alpine/hal/al_hal_common.h b/sys/arm/annapurna/alpine/hal/al_hal_common.h deleted file mode 100644 index 6e27e1795cb1..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_common.h +++ /dev/null @@ -1,70 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @defgroup group_common HAL Common Layer - * Includes all common header files used by HAL - * @{ - * @file al_hal_common.h - * - */ - -#ifndef __AL_HAL_COMMON_H__ -#define __AL_HAL_COMMON_H__ - -#include "al_hal_plat_types.h" -#include "al_hal_plat_services.h" - -#include "al_hal_types.h" -#include "al_hal_reg_utils.h" - -/* Get the maximal value out of two typed values */ -#define al_max_t(type, x, y) ({ \ - type __max1 = (x); \ - type __max2 = (y); \ - __max1 > __max2 ? __max1 : __max2; }) - -/* Get the minimal value out of two typed values */ -#define al_min_t(type, x, y) ({ \ - type __min1 = (x); \ - type __min2 = (y); \ - __min1 < __min2 ? __min1 : __min2; }) - -/* Get the number of elements in an array */ -#define AL_ARR_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -/** @} end of Common group */ -#endif /* __AL_HAL_COMMON_H__ */ diff --git a/sys/arm/annapurna/alpine/hal/al_hal_iofic.h b/sys/arm/annapurna/alpine/hal/al_hal_iofic.h deleted file mode 100644 index 5c19e0a12606..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_iofic.h +++ /dev/null @@ -1,222 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @defgroup group_interrupts Common I/O Fabric Interrupt Controller - * This HAL provides the API for programming the Common I/O Fabric Interrupt - * Controller (IOFIC) found in most of the units attached to the I/O Fabric of - * Alpine platform - * @{ - * @file al_hal_iofic.h - * - * @brief Header file for the interrupt controller that's embedded in various units - * - */ - -#ifndef __AL_HAL_IOFIC_H__ -#define __AL_HAL_IOFIC_H__ - -#include - -/* *INDENT-OFF* */ -#ifdef __cplusplus -extern "C" { -#endif -/* *INDENT-ON* */ - -#define AL_IOFIC_MAX_GROUPS 4 - -/* - * Configurations - */ - -/** - * Configure the interrupt controller registers, actual interrupts are still - * masked at this stage. - * - * @param regs_base regs pointer to interrupt controller registers - * @param group the interrupt group. - * @param flags flags of Interrupt Control Register - * - * @return 0 on success. -EINVAL otherwise. - */ -int al_iofic_config(void __iomem *regs_base, int group, - uint32_t flags); - -/** - * configure the moderation timer resolution for a given group - * Applies for both msix and legacy mode. - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - * @param resolution resolution of the timer interval, the resolution determines the rate - * of decrementing the interval timer, setting value N means that the interval - * timer will be decremented each (N+1) * (0.68) micro seconds. - * - * @return 0 on success. -EINVAL otherwise. - */ -int al_iofic_moder_res_config(void __iomem *regs_base, int group, - uint8_t resolution); - -/** - * configure the moderation timer interval for a given legacy interrupt group - * - * @param regs_base regs pointer to unit registers - * @param group the interrupt group - * @param interval between interrupts in resolution units. 0 disable - * - * @return 0 on success. -EINVAL otherwise. - */ -int al_iofic_legacy_moder_interval_config(void __iomem *regs_base, int group, - uint8_t interval); - -/** - * configure the moderation timer interval for a given msix vector - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - * @param vector vector index - * @param interval interval between interrupts, 0 disable - * - * @return 0 on success. -EINVAL otherwise. - */ -int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group, - uint8_t vector, uint8_t interval); - -/** -* configure the vmid attributes for a given msix vector. -* -* @param group the interrupt group -* @param vector index -* @param vmid the vmid value -* @param vmid_en take vmid from the intc -* -* @return 0 on success. -EINVAL otherwise. -*/ -int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group, - uint8_t vector, uint32_t vmid, uint8_t vmid_en); - -/** - * return the offset of the unmask register for a given group. - * this function can be used when the upper layer wants to directly - * access the unmask regiter and bypass the al_iofic_unmask() API. - * - * @param regs_base regs pointer to unit registers - * @param group the interrupt group - * @return the offset of the unmask register. - */ -uint32_t __iomem * al_iofic_unmask_offset_get(void __iomem *regs_base, int group); - -/** - * unmask specific interrupts for a given group - * this functions guarantees atomic operations, it is performance optimized as - * it will not require read-modify-write. The unmask done using the interrupt - * mask clear register, so it's safe to call it while the mask is changed by - * the HW (auto mask) or another core. - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - * @param mask bitwise of interrupts to unmask, set bits will be unmasked. - */ -void al_iofic_unmask(void __iomem *regs_base, int group, uint32_t mask); - -/** - * mask specific interrupts for a given group - * this functions modifies interrupt mask register, the callee must make sure - * the mask is not changed by another cpu. - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - * @param mask bitwise of interrupts to mask, set bits will be masked. - */ -void al_iofic_mask(void __iomem *regs_base, int group, uint32_t mask); - -/** - * read the mask register for a given group - * this functions return the interrupt mask register - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - */ -uint32_t al_iofic_read_mask(void __iomem *regs_base, int group); - -/** - * read interrupt cause register for a given group - * this will clear the set bits if the Clear on Read mode enabled. - * @param regs_base pointer to unit registers - * @param group the interrupt group - */ -uint32_t al_iofic_read_cause(void __iomem *regs_base, int group); - -/** - * clear bits in the interrupt cause register for a given group - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - * @param mask bitwise of bits to be cleared, set bits will be cleared. - */ -void al_iofic_clear_cause(void __iomem *regs_base, int group, uint32_t mask); - -/** - * set the cause register for a given group - * this function set the cause register. It will generate an interrupt (if - * the the interrupt isn't masked ) - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - * @param mask bitwise of bits to be set. - */ -void al_iofic_set_cause(void __iomem *regs_base, int group, uint32_t mask); - -/** - * unmask specific interrupts from aborting the udma a given group - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - * @param mask bitwise of interrupts to mask - */ -void al_iofic_abort_mask(void __iomem *regs_base, int group, uint32_t mask); - -/** - * trigger all interrupts that are waiting for moderation timers to expire - * - * @param regs_base pointer to unit registers - * @param group the interrupt group - */ -void al_iofic_interrupt_moderation_reset(void __iomem *regs_base, int group); - -#endif -/** @} end of interrupt controller group */ diff --git a/sys/arm/annapurna/alpine/hal/al_hal_iofic_regs.h b/sys/arm/annapurna/alpine/hal/al_hal_iofic_regs.h deleted file mode 100644 index 81ba20fc9676..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_iofic_regs.h +++ /dev/null @@ -1,127 +0,0 @@ -/*_ -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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 __AL_HAL_IOFIC_REG_H -#define __AL_HAL_IOFIC_REG_H - -#ifdef __cplusplus -extern "C" { -#endif -/* -* Unit Registers -*/ - -struct al_iofic_grp_ctrl { - uint32_t int_cause_grp; /* Interrupt Cause RegisterSet by hardware */ - uint32_t rsrvd1; - uint32_t int_cause_set_grp; /* Interrupt Cause Set RegisterWriting 1 to a bit in t ... */ - uint32_t rsrvd2; - uint32_t int_mask_grp; /* Interrupt Mask RegisterIf Auto-mask control bit =TR ... */ - uint32_t rsrvd3; - uint32_t int_mask_clear_grp; /* Interrupt Mask Clear RegisterUsed when auto-mask co ... */ - uint32_t rsrvd4; - uint32_t int_status_grp; /* Interrupt status RegisterThis register latch the st ... */ - uint32_t rsrvd5; - uint32_t int_control_grp; /* Interrupt Control Register */ - uint32_t rsrvd6; - uint32_t int_abort_msk_grp; /* Interrupt Mask RegisterEach bit in this register ma ... */ - uint32_t rsrvd7; - uint32_t int_log_msk_grp; /* Interrupt Log RegisterEach bit in this register mas ... */ - uint32_t rsrvd8; -}; - -struct al_iofic_grp_mod { - uint32_t grp_int_mod_reg; /* Interrupt moderation registerDedicated moderation in ... */ - uint32_t grp_int_vmid_reg; -}; - -struct al_iofic_regs { - struct al_iofic_grp_ctrl ctrl[0]; - uint32_t rsrvd1[0x400 >> 2]; - struct al_iofic_grp_mod grp_int_mod[0][32]; -}; - - -/* -* Registers Fields -*/ - - -/**** int_control_grp register ****/ -/* When Clear_on_Read =1, All bits of Cause register ... */ -#define INT_CONTROL_GRP_CLEAR_ON_READ (1 << 0) -/* (must be set only when MSIX is enabled)When Auto-Ma ... */ -#define INT_CONTROL_GRP_AUTO_MASK (1 << 1) -/* Auto_Clear (RW)When Auto-Clear =1, the bits in the ... */ -#define INT_CONTROL_GRP_AUTO_CLEAR (1 << 2) -/* When Set_on_Posedge =1, the bits in the interrupt c ... */ -#define INT_CONTROL_GRP_SET_ON_POSEDGE (1 << 3) -/* When Moderation_Reset =1, all Moderation timers ass ... */ -#define INT_CONTROL_GRP_MOD_RST (1 << 4) -/* When mask_msi_x =1, No MSI-X from this group is sen ... */ -#define INT_CONTROL_GRP_MASK_MSI_X (1 << 5) -/* MSI-X AWID value, same ID for all cause bits */ -#define INT_CONTROL_GRP_AWID_MASK 0x00000F00 -#define INT_CONTROL_GRP_AWID_SHIFT 8 -/* This value determines the interval between interrup ... */ -#define INT_CONTROL_GRP_MOD_INTV_MASK 0x00FF0000 -#define INT_CONTROL_GRP_MOD_INTV_SHIFT 16 -/* This value determines the Moderation_Timer_Clock sp ... */ -#define INT_CONTROL_GRP_MOD_RES_MASK 0x0F000000 -#define INT_CONTROL_GRP_MOD_RES_SHIFT 24 - -/**** grp_int_mod_reg register ****/ -/* Interrupt Moderation Interval registerDedicated reg ... */ -#define INT_MOD_INTV_MASK 0x000000FF -#define INT_MOD_INTV_SHIFT 0 - -/**** grp_int_vmid_reg register ****/ -/* Interrupt vmid value registerDedicated reg ... */ -#define INT_MSIX_VMID_MASK 0x0000FFFF -#define INT_MSIX_VMID_SHIFT 0 -/* Interrupt vmid_en value registerDedicated reg ... */ -#define INT_MSIX_VMID_EN_SHIFT 31 - -#ifdef __cplusplus -} -#endif - -#endif /* __AL_HAL_IOFIC_REG_H */ - - - - diff --git a/sys/arm/annapurna/alpine/hal/al_hal_nb_regs.h b/sys/arm/annapurna/alpine/hal/al_hal_nb_regs.h deleted file mode 100644 index 9de3bd246865..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_nb_regs.h +++ /dev/null @@ -1,1823 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @{ - * @file al_hal_nb_regs.h - * - * @brief North Bridge service registers - * - */ - -#ifndef __AL_HAL_NB_REGS_H__ -#define __AL_HAL_NB_REGS_H__ - -#include "al_hal_plat_types.h" - -#ifdef __cplusplus -extern "C" { -#endif -/* -* Unit Registers -*/ - - - -struct al_nb_global { - /* [0x0] */ - uint32_t cpus_config; - /* [0x4] */ - uint32_t cpus_secure; - /* [0x8] Force init reset. */ - uint32_t cpus_init_control; - /* [0xc] Force init reset per DECEI mode. */ - uint32_t cpus_init_status; - /* [0x10] */ - uint32_t nb_int_cause; - /* [0x14] */ - uint32_t sev_int_cause; - /* [0x18] */ - uint32_t pmus_int_cause; - /* [0x1c] */ - uint32_t sev_mask; - /* [0x20] */ - uint32_t cpus_hold_reset; - /* [0x24] */ - uint32_t cpus_software_reset; - /* [0x28] */ - uint32_t wd_timer0_reset; - /* [0x2c] */ - uint32_t wd_timer1_reset; - /* [0x30] */ - uint32_t wd_timer2_reset; - /* [0x34] */ - uint32_t wd_timer3_reset; - /* [0x38] */ - uint32_t ddrc_hold_reset; - /* [0x3c] */ - uint32_t fabric_software_reset; - /* [0x40] */ - uint32_t cpus_power_ctrl; - uint32_t rsrvd_0[7]; - /* [0x60] */ - uint32_t acf_base_high; - /* [0x64] */ - uint32_t acf_base_low; - /* [0x68] */ - uint32_t acf_control_override; - /* [0x6c] Read-only that reflects CPU Cluster Local GIC base high address */ - uint32_t lgic_base_high; - /* [0x70] Read-only that reflects CPU Cluster Local GIC base low address */ - uint32_t lgic_base_low; - /* [0x74] Read-only that reflects the device's IOGIC base high address. */ - uint32_t iogic_base_high; - /* [0x78] Read-only that reflects IOGIC base low address */ - uint32_t iogic_base_low; - /* [0x7c] */ - uint32_t io_wr_split_control; - /* [0x80] */ - uint32_t io_rd_rob_control; - /* [0x84] */ - uint32_t sb_pos_error_log_1; - /* [0x88] */ - uint32_t sb_pos_error_log_0; - /* [0x8c] */ - uint32_t c2swb_config; - /* [0x90] */ - uint32_t msix_error_log; - /* [0x94] */ - uint32_t error_cause; - /* [0x98] */ - uint32_t error_mask; - uint32_t rsrvd_1; - /* [0xa0] */ - uint32_t qos_peak_control; - /* [0xa4] */ - uint32_t qos_set_control; - /* [0xa8] */ - uint32_t ddr_qos; - uint32_t rsrvd_2[9]; - /* [0xd0] */ - uint32_t acf_misc; - /* [0xd4] */ - uint32_t config_bus_control; - uint32_t rsrvd_3[2]; - /* [0xe0] */ - uint32_t pos_id_match; - uint32_t rsrvd_4[3]; - /* [0xf0] */ - uint32_t sb_sel_override_awuser; - /* [0xf4] */ - uint32_t sb_override_awuser; - /* [0xf8] */ - uint32_t sb_sel_override_aruser; - /* [0xfc] */ - uint32_t sb_override_aruser; - /* [0x100] */ - uint32_t cpu_max_pd_timer; - /* [0x104] */ - uint32_t cpu_max_pu_timer; - uint32_t rsrvd_5[2]; - /* [0x110] */ - uint32_t auto_ddr_self_refresh_counter; - uint32_t rsrvd_6[3]; - /* [0x120] */ - uint32_t coresight_pd; - /* [0x124] */ - uint32_t coresight_internal_0; - /* [0x128] */ - uint32_t coresight_dbgromaddr; - /* [0x12c] */ - uint32_t coresight_dbgselfaddr; - /* [0x130] */ - uint32_t coresght_targetid; - /* [0x134] */ - uint32_t coresght_targetid0; - uint32_t rsrvd_7[10]; - /* [0x160] */ - uint32_t sb_force_same_id_cfg_0; - /* [0x164] */ - uint32_t sb_mstr_force_same_id_sel_0; - /* [0x168] */ - uint32_t sb_force_same_id_cfg_1; - /* [0x16c] */ - uint32_t sb_mstr_force_same_id_sel_1; - uint32_t rsrvd[932]; -}; -struct al_nb_system_counter { - /* [0x0] */ - uint32_t cnt_control; - /* [0x4] */ - uint32_t cnt_base_freq; - /* [0x8] */ - uint32_t cnt_low; - /* [0xc] */ - uint32_t cnt_high; - /* [0x10] */ - uint32_t cnt_init_low; - /* [0x14] */ - uint32_t cnt_init_high; - uint32_t rsrvd[58]; -}; -struct al_nb_rams_control_misc { - /* [0x0] */ - uint32_t ca15_rf_misc; - uint32_t rsrvd_0; - /* [0x8] */ - uint32_t nb_rf_misc; - uint32_t rsrvd[61]; -}; -struct al_nb_ca15_rams_control { - /* [0x0] */ - uint32_t rf_0; - /* [0x4] */ - uint32_t rf_1; - /* [0x8] */ - uint32_t rf_2; - uint32_t rsrvd; -}; -struct al_nb_semaphores { - /* [0x0] This configuration is only sampled during reset of the processor */ - uint32_t lockn; -}; -struct al_nb_debug { - /* [0x0] */ - uint32_t ca15_outputs_1; - /* [0x4] */ - uint32_t ca15_outputs_2; - uint32_t rsrvd_0[2]; - /* [0x10] */ - uint32_t cpu_msg[4]; - /* [0x20] */ - uint32_t rsv0_config; - /* [0x24] */ - uint32_t rsv1_config; - uint32_t rsrvd_1[2]; - /* [0x30] */ - uint32_t rsv0_status; - /* [0x34] */ - uint32_t rsv1_status; - uint32_t rsrvd_2[2]; - /* [0x40] */ - uint32_t ddrc; - /* [0x44] */ - uint32_t ddrc_phy_smode_control; - /* [0x48] */ - uint32_t ddrc_phy_smode_status; - uint32_t rsrvd_3[5]; - /* [0x60] */ - uint32_t pmc; - uint32_t rsrvd_4[3]; - /* [0x70] */ - uint32_t cpus_general; - /* [0x74] */ - uint32_t cpus_general_1; - uint32_t rsrvd_5[2]; - /* [0x80] */ - uint32_t cpus_int_out; - uint32_t rsrvd_6[3]; - /* [0x90] */ - uint32_t latch_pc_req; - uint32_t rsrvd_7; - /* [0x98] */ - uint32_t latch_pc_low; - /* [0x9c] */ - uint32_t latch_pc_high; - uint32_t rsrvd_8[24]; - /* [0x100] */ - uint32_t track_dump_ctrl; - /* [0x104] */ - uint32_t track_dump_rdata_0; - /* [0x108] */ - uint32_t track_dump_rdata_1; - uint32_t rsrvd_9[5]; - /* [0x120] */ - uint32_t track_events; - uint32_t rsrvd_10[3]; - /* [0x130] */ - uint32_t pos_track_dump_ctrl; - /* [0x134] */ - uint32_t pos_track_dump_rdata_0; - /* [0x138] */ - uint32_t pos_track_dump_rdata_1; - uint32_t rsrvd_11; - /* [0x140] */ - uint32_t c2swb_track_dump_ctrl; - /* [0x144] */ - uint32_t c2swb_track_dump_rdata_0; - /* [0x148] */ - uint32_t c2swb_track_dump_rdata_1; - uint32_t rsrvd_12; - /* [0x150] */ - uint32_t cpus_track_dump_ctrl; - /* [0x154] */ - uint32_t cpus_track_dump_rdata_0; - /* [0x158] */ - uint32_t cpus_track_dump_rdata_1; - uint32_t rsrvd_13; - /* [0x160] */ - uint32_t c2swb_bar_ovrd_high; - /* [0x164] */ - uint32_t c2swb_bar_ovrd_low; - uint32_t rsrvd[38]; -}; -struct al_nb_cpun_config_status { - /* [0x0] This configuration is only sampled during reset of the processor. */ - uint32_t config; - /* [0x4] This configuration is only sampled during reset of the processor. */ - uint32_t config_aarch64; - /* [0x8] */ - uint32_t local_cause_mask; - uint32_t rsrvd_0; - /* [0x10] */ - uint32_t pmus_cause_mask; - /* [0x14] */ - uint32_t sei_cause_mask; - uint32_t rsrvd_1[2]; - /* [0x20] Specifies the state of the CPU with reference to power modes. */ - uint32_t power_ctrl; - /* [0x24] */ - uint32_t power_status; - /* [0x28] */ - uint32_t resume_addr_l; - /* [0x2c] */ - uint32_t resume_addr_h; - uint32_t rsrvd_2[4]; - /* [0x40] */ - uint32_t warm_rst_ctl; - uint32_t rsrvd_3; - /* [0x48] */ - uint32_t rvbar_low; - /* [0x4c] */ - uint32_t rvbar_high; - /* [0x50] */ - uint32_t pmu_snapshot; - uint32_t rsrvd_4[3]; - /* [0x60] */ - uint32_t cpu_msg_in; - uint32_t rsrvd[39]; -}; -struct al_nb_mc_pmu { - /* [0x0] PMU Global Control Register */ - uint32_t pmu_control; - /* [0x4] PMU Global Control Register */ - uint32_t overflow; - uint32_t rsrvd[62]; -}; -struct al_nb_mc_pmu_counters { - /* [0x0] Counter Configuration Register */ - uint32_t cfg; - /* [0x4] Counter Control Register */ - uint32_t cntl; - /* [0x8] Counter Control Register */ - uint32_t low; - /* [0xc] Counter Control Register */ - uint32_t high; - uint32_t rsrvd[4]; -}; -struct al_nb_nb_version { - /* [0x0] Northbridge Revision */ - uint32_t version; - uint32_t rsrvd; -}; -struct al_nb_sriov { - /* [0x0] */ - uint32_t cpu_vmid[4]; - uint32_t rsrvd[4]; -}; -struct al_nb_dram_channels { - /* [0x0] */ - uint32_t dram_0_control; - uint32_t rsrvd_0; - /* [0x8] */ - uint32_t dram_0_status; - uint32_t rsrvd_1; - /* [0x10] */ - uint32_t ddr_int_cause; - uint32_t rsrvd_2; - /* [0x18] */ - uint32_t ddr_cause_mask; - uint32_t rsrvd_3; - /* [0x20] */ - uint32_t address_map; - uint32_t rsrvd_4[3]; - /* [0x30] */ - uint32_t reorder_id_mask_0; - /* [0x34] */ - uint32_t reorder_id_value_0; - /* [0x38] */ - uint32_t reorder_id_mask_1; - /* [0x3c] */ - uint32_t reorder_id_value_1; - /* [0x40] */ - uint32_t reorder_id_mask_2; - /* [0x44] */ - uint32_t reorder_id_value_2; - /* [0x48] */ - uint32_t reorder_id_mask_3; - /* [0x4c] */ - uint32_t reorder_id_value_3; - /* [0x50] */ - uint32_t mrr_control_status; - uint32_t rsrvd[43]; -}; -struct al_nb_ddr_0_mrr { - /* [0x0] Counter Configuration Register */ - uint32_t val; -}; -struct al_nb_push_packet { - /* [0x0] */ - uint32_t pp_config; - uint32_t rsrvd_0[3]; - /* [0x10] */ - uint32_t pp_ext_awuser; - uint32_t rsrvd_1[3]; - /* [0x20] */ - uint32_t pp_base_low; - /* [0x24] */ - uint32_t pp_base_high; - uint32_t rsrvd_2[2]; - /* [0x30] */ - uint32_t pp_sel_awuser; - uint32_t rsrvd[51]; -}; - -struct al_nb_regs { - struct al_nb_global global; /* [0x0] */ - struct al_nb_system_counter system_counter; /* [0x1000] */ - struct al_nb_rams_control_misc rams_control_misc; /* [0x1100] */ - struct al_nb_ca15_rams_control ca15_rams_control[5]; /* [0x1200] */ - uint32_t rsrvd_0[108]; - struct al_nb_semaphores semaphores[64]; /* [0x1400] */ - uint32_t rsrvd_1[320]; - struct al_nb_debug debug; /* [0x1a00] */ - uint32_t rsrvd_2[256]; - struct al_nb_cpun_config_status cpun_config_status[4]; /* [0x2000] */ - uint32_t rsrvd_3[1792]; - struct al_nb_mc_pmu mc_pmu; /* [0x4000] */ - struct al_nb_mc_pmu_counters mc_pmu_counters[4]; /* [0x4100] */ - uint32_t rsrvd_4[160]; - struct al_nb_nb_version nb_version; /* [0x4400] */ - uint32_t rsrvd_5[126]; - struct al_nb_sriov sriov; /* [0x4600] */ - uint32_t rsrvd_6[120]; - struct al_nb_dram_channels dram_channels; /* [0x4800] */ - struct al_nb_ddr_0_mrr ddr_0_mrr[9]; /* [0x4900] */ - uint32_t rsrvd_7[439]; - uint32_t rsrvd_8[1024]; /* [0x5000] */ - struct al_nb_push_packet push_packet; /* [0x6000] */ -}; - - -/* -* Registers Fields -*/ - - -/**** CPUs_Config register ****/ -/* Disable broadcast of barrier onto system bus. -Connect to Processor Cluster SYSBARDISABLE. */ -#define NB_GLOBAL_CPUS_CONFIG_SYSBARDISABLE (1 << 0) -/* Enable broadcast of inner shareable transactions from CPUs. -Connect to Processor Cluster BROADCASTINNER. */ -#define NB_GLOBAL_CPUS_CONFIG_BROADCASTINNER (1 << 1) -/* Disable broadcast of cache maintenance system bus. -Connect to Processor Cluster BROADCASTCACHEMAIN */ -#define NB_GLOBAL_CPUS_CONFIG_BROADCASTCACHEMAINT (1 << 2) -/* Enable broadcast of outer shareable transactions from CPUs. -Connect to Processor Cluster BROADCASTOUTER. */ -#define NB_GLOBAL_CPUS_CONFIG_BROADCASTOUTER (1 << 3) -/* Defines the internal CPU GIC operating frequency ratio with the main CPU clock. -0x0: 1:1 -0x1: 1:2 -0x2: 1:3 -0x3: 1:4 - -Note: This is not in used with CA57 */ -#define NB_GLOBAL_CPUS_CONFIG_PERIPHCLKEN_MASK 0x00000030 -#define NB_GLOBAL_CPUS_CONFIG_PERIPHCLKEN_SHIFT 4 -/* Disables the GIC CPU interface logic and routes the legacy nIRQ, nFIQ, nVIRQ, and nVFIQ -signals directly to the processor: -0 Enable the GIC CPU interface logic. -1 Disable the GIC CPU interface logic. -The processor only samples this signal as it exits reset. */ -#define NB_GLOBAL_CPUS_CONFIG_GIC_DISABLE (1 << 6) -/* Disable L1 data cache and L2 snoop tag RAMs automatic invalidate on reset functionality */ -#define NB_GLOBAL_CPUS_CONFIG_DBG_L1_RESET_DISABLE (1 << 7) -/* Value read in the Cluster ID Affinity Level-1 field, bits[15:8], of the Multiprocessor Affinity -Register (MPIDR). -This signal is only sampled during reset of the processor. */ -#define NB_GLOBAL_CPUS_CONFIG_CLUSTERIDAFF1_MASK 0x00FF0000 -#define NB_GLOBAL_CPUS_CONFIG_CLUSTERIDAFF1_SHIFT 16 -/* Value read in the Cluster ID Affinity Level-2 field, bits[23:16], of the Multiprocessor Affinity -Register (MPIDR). -This signal is only sampled during reset of the processor.. */ -#define NB_GLOBAL_CPUS_CONFIG_CLUSTERIDAFF2_MASK 0xFF000000 -#define NB_GLOBAL_CPUS_CONFIG_CLUSTERIDAFF2_SHIFT 24 - -/**** CPUs_Secure register ****/ -/* DBGEN - */ -#define NB_GLOBAL_CPUS_SECURE_DBGEN (1 << 0) -/* NIDEN - */ -#define NB_GLOBAL_CPUS_SECURE_NIDEN (1 << 1) -/* SPIDEN - */ -#define NB_GLOBAL_CPUS_SECURE_SPIDEN (1 << 2) -/* SPNIDEN - */ -#define NB_GLOBAL_CPUS_SECURE_SPNIDEN (1 << 3) -/* Disable write access to some secure GIC registers */ -#define NB_GLOBAL_CPUS_SECURE_CFGSDISABLE (1 << 4) -/* Disable write access to some secure IOGIC registers */ -#define NB_GLOBAL_CPUS_SECURE_IOGIC_CFGSDISABLE (1 << 5) - -/**** CPUs_Init_Control register ****/ -/* CPU Init Done -Specifies which CPUs' inits are done and can exit poreset. -By default, CPU0 only exits poreset when the CPUs cluster exits power-on-reset and then kicks other CPUs. -If this bit is cleared for a specific CPU, setting it by primary CPU as part of the initialization process will initiate power-on-reset to this specific CPU. */ -#define NB_GLOBAL_CPUS_INIT_CONTROL_CPUS_INITDONE_MASK 0x0000000F -#define NB_GLOBAL_CPUS_INIT_CONTROL_CPUS_INITDONE_SHIFT 0 -/* DBGPWRDNREQ Mask -When CPU does not exist, its DBGPWRDNREQ must be asserted. -If corresponding mask bit is set, the DBGPWDNREQ is deasserted. */ -#define NB_GLOBAL_CPUS_INIT_CONTROL_DBGPWRDNREQ_MASK_MASK 0x000000F0 -#define NB_GLOBAL_CPUS_INIT_CONTROL_DBGPWRDNREQ_MASK_SHIFT 4 -/* Force CPU init power-on-reset exit. -For debug purposes only. */ -#define NB_GLOBAL_CPUS_INIT_CONTROL_FORCE_CPUPOR_MASK 0x00000F00 -#define NB_GLOBAL_CPUS_INIT_CONTROL_FORCE_CPUPOR_SHIFT 8 -/* Force dbgpwrdup signal high -If dbgpwrdup is clear on the processor interface it indicates that the process debug resources are not available for APB access. */ -#define NB_GLOBAL_CPUS_INIT_CONTROL_FORCE_DBGPWRDUP_MASK 0x0000F000 -#define NB_GLOBAL_CPUS_INIT_CONTROL_FORCE_DBGPWRDUP_SHIFT 12 - -/**** CPUs_Init_Status register ****/ -/* Specifies which CPUs are enabled in the device configuration. -sample at rst_cpus_exist[3:0] reset strap. */ -#define NB_GLOBAL_CPUS_INIT_STATUS_CPUS_EXIST_MASK 0x0000000F -#define NB_GLOBAL_CPUS_INIT_STATUS_CPUS_EXIST_SHIFT 0 - -/**** NB_Int_Cause register ****/ -/* - * Each bit corresponds to an IRQ. - * value is 1 for level irq, 0 for trigger irq - * Level IRQ indices: 12-13, 23, 24, 26-29 - */ -#define NB_GLOBAL_NB_INT_CAUSE_LEVEL_IRQ_MASK 0x3D803000 -/* Cross trigger interrupt */ -#define NB_GLOBAL_NB_INT_CAUSE_NCTIIRQ_MASK 0x0000000F -#define NB_GLOBAL_NB_INT_CAUSE_NCTIIRQ_SHIFT 0 -/* Communications channel receive. Receive portion of Data Transfer Register full flag */ -#define NB_GLOBAL_NB_INT_CAUSE_COMMRX_MASK 0x000000F0 -#define NB_GLOBAL_NB_INT_CAUSE_COMMRX_SHIFT 4 -/* Communication channel transmit. Transmit portion of Data Transfer Register empty flag. */ -#define NB_GLOBAL_NB_INT_CAUSE_COMMTX_MASK 0x00000F00 -#define NB_GLOBAL_NB_INT_CAUSE_COMMTX_SHIFT 8 -/* Reserved, read undefined must write as zeros. */ -#define NB_GLOBAL_NB_INT_CAUSE_RESERVED_15_15 (1 << 15) -/* Error indicator for AXI write transactions with a BRESP error condition. Writing 0 to bit[29] of the L2ECTLR clears the error indicator connected to CA15 nAXIERRIRQ. */ -#define NB_GLOBAL_NB_INT_CAUSE_CPU_AXIERRIRQ (1 << 16) -/* Error indicator for: L2 RAM double-bit ECC error, illegal writes to the GIC memory-map region. */ -#define NB_GLOBAL_NB_INT_CAUSE_CPU_INTERRIRQ (1 << 17) -/* Coherent fabric error summary interrupt */ -#define NB_GLOBAL_NB_INT_CAUSE_ACF_ERRORIRQ (1 << 18) -/* DDR Controller ECC Correctable error summary interrupt */ -#define NB_GLOBAL_NB_INT_CAUSE_MCTL_ECC_CORR_ERR (1 << 19) -/* DDR Controller ECC Uncorrectable error summary interrupt */ -#define NB_GLOBAL_NB_INT_CAUSE_MCTL_ECC_UNCORR_ERR (1 << 20) -/* DRAM parity error interrupt */ -#define NB_GLOBAL_NB_INT_CAUSE_MCTL_PARITY_ERR (1 << 21) -/* Reserved, not functional */ -#define NB_GLOBAL_NB_INT_CAUSE_MCTL_WDATARAM_PAR (1 << 22) -/* Error cause summary interrupt */ -#define NB_GLOBAL_NB_INT_CAUSE_ERR_CAUSE_SUM_A0 (1 << 23) -/* SB PoS error */ -#define NB_GLOBAL_NB_INT_CAUSE_SB_POS_ERR (1 << 24) -/* Received msix is not mapped to local GIC or IO-GIC spin */ -#define NB_GLOBAL_NB_INT_CAUSE_MSIX_ERR_INT_M0 (1 << 25) -/* Coresight timestamp overflow */ -#define NB_GLOBAL_NB_INT_CAUSE_CORESIGHT_TS_OVERFLOW_M0 (1 << 26) - -/**** SEV_Int_Cause register ****/ -/* SMMU 0/1 global non-secure fault interrupt */ -#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_GBL_FLT_IRPT_NS_MASK 0x00000003 -#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_GBL_FLT_IRPT_NS_SHIFT 0 -/* SMMU 0/1 non-secure context interrupt */ -#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_CXT_IRPT_NS_MASK 0x0000000C -#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_CXT_IRPT_NS_SHIFT 2 -/* SMMU0/1 Non-secure configuration access fault interrupt */ -#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_CFG_FLT_IRPT_S_MASK 0x00000030 -#define NB_GLOBAL_SEV_INT_CAUSE_SMMU_CFG_FLT_IRPT_S_SHIFT 4 -/* Reserved. Read undefined; must write as zeros. */ -#define NB_GLOBAL_SEV_INT_CAUSE_RESERVED_11_6_MASK 0x00000FC0 -#define NB_GLOBAL_SEV_INT_CAUSE_RESERVED_11_6_SHIFT 6 -/* Reserved. Read undefined; must write as zeros. */ -#define NB_GLOBAL_SEV_INT_CAUSE_RESERVED_31_20_MASK 0xFFF00000 -#define NB_GLOBAL_SEV_INT_CAUSE_RESERVED_31_20_SHIFT 20 - -/**** PMUs_Int_Cause register ****/ -/* CPUs PMU Overflow interrupt */ -#define NB_GLOBAL_PMUS_INT_CAUSE_CPUS_OVFL_MASK 0x0000000F -#define NB_GLOBAL_PMUS_INT_CAUSE_CPUS_OVFL_SHIFT 0 -/* Northbridge PMU overflow */ -#define NB_GLOBAL_PMUS_INT_CAUSE_NB_OVFL (1 << 4) -/* Memory Controller PMU overflow */ -#define NB_GLOBAL_PMUS_INT_CAUSE_MCTL_OVFL (1 << 5) -/* Coherency Interconnect PMU overflow */ -#define NB_GLOBAL_PMUS_INT_CAUSE_CCI_OVFL_MASK 0x000007C0 -#define NB_GLOBAL_PMUS_INT_CAUSE_CCI_OVFL_SHIFT 6 -/* Coherency Interconnect PMU overflow */ -#define NB_GLOBAL_PMUS_INT_CAUSE_SMMU_OVFL_MASK 0x00001800 -#define NB_GLOBAL_PMUS_INT_CAUSE_SMMU_OVFL_SHIFT 11 -/* Reserved. Read undefined; must write as zeros. */ -#define NB_GLOBAL_PMUS_INT_CAUSE_RESERVED_23_13_MASK 0x00FFE000 -#define NB_GLOBAL_PMUS_INT_CAUSE_RESERVED_23_13_SHIFT 13 -/* Southbridge PMUs overflow */ -#define NB_GLOBAL_PMUS_INT_CAUSE_SB_PMUS_OVFL_MASK 0xFF000000 -#define NB_GLOBAL_PMUS_INT_CAUSE_SB_PMUS_OVFL_SHIFT 24 - -/**** CPUs_Hold_Reset register ****/ -/* Shared L2 memory system, interrupt controller and timer logic reset. -Reset is applied only when all processors are in STNDBYWFI state. */ -#define NB_GLOBAL_CPUS_HOLD_RESET_L2RESET (1 << 0) -/* Shared debug domain reset */ -#define NB_GLOBAL_CPUS_HOLD_RESET_PRESETDBG (1 << 1) -/* Individual CPU debug, PTM, watchpoint and breakpoint logic reset */ -#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_DBGRESET_MASK 0x000000F0 -#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_DBGRESET_SHIFT 4 -/* Individual CPU core and VFP/NEON logic reset. -Reset is applied only when specific CPU is in STNDBYWFI state. */ -#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_CORERESET_MASK 0x00000F00 -#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_CORERESET_SHIFT 8 -/* Individual CPU por-on-reset. -Reset is applied only when specific CPU is in STNDBYWFI state. */ -#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_PORESET_MASK 0x0000F000 -#define NB_GLOBAL_CPUS_HOLD_RESET_CPU_PORESET_SHIFT 12 -/* Wait for interrupt mask. -If set, reset is applied without waiting for the specified CPU's STNDBYWFI state. */ -#define NB_GLOBAL_CPUS_HOLD_RESET_WFI_MASK_MASK 0x000F0000 -#define NB_GLOBAL_CPUS_HOLD_RESET_WFI_MASK_SHIFT 16 - -/**** CPUs_Software_Reset register ****/ -/* Write 1. Apply the software reset. */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_SWRESET_REQ (1 << 0) -/* Defines the level of software reset. -0x0 - cpu_core: Individual CPU core reset. -0x1 - cpu_poreset: Individual CPU power-on-reset. -0x2 - cpu_dbg: Individual CPU debug reset. -0x3 - cluster_no_dbg: A Cluster reset puts each core into core reset (no dbg) and also resets the interrupt controller and L2 logic. -0x4 - cluster: A Cluster reset puts each core into power-on-reset and also resets the interrupt controller and L2 logic. Debug is active. -0x5 - cluster_poreset: A Cluster power-on-reset puts each core into power-on-reset and also resets the interrupt controller and L2 logic. This include the cluster debug logic. */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_MASK 0x0000000E -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT 1 -/* Individual CPU core reset. */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CPU_CORE \ - (0x0 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) -/* Individual CPU power-on-reset. */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CPU_PORESET \ - (0x1 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) -/* Individual CPU debug reset. */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CPU_DBG \ - (0x2 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) -/* A Cluster reset puts each core into core reset (no dbg) and a ... */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CLUSTER_NO_DBG \ - (0x3 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) -/* A Cluster reset puts each core into power-on-reset and also r ... */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CLUSTER \ - (0x4 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) -/* A Cluster power-on-reset puts each core into power-on-reset a ... */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_CLUSTER_PORESET \ - (0x5 << NB_GLOBAL_CPUS_SOFTWARE_RESET_LEVEL_SHIFT) -/* Defines which cores to reset when no cluster_poreset is requested. */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_CORES_MASK 0x000000F0 -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_CORES_SHIFT 4 -/* CPUn wait for interrupt enable. -Defines which CPU WFI indication to wait for before applying the software reset. */ -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_WFI_MASK_MASK 0x000F0000 -#define NB_GLOBAL_CPUS_SOFTWARE_RESET_WFI_MASK_SHIFT 16 - -/**** WD_Timer0_Reset register ****/ -/* Shared L2 memory system, interrupt controller and timer logic reset */ -#define NB_GLOBAL_WD_TIMER0_RESET_L2RESET (1 << 0) -/* Shared debug domain reset */ -#define NB_GLOBAL_WD_TIMER0_RESET_PRESETDBG (1 << 1) -/* Individual CPU debug PTM, watchpoint and breakpoint logic reset */ -#define NB_GLOBAL_WD_TIMER0_RESET_CPU_DBGRESET_MASK 0x000000F0 -#define NB_GLOBAL_WD_TIMER0_RESET_CPU_DBGRESET_SHIFT 4 -/* Individual CPU core and VFP/NEON logic reset */ -#define NB_GLOBAL_WD_TIMER0_RESET_CPU_CORERESET_MASK 0x00000F00 -#define NB_GLOBAL_WD_TIMER0_RESET_CPU_CORERESET_SHIFT 8 -/* Individual CPU por-on-reset */ -#define NB_GLOBAL_WD_TIMER0_RESET_CPU_PORESET_MASK 0x0000F000 -#define NB_GLOBAL_WD_TIMER0_RESET_CPU_PORESET_SHIFT 12 - -/**** WD_Timer1_Reset register ****/ -/* Shared L2 memory system, interrupt controller and timer logic reset */ -#define NB_GLOBAL_WD_TIMER1_RESET_L2RESET (1 << 0) -/* Shared debug domain reset */ -#define NB_GLOBAL_WD_TIMER1_RESET_PRESETDBG (1 << 1) -/* Individual CPU debug PTM, watchpoint and breakpoint logic reset */ -#define NB_GLOBAL_WD_TIMER1_RESET_CPU_DBGRESET_MASK 0x000000F0 -#define NB_GLOBAL_WD_TIMER1_RESET_CPU_DBGRESET_SHIFT 4 -/* Individual CPU core and VFP/NEON logic reset */ -#define NB_GLOBAL_WD_TIMER1_RESET_CPU_CORERESET_MASK 0x00000F00 -#define NB_GLOBAL_WD_TIMER1_RESET_CPU_CORERESET_SHIFT 8 -/* Individual CPU por-on-reset */ -#define NB_GLOBAL_WD_TIMER1_RESET_CPU_PORESET_MASK 0x0000F000 -#define NB_GLOBAL_WD_TIMER1_RESET_CPU_PORESET_SHIFT 12 - -/**** WD_Timer2_Reset register ****/ -/* Shared L2 memory system, interrupt controller and timer logic reset */ -#define NB_GLOBAL_WD_TIMER2_RESET_L2RESET (1 << 0) -/* Shared debug domain reset */ -#define NB_GLOBAL_WD_TIMER2_RESET_PRESETDBG (1 << 1) -/* Individual CPU debug, PTM, watchpoint and breakpoint logic reset */ -#define NB_GLOBAL_WD_TIMER2_RESET_CPU_DBGRESET_MASK 0x000000F0 -#define NB_GLOBAL_WD_TIMER2_RESET_CPU_DBGRESET_SHIFT 4 -/* Individual CPU core and VFP/NEON logic reset */ -#define NB_GLOBAL_WD_TIMER2_RESET_CPU_CORERESET_MASK 0x00000F00 -#define NB_GLOBAL_WD_TIMER2_RESET_CPU_CORERESET_SHIFT 8 -/* Individual CPU por-on-reset */ -#define NB_GLOBAL_WD_TIMER2_RESET_CPU_PORESET_MASK 0x0000F000 -#define NB_GLOBAL_WD_TIMER2_RESET_CPU_PORESET_SHIFT 12 - -/**** WD_Timer3_Reset register ****/ -/* Shared L2 memory system, interrupt controller and timer logic reset */ -#define NB_GLOBAL_WD_TIMER3_RESET_L2RESET (1 << 0) -/* Shared debug domain reset */ -#define NB_GLOBAL_WD_TIMER3_RESET_PRESETDBG (1 << 1) -/* Individual CPU debug, PTM, watchpoint and breakpoint logic reset */ -#define NB_GLOBAL_WD_TIMER3_RESET_CPU_DBGRESET_MASK 0x000000F0 -#define NB_GLOBAL_WD_TIMER3_RESET_CPU_DBGRESET_SHIFT 4 -/* Individual CPU core and VFP/NEON logic reset */ -#define NB_GLOBAL_WD_TIMER3_RESET_CPU_CORERESET_MASK 0x00000F00 -#define NB_GLOBAL_WD_TIMER3_RESET_CPU_CORERESET_SHIFT 8 -/* Individual CPU por-on-reset */ -#define NB_GLOBAL_WD_TIMER3_RESET_CPU_PORESET_MASK 0x0000F000 -#define NB_GLOBAL_WD_TIMER3_RESET_CPU_PORESET_SHIFT 12 - -/**** DDRC_Hold_Reset register ****/ -/* DDR Control and PHY memory mapped registers reset control -0 - Reset is deasserted. -1 - Reset is asserted (active). */ -#define NB_GLOBAL_DDRC_HOLD_RESET_APB_SYNC_RESET (1 << 0) -/* DDR Control Core reset control -0 - Reset is deasserted. -1 - Reset is asserted. -This field must be set to 0 to start the initialization process after configuring the DDR Controller registers. */ -#define NB_GLOBAL_DDRC_HOLD_RESET_CORE_SYNC_RESET (1 << 1) -/* DDR Control AXI Interface reset control -0 - Reset is deasserted. -1 - Reset is asserted. -This field must not be set to 0 while core_sync_reset is set to 1. */ -#define NB_GLOBAL_DDRC_HOLD_RESET_AXI_SYNC_RESET (1 << 2) -/* DDR PUB Controller reset control -0 - Reset is deasserted. -1 - Reset is asserted. -This field must be set to 0 to start the initialization process after configuring the PUB Controller registers. */ -#define NB_GLOBAL_DDRC_HOLD_RESET_PUB_CTL_SYNC_RESET (1 << 3) -/* DDR PUB SDR Controller reset control -0 - Reset is deasserted. -1 - Reset is asserted. -This field must be set to 0 to start the initialization process after configuring the PUB Controller registers. */ -#define NB_GLOBAL_DDRC_HOLD_RESET_PUB_SDR_SYNC_RESET (1 << 4) -/* DDR PHY reset control -0 - Reset is deasserted. -1 - Reset is asserted. */ -#define NB_GLOBAL_DDRC_HOLD_RESET_PHY_SYNC_RESET (1 << 5) -/* Memory initialization input to DDR SRAM for parity check support */ -#define NB_GLOBAL_DDRC_HOLD_RESET_DDR_UNIT_MEM_INIT (1 << 6) - -/**** Fabric_Software_Reset register ****/ -/* Write 1 apply the software reset. */ -#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_SWRESET_REQ (1 << 0) -/* Defines the level of software reset: -0x0 - fabric: Fabric reset -0x1 - gic: GIC reset -0x2 - smmu: SMMU reset */ -#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_MASK 0x0000000E -#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SHIFT 1 -/* Fabric reset */ -#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_FABRIC \ - (0x0 << NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SHIFT) -/* GIC reset */ -#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_GIC \ - (0x1 << NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SHIFT) -/* SMMU reset */ -#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SMMU \ - (0x2 << NB_GLOBAL_FABRIC_SOFTWARE_RESET_LEVEL_SHIFT) -/* CPUn waiting for interrupt enable. -Defines which CPU WFI indication to wait before applying the software reset. */ -#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_WFI_MASK_MASK 0x000F0000 -#define NB_GLOBAL_FABRIC_SOFTWARE_RESET_WFI_MASK_SHIFT 16 - -/**** CPUs_Power_Ctrl register ****/ -/* L2 WFI enable -When all the processors are in WFI mode or powered-down, the shared L2 memory system Power Management controller resumes clock on any interrupt. -Power management controller resumes clock on snoop request. -NOT IMPLEMENTED */ -#define NB_GLOBAL_CPUS_POWER_CTRL_L2WFI_EN (1 << 0) -/* L2 WFI status */ -#define NB_GLOBAL_CPUS_POWER_CTRL_L2WFI_STATUS (1 << 1) -/* L2 RAMs Power Down -Power down the L2 RAMs. L2 caches must be flushed prior to entering this state. */ -#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_EN (1 << 2) -/* L2 RAMs power down status */ -#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_STATUS (1 << 3) -/* CPU state condition to enable L2 RAM power down -0 - Power down -1 - WFI -NOT IMPLEMENTED */ -#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_CPUS_STATE_MASK 0x000000F0 -#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_CPUS_STATE_SHIFT 4 -/* Enable external debugger over power-down. -Provides support for external debug over power down. If any or all of the processors are powered down, the SoC can still use the debug facilities if the debug PCLKDBG domain is powered up. */ -#define NB_GLOBAL_CPUS_POWER_CTRL_EXT_DEBUGGER_OVER_PD_EN (1 << 8) -/* L2 hardware flush request. This signal indicates: -0 L2 hardware flush request is not asserted. flush is performed by SW -1 L2 hardware flush request is asserted by power management block as part of cluster rams power down flow. HW starts L2 flush flow when all CPUs are in WFI */ -#define NB_GLOBAL_CPUS_POWER_CTRL_L2FLUSH_EN (1 << 9) -/* Force wakeup the CPU in L2RAM power down -INTERNAL DEBUG PURPOSE ONLY */ -#define NB_GLOBAL_CPUS_POWER_CTRL_FORCE_CPUS_OK_PWRUP (1 << 27) -/* L2 RAMs power down SM status */ -#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_SM_STATUS_MASK 0xF0000000 -#define NB_GLOBAL_CPUS_POWER_CTRL_L2RAMS_PWRDN_SM_STATUS_SHIFT 28 - -/**** ACF_Base_High register ****/ -/* Coherency Fabric registers base [39:32]. */ -#define NB_GLOBAL_ACF_BASE_HIGH_BASE_39_32_MASK 0x000000FF -#define NB_GLOBAL_ACF_BASE_HIGH_BASE_39_32_SHIFT 0 -/* Coherency Fabric registers base [31:15] */ -#define NB_GLOBAL_ACF_BASE_LOW_BASED_31_15_MASK 0xFFFF8000 -#define NB_GLOBAL_ACF_BASE_LOW_BASED_31_15_SHIFT 15 - -/**** ACF_Control_Override register ****/ -/* Override the AWCACHE[0] and ARCACHE[0] outputs to be -non-bufferable. One bit exists for each master interface. -Connected to BUFFERABLEOVERRIDE[2:0] */ -#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_BUFFOVRD_MASK 0x00000007 -#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_BUFFOVRD_SHIFT 0 -/* Overrides the ARQOS and AWQOS input signals. One bit exists for each slave -interface. -Connected to QOSOVERRIDE[4:0] */ -#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_QOSOVRD_MASK 0x000000F8 -#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_QOSOVRD_SHIFT 3 -/* If LOW, then AC requests are never issued on the corresponding slave -interface. One bit exists for each slave interface. -Connected to ACCHANNELEN[4:0]. */ -#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_ACE_CH_EN_MASK 0x00001F00 -#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_ACE_CH_EN_SHIFT 8 -/* Internal register: -Enables 4k hazard of post-barrier vs pre-barrier transactions. Otherwise, 64B hazard granularity is applied. */ -#define NB_GLOBAL_ACF_CONTROL_OVERRIDE_DMB_4K_HAZARD_EN (1 << 13) - -/**** LGIC_Base_High register ****/ -/* GIC registers base [39:32]. -This value is sampled into the CP15 Configuration Base Address Register (CBAR) at reset. */ -#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_39_32_MASK 0x000000FF -#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_39_32_SHIFT 0 -#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_MASK_PKR 0x00000FFF -#define NB_GLOBAL_LGIC_BASE_HIGH_BASE_43_32_SHIFT_PKR 0 -/* GIC registers base [31:15]. -This value is sampled into the CP15 Configuration Base Address Register (CBAR) at reset */ -#define NB_GLOBAL_LGIC_BASE_LOW_BASED_31_15_MASK 0xFFFF8000 -#define NB_GLOBAL_LGIC_BASE_LOW_BASED_31_15_SHIFT 15 - -/**** IOGIC_Base_High register ****/ -/* IOGIC registers base [39:32] */ -#define NB_GLOBAL_IOGIC_BASE_HIGH_BASE_39_32_MASK 0x000000FF -#define NB_GLOBAL_IOGIC_BASE_HIGH_BASE_39_32_SHIFT 0 -/* IOGIC registers base [31:15] */ -#define NB_GLOBAL_IOGIC_BASE_LOW_BASED_31_15_MASK 0xFFFF8000 -#define NB_GLOBAL_IOGIC_BASE_LOW_BASED_31_15_SHIFT 15 - -/**** IO_Wr_Split_Control register ****/ -/* Write splitters bypass. -[0] Splitter 0 bypass enable -[1] Splitter 1 bypass enable */ -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_BYPASS_MASK 0x00000003 -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_BYPASS_SHIFT 0 -/* Write splitters store and forward. -If store and forward is disabled, splitter does not check non-active BE in the middle of a transaction. */ -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_ST_FW_MASK 0x0000000C -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_ST_FW_SHIFT 2 -/* Write splitters unmodify snoop type. -Disables modifying snoop type from Clean & Invalidate to Invalidate when conditions enable it. Only split operation to 64B is applied. */ -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_UNMODIFY_SNP_MASK 0x00000030 -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_UNMODIFY_SNP_SHIFT 4 -/* Write splitters unsplit non-coherent access. -Disables splitting of non-coherent access to cache-line chunks. */ -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_UNSPLIT_NOSNP_MASK 0x000000C0 -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_UNSPLIT_NOSNP_SHIFT 6 -/* Write splitter rate limit. */ -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR0_SPLT_RATE_LIMIT_MASK 0x00001F00 -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR0_SPLT_RATE_LIMIT_SHIFT 8 -/* Write splitter rate limit */ -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR1_SPLT_RATE_LIMIT_MASK 0x0003E000 -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR1_SPLT_RATE_LIMIT_SHIFT 13 -/* Write splitters 64bit remap enable -Enables remapping of 64bit transactions */ -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_REMAP_64BIT_EN_MASK 0x000C0000 -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_REMAP_64BIT_EN_SHIFT 18 -/* Clear is not supported. This bit was changed to wr_pack_disable. -In default mode, AWADDR waits for WDATA. */ -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_CLEAR_MASK 0xC0000000 -#define NB_GLOBAL_IO_WR_SPLIT_CONTROL_WR_SPLT_CLEAR_SHIFT 30 - -/**** IO_Rd_ROB_Control register ****/ -/* Read ROB Bypass -[0] Rd ROB 0 bypass enable. -[1] Rd ROB 1 bypass enable. */ -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_BYPASS_MASK 0x00000003 -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_BYPASS_SHIFT 0 -/* Read ROB in order. -Return data in the order of request acceptance. */ -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_INORDER_MASK 0x0000000C -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_INORDER_SHIFT 2 -/* Read ROB response rate -When enabled drops one cycle from back to back read responses */ -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_RSP_RATE_MASK 0x00000030 -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD_ROB_RSP_RATE_SHIFT 4 -/* Read splitter rate limit */ -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD0_ROB_RATE_LIMIT_MASK 0x00001F00 -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD0_ROB_RATE_LIMIT_SHIFT 8 -/* Read splitter rate limit */ -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD1_ROB_RATE_LIMIT_MASK 0x0003E000 -#define NB_GLOBAL_IO_RD_ROB_CONTROL_RD1_ROB_RATE_LIMIT_SHIFT 13 - -/**** SB_PoS_Error_Log_1 register ****/ -/* Error Log 1 -[7:0] address_high -[16:8] request id -[18:17] bresp */ -#define NB_GLOBAL_SB_POS_ERROR_LOG_1_ERR_LOG_MASK 0x7FFFFFFF -#define NB_GLOBAL_SB_POS_ERROR_LOG_1_ERR_LOG_SHIFT 0 -/* Valid logged error -Set on SB PoS error occurrence on capturing the error information. Subsequent errors will not be captured until the valid bit is cleared. -The SB PoS reports on write errors. -When valid, an interrupt is set in the NB Cause Register. */ -#define NB_GLOBAL_SB_POS_ERROR_LOG_1_VALID (1 << 31) - -/**** MSIx_Error_Log register ****/ -/* Error Log -Corresponds to MSIx address message [30:0]. */ -#define NB_GLOBAL_MSIX_ERROR_LOG_ERR_LOG_MASK 0x7FFFFFFF -#define NB_GLOBAL_MSIX_ERROR_LOG_ERR_LOG_SHIFT 0 -/* Valid logged error */ -#define NB_GLOBAL_MSIX_ERROR_LOG_VALID (1 << 31) - -/**** Error_Cause register ****/ -/* Received msix is not mapped to local GIC or IO-GIC spin */ -#define NB_GLOBAL_ERROR_CAUSE_MSIX_ERR_INT (1 << 2) -/* Coresight timestamp overflow */ -#define NB_GLOBAL_ERROR_CAUSE_CORESIGHT_TS_OVERFLOW (1 << 3) -/* Write data parity error from SB channel 0. */ -#define NB_GLOBAL_ERROR_CAUSE_SB0_WRDATA_PERR (1 << 4) -/* Write data parity error from SB channel 1. */ -#define NB_GLOBAL_ERROR_CAUSE_SB1_WRDATA_PERR (1 << 5) -/* Read data parity error from SB slaves. */ -#define NB_GLOBAL_ERROR_CAUSE_SB_SLV_RDATA_PERR (1 << 6) -/* Local GIC uncorrectable ECC error */ -#define NB_GLOBAL_ERROR_CAUSE_LOCAL_GIC_ECC_FATAL (1 << 7) -/* SB PoS error */ -#define NB_GLOBAL_ERROR_CAUSE_SB_POS_ERR (1 << 8) -/* Coherent fabric error summary interrupt */ -#define NB_GLOBAL_ERROR_CAUSE_ACF_ERRORIRQ (1 << 9) -/* Error indicator for AXI write transactions with a BRESP error condition. Writing 0 to bit[29] of the L2ECTLR clears the error indicator connected to CA15 nAXIERRIRQ. */ -#define NB_GLOBAL_ERROR_CAUSE_CPU_AXIERRIRQ (1 << 10) -/* Error indicator for: L2 RAM double-bit ECC error, illegal writes to the GIC memory-map region. */ -#define NB_GLOBAL_ERROR_CAUSE_CPU_INTERRIRQ (1 << 12) -/* DDR cause summery interrupt */ -#define NB_GLOBAL_ERROR_CAUSE_DDR_CAUSE_SUM (1 << 14) - -/**** QoS_Peak_Control register ****/ -/* Peak Read Low Threshold -When the number of outstanding read transactions from SB masters is below this value, the CPU is assigned high-priority QoS. */ -#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_RD_L_THRESHOLD_MASK 0x0000007F -#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_RD_L_THRESHOLD_SHIFT 0 -/* Peak Read High Threshold -When the number of outstanding read transactions from SB masters exceeds this value, the CPU is assigned high-priority QoS. */ -#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_RD_H_THRESHOLD_MASK 0x00007F00 -#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_RD_H_THRESHOLD_SHIFT 8 -/* Peak Write Low Threshold -When the number of outstanding write transactions from SB masters is below this value, the CPU is assigned high-priority QoS */ -#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_WR_L_THRESHOLD_MASK 0x007F0000 -#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_WR_L_THRESHOLD_SHIFT 16 -/* Peak Write High Threshold -When the number of outstanding write transactions from SB masters exceeds this value, the CPU is assigned high-priority QoS. */ -#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_WR_H_THRESHOLD_MASK 0x7F000000 -#define NB_GLOBAL_QOS_PEAK_CONTROL_PEAK_WR_H_THRESHOLD_SHIFT 24 - -/**** QoS_Set_Control register ****/ -/* CPU Low priority Read QoS */ -#define NB_GLOBAL_QOS_SET_CONTROL_CPU_LP_ARQOS_MASK 0x0000000F -#define NB_GLOBAL_QOS_SET_CONTROL_CPU_LP_ARQOS_SHIFT 0 -/* CPU High priority Read QoS */ -#define NB_GLOBAL_QOS_SET_CONTROL_CPU_HP_ARQOS_MASK 0x000000F0 -#define NB_GLOBAL_QOS_SET_CONTROL_CPU_HP_ARQOS_SHIFT 4 -/* CPU Low priority Write QoS */ -#define NB_GLOBAL_QOS_SET_CONTROL_CPU_LP_AWQOS_MASK 0x00000F00 -#define NB_GLOBAL_QOS_SET_CONTROL_CPU_LP_AWQOS_SHIFT 8 -/* CPU High priority Write QoS */ -#define NB_GLOBAL_QOS_SET_CONTROL_CPU_HP_AWQOS_MASK 0x0000F000 -#define NB_GLOBAL_QOS_SET_CONTROL_CPU_HP_AWQOS_SHIFT 12 -/* SB Low priority Read QoS */ -#define NB_GLOBAL_QOS_SET_CONTROL_SB_LP_ARQOS_MASK 0x000F0000 -#define NB_GLOBAL_QOS_SET_CONTROL_SB_LP_ARQOS_SHIFT 16 -/* SB Low-priority Write QoS */ -#define NB_GLOBAL_QOS_SET_CONTROL_SB_LP_AWQOS_MASK 0x00F00000 -#define NB_GLOBAL_QOS_SET_CONTROL_SB_LP_AWQOS_SHIFT 20 - -/**** DDR_QoS register ****/ -/* High Priority Read Threshold -Limits the number of outstanding high priority reads in the system through the memory controller. -This parameter is programmed in conjunction with number of outstanding high priority reads supported by the DDR controller. */ -#define NB_GLOBAL_DDR_QOS_HIGH_PRIO_THRESHOLD_MASK 0x0000007F -#define NB_GLOBAL_DDR_QOS_HIGH_PRIO_THRESHOLD_SHIFT 0 -/* DDR Low Priority QoS -Fabric priority below this value is mapped to DDR low priority queue. */ -#define NB_GLOBAL_DDR_QOS_LP_QOS_MASK 0x00000F00 -#define NB_GLOBAL_DDR_QOS_LP_QOS_SHIFT 8 - -/**** ACF_Misc register ****/ -/* Disable DDR Write Chop -Performance optimization feature to chop non-active data beats to the DDR. */ -#define NB_GLOBAL_ACF_MISC_DDR_WR_CHOP_DIS (1 << 0) -/* Disable SB-2-SB path through NB fabric. */ -#define NB_GLOBAL_ACF_MISC_SB2SB_PATH_DIS (1 << 1) -/* Disable ETR tracing to non-DDR. */ -#define NB_GLOBAL_ACF_MISC_ETR2SB_PATH_DIS (1 << 2) -/* Disable ETR tracing to non-DDR. */ -#define NB_GLOBAL_ACF_MISC_CPU2MSIX_DIS (1 << 3) -/* Disable CPU generation of MSIx -By default, the CPU can set any MSIx message results by setting any SPIn bit in the local and IO-GIC. */ -#define NB_GLOBAL_ACF_MISC_MSIX_TERMINATE_DIS (1 << 4) -/* Disable snoop override for MSIx -By default, an MSIx transaction is downgraded to non-coherent. */ -#define NB_GLOBAL_ACF_MISC_MSIX_SNOOPOVRD_DIS (1 << 5) -/* POS bypass */ -#define NB_GLOBAL_ACF_MISC_POS_BYPASS (1 << 6) -/* PoS ReadStronglyOrdered enable -SO read forces flushing of all prior writes */ -#define NB_GLOBAL_ACF_MISC_POS_RSO_EN (1 << 7) -/* WRAP to INC transfer enable */ -#define NB_GLOBAL_ACF_MISC_POS_WRAP2INC (1 << 8) -/* PoS DSB flush Disable -On DSB from CPU, PoS blocks the progress of post-barrier reads and writes until all pre-barrier writes have been completed. */ -#define NB_GLOBAL_ACF_MISC_POS_DSB_FLUSH_DIS (1 << 9) -/* PoS DMB Flush Disable -On DMB from CPU, the PoS blocks the progress of post-barrier non-buffereable reads or writes when there are outstanding non-bufferable writes that have not yet been completed. -Other access types are hazard check against the pre-barrier requests. */ -#define NB_GLOBAL_ACF_MISC_POS_DMB_FLUSH_DIS (1 << 10) -/* change DMB functionality to DSB (block and drain) */ -#define NB_GLOBAL_ACF_MISC_POS_DMB_TO_DSB_EN (1 << 11) -/* Disable write after read stall when accessing IO fabric slaves. */ -#define NB_GLOBAL_ACF_MISC_M0_WAR_STALL_DIS (1 << 12) -/* Disable write after read stall when accessing DDR */ -#define NB_GLOBAL_ACF_MISC_M1_WAR_STALL_DIS (1 << 13) -/* Disable counter (wait 1000 NB cycles) before applying PoS enable/disable configuration */ -#define NB_GLOBAL_ACF_MISC_POS_CONFIG_CNT_DIS (1 << 14) -/* Disable wr spliter A0 bug fixes */ -#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_M0_MODE (1 << 16) -/* Disable wr spliter PKR bug fixes */ -#define NB_GLOBAL_ACF_MISC_WRSPLT_ALPINE_A0_MODE (1 << 17) -/* Override the address parity calucation for write transactions going to IO-fabric */ -#define NB_GLOBAL_ACF_MISC_NB_NIC_AWADDR_PAR_OVRD (1 << 18) -/* Override the data parity calucation for write transactions going to IO-fabric */ -#define NB_GLOBAL_ACF_MISC_NB_NIC_WDATA_PAR_OVRD (1 << 19) -/* Override the address parity calucation for read transactions going to IO-fabric */ -#define NB_GLOBAL_ACF_MISC_NB_NIC_ARADDR_PAR_OVRD (1 << 20) -/* Halts CPU AXI interface (Ar/Aw channels), not allowing the CPU to send additional transactions */ -#define NB_GLOBAL_ACF_MISC_CPU_AXI_HALT (1 << 23) -/* Disable early arbar termination when fabric write buffer is enabled. */ -#define NB_GLOBAL_ACF_MISC_CCIWB_EARLY_ARBAR_TERM_DIS (1 << 24) -/* Enable wire interrupts connectivity to IO-GIC IRQs */ -#define NB_GLOBAL_ACF_MISC_IOGIC_CHIP_SPI_EN (1 << 25) -/* Enable DMB flush request to NB to SB PoS when barrier is terminted inside the processor cluster */ -#define NB_GLOBAL_ACF_MISC_CPU_DSB_FLUSH_DIS (1 << 26) -/* Enable DMB flush request to NB to SB PoS when barrier is terminted inside the processor cluster */ -#define NB_GLOBAL_ACF_MISC_CPU_DMB_FLUSH_DIS (1 << 27) -/* Peakrock only: remap CPU address above 40 bits to Slave Error -INTERNAL */ -#define NB_GLOBAL_ACF_MISC_ADDR43_40_REMAP_DIS (1 << 28) -/* Enable CPU WriteUnique to WriteNoSnoop trasform */ -#define NB_GLOBAL_ACF_MISC_CPU_WU2WNS_EN (1 << 29) -/* Disable device after device check */ -#define NB_GLOBAL_ACF_MISC_WR_POS_DEV_AFTER_DEV_DIS (1 << 30) -/* Disable wrap to inc on write */ -#define NB_GLOBAL_ACF_MISC_WR_INC2WRAP_EN (1 << 31) - -/**** Config_Bus_Control register ****/ -/* Write slave error enable */ -#define NB_GLOBAL_CONFIG_BUS_CONTROL_WR_SLV_ERR_EN (1 << 0) -/* Write decode error enable */ -#define NB_GLOBAL_CONFIG_BUS_CONTROL_WR_DEC_ERR_EN (1 << 1) -/* Read slave error enable */ -#define NB_GLOBAL_CONFIG_BUS_CONTROL_RD_SLV_ERR_EN (1 << 2) -/* Read decode error enable */ -#define NB_GLOBAL_CONFIG_BUS_CONTROL_RD_DEC_ERR_EN (1 << 3) -/* Ignore Write ID */ -#define NB_GLOBAL_CONFIG_BUS_CONTROL_IGNORE_WR_ID (1 << 4) -/* Timeout limit before terminating configuration bus access with slave error */ -#define NB_GLOBAL_CONFIG_BUS_CONTROL_TIMEOUT_LIMIT_MASK 0xFFFFFF00 -#define NB_GLOBAL_CONFIG_BUS_CONTROL_TIMEOUT_LIMIT_SHIFT 8 - -/**** Pos_ID_Match register ****/ -/* Enable Device (GRE and nGRE) after Device ID hazard */ -#define NB_GLOBAL_POS_ID_MATCH_ENABLE (1 << 0) -/* ID Field Mask -If set, corresonpding ID bits are not used for ID match */ -#define NB_GLOBAL_POS_ID_MATCH_MASK_MASK 0xFFFF0000 -#define NB_GLOBAL_POS_ID_MATCH_MASK_SHIFT 16 - -/**** sb_sel_override_awuser register ****/ -/* Select whether to use transaction awuser or sb_override_awuser value for awuser field on outgoing write transactions to SB. -Each bit if set to 1 selects the corresponding sb_override_awuser bit. Otherwise, selects the corersponding transaction awuser bit. */ -#define NB_GLOBAL_SB_SEL_OVERRIDE_AWUSER_SEL_MASK 0x03FFFFFF -#define NB_GLOBAL_SB_SEL_OVERRIDE_AWUSER_SEL_SHIFT 0 - -/**** sb_override_awuser register ****/ -/* Awuser to use on overriden transactions -Only applicable if sel_override_awuser.sel is set to 1'b1 for the coressponding bit */ -#define NB_GLOBAL_SB_OVERRIDE_AWUSER_AWUSER_MASK 0x03FFFFFF -#define NB_GLOBAL_SB_OVERRIDE_AWUSER_AWUSER_SHIFT 0 - -/**** sb_sel_override_aruser register ****/ -/* Select whether to use transaction aruser or sb_override_aruser value for aruser field on outgoing read transactions to SB. -Each bit if set to 1 selects the corresponding sb_override_aruser bit. Otherwise, selects the corersponding transaction aruser bit. */ -#define NB_GLOBAL_SB_SEL_OVERRIDE_ARUSER_SEL_MASK 0x03FFFFFF -#define NB_GLOBAL_SB_SEL_OVERRIDE_ARUSER_SEL_SHIFT 0 - -/**** sb_override_aruser register ****/ -/* Aruser to use on overriden transactions -Only applicable if sb_sel_override_aruser.sel is set to 1'b1 for the coressponding bit */ -#define NB_GLOBAL_SB_OVERRIDE_ARUSER_ARUSER_MASK 0x03FFFFFF -#define NB_GLOBAL_SB_OVERRIDE_ARUSER_ARUSER_SHIFT 0 - -/**** Coresight_PD register ****/ -/* ETF0 RAM force power down */ -#define NB_GLOBAL_CORESIGHT_PD_ETF0_RAM_FORCE_PD (1 << 0) -/* ETF1 RAM force power down */ -#define NB_GLOBAL_CORESIGHT_PD_ETF1_RAM_FORCE_PD (1 << 1) -/* ETF0 RAM force clock gate */ -#define NB_GLOBAL_CORESIGHT_PD_ETF0_RAM_FORCE_CG (1 << 2) -/* ETF1 RAM force clock gate */ -#define NB_GLOBAL_CORESIGHT_PD_ETF1_RAM_FORCE_CG (1 << 3) -/* APBIC clock enable */ -#define NB_GLOBAL_CORESIGHT_PD_APBICLKEN (1 << 4) -/* DAP system clock enable */ -#define NB_GLOBAL_CORESIGHT_PD_DAP_SYS_CLKEN (1 << 5) - -/**** Coresight_INTERNAL_0 register ****/ - -#define NB_GLOBAL_CORESIGHT_INTERNAL_0_CTIAPBSBYPASS (1 << 0) -/* CA15 CTM and Coresight CTI operate at same clock, bypass modes can be enabled but it's being set to bypass disable to break timing path. */ -#define NB_GLOBAL_CORESIGHT_INTERNAL_0_CISBYPASS (1 << 1) -/* CA15 CTM and Coresight CTI operate according to the same clock. -Bypass modes can be enabled, but it is set to bypass disable, to break the timing path. */ -#define NB_GLOBAL_CORESIGHT_INTERNAL_0_CIHSBYPASS_MASK 0x0000003C -#define NB_GLOBAL_CORESIGHT_INTERNAL_0_CIHSBYPASS_SHIFT 2 - -/**** Coresight_DBGROMADDR register ****/ -/* Valid signal for DBGROMADDR. -Connected to DBGROMADDRV */ -#define NB_GLOBAL_CORESIGHT_DBGROMADDR_VALID (1 << 0) -/* Specifies bits [39:12] of the ROM table physical address. */ -#define NB_GLOBAL_CORESIGHT_DBGROMADDR_ADDR_39_12_MASK 0x3FFFFFFC -#define NB_GLOBAL_CORESIGHT_DBGROMADDR_ADDR_39_12_SHIFT 2 - -/**** Coresight_DBGSELFADDR register ****/ -/* Valid signal for DBGROMADDR. -Connected to DBGROMADDRV */ -#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_VALID (1 << 0) -/* Specifies bits [18:17] of the two's complement signed offset from the ROM table physical address to the physical address where the debug registers are memory-mapped. -Note: The CA15 debug unit starts at offset 0x1 within the Coresight cluster. */ -#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_ADDR_18_17_MASK 0x00000180 -#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_ADDR_18_17_SHIFT 7 -/* Specifies bits [39:19] of the two's complement signed offset from the ROM table physical address to the physical address where the debug registers are memory-mapped. -Note: The CA15 debug unit starts at offset 0x1 within the Coresight cluster, so this offset if fixed to zero. */ -#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_ADDR_39_19_MASK 0x3FFFFE00 -#define NB_GLOBAL_CORESIGHT_DBGSELFADDR_ADDR_39_19_SHIFT 9 - -/**** SB_force_same_id_cfg_0 register ****/ -/* Enables force same id mechanism for SB port 0 */ -#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_0_FORCE_SAME_ID_EN (1 << 0) -/* Enables MSIx stall when write transactions from same ID mechanism are in progress for SB port 0 */ -#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_0_FORCE_SAME_ID_MSIX_STALL_EN (1 << 1) -/* Mask for choosing which ID bits to match for indicating the originating master */ -#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_0_SB_MSTR_ID_MASK_MASK 0x000000F8 -#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_0_SB_MSTR_ID_MASK_SHIFT 3 - -/**** SB_force_same_id_cfg_1 register ****/ -/* Enables force same id mechanism for SB port 1 */ -#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_1_FORCE_SAME_ID_EN (1 << 0) -/* Enables MSIx stall when write transactions from same ID mechanism are in progress for SB port 1 */ -#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_1_FORCE_SAME_ID_MSIX_STALL_EN (1 << 1) -/* Mask for choosing which ID bits to match for indicating the originating master */ -#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_1_SB_MSTR_ID_MASK_MASK 0x000000F8 -#define NB_GLOBAL_SB_FORCE_SAME_ID_CFG_1_SB_MSTR_ID_MASK_SHIFT 3 - -/**** Cnt_Control register ****/ -/* System counter enable -Counter is enabled after reset. */ -#define NB_SYSTEM_COUNTER_CNT_CONTROL_EN (1 << 0) -/* System counter restart -Initial value is reloaded from Counter_Init_L and Counter_Init_H registers. -Transition from 0 to 1 reloads the register. */ -#define NB_SYSTEM_COUNTER_CNT_CONTROL_RESTART (1 << 1) -/* Disable CTI trigger out that halt the counter progress */ -#define NB_SYSTEM_COUNTER_CNT_CONTROL_CTI_TRIGOUT_HALT_DIS (1 << 2) -/* System counter tick -Specifies the counter tick rate relative to the Northbridge clock, e.g., the counter is incremented every 16 NB cycles if programmed to 0x0f. */ -#define NB_SYSTEM_COUNTER_CNT_CONTROL_SCALE_MASK 0x0000FF00 -#define NB_SYSTEM_COUNTER_CNT_CONTROL_SCALE_SHIFT 8 - -/**** CA15_RF_Misc register ****/ - -#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_NONECPU_RF_MISC_MASK 0x0000000F -#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_NONECPU_RF_MISC_SHIFT 0 - -#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_CPU_RF_MISC_MASK 0x00FFFF00 -#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_CPU_RF_MISC_SHIFT 8 -/* Pause for CPUs from the time all power is up to the time the SRAMs start opening. */ -#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_PWR_UP_PAUSE_MASK 0xF8000000 -#define NB_RAMS_CONTROL_MISC_CA15_RF_MISC_PWR_UP_PAUSE_SHIFT 27 - -/**** NB_RF_Misc register ****/ -/* SMMU TLB RAMs force power down */ -#define NB_RAMS_CONTROL_MISC_NB_RF_MISC_SMMU_RAM_FORCE_PD (1 << 0) - -/**** Lockn register ****/ -/* Semaphore Lock -CPU reads it: -If current value ==0, return 0 to CPU but set bit to 1. (CPU knows it captured the semaphore.) -If current value ==1, return 1 to CPU. (CPU knows it is already used and waits.) -CPU writes 0 to it to release the semaphore. */ -#define NB_SEMAPHORES_LOCKN_LOCK (1 << 0) - -/**** CA15_outputs_1 register ****/ -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_1_STANDBYWFI_MASK 0x0000000F -#define NB_DEBUG_CA15_OUTPUTS_1_STANDBYWFI_SHIFT 0 -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_1_CPU_PWR_DN_ACK_MASK 0x000000F0 -#define NB_DEBUG_CA15_OUTPUTS_1_CPU_PWR_DN_ACK_SHIFT 4 -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_1_IRQOUT_N_MASK 0x00000F00 -#define NB_DEBUG_CA15_OUTPUTS_1_IRQOUT_N_SHIFT 8 -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_1_FIQOUT_N_MASK 0x0000F000 -#define NB_DEBUG_CA15_OUTPUTS_1_FIQOUT_N_SHIFT 12 -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_1_CNTHPIRQ_N_MASK 0x000F0000 -#define NB_DEBUG_CA15_OUTPUTS_1_CNTHPIRQ_N_SHIFT 16 -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_1_NCNTPNSIRQ_N_MASK 0x00F00000 -#define NB_DEBUG_CA15_OUTPUTS_1_NCNTPNSIRQ_N_SHIFT 20 -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_1_NCNTPSIRQ_N_MASK 0x0F000000 -#define NB_DEBUG_CA15_OUTPUTS_1_NCNTPSIRQ_N_SHIFT 24 -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_1_NCNTVIRQ_N_MASK 0xF0000000 -#define NB_DEBUG_CA15_OUTPUTS_1_NCNTVIRQ_N_SHIFT 28 - -/**** CA15_outputs_2 register ****/ -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_2_STANDBYWFIL2 (1 << 0) -/* - */ -#define NB_DEBUG_CA15_OUTPUTS_2_L2RAM_PWR_DN_ACK (1 << 1) -/* Indicates for each CPU if coherency is enabled - */ -#define NB_DEBUG_CA15_OUTPUTS_2_SMPEN_MASK 0x0000003C -#define NB_DEBUG_CA15_OUTPUTS_2_SMPEN_SHIFT 2 - -/**** cpu_msg register ****/ -/* Status/ASCII code */ -#define NB_DEBUG_CPU_MSG_STATUS_MASK 0x000000FF -#define NB_DEBUG_CPU_MSG_STATUS_SHIFT 0 -/* Toggle with each ASCII write */ -#define NB_DEBUG_CPU_MSG_ASCII_TOGGLE (1 << 8) -/* Signals ASCII */ -#define NB_DEBUG_CPU_MSG_ASCII (1 << 9) - -#define NB_DEBUG_CPU_MSG_RESERVED_11_10_MASK 0x00000C00 -#define NB_DEBUG_CPU_MSG_RESERVED_11_10_SHIFT 10 -/* Signals new section started in S/W */ -#define NB_DEBUG_CPU_MSG_SECTION_START (1 << 12) - -#define NB_DEBUG_CPU_MSG_RESERVED_13 (1 << 13) -/* Signals a single CPU is done. */ -#define NB_DEBUG_CPU_MSG_CPU_DONE (1 << 14) -/* Signals test is done */ -#define NB_DEBUG_CPU_MSG_TEST_DONE (1 << 15) - -/**** ddrc register ****/ -/* External DLL calibration request. Also compensates for VT variations, such as an external request for the controller (can be performed automatically by the controller at the normal settings). */ -#define NB_DEBUG_DDRC_DLL_CALIB_EXT_REQ (1 << 0) -/* External request to perform short (long is performed during initialization) and/or ODT calibration. */ -#define NB_DEBUG_DDRC_ZQ_SHORT_CALIB_EXT_REQ (1 << 1) -/* External request to perform a refresh command to a specific bank. Usually performed automatically by the controller, however, the controller supports disabling of the automatic mechanism, and use of an external pulse instead. */ -#define NB_DEBUG_DDRC_RANK_REFRESH_EXT_REQ_MASK 0x0000003C -#define NB_DEBUG_DDRC_RANK_REFRESH_EXT_REQ_SHIFT 2 - -/**** ddrc_phy_smode_control register ****/ -/* DDR PHY special mode */ -#define NB_DEBUG_DDRC_PHY_SMODE_CONTROL_CTL_MASK 0x0000FFFF -#define NB_DEBUG_DDRC_PHY_SMODE_CONTROL_CTL_SHIFT 0 - -/**** ddrc_phy_smode_status register ****/ -/* DDR PHY special mode */ -#define NB_DEBUG_DDRC_PHY_SMODE_STATUS_STT_MASK 0x0000FFFF -#define NB_DEBUG_DDRC_PHY_SMODE_STATUS_STT_SHIFT 0 - -/**** pmc register ****/ -/* Enable system control on NB DRO */ -#define NB_DEBUG_PMC_SYS_EN (1 << 0) -/* NB PMC HVT35 counter value */ -#define NB_DEBUG_PMC_HVT35_VAL_14_0_MASK 0x0000FFFE -#define NB_DEBUG_PMC_HVT35_VAL_14_0_SHIFT 1 -/* NB PMC SVT31 counter value */ -#define NB_DEBUG_PMC_SVT31_VAL_14_0_MASK 0x7FFF0000 -#define NB_DEBUG_PMC_SVT31_VAL_14_0_SHIFT 16 - -/**** cpus_general register ****/ -/* Swaps sysaddr[16:14] with sysaddr[19:17] for DDR access*/ -#define NB_DEBUG_CPUS_GENERAL_ADDR_MAP_ECO (1 << 23) - -/**** cpus_int_out register ****/ -/* Defines which CPUs' FIQ will be triggered out through the cpus_int_out[1] pinout. */ -#define NB_DEBUG_CPUS_INT_OUT_FIQ_EN_MASK 0x0000000F -#define NB_DEBUG_CPUS_INT_OUT_FIQ_EN_SHIFT 0 -/* Defines which CPUs' IRQ will be triggered out through the cpus_int_out[0] pinout. */ -#define NB_DEBUG_CPUS_INT_OUT_IRQ_EN_MASK 0x000000F0 -#define NB_DEBUG_CPUS_INT_OUT_IRQ_EN_SHIFT 4 -/* Defines which CPUs' SEI will be triggered out through the cpus_int_out[0] pinout. */ -#define NB_DEBUG_CPUS_INT_OUT_IRQ_SEI_EN_MASK 0x00000F00 -#define NB_DEBUG_CPUS_INT_OUT_IRQ_SEI_EN_SHIFT 8 - -/**** latch_pc_req register ****/ -/* If set, request to latch execution PC from processor cluster */ -#define NB_DEBUG_LATCH_PC_REQ_EN (1 << 0) -/* target CPU id to latch its execution PC */ -#define NB_DEBUG_LATCH_PC_REQ_CPU_ID_MASK 0x000000F0 -#define NB_DEBUG_LATCH_PC_REQ_CPU_ID_SHIFT 4 - -/**** latch_pc_low register ****/ -/* Set by hardware when the processor cluster ack the PC latch request. -Clear on read latch_pc_high */ -#define NB_DEBUG_LATCH_PC_LOW_VALID (1 << 0) -/* Latched PC value [31:1] */ -#define NB_DEBUG_LATCH_PC_LOW_VAL_MASK 0xFFFFFFFE -#define NB_DEBUG_LATCH_PC_LOW_VAL_SHIFT 1 - -/**** track_dump_ctrl register ****/ -/* [24:16]: Queue entry pointer -[2] Target queue: 1'b0: HazardTrack or 1'b1: AmiRMI queues -[1:0]: CCI target master: 2'b00: M0, 2'b01: M1, 2'b10: M2 */ -#define NB_DEBUG_TRACK_DUMP_CTRL_PTR_MASK 0x7FFFFFFF -#define NB_DEBUG_TRACK_DUMP_CTRL_PTR_SHIFT 0 -/* Track Dump Request -If set, queue entry info is latched on track_dump_rdata register. -Program the pointer and target queue. -This is a full handshake register. -Read bit from track_dump_rdata register. If set, clear the request field before triggering a new request. */ -#define NB_DEBUG_TRACK_DUMP_CTRL_REQ (1 << 31) - -/**** track_dump_rdata_0 register ****/ -/* Valid */ -#define NB_DEBUG_TRACK_DUMP_RDATA_0_VALID (1 << 0) -/* Low data */ -#define NB_DEBUG_TRACK_DUMP_RDATA_0_DATA_MASK 0xFFFFFFFE -#define NB_DEBUG_TRACK_DUMP_RDATA_0_DATA_SHIFT 1 - -/**** pos_track_dump_ctrl register ****/ -/* [24:16]: queue entry pointer */ -#define NB_DEBUG_POS_TRACK_DUMP_CTRL_PTR_MASK 0x7FFFFFFF -#define NB_DEBUG_POS_TRACK_DUMP_CTRL_PTR_SHIFT 0 -/* Track Dump Request -If set, queue entry info is latched on track_dump_rdata register. -Program the pointer and target queue. -This is a full handshake register -Read bit from track_dump_rdata register. If set, clear the request field before triggering a new request. */ -#define NB_DEBUG_POS_TRACK_DUMP_CTRL_REQ (1 << 31) - -/**** pos_track_dump_rdata_0 register ****/ -/* Valid */ -#define NB_DEBUG_POS_TRACK_DUMP_RDATA_0_VALID (1 << 0) -/* Low data */ -#define NB_DEBUG_POS_TRACK_DUMP_RDATA_0_DATA_MASK 0xFFFFFFFE -#define NB_DEBUG_POS_TRACK_DUMP_RDATA_0_DATA_SHIFT 1 - -/**** c2swb_track_dump_ctrl register ****/ -/* [24:16]: Queue entry pointer */ -#define NB_DEBUG_C2SWB_TRACK_DUMP_CTRL_PTR_MASK 0x7FFFFFFF -#define NB_DEBUG_C2SWB_TRACK_DUMP_CTRL_PTR_SHIFT 0 -/* Track Dump Request -If set, queue entry info is latched on track_dump_rdata register. -Program the pointer and target queue. -This is a full handshake register -Read bit from track_dump_rdata register. If set, clear the request field before triggering a new request. */ -#define NB_DEBUG_C2SWB_TRACK_DUMP_CTRL_REQ (1 << 31) - -/**** c2swb_track_dump_rdata_0 register ****/ -/* Valid */ -#define NB_DEBUG_C2SWB_TRACK_DUMP_RDATA_0_VALID (1 << 0) -/* Low data */ -#define NB_DEBUG_C2SWB_TRACK_DUMP_RDATA_0_DATA_MASK 0xFFFFFFFE -#define NB_DEBUG_C2SWB_TRACK_DUMP_RDATA_0_DATA_SHIFT 1 - -/**** cpus_track_dump_ctrl register ****/ -/* [24:16]: Queue entry pointer -[3:2] Target queue - 0:ASI, 1: AMI -[1:0]: Target Processor Cluster - 0: Cluster0, 1: Cluster1 */ -#define NB_DEBUG_CPUS_TRACK_DUMP_CTRL_PTR_MASK 0x7FFFFFFF -#define NB_DEBUG_CPUS_TRACK_DUMP_CTRL_PTR_SHIFT 0 -/* Track Dump Request -If set, queue entry info is latched on track_dump_rdata register. -Program the pointer and target queue. -This is a full handshake register -Read bit from track_dump_rdata register. If set, clear the request field before triggering a new request. */ -#define NB_DEBUG_CPUS_TRACK_DUMP_CTRL_REQ (1 << 31) - -/**** cpus_track_dump_rdata_0 register ****/ -/* Valid */ -#define NB_DEBUG_CPUS_TRACK_DUMP_RDATA_0_VALID (1 << 0) -/* Low data */ -#define NB_DEBUG_CPUS_TRACK_DUMP_RDATA_0_DATA_MASK 0xFFFFFFFE -#define NB_DEBUG_CPUS_TRACK_DUMP_RDATA_0_DATA_SHIFT 1 - -/**** c2swb_bar_ovrd_high register ****/ -/* Read barrier is progressed downstream when not terminated in the CCI. -By specification, barrier address is 0x0. -This register enables barrier address OVRD to a programmable value. */ -#define NB_DEBUG_C2SWB_BAR_OVRD_HIGH_RD_ADDR_OVRD_EN (1 << 0) -/* Address bits 39:32 */ -#define NB_DEBUG_C2SWB_BAR_OVRD_HIGH_ADDR_39_32_MASK 0x00FF0000 -#define NB_DEBUG_C2SWB_BAR_OVRD_HIGH_ADDR_39_32_SHIFT 16 - -/**** Config register ****/ -/* Individual processor control of the endianness configuration at reset. It sets the initial value of the EE bit in the CP15 System Control Register (SCTLR) related to CFGEND input: -little - 0x0: Little endian -bit - 0x1: Bit endian */ -#define NB_CPUN_CONFIG_STATUS_CONFIG_ENDIAN (1 << 0) -/* Individual processor control of the default exception handling state. It sets the initial value of the TE bit in the CP15 System Control Register (SCTLR) related to CFGTE input: -arm: 0x0: Exception operates ARM code. -Thumb: 0x1: Exception operates Thumb code. */ -#define NB_CPUN_CONFIG_STATUS_CONFIG_TE (1 << 1) -/* Individual processor control of the location of the exception vectors at reset. It sets the initial value of the V bit in the CP15 System Control Register (SCTLR). -Connected to VINITHIGH input. -low - 0x0: Exception vectors start at address 0x00000000. -high - 0x1: Exception vectors start at address 0xFFFF0000. */ -#define NB_CPUN_CONFIG_STATUS_CONFIG_VINITHI (1 << 2) -/* Individual processor control to disable write access to some secure CP15 registers -connected to CP15SDISABLE input. */ -#define NB_CPUN_CONFIG_STATUS_CONFIG_CP15DISABLE (1 << 3) -/* Force Write init implementation to ConfigAARch64 register */ -#define NB_CPUN_CONFIG_STATUS_CONFIG_AARCH64_REG_FORCE_WINIT (1 << 4) -/* Force Write Once implementation to ConfigAARch64 register. */ -#define NB_CPUN_CONFIG_STATUS_CONFIG_AARCH64_REG_FORCE_WONCE (1 << 5) - -/**** Config_AARch64 register ****/ -/* Individual processor register width state. The register width states are: -0 AArch32. -1 AArch64. -This signal is only sampled during reset of the processor. -This is Write Init register */ -#define NB_CPUN_CONFIG_STATUS_CONFIG_AARCH64_AA64_NAA32 (1 << 0) -/* Individual processor Cryptography engine disable: -0 Enable the Cryptography engine. -1 Disable the Cryptography engine. -This signal is only sampled during reset of the processor */ -#define NB_CPUN_CONFIG_STATUS_CONFIG_AARCH64_CRYPTO_DIS (1 << 1) - -/**** Power_Ctrl register ****/ -/* Individual CPU power mode transition request -If requested to enter power mode other than normal mode, low power state is resumed whenever CPU reenters STNDBYWFI state: -normal: 0x0: normal power state -deep_idle: 0x2: Dormant power mode state -poweredoff: 0x3: Powered-off power mode */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_MASK 0x00000003 -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_SHIFT 0 -/* Normal power mode state */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_NORMAL \ - (0x0 << NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_SHIFT) -/* Dormant power mode state */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_DEEP_IDLE \ - (0x2 << NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_SHIFT) -/* Powered-off power mode */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_POWEREDOFF \ - (0x3 << NB_CPUN_CONFIG_STATUS_POWER_CTRL_PM_REQ_SHIFT) -/* Power down regret disable -When power down regret is enabled, the powerdown enter flow can be halted whenever a valid wakeup event occurs. */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PWRDN_RGRT_DIS (1 << 16) -/* Power down emulation enable -If set, the entire power down sequence is applied, but the CPU is placed in soft reset instead of hardware power down. */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_PWRDN_EMULATE (1 << 17) -/* Disable wakeup from Local--GIC FIQ. */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_WU_LGIC_FIQ_DIS (1 << 18) -/* Disable wakeup from Local-GIC IRQ. */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_WU_LGIC_IRQ_DIS (1 << 19) -/* Disable wakeup from IO-GIC FIQ. */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_WU_IOGIC_FIQ_DIS (1 << 20) -/* Disable wakeup from IO-GIC IRQ. */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_WU_IOGIC_IRQ_DIS (1 << 21) -/* Disable scheduling of interrrupts in GIC(500) to non-active CPU */ -#define NB_CPUN_CONFIG_STATUS_POWER_CTRL_IOGIC_DIS_CPU (1 << 22) - -/**** Power_Status register ****/ -/* Read-only bits that reflect the individual CPU power mode status. -Default value for non-exist CPU is 2b11: -normal - 0x0: Normal mode -por - 0x1: por on reset mode -deep_idle - 0x2: Dormant power mode state -poweredoff - 0x3: Powered-off power mode */ -#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_MASK 0x00000003 -#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT 0 -/* Normal power mode state */ -#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_NORMAL \ - (0x0 << NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT) -/* Idle power mode state (WFI) */ -#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_IDLE \ - (0x1 << NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT) -/* Dormant power mode state */ -#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_DEEP_IDLE \ - (0x2 << NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT) -/* Powered-off power mode */ -#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_POWEREDOFF \ - (0x3 << NB_CPUN_CONFIG_STATUS_POWER_STATUS_CPU_PM_SHIFT) -/* WFI status */ -#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_WFI (1 << 2) -/* WFE status */ -#define NB_CPUN_CONFIG_STATUS_POWER_STATUS_WFE (1 << 3) - -/**** Warm_Rst_Ctl register ****/ -/* Disable CPU Warm Reset when warmrstreq is asserted - -When the Reset Request bit in the RMR or RMR_EL3 register is set to 1 in the CPU Core , the processor asserts the WARMRSTREQ signal and the SoC reset controller use this request to trigger a Warm reset of the processor and change the register width state. */ -#define NB_CPUN_CONFIG_STATUS_WARM_RST_CTL_REQ_DIS (1 << 0) -/* Disable waiting WFI on Warm Reset */ -#define NB_CPUN_CONFIG_STATUS_WARM_RST_CTL_WFI_DIS (1 << 1) -/* CPU Core AARach64 reset vector bar -This is Write Once register (controlled by aarch64_reg_force_* fields) */ -#define NB_CPUN_CONFIG_STATUS_RVBAR_LOW_ADDR_31_2_MASK 0xFFFFFFFC -#define NB_CPUN_CONFIG_STATUS_RVBAR_LOW_ADDR_31_2_SHIFT 2 - -/**** Rvbar_High register ****/ -/* CPU Core AARach64 reset vector bar high bits -This is Write Once register (controlled by aarch64_reg_force_* fields) */ -#define NB_CPUN_CONFIG_STATUS_RVBAR_HIGH_ADDR_43_32_MASK 0x00000FFF -#define NB_CPUN_CONFIG_STATUS_RVBAR_HIGH_ADDR_43_32_SHIFT 0 - -/**** pmu_snapshot register ****/ -/* PMU Snapshot Request */ -#define NB_CPUN_CONFIG_STATUS_PMU_SNAPSHOT_REQ (1 << 0) -/* 0: HW deassert requests when received ack -1: SW deasserts request when received done */ -#define NB_CPUN_CONFIG_STATUS_PMU_SNAPSHOT_MODE (1 << 1) -/* Snapshot process completed */ -#define NB_CPUN_CONFIG_STATUS_PMU_SNAPSHOT_DONE (1 << 31) - -/**** cpu_msg_in register ****/ -/* CPU read this register to receive input (char) from simulation. */ -#define NB_CPUN_CONFIG_STATUS_CPU_MSG_IN_DATA_MASK 0x000000FF -#define NB_CPUN_CONFIG_STATUS_CPU_MSG_IN_DATA_SHIFT 0 -/* Indicates the data is valid. -Cleared on read */ -#define NB_CPUN_CONFIG_STATUS_CPU_MSG_IN_VALID (1 << 8) - -/**** PMU_Control register ****/ -/* Disable all counters -When this bit is clear, counter state is determined through the specific counter control register */ -#define NB_MC_PMU_PMU_CONTROL_DISABLE_ALL (1 << 0) -/* Pause all counters. -When this bit is clear, counter state is determined through the specific counter control register. */ -#define NB_MC_PMU_PMU_CONTROL_PAUSE_ALL (1 << 1) -/* Overflow interrupt enable: -disable - 0x0: Disable interrupt on overflow. -enable - 0x1: Enable interrupt on overflow. */ -#define NB_MC_PMU_PMU_CONTROL_OVRF_INTR_EN (1 << 2) -/* Number of monitored events supported by the PMU. */ -#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_MASK 0x00FC0000 -#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT 18 -#define NB_MC_PMU_PMU_CONTROL_NUM_OF_EVENTS_SHIFT_ALPINE 19 -/* Number of counters implemented by PMU. */ -#define NB_MC_PMU_PMU_CONTROL_NUM_OF_CNTS_MASK 0x0F000000 -#define NB_MC_PMU_PMU_CONTROL_NUM_OF_CNTS_SHIFT 24 - -/**** Cfg register ****/ -/* Event select */ -#define NB_MC_PMU_COUNTERS_CFG_EVENT_SEL_MASK 0x0000003F -#define NB_MC_PMU_COUNTERS_CFG_EVENT_SEL_SHIFT 0 -/* Enable setting of counter low overflow status bit: -disable - 0x0: Disable setting. -enable - 0x1: Enable setting. */ -#define NB_MC_PMU_COUNTERS_CFG_OVRF_LOW_STT_EN (1 << 6) -/* Enable setting of counter high overflow status bit: -disable - 0x0: Disable setting. -enable - 0x1: Enable setting. */ -#define NB_MC_PMU_COUNTERS_CFG_OVRF_HIGH_STT_EN (1 << 7) -/* Enable pause on trigger in assertion: -disable - 0x0: Disable pause. -enable - 0x1: Enable pause. */ -#define NB_MC_PMU_COUNTERS_CFG_TRIGIN_PAUSE_EN (1 << 8) -/* Enable increment trigger out for trace. -Trigger is generated whenever counter reaches value: -disable - 0x0: Disable trigger out. -enable - 0x1: Enable trigger out. */ -#define NB_MC_PMU_COUNTERS_CFG_TRIGOUT_EN (1 << 9) -/* Trigger out granule value -Specifies the number of events counted between two consecutive trigger out events -0x0: 1 - Trigger out on every event occurrence. -0x1: 2 - Trigger out on every two events. -... -0xn: 2^(n-1) - Trigger out on event 2^(n-1) events. -... -0x1F: 2^31 */ -#define NB_MC_PMU_COUNTERS_CFG_TRIGOUT_GRANULA_MASK 0x00007C00 -#define NB_MC_PMU_COUNTERS_CFG_TRIGOUT_GRANULA_SHIFT 10 -/* Pause on overflow bitmask -If set for counter , current counter pauses counting when counter is overflowed, including self-pause. -Bit [16]: counter 0 -Bit [17]: counter 1 -Note: This field must be changed for larger counters. */ -#define NB_MC_PMU_COUNTERS_CFG_PAUSE_ON_OVRF_BITMASK_MASK 0x000F0000 -#define NB_MC_PMU_COUNTERS_CFG_PAUSE_ON_OVRF_BITMASK_SHIFT 16 - -/**** Cntl register ****/ -/* Set the counter state to disable, enable, or pause: -0x0 - disable: Disable counter. -0x1 - enable: Enable counter. -0x3 - pause: Pause counter. */ -#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_MASK 0x00000003 -#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_SHIFT 0 -/* Disable counter. */ -#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_DISABLE \ - (0x0 << NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_SHIFT) -/* Enable counter. */ -#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_ENABLE \ - (0x1 << NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_SHIFT) -/* Pause counter. */ -#define NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_PAUSE \ - (0x3 << NB_MC_PMU_COUNTERS_CNTL_CNT_STATE_SHIFT) - -/**** High register ****/ -/* Counter high value */ -#define NB_MC_PMU_COUNTERS_HIGH_COUNTER_MASK 0x0000FFFF -#define NB_MC_PMU_COUNTERS_HIGH_COUNTER_SHIFT 0 - -/**** version register ****/ -/* Revision number (Minor) */ -#define NB_NB_VERSION_VERSION_RELEASE_NUM_MINOR_MASK 0x000000FF -#define NB_NB_VERSION_VERSION_RELEASE_NUM_MINOR_SHIFT 0 -/* Revision number (Major) */ -#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_MASK 0x0000FF00 -#define NB_NB_VERSION_VERSION_RELEASE_NUM_MAJOR_SHIFT 8 -/* Date of release */ -#define NB_NB_VERSION_VERSION_DATE_DAY_MASK 0x001F0000 -#define NB_NB_VERSION_VERSION_DATE_DAY_SHIFT 16 -/* Month of release */ -#define NB_NB_VERSION_VERSION_DATA_MONTH_MASK 0x01E00000 -#define NB_NB_VERSION_VERSION_DATA_MONTH_SHIFT 21 -/* Year of release (starting from 2000) */ -#define NB_NB_VERSION_VERSION_DATE_YEAR_MASK 0x3E000000 -#define NB_NB_VERSION_VERSION_DATE_YEAR_SHIFT 25 -/* Reserved */ -#define NB_NB_VERSION_VERSION_RESERVED_MASK 0xC0000000 -#define NB_NB_VERSION_VERSION_RESERVED_SHIFT 30 - -/**** cpu_vmid register ****/ -/* Target VMID */ -#define NB_SRIOV_CPU_VMID_VAL_MASK 0x000000FF -#define NB_SRIOV_CPU_VMID_VAL_SHIFT 0 - -/**** DRAM_0_Control register ****/ -/* Controller Idle -Indicates to the DDR PHY, if set, that the memory controller is idle */ -#define NB_DRAM_CHANNELS_DRAM_0_CONTROL_DDR_PHY_CTL_IDLE (1 << 0) -/* Disable clear exclusive monitor request from DDR controller to CPU -Clear request is triggered whenever an exlusive monitor inside the DDR controller is being invalidated. */ -#define NB_DRAM_CHANNELS_DRAM_0_CONTROL_DDR_EXMON_REQ_DIS (1 << 1) - -/**** DRAM_0_Status register ****/ -/* Bypass Mode: Indicates if set that the PHY is in PLL bypass mod */ -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_DDR_PHY_BYP_MODE (1 << 0) -/* Number of available AXI transactions (used positions) in the DDR controller read address FIFO. */ -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_RAQ_WCOUNT_MASK 0x00000030 -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_RAQ_WCOUNT_SHIFT 4 -/* Number of available AXI transactions (used positions) in the DDR controller write address FIFO */ -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_WAQ_WCOUNT_0_MASK 0x000000C0 -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_WAQ_WCOUNT_0_SHIFT 6 -/* Number of available Low priority read CAM slots (free positions) in the DDR controller. -Each slots holds a DRAM burst */ -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_LPR_CREDIT_CNT_MASK 0x00007F00 -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_LPR_CREDIT_CNT_SHIFT 8 -/* Number of available High priority read CAM slots (free positions) in the DDR controller. -Each slots holds a DRAM burst */ -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_HPR_CREDIT_CNT_MASK 0x003F8000 -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_HPR_CREDIT_CNT_SHIFT 15 -/* Number of available write CAM slots (free positions) in the DDR controller. -Each slots holds a DRAM burst */ -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_WR_CREDIT_CNT_MASK 0x1FC00000 -#define NB_DRAM_CHANNELS_DRAM_0_STATUS_WR_CREDIT_CNT_SHIFT 22 - -/**** DDR_Int_Cause register ****/ -/* This interrupt is asserted when a correctable ECC error is detected */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_ECC_CORRECTED_ERR (1 << 0) -/* This interrupt is asserted when a uncorrectable ECC error is detected */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_ECC_UNCORRECTED_ERR (1 << 1) -/* This interrupt is asserted when a parity or CRC error is detected on the DFI interface */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_DFI_ALERT_ERR (1 << 2) -/* On-Chip Write data parity error interrupt on output */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_WDATA_OUT_ERR (1 << 3) -/* This interrupt is asserted when a parity error due to MRS is detected on the DFI interface */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_DFI_ALERT_ERR_FATL (1 << 4) -/* This interrupt is asserted when the CRC/parity retry counter reaches it maximum value */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_DFI_ALERT_ERR_MAX_REACHED (1 << 5) -/* AXI Read address parity error interrupt. -This interrupt is asserted when an on-chip parity error occurred on the DDR controller AXI read address. */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_RADDR_ERR (1 << 6) -/* AXI Read data parity error interrupt. -This interrupt is asserted when an on-chip parity error occurred on the DDR controller AXI read data */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_RDATA_ERR (1 << 7) -/* AXI Write address parity error interrupt. -This interrupt is asserted when an on-chip parity error occurred on the DDR controller AXI write address. */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_WADDR_ERR (1 << 8) -/* AXI Write data parity error interrupt on input. -This interrupt is asserted when an on-chip parity error occurred on the DDR controller AXI write data */ -#define NB_DRAM_CHANNELS_DDR_INT_CAUSE_PAR_WDATA_IN_ERR (1 << 9) - -/**** Address_Map register ****/ -/* Controls which system address bit will be mapped to DDR row bit 2. -This field is only used when addrmap_part_en == 1 */ -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B2_MASK 0x0000000F -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B2_SHIFT 0 -/* Controls which system address bit will be mapped to DDR row bit 3. -This field is only used when addrmap_part_en == 1 */ -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B3_MASK 0x000003C0 -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B3_SHIFT 6 -/* Controls which system address bit will be mapped to DDR row bit 4. -This field is only used when addrmap_part_en == 1 */ -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B4_MASK 0x0000F000 -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B4_SHIFT 12 -/* Controls which system address bit will be mapped to DDR row bit 5. -This field is only used when addrmap_part_en == 1 */ -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B5_MASK 0x003C0000 -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_ROW_B5_SHIFT 18 -/* Enables partitioning of the address mapping control. -When set, addrmap_row_b2-5 are used inside DDR controler instead of the built in address mapping registers */ -#define NB_DRAM_CHANNELS_ADDRESS_MAP_ADDRMAP_PART_EN (1 << 31) - -/**** Reorder_ID_Mask register ****/ -/* DDR Read Reorder buffer ID mask. -If incoming read transaction ID ANDed with mask is equal Reorder_ID_Value, then the transaction is mapped to the DDR controller bypass channel. -Setting this register to 0 will disable the check */ -#define NB_DRAM_CHANNELS_REORDER_ID_MASK_MASK_MASK 0x003FFFFF -#define NB_DRAM_CHANNELS_REORDER_ID_MASK_MASK_SHIFT 0 - -/**** Reorder_ID_Value register ****/ -/* DDR Read Reorder buffer ID value -If incoming read transaction ID ANDed with Reorder_ID_Mask is equal to this register, then the transaction is mapped to the DDR controller bypass channel */ -#define NB_DRAM_CHANNELS_REORDER_ID_VALUE_VALUE_MASK 0x003FFFFF -#define NB_DRAM_CHANNELS_REORDER_ID_VALUE_VALUE_SHIFT 0 - -/**** MRR_Control_Status register ****/ -/* DDR4 Mode Register Read Data Valid */ -#define NB_DRAM_CHANNELS_MRR_CONTROL_STATUS_MRR_VLD (1 << 0) -/* MRR Ack, when asserted it clears the mrr_val indication and ready to load new MRR data. Write 1 to clear and then 0 */ -#define NB_DRAM_CHANNELS_MRR_CONTROL_STATUS_MRR_ACK (1 << 16) - -/**** pp_config register ****/ -/* Bypass PP module (formality equivalent) */ -#define NB_PUSH_PACKET_PP_CONFIG_FM_BYPASS (1 << 0) -/* Bypass PP module */ -#define NB_PUSH_PACKET_PP_CONFIG_BYPASS (1 << 1) -/* Force Cleanup of entries */ -#define NB_PUSH_PACKET_PP_CONFIG_CLEAR (1 << 2) -/* Enable forwarding DECERR response */ -#define NB_PUSH_PACKET_PP_CONFIG_DECERR_EN (1 << 3) -/* Enable forwarding SLVERR response */ -#define NB_PUSH_PACKET_PP_CONFIG_SLVERR_EN (1 << 4) -/* Enable forwarding of data parity generation */ -#define NB_PUSH_PACKET_PP_CONFIG_PAR_GEN_EN (1 << 5) -/* Select channel on 8K boundaries ([15:13]) instead of 64k boundaries ([18:16]). */ -#define NB_PUSH_PACKET_PP_CONFIG_SEL_8K (1 << 6) -/* Forces awuser to be as configured in ext_awuser register. -Not functional */ -#define NB_PUSH_PACKET_PP_CONFIG_SEL_EXT_AWUSER (1 << 7) -/* Enables PP channel. -1 bit per channel */ -#define NB_PUSH_PACKET_PP_CONFIG_CHANNEL_ENABLE_MASK 0x00030000 -#define NB_PUSH_PACKET_PP_CONFIG_CHANNEL_ENABLE_SHIFT 16 - -#define NB_PUSH_PACKET_PP_CONFIG_CHANNEL_ENABLE(i) \ - (1 << (NB_PUSH_PACKET_PP_CONFIG_CHANNEL_ENABLE_SHIFT + i)) - -/**** pp_ext_awuser register ****/ -/* Awuser to use on PP transactions -Only applicable if config.sel_ext_awuser is set to 1'b1 -Parity bits are still generated per transaction */ -#define NB_PUSH_PACKET_PP_EXT_AWUSER_AWUSER_MASK 0x03FFFFFF -#define NB_PUSH_PACKET_PP_EXT_AWUSER_AWUSER_SHIFT 0 - -/**** pp_sel_awuser register ****/ -/* Select whether to use addr[63:48] or PP awmisc as vmid. -Each bit if set to 1 selects the corresponding address bit. Otherwise, selects the corersponding awmis bit. */ -#define NB_PUSH_PACKET_PP_SEL_AWUSER_SEL_MASK 0x0000FFFF -#define NB_PUSH_PACKET_PP_SEL_AWUSER_SEL_SHIFT 0 - -#ifdef __cplusplus -} -#endif - -#endif /* __AL_HAL_NB_REGS_H__ */ - -/** @} end of ... group */ - - diff --git a/sys/arm/annapurna/alpine/hal/al_hal_pbs_regs.h b/sys/arm/annapurna/alpine/hal/al_hal_pbs_regs.h deleted file mode 100644 index b1f9c4f44d93..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_pbs_regs.h +++ /dev/null @@ -1,2751 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @{ - * @file al_hal_pbs_regs.h - * - * @brief ... registers - * - */ - -#ifndef __AL_HAL_PBS_REGS_H__ -#define __AL_HAL_PBS_REGS_H__ - -#include "al_hal_plat_types.h" - -#ifdef __cplusplus -extern "C" { -#endif -/* -* Unit Registers -*/ - - - -struct al_pbs_unit { - /* [0x0] Conf_bus, Configuration of the SB */ - uint32_t conf_bus; - /* [0x4] PASW high */ - uint32_t dram_0_nb_bar_high; - /* [0x8] PASW low */ - uint32_t dram_0_nb_bar_low; - /* [0xc] PASW high */ - uint32_t dram_1_nb_bar_high; - /* [0x10] PASW low */ - uint32_t dram_1_nb_bar_low; - /* [0x14] PASW high */ - uint32_t dram_2_nb_bar_high; - /* [0x18] PASW low */ - uint32_t dram_2_nb_bar_low; - /* [0x1c] PASW high */ - uint32_t dram_3_nb_bar_high; - /* [0x20] PASW low */ - uint32_t dram_3_nb_bar_low; - /* [0x24] PASW high */ - uint32_t msix_nb_bar_high; - /* [0x28] PASW low */ - uint32_t msix_nb_bar_low; - /* [0x2c] PASW high */ - uint32_t dram_0_sb_bar_high; - /* [0x30] PASW low */ - uint32_t dram_0_sb_bar_low; - /* [0x34] PASW high */ - uint32_t dram_1_sb_bar_high; - /* [0x38] PASW low */ - uint32_t dram_1_sb_bar_low; - /* [0x3c] PASW high */ - uint32_t dram_2_sb_bar_high; - /* [0x40] PASW low */ - uint32_t dram_2_sb_bar_low; - /* [0x44] PASW high */ - uint32_t dram_3_sb_bar_high; - /* [0x48] PASW low */ - uint32_t dram_3_sb_bar_low; - /* [0x4c] PASW high */ - uint32_t msix_sb_bar_high; - /* [0x50] PASW low */ - uint32_t msix_sb_bar_low; - /* [0x54] PASW high */ - uint32_t pcie_mem0_bar_high; - /* [0x58] PASW low */ - uint32_t pcie_mem0_bar_low; - /* [0x5c] PASW high */ - uint32_t pcie_mem1_bar_high; - /* [0x60] PASW low */ - uint32_t pcie_mem1_bar_low; - /* [0x64] PASW high */ - uint32_t pcie_mem2_bar_high; - /* [0x68] PASW low */ - uint32_t pcie_mem2_bar_low; - /* [0x6c] PASW high */ - uint32_t pcie_ext_ecam0_bar_high; - /* [0x70] PASW low */ - uint32_t pcie_ext_ecam0_bar_low; - /* [0x74] PASW high */ - uint32_t pcie_ext_ecam1_bar_high; - /* [0x78] PASW low */ - uint32_t pcie_ext_ecam1_bar_low; - /* [0x7c] PASW high */ - uint32_t pcie_ext_ecam2_bar_high; - /* [0x80] PASW low */ - uint32_t pcie_ext_ecam2_bar_low; - /* [0x84] PASW high */ - uint32_t pbs_nor_bar_high; - /* [0x88] PASW low */ - uint32_t pbs_nor_bar_low; - /* [0x8c] PASW high */ - uint32_t pbs_spi_bar_high; - /* [0x90] PASW low */ - uint32_t pbs_spi_bar_low; - uint32_t rsrvd_0[3]; - /* [0xa0] PASW high */ - uint32_t pbs_nand_bar_high; - /* [0xa4] PASW low */ - uint32_t pbs_nand_bar_low; - /* [0xa8] PASW high */ - uint32_t pbs_int_mem_bar_high; - /* [0xac] PASW low */ - uint32_t pbs_int_mem_bar_low; - /* [0xb0] PASW high */ - uint32_t pbs_boot_bar_high; - /* [0xb4] PASW low */ - uint32_t pbs_boot_bar_low; - /* [0xb8] PASW high */ - uint32_t nb_int_bar_high; - /* [0xbc] PASW low */ - uint32_t nb_int_bar_low; - /* [0xc0] PASW high */ - uint32_t nb_stm_bar_high; - /* [0xc4] PASW low */ - uint32_t nb_stm_bar_low; - /* [0xc8] PASW high */ - uint32_t pcie_ecam_int_bar_high; - /* [0xcc] PASW low */ - uint32_t pcie_ecam_int_bar_low; - /* [0xd0] PASW high */ - uint32_t pcie_mem_int_bar_high; - /* [0xd4] PASW low */ - uint32_t pcie_mem_int_bar_low; - /* [0xd8] Control */ - uint32_t winit_cntl; - /* [0xdc] Control */ - uint32_t latch_bars; - /* [0xe0] Control */ - uint32_t pcie_conf_0; - /* [0xe4] Control */ - uint32_t pcie_conf_1; - /* [0xe8] Control */ - uint32_t serdes_mux_pipe; - /* [0xec] Control */ - uint32_t dma_io_master_map; - /* [0xf0] Status */ - uint32_t i2c_pld_status_high; - /* [0xf4] Status */ - uint32_t i2c_pld_status_low; - /* [0xf8] Status */ - uint32_t spi_dbg_status_high; - /* [0xfc] Status */ - uint32_t spi_dbg_status_low; - /* [0x100] Status */ - uint32_t spi_mst_status_high; - /* [0x104] Status */ - uint32_t spi_mst_status_low; - /* [0x108] Log */ - uint32_t mem_pbs_parity_err_high; - /* [0x10c] Log */ - uint32_t mem_pbs_parity_err_low; - /* [0x110] Log */ - uint32_t boot_strap; - /* [0x114] Conf */ - uint32_t cfg_axi_conf_0; - /* [0x118] Conf */ - uint32_t cfg_axi_conf_1; - /* [0x11c] Conf */ - uint32_t cfg_axi_conf_2; - /* [0x120] Conf */ - uint32_t cfg_axi_conf_3; - /* [0x124] Conf */ - uint32_t spi_mst_conf_0; - /* [0x128] Conf */ - uint32_t spi_mst_conf_1; - /* [0x12c] Conf */ - uint32_t spi_slv_conf_0; - /* [0x130] Conf */ - uint32_t apb_mem_conf_int; - /* [0x134] PASW remap register */ - uint32_t sb2nb_cfg_dram_remap; - /* [0x138] Control */ - uint32_t pbs_mux_sel_0; - /* [0x13c] Control */ - uint32_t pbs_mux_sel_1; - /* [0x140] Control */ - uint32_t pbs_mux_sel_2; - /* [0x144] Control */ - uint32_t pbs_mux_sel_3; - /* [0x148] PASW high */ - uint32_t sb_int_bar_high; - /* [0x14c] PASW low */ - uint32_t sb_int_bar_low; - /* [0x150] log */ - uint32_t ufc_pbs_parity_err_high; - /* [0x154] log */ - uint32_t ufc_pbs_parity_err_low; - /* [0x158] Cntl - internal */ - uint32_t gen_conf; - /* [0x15c] Device ID and Rev ID */ - uint32_t chip_id; - /* [0x160] Status - internal */ - uint32_t uart0_debug; - /* [0x164] Status - internal */ - uint32_t uart1_debug; - /* [0x168] Status - internal */ - uint32_t uart2_debug; - /* [0x16c] Status - internal */ - uint32_t uart3_debug; - /* [0x170] Control - internal */ - uint32_t uart0_conf_status; - /* [0x174] Control - internal */ - uint32_t uart1_conf_status; - /* [0x178] Control - internal */ - uint32_t uart2_conf_status; - /* [0x17c] Control - internal */ - uint32_t uart3_conf_status; - /* [0x180] Control - internal */ - uint32_t gpio0_conf_status; - /* [0x184] Control - internal */ - uint32_t gpio1_conf_status; - /* [0x188] Control - internal */ - uint32_t gpio2_conf_status; - /* [0x18c] Control - internal */ - uint32_t gpio3_conf_status; - /* [0x190] Control - internal */ - uint32_t gpio4_conf_status; - /* [0x194] Control - internal */ - uint32_t i2c_gen_conf_status; - /* [0x198] Control - internal */ - uint32_t i2c_gen_debug; - /* [0x19c] Cntl */ - uint32_t watch_dog_reset_out; - /* [0x1a0] Cntl */ - uint32_t otp_magic_num; - /* - * [0x1a4] Control - internal - */ - uint32_t otp_cntl; - /* [0x1a8] Cfg - internal */ - uint32_t otp_cfg_0; - /* [0x1ac] Cfg - internal */ - uint32_t otp_cfg_1; - /* [0x1b0] Cfg - internal */ - uint32_t otp_cfg_3; - /* [0x1b4] Cfg */ - uint32_t cfg_nand_0; - /* [0x1b8] Cfg */ - uint32_t cfg_nand_1; - /* [0x1bc] Cfg-- timing parameters internal. */ - uint32_t cfg_nand_2; - /* [0x1c0] Cfg - internal */ - uint32_t cfg_nand_3; - /* [0x1c4] PASW high */ - uint32_t nb_nic_regs_bar_high; - /* [0x1c8] PASW low */ - uint32_t nb_nic_regs_bar_low; - /* [0x1cc] PASW high */ - uint32_t sb_nic_regs_bar_high; - /* [0x1d0] PASW low */ - uint32_t sb_nic_regs_bar_low; - /* [0x1d4] Control */ - uint32_t serdes_mux_multi_0; - /* [0x1d8] Control */ - uint32_t serdes_mux_multi_1; - /* [0x1dc] Control - not in use any more - internal */ - uint32_t pbs_ulpi_mux_conf; - /* [0x1e0] Cntl */ - uint32_t wr_once_dbg_dis_ovrd_reg; - /* [0x1e4] Cntl - internal */ - uint32_t gpio5_conf_status; - /* [0x1e8] PASW high */ - uint32_t pcie_mem3_bar_high; - /* [0x1ec] PASW low */ - uint32_t pcie_mem3_bar_low; - /* [0x1f0] PASW high */ - uint32_t pcie_mem4_bar_high; - /* [0x1f4] PASW low */ - uint32_t pcie_mem4_bar_low; - /* [0x1f8] PASW high */ - uint32_t pcie_mem5_bar_high; - /* [0x1fc] PASW low */ - uint32_t pcie_mem5_bar_low; - /* [0x200] PASW high */ - uint32_t pcie_ext_ecam3_bar_high; - /* [0x204] PASW low */ - uint32_t pcie_ext_ecam3_bar_low; - /* [0x208] PASW high */ - uint32_t pcie_ext_ecam4_bar_high; - /* [0x20c] PASW low */ - uint32_t pcie_ext_ecam4_bar_low; - /* [0x210] PASW high */ - uint32_t pcie_ext_ecam5_bar_high; - /* [0x214] PASW low */ - uint32_t pcie_ext_ecam5_bar_low; - /* [0x218] PASW high */ - uint32_t low_latency_sram_bar_high; - /* [0x21c] PASW low */ - uint32_t low_latency_sram_bar_low; - /* [0x220] Control */ - uint32_t pbs_mux_sel_4; - /* [0x224] Control */ - uint32_t pbs_mux_sel_5; - /* [0x228] Control */ - uint32_t serdes_mux_eth; - /* [0x22c] Control */ - uint32_t serdes_mux_pcie; - /* [0x230] Control */ - uint32_t serdes_mux_sata; - uint32_t rsrvd[7]; -}; -struct al_pbs_low_latency_sram_remap { - /* [0x0] PBS MEM Remap */ - uint32_t bar1_orig; - /* [0x4] PBS MEM Remap */ - uint32_t bar1_remap; - /* [0x8] ETH0 MEM Remap */ - uint32_t bar2_orig; - /* [0xc] ETH0 MEM Remap */ - uint32_t bar2_remap; - /* [0x10] ETH1 MEM Remap */ - uint32_t bar3_orig; - /* [0x14] ETH1 MEM Remap */ - uint32_t bar3_remap; - /* [0x18] ETH2 MEM Remap */ - uint32_t bar4_orig; - /* [0x1c] ETH2 MEM Remap */ - uint32_t bar4_remap; - /* [0x20] ETH3 MEM Remap */ - uint32_t bar5_orig; - /* [0x24] ETH3 MEM Remap */ - uint32_t bar5_remap; - /* [0x28] CRYPTO0 MEM Remap */ - uint32_t bar6_orig; - /* [0x2c] CRYPTO0 MEM Remap */ - uint32_t bar6_remap; - /* [0x30] RAID0 MEM Remap */ - uint32_t bar7_orig; - /* [0x34] RAID0 MEM Remap */ - uint32_t bar7_remap; - /* [0x38] CRYPTO1 MEM Remap */ - uint32_t bar8_orig; - /* [0x3c] CRYPTO1 MEM Remap */ - uint32_t bar8_remap; - /* [0x40] RAID1 MEM Remap */ - uint32_t bar9_orig; - /* [0x44] RAID2 MEM Remap */ - uint32_t bar9_remap; - /* [0x48] RESERVED MEM Remap */ - uint32_t bar10_orig; - /* [0x4c] RESERVED MEM Remap */ - uint32_t bar10_remap; -}; -struct al_pbs_target_id_enforcement { - /* [0x0] target enforcement */ - uint32_t cpu; - /* [0x4] target enforcement mask (bits which are 0 are not compared) */ - uint32_t cpu_mask; - /* [0x8] target enforcement */ - uint32_t debug_nb; - /* [0xc] target enforcement mask (bits which are 0 are not compared) */ - uint32_t debug_nb_mask; - /* [0x10] target enforcement */ - uint32_t debug_sb; - /* [0x14] target enforcement mask (bits which are 0 are not compared) */ - uint32_t debug_sb_mask; - /* [0x18] target enforcement */ - uint32_t eth_0; - /* [0x1c] target enforcement mask (bits which are 0 are not compared) */ - uint32_t eth_0_mask; - /* [0x20] target enforcement */ - uint32_t eth_1; - /* [0x24] target enforcement mask (bits which are 0 are not compared) */ - uint32_t eth_1_mask; - /* [0x28] target enforcement */ - uint32_t eth_2; - /* [0x2c] target enforcement mask (bits which are 0 are not compared) */ - uint32_t eth_2_mask; - /* [0x30] target enforcement */ - uint32_t eth_3; - /* [0x34] target enforcement mask (bits which are 0 are not compared) */ - uint32_t eth_3_mask; - /* [0x38] target enforcement */ - uint32_t sata_0; - /* [0x3c] target enforcement mask (bits which are 0 are not compared) */ - uint32_t sata_0_mask; - /* [0x40] target enforcement */ - uint32_t sata_1; - /* [0x44] target enforcement mask (bits which are 0 are not compared) */ - uint32_t sata_1_mask; - /* [0x48] target enforcement */ - uint32_t crypto_0; - /* [0x4c] target enforcement mask (bits which are 0 are not compared) */ - uint32_t crypto_0_mask; - /* [0x50] target enforcement */ - uint32_t crypto_1; - /* [0x54] target enforcement mask (bits which are 0 are not compared) */ - uint32_t crypto_1_mask; - /* [0x58] target enforcement */ - uint32_t pcie_0; - /* [0x5c] target enforcement mask (bits which are 0 are not compared) */ - uint32_t pcie_0_mask; - /* [0x60] target enforcement */ - uint32_t pcie_1; - /* [0x64] target enforcement mask (bits which are 0 are not compared) */ - uint32_t pcie_1_mask; - /* [0x68] target enforcement */ - uint32_t pcie_2; - /* [0x6c] target enforcement mask (bits which are 0 are not compared) */ - uint32_t pcie_2_mask; - /* [0x70] target enforcement */ - uint32_t pcie_3; - /* [0x74] target enforcement mask (bits which are 0 are not compared) */ - uint32_t pcie_3_mask; - /* [0x78] Control */ - uint32_t latch; - uint32_t rsrvd[9]; -}; - -struct al_pbs_regs { - struct al_pbs_unit unit; /* [0x0] */ -struct al_pbs_low_latency_sram_remap low_latency_sram_remap; -/* [0x250] */ - uint32_t rsrvd_0[88]; - struct al_pbs_target_id_enforcement target_id_enforcement; /* [0x400] */ -}; - - -/* -* Registers Fields -*/ - - -/**** conf_bus register ****/ -/* Read slave error enable */ -#define PBS_UNIT_CONF_BUS_RD_SLVERR_EN (1 << 0) -/* Write slave error enable */ -#define PBS_UNIT_CONF_BUS_WR_SLVERR_EN (1 << 1) -/* Read decode error enable */ -#define PBS_UNIT_CONF_BUS_RD_DECERR_EN (1 << 2) -/* Write decode error enable */ -#define PBS_UNIT_CONF_BUS_WR_DECERR_EN (1 << 3) -/* For debug clear the APB SM */ -#define PBS_UNIT_CONF_BUS_CLR_APB_FSM (1 << 4) -/* For debug clear the WFIFO */ -#define PBS_UNIT_CONF_BUS_CLR_WFIFO_CLEAR (1 << 5) -/* Arbiter between read and write channel */ -#define PBS_UNIT_CONF_BUS_WRR_CNT_MASK 0x000001C0 -#define PBS_UNIT_CONF_BUS_WRR_CNT_SHIFT 6 - - -/* general PASWS */ -/* window size = 2 ^ (15 + win_size), zero value disable the win ... */ -#define PBS_PASW_WIN_SIZE_MASK 0x0000003F -#define PBS_PASW_WIN_SIZE_SHIFT 0 -/* reserved fields */ -#define PBS_PASW_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_PASW_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_PASW_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_PASW_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** dram_0_nb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_DRAM_0_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_DRAM_0_NB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DRAM_0_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_DRAM_0_NB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_DRAM_0_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_DRAM_0_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** dram_1_nb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_DRAM_1_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_DRAM_1_NB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DRAM_1_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_DRAM_1_NB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_DRAM_1_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_DRAM_1_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** dram_2_nb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_DRAM_2_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_DRAM_2_NB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DRAM_2_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_DRAM_2_NB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_DRAM_2_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_DRAM_2_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** dram_3_nb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_DRAM_3_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_DRAM_3_NB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DRAM_3_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_DRAM_3_NB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_DRAM_3_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_DRAM_3_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** msix_nb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_MSIX_NB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_MSIX_NB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_MSIX_NB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_MSIX_NB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_MSIX_NB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_MSIX_NB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** dram_0_sb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_DRAM_0_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_DRAM_0_SB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DRAM_0_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_DRAM_0_SB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_DRAM_0_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_DRAM_0_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** dram_1_sb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_DRAM_1_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_DRAM_1_SB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DRAM_1_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_DRAM_1_SB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_DRAM_1_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_DRAM_1_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** dram_2_sb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_DRAM_2_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_DRAM_2_SB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DRAM_2_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_DRAM_2_SB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_DRAM_2_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_DRAM_2_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** dram_3_sb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_DRAM_3_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_DRAM_3_SB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DRAM_3_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_DRAM_3_SB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_DRAM_3_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_DRAM_3_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** msix_sb_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_MSIX_SB_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_MSIX_SB_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_MSIX_SB_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_MSIX_SB_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_MSIX_SB_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_MSIX_SB_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_mem0_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_MEM0_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_MEM0_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_MEM0_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_MEM0_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PCIE_MEM0_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_MEM0_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_mem1_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_MEM1_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_MEM1_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_MEM1_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_MEM1_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PCIE_MEM1_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_MEM1_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_mem2_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_MEM2_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_MEM2_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_MEM2_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_MEM2_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PCIE_MEM2_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_MEM2_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_ext_ecam0_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_EXT_ECAM0_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_ext_ecam1_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_EXT_ECAM1_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_ext_ecam2_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_EXT_ECAM2_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pbs_nor_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PBS_NOR_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PBS_NOR_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PBS_NOR_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PBS_NOR_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PBS_NOR_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PBS_NOR_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pbs_spi_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PBS_SPI_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PBS_SPI_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PBS_SPI_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PBS_SPI_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PBS_SPI_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PBS_SPI_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pbs_nand_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PBS_NAND_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PBS_NAND_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PBS_NAND_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PBS_NAND_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PBS_NAND_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PBS_NAND_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pbs_int_mem_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PBS_INT_MEM_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pbs_boot_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PBS_BOOT_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PBS_BOOT_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PBS_BOOT_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PBS_BOOT_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PBS_BOOT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PBS_BOOT_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** nb_int_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_NB_INT_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_NB_INT_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_NB_INT_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_NB_INT_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_NB_INT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_NB_INT_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** nb_stm_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_NB_STM_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_NB_STM_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_NB_STM_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_NB_STM_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_NB_STM_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_NB_STM_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_ecam_int_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_ECAM_INT_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_mem_int_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_MEM_INT_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** winit_cntl register ****/ -/* When set, enables access to winit regs, in normal mode. */ -#define PBS_UNIT_WINIT_CNTL_ENABLE_WINIT_REGS_ACCESS (1 << 0) -/* Reserved */ -#define PBS_UNIT_WINIT_CNTL_RSRVD_MASK 0xFFFFFFFE -#define PBS_UNIT_WINIT_CNTL_RSRVD_SHIFT 1 - -/**** latch_bars register ****/ -/* - * Software clears this bit before any bar update, and set it after all bars - * updated. - */ -#define PBS_UNIT_LATCH_BARS_ENABLE (1 << 0) -/* Reserved */ -#define PBS_UNIT_LATCH_BARS_RSRVD_MASK 0xFFFFFFFE -#define PBS_UNIT_LATCH_BARS_RSRVD_SHIFT 1 - -/**** pcie_conf_0 register ****/ -/* NOT_use, config internal inside each PCIe core */ -#define PBS_UNIT_PCIE_CONF_0_DEVS_TYPE_MASK 0x00000FFF -#define PBS_UNIT_PCIE_CONF_0_DEVS_TYPE_SHIFT 0 -/* sys_aux_det value */ -#define PBS_UNIT_PCIE_CONF_0_SYS_AUX_PWR_DET_VEC_MASK 0x00007000 -#define PBS_UNIT_PCIE_CONF_0_SYS_AUX_PWR_DET_VEC_SHIFT 12 -/* Reserved */ -#define PBS_UNIT_PCIE_CONF_0_RSRVD_MASK 0xFFFF8000 -#define PBS_UNIT_PCIE_CONF_0_RSRVD_SHIFT 15 - -/**** pcie_conf_1 register ****/ -/* - * Which PCIe exists? The PCIe device is under reset until the corresponding bit - * is set. - */ -#define PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_MASK 0x0000003F -#define PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT 0 -/* Reserved */ -#define PBS_UNIT_PCIE_CONF_1_RSRVD_MASK 0xFFFFFFC0 -#define PBS_UNIT_PCIE_CONF_1_RSRVD_SHIFT 6 - -/**** serdes_mux_pipe register ****/ -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_SERDES_2_MASK 0x00000007 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_SERDES_2_SHIFT 0 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_3 (1 << 3) -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_SERDES_3_MASK 0x00000070 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_SERDES_3_SHIFT 4 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_7 (1 << 7) -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_B_0_MASK 0x00000300 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_B_0_SHIFT 8 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_B_1_MASK 0x00000C00 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_B_1_SHIFT 10 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_C_0_MASK 0x00003000 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_C_0_SHIFT 12 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_C_1_MASK 0x0000C000 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_PCI_C_1_SHIFT 14 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_USB_A_0_MASK 0x00030000 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_USB_A_0_SHIFT 16 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_USB_B_0_MASK 0x000C0000 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_USB_B_0_SHIFT 18 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_CLKI_SER_2_MASK 0x00300000 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_CLKI_SER_2_SHIFT 20 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_23_22_MASK 0x00C00000 -#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_23_22_SHIFT 22 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_CLKI_SER_3_MASK 0x07000000 -#define PBS_UNIT_SERDES_MUX_PIPE_SELECT_OH_CLKI_SER_3_SHIFT 24 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_MASK 0xF8000000 -#define PBS_UNIT_SERDES_MUX_PIPE_RSRVD_SHIFT 27 - -/* - * 2'b01 - select pcie_b[0] - * 2'b10 - select pcie_a[2] - */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_2_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_2_SHIFT 0 -/* - * 2'b01 - select pcie_b[1] - * 2'b10 - select pcie_a[3] - */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_3_MASK 0x00000030 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_3_SHIFT 4 -/* - * 2'b01 - select pcie_b[0] - * 2'b10 - select pcie_a[4] - */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_4_MASK 0x00000300 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_4_SHIFT 8 -/* - * 2'b01 - select pcie_b[1] - * 2'b10 - select pcie_a[5] - */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_5_MASK 0x00003000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_5_SHIFT 12 -/* - * 2'b01 - select pcie_b[2] - * 2'b10 - select pcie_a[6] - */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_6_MASK 0x00030000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_6_SHIFT 16 -/* - * 2'b01 - select pcie_b[3] - * 2'b10 - select pcie_a[7] - */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_7_MASK 0x00300000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_7_SHIFT 20 -/* - * 2'b01 - select pcie_d[0] - * 2'b10 - select pcie_c[2] - */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_10_MASK 0x03000000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_10_SHIFT 24 -/* - * 2'b01 - select pcie_d[1] - * 2'b10 - select pcie_c[3] - */ -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_11_MASK 0x30000000 -#define PBS_UNIT_SERDES_MUX_PIPE_PKR_SELECT_OH_SERDES_11_SHIFT 28 - -/**** dma_io_master_map register ****/ -/* - * [0]: When set, maps all the io_dma transactions to the NB/DRAM, regardless of - * the window hit. - * [1]: When set, maps all the eth_0 transactions to the NB/DRAM, regardless of - * the window hit. - * [2]: When set, maps all the eth_2 transaction to the NB/DRAM, regardless of - * the window hit. - * [3]: When set, maps all the sata_0 transactions to the NB/DRAM, regardless of - * the window hit. - * [4]: When set, maps all the sata_1 transactions to the NB/DRAM, regardless of - * the window hit. - * [5]: When set, maps all the pcie_0 master transactions to the NB/DRAM, - * regardless of the window hit. - * [6]: When set, maps all the SPI debug port transactions to the NB/DRAM, - * regardless of the window hit. - * [7]: When set, maps all the CPU debug port transactions to the NB/DRAM, - * regardless of the window hit. - * [8] When set, maps all the Crypto transactions to the NB/DRAM, regardless of - * the window hit. - * [15:9] - Reserved - */ -#define PBS_UNIT_DMA_IO_MASTER_MAP_CNTL_MASK 0x0000FFFF -#define PBS_UNIT_DMA_IO_MASTER_MAP_CNTL_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_DMA_IO_MASTER_MAP_RSRVD_MASK 0xFFFF0000 -#define PBS_UNIT_DMA_IO_MASTER_MAP_RSRVD_SHIFT 16 - -/**** i2c_pld_status_high register ****/ -/* I2C pre-load status */ -#define PBS_UNIT_I2C_PLD_STATUS_HIGH_STATUS_MASK 0x000000FF -#define PBS_UNIT_I2C_PLD_STATUS_HIGH_STATUS_SHIFT 0 - -/**** spi_dbg_status_high register ****/ -/* SPI DBG load status */ -#define PBS_UNIT_SPI_DBG_STATUS_HIGH_STATUS_MASK 0x000000FF -#define PBS_UNIT_SPI_DBG_STATUS_HIGH_STATUS_SHIFT 0 - -/**** spi_mst_status_high register ****/ -/* SP IMST load status */ -#define PBS_UNIT_SPI_MST_STATUS_HIGH_STATUS_MASK 0x000000FF -#define PBS_UNIT_SPI_MST_STATUS_HIGH_STATUS_SHIFT 0 - -/**** mem_pbs_parity_err_high register ****/ -/* Address latch in the case of a parity error */ -#define PBS_UNIT_MEM_PBS_PARITY_ERR_HIGH_ADDR_MASK 0x000000FF -#define PBS_UNIT_MEM_PBS_PARITY_ERR_HIGH_ADDR_SHIFT 0 - -/**** cfg_axi_conf_0 register ****/ -/* Sets the AXI field in the I2C preloader interface. */ -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_RD_ID_MASK 0x0000007F -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_RD_ID_SHIFT 0 -/* Sets the AXI field in the I2C preloader interface. */ -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_WR_ID_MASK 0x00003F80 -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_WR_ID_SHIFT 7 -/* Sets the AXI field in the I2C preloader interface. */ -#define PBS_UNIT_CFG_AXI_CONF_0_PLD_WR_ID_MASK 0x001FC000 -#define PBS_UNIT_CFG_AXI_CONF_0_PLD_WR_ID_SHIFT 14 -/* Sets the AXI field in the SPI debug interface. */ -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_AWCACHE_MASK 0x01E00000 -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_AWCACHE_SHIFT 21 -/* Sets the AXI field in the SPI debug interface. */ -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_ARCACHE_MASK 0x1E000000 -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_ARCACHE_SHIFT 25 -/* Sets the AXI field in the SPI debug interface. */ -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_AXPROT_MASK 0xE0000000 -#define PBS_UNIT_CFG_AXI_CONF_0_DBG_AXPROT_SHIFT 29 - -/**** cfg_axi_conf_1 register ****/ -/* Sets the AXI field in the SPI debug interface. */ -#define PBS_UNIT_CFG_AXI_CONF_1_DBG_ARUSER_MASK 0x03FFFFFF -#define PBS_UNIT_CFG_AXI_CONF_1_DBG_ARUSER_SHIFT 0 -/* Sets the AXI field in the SPI debug interface. */ -#define PBS_UNIT_CFG_AXI_CONF_1_DBG_ARQOS_MASK 0x3C000000 -#define PBS_UNIT_CFG_AXI_CONF_1_DBG_ARQOS_SHIFT 26 - -/**** cfg_axi_conf_2 register ****/ -/* Sets the AXI field in the SPI debug interface. */ -#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWUSER_MASK 0x03FFFFFF -#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWUSER_SHIFT 0 -/* Sets the AXI field in the SPI debug interface. */ -#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWQOS_MASK 0x3C000000 -#define PBS_UNIT_CFG_AXI_CONF_2_DBG_AWQOS_SHIFT 26 - -/**** spi_mst_conf_0 register ****/ -/* - * Sets the SPI master Configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SRL (1 << 0) -/* - * Sets the SPI master Configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SCPOL (1 << 1) -/* - * Sets the SPI master Configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SCPH (1 << 2) -/* - * Set the SPI master configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SER_MASK 0x00000078 -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_SER_SHIFT 3 -/* - * Set the SPI master configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_BAUD_MASK 0x007FFF80 -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_BAUD_SHIFT 7 -/* - * Sets the SPI master configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_RD_CMD_MASK 0x7F800000 -#define PBS_UNIT_SPI_MST_CONF_0_CFG_SPI_MST_RD_CMD_SHIFT 23 - -/**** spi_mst_conf_1 register ****/ -/* - * Sets the SPI master Configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_WR_CMD_MASK 0x000000FF -#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_WR_CMD_SHIFT 0 -/* - * Sets the SPI master Configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_ADDR_BYTES_NUM_MASK 0x00000700 -#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_ADDR_BYTES_NUM_SHIFT 8 -/* - * Sets the SPI master Configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_TMODE_MASK 0x00001800 -#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_TMODE_SHIFT 11 -/* - * Sets the SPI master Configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_MST_CONF_1_CFG_SPI_MST_FAST_RD (1 << 13) - -/**** spi_slv_conf_0 register ****/ -/* - * Sets the SPI slave configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_BAUD_MASK 0x0000FFFF -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_BAUD_SHIFT 0 -/* Value. The reset value is according to bootstrap. */ -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SCPOL (1 << 16) -/* Value. The reset value is according to bootstrap. */ -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SCPH (1 << 17) -/* - * Sets the SPI slave configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SER_MASK 0x03FC0000 -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SER_SHIFT 18 -/* - * Sets the SPI slave configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_SRL (1 << 26) -/* - * Sets the SPI slave configuration. For details see the SPI section in the - * documentation. - */ -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_TMODE_MASK 0x18000000 -#define PBS_UNIT_SPI_SLV_CONF_0_CFG_SPI_SLV_TMODE_SHIFT 27 - -/**** apb_mem_conf_int register ****/ -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_PBS_WRR_CNT_MASK 0x00000007 -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_PBS_WRR_CNT_SHIFT 0 -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_I2C_PLD_APB_MIX_ARB (1 << 3) -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_SPI_DBG_APB_MIX_ARB (1 << 4) -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_SPI_MST_APB_MIX_ARB (1 << 5) -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_I2C_PLD_CLEAR_FSM (1 << 6) -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_SPI_DBG_CLEAR_FSM (1 << 7) -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_SPI_MST_CLEAR_FSM (1 << 8) -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_PBS_AXI_FSM_CLEAR (1 << 9) -/* Value-- internal */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_PBS_AXI_FIFOS_CLEAR (1 << 10) -/* Enables parity protection on the integrated SRAM. */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_BOOTROM_PARITY_EN (1 << 11) -/* - * When set, reports a slave error whenthe slave returns an AXI slave error, for - * configuration access to the internal configuration space. - */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_RD_SLV_ERR_EN (1 << 12) -/* - * When set, reports a decode error when timeout has occurred for configuration - * access to the internal configuration space. - */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_RD_DEC_ERR_EN (1 << 13) -/* - * When set, reports a slave error, when the slave returns an AXI slave error, - * for configuration access to the internal configuration space. - */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_WR_SLV_ERR_EN (1 << 14) -/* - * When set, reports a decode error when timeout has occurred for configuration - * access to the internal configuration space. - */ -#define PBS_UNIT_APB_MEM_CONF_INT_CFG_WR_DEC_ERR_EN (1 << 15) - -/**** sb_int_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_SB_INT_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_SB_INT_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_SB_INT_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_SB_INT_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_SB_INT_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_SB_INT_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** ufc_pbs_parity_err_high register ****/ -/* - * Address latch in the case of a parity error in the Flash Controller internal - * memories. - */ -#define PBS_UNIT_UFC_PBS_PARITY_ERR_HIGH_ADDR_MASK 0x000000FF -#define PBS_UNIT_UFC_PBS_PARITY_ERR_HIGH_ADDR_SHIFT 0 - -/**** chip_id register ****/ -/* [15:0] : Dev Rev ID */ -#define PBS_UNIT_CHIP_ID_DEV_REV_ID_MASK 0x0000FFFF -#define PBS_UNIT_CHIP_ID_DEV_REV_ID_SHIFT 0 -/* [31:16] : 0x0 - Dev ID */ -#define PBS_UNIT_CHIP_ID_DEV_ID_MASK 0xFFFF0000 -#define PBS_UNIT_CHIP_ID_DEV_ID_SHIFT 16 - -#define PBS_UNIT_CHIP_ID_DEV_ID_ALPINE 0 -#define PBS_UNIT_CHIP_ID_DEV_ID_PEAKROCK 1 -#define PBS_UNIT_CHIP_ID_DEV_ID_COYOTE 2 - -/**** uart0_conf_status register ****/ -/* - * Conf: - * // [0] -- DSR_N RW bit - * // [1] -- DCD_N RW bit - * // [2] -- RI_N bit - * // [3] -- dma_tx_ack_n - * // [4] -- dma_rx_ack_n - */ -#define PBS_UNIT_UART0_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_UART0_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: - * // [16] -- dtr_n RO bit - * // [17] -- OUT1_N RO bit - * // [18] -- OUT2_N RO bit - * // [19] -- dma_tx_req_n RO bit - * // [20] -- dma_tx_single_n RO bit - * // [21] -- dma_rx_req_n RO bit - * // [22] -- dma_rx_single_n RO bit - * // [23] -- uart_lp_req_pclk RO bit - * // [24] -- baudout_n RO bit - */ -#define PBS_UNIT_UART0_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_UART0_CONF_STATUS_STATUS_SHIFT 16 - -/**** uart1_conf_status register ****/ -/* - * Conf: // [0] -- DSR_N RW bit // [1] -- DCD_N RW bit // [2] -- RI_N bit // [3] - * -- dma_tx_ack_n // [4] - dma_rx_ack_n - */ -#define PBS_UNIT_UART1_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_UART1_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: // [16] -- dtr_n RO bit // [17] -- OUT1_N RO bit // [18] -- OUT2_N RO - * bit // [19] -- dma_tx_req_n RO bit // [20] -- dma_tx_single_n RO bit // [21] - * -- dma_rx_req_n RO bit // [22] -- dma_rx_single_n RO bit // [23] -- - * uart_lp_req_pclk RO bit // [24] -- baudout_n RO bit - */ -#define PBS_UNIT_UART1_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_UART1_CONF_STATUS_STATUS_SHIFT 16 - -/**** uart2_conf_status register ****/ -/* - * Conf: // [0] -- DSR_N RW bit // [1] -- DCD_N RW bit // [2] -- RI_N bit // [3] - * -- dma_tx_ack_n // [4] - dma_rx_ack_n - */ -#define PBS_UNIT_UART2_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_UART2_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: // [16] -- dtr_n RO bit // [17] -- OUT1_N RO bit // [18] -- OUT2_N RO - * bit // [19] -- dma_tx_req_n RO bit // [20] -- dma_tx_single_n RO bit // [21] - * -- dma_rx_req_n RO bit // [22] -- dma_rx_single_n RO bit // [23] -- - * uart_lp_req_pclk RO bit // [24] -- baudout_n RO bit - */ -#define PBS_UNIT_UART2_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_UART2_CONF_STATUS_STATUS_SHIFT 16 - -/**** uart3_conf_status register ****/ -/* - * Conf: // [0] -- DSR_N RW bit // [1] -- DCD_N RW bit // [2] -- RI_N bit // [3] - * -- dma_tx_ack_n // [4] - dma_rx_ack_n - */ -#define PBS_UNIT_UART3_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_UART3_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: // [16] -- dtr_n RO bit // [17] -- OUT1_N RO bit // [18] -- OUT2_N RO - * bit // [19] -- dma_tx_req_n RO bit // [20] -- dma_tx_single_n RO bit // [21] - * -- dma_rx_req_n RO bit // [22] -- dma_rx_single_n RO bit // [23] -- - * uart_lp_req_pclk RO bit // [24] -- baudout_n RO bit - */ -#define PBS_UNIT_UART3_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_UART3_CONF_STATUS_STATUS_SHIFT 16 - -/**** gpio0_conf_status register ****/ -/* - * Cntl: - * // [7:0] nGPAFEN; // from regfile - * // [15:8] GPAFOUT; // from regfile - */ -#define PBS_UNIT_GPIO0_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_GPIO0_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: - * // [24:16] GPAFIN; // to regfile - */ -#define PBS_UNIT_GPIO0_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_GPIO0_CONF_STATUS_STATUS_SHIFT 16 - -/**** gpio1_conf_status register ****/ -/* - * Cntl: - * // [7:0] nGPAFEN; // from regfile - * // [15:8] GPAFOUT; // from regfile - */ -#define PBS_UNIT_GPIO1_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_GPIO1_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: - * // [24:16] GPAFIN; // to regfile - */ -#define PBS_UNIT_GPIO1_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_GPIO1_CONF_STATUS_STATUS_SHIFT 16 - -/**** gpio2_conf_status register ****/ -/* - * Cntl: - * // [7:0] nGPAFEN; // from regfile - * // [15:8] GPAFOUT; // from regfile - */ -#define PBS_UNIT_GPIO2_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_GPIO2_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: - * // [24:16] GPAFIN; // to regfile - */ -#define PBS_UNIT_GPIO2_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_GPIO2_CONF_STATUS_STATUS_SHIFT 16 - -/**** gpio3_conf_status register ****/ -/* - * Cntl: - * // [7:0] nGPAFEN; // from regfile - * // [15:8] GPAFOUT; // from regfile - */ -#define PBS_UNIT_GPIO3_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_GPIO3_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: - * // [24:16] GPAFIN; // to regfile - */ -#define PBS_UNIT_GPIO3_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_GPIO3_CONF_STATUS_STATUS_SHIFT 16 - -/**** gpio4_conf_status register ****/ -/* - * Cntl: - * // [7:0] nGPAFEN; // from regfile - * // [15:8] GPAFOUT; // from regfile - */ -#define PBS_UNIT_GPIO4_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_GPIO4_CONF_STATUS_CONF_SHIFT 0 -/* - * Status: - * // [24:16] GPAFIN; // to regfile - */ -#define PBS_UNIT_GPIO4_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_GPIO4_CONF_STATUS_STATUS_SHIFT 16 - -/**** i2c_gen_conf_status register ****/ -/* - * cntl - * // [0] -- dma_tx_ack - * // [1] -- dma_rx_ack - */ -#define PBS_UNIT_I2C_GEN_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_I2C_GEN_CONF_STATUS_CONF_SHIFT 0 -/* - * Status - * - * // [16] -- dma_tx_req RO bit - * // [17] -- dma_tx_single RO bit - * // [18] -- dma_rx_req RO bit - * // [19] -- dma_rx_single RO bit - */ -#define PBS_UNIT_I2C_GEN_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_I2C_GEN_CONF_STATUS_STATUS_SHIFT 16 - -/**** watch_dog_reset_out register ****/ -/* - * [0] If set to 1'b1, WD0 cannot generate reset_out_n - * [1] If set to 1'b1, WD1 cannot generate reset_out_n - * [2] If set to 1'b1, WD2 cannot generate reset_out_n - * [3] If set to 1'b1, WD3 cannot generate reset_out_n - * [4] If set to 1'b1, WD4 cannot generate reset_out_n - * [5] If set to 1'b1, WD5 cannot generate reset_out_n - * [6] If set to 1'b1, WD6 cannot generate reset_out_n - * [7] If set to 1'b1, WD7 cannot generate reset_out_n - */ -#define PBS_UNIT_WATCH_DOG_RESET_OUT_DISABLE_MASK 0x000000FF -#define PBS_UNIT_WATCH_DOG_RESET_OUT_DISABLE_SHIFT 0 - -/**** otp_cntl register ****/ -/* from reg file Config To bypass the copy from OTPW to OTPR */ -#define PBS_UNIT_OTP_CNTL_IGNORE_OTPW (1 << 0) -/* Not in use.Comes from bond. */ -#define PBS_UNIT_OTP_CNTL_IGNORE_PRELOAD (1 << 1) -/* Margin read from the fuse box */ -#define PBS_UNIT_OTP_CNTL_OTPW_MARGIN_READ (1 << 2) -/* Indicates when OTPis busy. */ -#define PBS_UNIT_OTP_CNTL_OTP_BUSY (1 << 3) - -/**** otp_cfg_0 register ****/ -/* Cfg to OTP cntl. */ -#define PBS_UNIT_OTP_CFG_0_CFG_OTPW_PWRDN_CNT_MASK 0x0000FFFF -#define PBS_UNIT_OTP_CFG_0_CFG_OTPW_PWRDN_CNT_SHIFT 0 -/* Cfg to OTP cntl. */ -#define PBS_UNIT_OTP_CFG_0_CFG_OTPW_READ_CNT_MASK 0xFFFF0000 -#define PBS_UNIT_OTP_CFG_0_CFG_OTPW_READ_CNT_SHIFT 16 - -/**** otp_cfg_1 register ****/ -/* Cfg to OTP cntl. */ -#define PBS_UNIT_OTP_CFG_1_CFG_OTPW_PGM_CNT_MASK 0x0000FFFF -#define PBS_UNIT_OTP_CFG_1_CFG_OTPW_PGM_CNT_SHIFT 0 -/* Cfg to OTP cntl. */ -#define PBS_UNIT_OTP_CFG_1_CFG_OTPW_PREP_CNT_MASK 0xFFFF0000 -#define PBS_UNIT_OTP_CFG_1_CFG_OTPW_PREP_CNT_SHIFT 16 - -/**** otp_cfg_3 register ****/ -/* Cfg to OTP cntl. */ -#define PBS_UNIT_OTP_CFG_3_CFG_OTPW_PS18_CNT_MASK 0x0000FFFF -#define PBS_UNIT_OTP_CFG_3_CFG_OTPW_PS18_CNT_SHIFT 0 -/* Cfg to OTP cntl. */ -#define PBS_UNIT_OTP_CFG_3_CFG_OTPW_PWRUP_CNT_MASK 0xFFFF0000 -#define PBS_UNIT_OTP_CFG_3_CFG_OTPW_PWRUP_CNT_SHIFT 16 - -/**** nb_nic_regs_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_NB_NIC_REGS_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** sb_nic_regs_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_RSRVD_SHIFT 6 -/* bar low address 16 MSB bits */ -#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_SB_NIC_REGS_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** serdes_mux_multi_0 register ****/ -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_8_MASK 0x00000007 -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_8_SHIFT 0 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_3 (1 << 3) -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_9_MASK 0x00000070 -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_9_SHIFT 4 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_7 (1 << 7) -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_10_MASK 0x00000700 -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_10_SHIFT 8 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_11 (1 << 11) -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_11_MASK 0x00007000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_11_SHIFT 12 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_15 (1 << 15) -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_12_MASK 0x00030000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_12_SHIFT 16 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_13_MASK 0x000C0000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_13_SHIFT 18 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_14_MASK 0x00300000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_14_SHIFT 20 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_15_MASK 0x00C00000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_SELECT_OH_SERDES_15_SHIFT 22 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_MASK 0xFF000000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_RSRVD_SHIFT 24 - -/* - * 2'b01 - select sata_b[0] - * 2'b10 - select eth_a[0] - */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_8_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_8_SHIFT 0 -/* - * 3'b001 - select sata_b[1] - * 3'b010 - select eth_b[0] - * 3'b100 - select eth_a[1] - */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_9_MASK 0x00000070 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_9_SHIFT 4 -/* - * 3'b001 - select sata_b[2] - * 3'b010 - select eth_c[0] - * 3'b100 - select eth_a[2] - */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_10_MASK 0x00000700 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_10_SHIFT 8 -/* - * 3'b001 - select sata_b[3] - * 3'b010 - select eth_d[0] - * 3'b100 - select eth_a[3] - */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_11_MASK 0x00007000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_11_SHIFT 12 -/* - * 2'b01 - select eth_a[0] - * 2'b10 - select sata_a[0] - */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_12_MASK 0x00030000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_12_SHIFT 16 -/* - * 3'b001 - select eth_b[0] - * 3'b010 - select eth_c[1] - * 3'b100 - select sata_a[1] - */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_13_MASK 0x00700000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_13_SHIFT 20 -/* - * 3'b001 - select eth_a[0] - * 3'b010 - select eth_c[2] - * 3'b100 - select sata_a[2] - */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_14_MASK 0x07000000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_14_SHIFT 24 -/* - * 3'b001 - select eth_d[0] - * 3'b010 - select eth_c[3] - * 3'b100 - select sata_a[3] - */ -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_15_MASK 0x70000000 -#define PBS_UNIT_SERDES_MUX_MULTI_0_PKR_SELECT_OH_SERDES_15_SHIFT 28 - -/**** serdes_mux_multi_1 register ****/ -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_A_0_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_A_0_SHIFT 0 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_3_2_MASK 0x0000000C -#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_3_2_SHIFT 2 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_B_0_MASK 0x00000070 -#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_B_0_SHIFT 4 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_7 (1 << 7) -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_C_0_MASK 0x00000300 -#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_C_0_SHIFT 8 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_11_10_MASK 0x00000C00 -#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_11_10_SHIFT 10 -/* SerDes one hot mux control. For details see datasheet. */ -#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_D_0_MASK 0x00007000 -#define PBS_UNIT_SERDES_MUX_MULTI_1_SELECT_OH_ETH_D_0_SHIFT 12 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_MASK 0xFFFF8000 -#define PBS_UNIT_SERDES_MUX_MULTI_1_RSRVD_SHIFT 15 - -/**** pbs_ulpi_mux_conf register ****/ -/* - * Value 0 - Select dedicated pins for the USB-1 inputs. - * Value 1 - Select PBS mux pins for the USB-1 inputs. - * [0] ULPI_B_CLK - * [1] ULPI_B_DIR - * [2] ULPI_B_NXT - * [10:3] ULPI_B_DATA[7:0] - */ -#define PBS_UNIT_PBS_ULPI_MUX_CONF_SEL_UPLI_IN_PBSMUX_MASK 0x000007FF -#define PBS_UNIT_PBS_ULPI_MUX_CONF_SEL_UPLI_IN_PBSMUX_SHIFT 0 -/* - * [3] - Force to zero - * [2] == 1 - Force register selection - * [1 : 0] -Binary selection of the input in bypass mode - */ -#define PBS_UNIT_PBS_ULPI_MUX_CONF_REG_MDIO_BYPASS_SEL_MASK 0x0000F000 -#define PBS_UNIT_PBS_ULPI_MUX_CONF_REG_MDIO_BYPASS_SEL_SHIFT 12 -/* - * [0] Sets the clk_ulpi OE for USB0, 1'b0 set to input, 1'b1 set to output. - * [1] Sets the clk_ulpi OE for USB01, 1'b0 set to input, 1'b1 set to output. - */ -#define PBS_UNIT_PBS_ULPI_MUX_CONF_RSRVD_MASK 0xFFFF0000 -#define PBS_UNIT_PBS_ULPI_MUX_CONF_RSRVD_SHIFT 16 - -/**** wr_once_dbg_dis_ovrd_reg register ****/ -/* This register can be written only once. Use in the secure boot process. */ -#define PBS_UNIT_WR_ONCE_DBG_DIS_OVRD_REG_WR_ONCE_DBG_DIS_OVRD (1 << 0) - -#define PBS_UNIT_WR_ONCE_DBG_DIS_OVRD_REG_RSRVD_MASK 0xFFFFFFFE -#define PBS_UNIT_WR_ONCE_DBG_DIS_OVRD_REG_RSRVD_SHIFT 1 - -/**** gpio5_conf_status register ****/ -/* - * Cntl: // [7:0] nGPAFEN; // from regfile // [15:8] GPAFOUT; // from regfile - */ -#define PBS_UNIT_GPIO5_CONF_STATUS_CONF_MASK 0x0000FFFF -#define PBS_UNIT_GPIO5_CONF_STATUS_CONF_SHIFT 0 -/* Status: // [24:16] GPAFIN; // to regfile */ -#define PBS_UNIT_GPIO5_CONF_STATUS_STATUS_MASK 0xFFFF0000 -#define PBS_UNIT_GPIO5_CONF_STATUS_STATUS_SHIFT 16 - -/**** pcie_mem3_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_MEM3_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_MEM3_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_MEM3_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_MEM3_BAR_LOW_RSRVD_SHIFT 6 -/* Reserved */ -#define PBS_UNIT_PCIE_MEM3_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_MEM3_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_mem4_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_MEM4_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_MEM4_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_MEM4_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_MEM4_BAR_LOW_RSRVD_SHIFT 6 -/* Reserved */ -#define PBS_UNIT_PCIE_MEM4_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_MEM4_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_mem5_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_MEM5_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_MEM5_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_MEM5_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_MEM5_BAR_LOW_RSRVD_SHIFT 6 -/* Reserved */ -#define PBS_UNIT_PCIE_MEM5_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_MEM5_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_ext_ecam3_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_RSRVD_SHIFT 6 -/* Reserved */ -#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_EXT_ECAM3_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_ext_ecam4_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_RSRVD_SHIFT 6 -/* Reserved */ -#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_EXT_ECAM4_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pcie_ext_ecam5_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_RSRVD_SHIFT 6 -/* Reserved */ -#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_PCIE_EXT_ECAM5_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** low_latency_sram_bar_low register ****/ -/* Window size = 2 ^ (15 + win_size). Zero value: disable the window. */ -#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_WIN_SIZE_MASK 0x0000003F -#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_RSRVD_MASK 0x0000FFC0 -#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_RSRVD_SHIFT 6 -/* Reserved */ -#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_ADDR_HIGH_MASK 0xFFFF0000 -#define PBS_UNIT_LOW_LATENCY_SRAM_BAR_LOW_ADDR_HIGH_SHIFT 16 - -/**** pbs_sb2nb_cfg_dram_remap register ****/ -#define PBS_UNIT_SB2NB_REMAP_BASE_ADDR_SHIFT 5 -#define PBS_UNIT_SB2NB_REMAP_BASE_ADDR_MASK 0x0000FFE0 -#define PBS_UNIT_SB2NB_REMAP_TRANSL_BASE_ADDR_SHIFT 21 -#define PBS_UNIT_SB2NB_REMAP_TRANSL_BASE_ADDR_MASK 0xFFE00000 - -/* For remapping are used bits [39 - 29] of DRAM 40bit Physical address */ -#define PBS_UNIT_DRAM_SRC_REMAP_BASE_ADDR_SHIFT 29 -#define PBS_UNIT_DRAM_DST_REMAP_BASE_ADDR_SHIFT 29 -#define PBS_UNIT_DRAM_REMAP_BASE_ADDR_MASK 0xFFE0000000UL - - -/**** serdes_mux_eth register ****/ -/* - * 2'b01 - eth_a[0] from serdes_8 - * 2'b10 - eth_a[0] from serdes_14 - */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_0_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_0_SHIFT 0 -/* - * 2'b01 - eth_b[0] from serdes_9 - * 2'b10 - eth_b[0] from serdes_13 - */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_B_0_MASK 0x00000030 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_B_0_SHIFT 4 -/* - * 2'b01 - eth_c[0] from serdes_10 - * 2'b10 - eth_c[0] from serdes_12 - */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_0_MASK 0x00000300 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_0_SHIFT 8 -/* - * 2'b01 - eth_d[0] from serdes_11 - * 2'b10 - eth_d[0] from serdes_15 - */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_D_0_MASK 0x00003000 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_D_0_SHIFT 12 -/* which lane's is master clk */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_ICK_MASTER_MASK 0x00030000 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_ICK_MASTER_SHIFT 16 -/* which lane's is master clk */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_ICK_MASTER_MASK 0x00300000 -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_ICK_MASTER_SHIFT 20 -/* enable xlaui on eth a */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_A_XLAUI_ENABLE (1 << 24) -/* enable xlaui on eth c */ -#define PBS_UNIT_SERDES_MUX_ETH_PKR_SELECT_OH_ETH_C_XLAUI_ENABLE (1 << 28) - -/**** serdes_mux_pcie register ****/ -/* - * 2'b01 - select pcie_b[0] from serdes 2 - * 2'b10 - select pcie_b[0] from serdes 4 - */ -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_0_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_0_SHIFT 0 -/* - * 2'b01 - select pcie_b[1] from serdes 3 - * 2'b10 - select pcie_b[1] from serdes 5 - */ -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_1_MASK 0x00000030 -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_B_1_SHIFT 4 -/* - * 2'b01 - select pcie_d[0] from serdes 10 - * 2'b10 - select pcie_d[0] from serdes 12 - */ -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_0_MASK 0x00000300 -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_0_SHIFT 8 -/* - * 2'b01 - select pcie_d[1] from serdes 11 - * 2'b10 - select pcie_d[1] from serdes 13 - */ -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_1_MASK 0x00003000 -#define PBS_UNIT_SERDES_MUX_PCIE_PKR_SELECT_OH_PCIE_D_1_SHIFT 12 - -/**** serdes_mux_sata register ****/ -/* - * 2'b01 - select sata_a from serdes group 1 - * 2'b10 - select sata_a from serdes group 3 - */ -#define PBS_UNIT_SERDES_MUX_SATA_SELECT_OH_SATA_A_MASK 0x00000003 -#define PBS_UNIT_SERDES_MUX_SATA_SELECT_OH_SATA_A_SHIFT 0 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_SATA_RESERVED_3_2_MASK 0x0000000C -#define PBS_UNIT_SERDES_MUX_SATA_RESERVED_3_2_SHIFT 2 -/* Reserved */ -#define PBS_UNIT_SERDES_MUX_SATA_RESERVED_MASK 0xFFFFFFF0 -#define PBS_UNIT_SERDES_MUX_SATA_RESERVED_SHIFT 4 - -/**** bar1_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar1_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR1_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar2_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar2_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR2_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar3_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar3_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR3_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar4_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar4_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR4_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar5_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar5_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR5_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar6_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar6_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR6_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar7_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar7_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR7_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar8_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar8_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR8_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar9_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar9_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR9_REMAP_ADDR_HIGH_SHIFT 12 - -/**** bar10_orig register ****/ -/* - * Window size = 2 ^ (11 + win_size). - * Zero value: disable the window. - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_WIN_SIZE_MASK 0x00000007 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_WIN_SIZE_SHIFT 0 -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_RSRVD_MASK 0x00000FF8 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_RSRVD_SHIFT 3 -/* - * offset within the SRAM, in resolution of 4KB. - * Only offsets which are inside the boundaries of the SRAM bar are allowed - */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_ORIG_ADDR_HIGH_SHIFT 12 - -/**** bar10_remap register ****/ -/* Reserved fields */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_REMAP_RSRVD_MASK 0x00000FFF -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_REMAP_RSRVD_SHIFT 0 -/* remapped address */ -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_REMAP_ADDR_HIGH_MASK 0xFFFFF000 -#define PBS_LOW_LATENCY_SRAM_REMAP_BAR10_REMAP_ADDR_HIGH_SHIFT 12 - -/**** cpu register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_CPU_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_DRAM_SHIFT 28 - -/**** cpu_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_CPU_MASK_DRAM_SHIFT 28 - -/**** debug_nb register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_DRAM_SHIFT 28 - -/**** debug_nb_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_NB_MASK_DRAM_SHIFT 28 - -/**** debug_sb register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_DRAM_SHIFT 28 - -/**** debug_sb_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_DEBUG_SB_MASK_DRAM_SHIFT 28 - -/**** eth_0 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_DRAM_SHIFT 28 - -/**** eth_0_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_0_MASK_DRAM_SHIFT 28 - -/**** eth_1 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_DRAM_SHIFT 28 - -/**** eth_1_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_1_MASK_DRAM_SHIFT 28 - -/**** eth_2 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_DRAM_SHIFT 28 - -/**** eth_2_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_2_MASK_DRAM_SHIFT 28 - -/**** eth_3 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_DRAM_SHIFT 28 - -/**** eth_3_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_ETH_3_MASK_DRAM_SHIFT 28 - -/**** sata_0 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_DRAM_SHIFT 28 - -/**** sata_0_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_0_MASK_DRAM_SHIFT 28 - -/**** sata_1 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_DRAM_SHIFT 28 - -/**** sata_1_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_SATA_1_MASK_DRAM_SHIFT 28 - -/**** crypto_0 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_DRAM_SHIFT 28 - -/**** crypto_0_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_0_MASK_DRAM_SHIFT 28 - -/**** crypto_1 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_DRAM_SHIFT 28 - -/**** crypto_1_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_CRYPTO_1_MASK_DRAM_SHIFT 28 - -/**** pcie_0 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_DRAM_SHIFT 28 - -/**** pcie_0_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_0_MASK_DRAM_SHIFT 28 - -/**** pcie_1 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_DRAM_SHIFT 28 - -/**** pcie_1_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_1_MASK_DRAM_SHIFT 28 - -/**** pcie_2 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_DRAM_SHIFT 28 - -/**** pcie_2_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_2_MASK_DRAM_SHIFT 28 - -/**** pcie_3 register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_DRAM_SHIFT 28 - -/**** pcie_3_mask register ****/ -/* map transactions according to address decoding */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_NO_ENFORCEMENT_MASK 0x0000000F -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_NO_ENFORCEMENT_SHIFT 0 -/* map transactions to pcie_0 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_0_MASK 0x000000F0 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_0_SHIFT 4 -/* map transactions to pcie_1 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_1_MASK 0x00000F00 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_1_SHIFT 8 -/* map transactions to pcie_2 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_2_MASK 0x0000F000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_2_SHIFT 12 -/* map transactions to pcie_3 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_3_MASK 0x000F0000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_3_SHIFT 16 -/* map transactions to pcie_4 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_4_MASK 0x00F00000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_4_SHIFT 20 -/* map transactions to pcie_5 */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_5_MASK 0x0F000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_PCIE_5_SHIFT 24 -/* map transactions to dram */ -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_DRAM_MASK 0xF0000000 -#define PBS_TARGET_ID_ENFORCEMENT_PCIE_3_MASK_DRAM_SHIFT 28 - -/**** latch register ****/ -/* - * Software clears this bit before any bar update, and set it after all bars - * updated. - */ -#define PBS_TARGET_ID_ENFORCEMENT_LATCH_ENABLE (1 << 0) - -#ifdef __cplusplus -} -#endif - -#endif /* __AL_HAL_PBS_REGS_H__ */ - -/** @} end of ... group */ - - diff --git a/sys/arm/annapurna/alpine/hal/al_hal_pcie.c b/sys/arm/annapurna/alpine/hal/al_hal_pcie.c deleted file mode 100644 index 3a221d365732..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_pcie.c +++ /dev/null @@ -1,2788 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*******************************************************************************/ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include "al_hal_pcie.h" -#include "al_hal_pbs_regs.h" -#include "al_hal_unit_adapter_regs.h" - -/** - * Parameter definitions - */ -#define AL_PCIE_AXI_REGS_OFFSET 0x0 - -#define AL_PCIE_LTSSM_STATE_L0 0x11 -#define AL_PCIE_LTSSM_STATE_L0S 0x12 -#define AL_PCIE_DEVCTL_PAYLOAD_128B 0x00 -#define AL_PCIE_DEVCTL_PAYLOAD_256B 0x20 - -#define AL_PCIE_SECBUS_DEFAULT 0x1 -#define AL_PCIE_SUBBUS_DEFAULT 0x1 -#define AL_PCIE_LINKUP_WAIT_INTERVAL 50 /* measured in usec */ -#define AL_PCIE_LINKUP_WAIT_INTERVALS_PER_SEC 20 - -#define AL_PCIE_LINKUP_RETRIES 8 - -#define AL_PCIE_MAX_32_MEMORY_BAR_SIZE (0x100000000ULL) -#define AL_PCIE_MIN_MEMORY_BAR_SIZE (1 << 12) -#define AL_PCIE_MIN_IO_BAR_SIZE (1 << 8) - -/** - * inbound header credits and outstanding outbound reads defaults - */ -/** RC - Revisions 1/2 */ -#define AL_PCIE_REV_1_2_RC_OB_OS_READS_DEFAULT (8) -#define AL_PCIE_REV_1_2_RC_NOF_CPL_HDR_DEFAULT (41) -#define AL_PCIE_REV_1_2_RC_NOF_NP_HDR_DEFAULT (25) -#define AL_PCIE_REV_1_2_RC_NOF_P_HDR_DEFAULT (31) -/** EP - Revisions 1/2 */ -#define AL_PCIE_REV_1_2_EP_OB_OS_READS_DEFAULT (15) -#define AL_PCIE_REV_1_2_EP_NOF_CPL_HDR_DEFAULT (76) -#define AL_PCIE_REV_1_2_EP_NOF_NP_HDR_DEFAULT (6) -#define AL_PCIE_REV_1_2_EP_NOF_P_HDR_DEFAULT (15) -/** RC - Revision 3 */ -#define AL_PCIE_REV_3_RC_OB_OS_READS_DEFAULT (32) -#define AL_PCIE_REV_3_RC_NOF_CPL_HDR_DEFAULT (161) -#define AL_PCIE_REV_3_RC_NOF_NP_HDR_DEFAULT (38) -#define AL_PCIE_REV_3_RC_NOF_P_HDR_DEFAULT (60) -/** EP - Revision 3 */ -#define AL_PCIE_REV_3_EP_OB_OS_READS_DEFAULT (32) -#define AL_PCIE_REV_3_EP_NOF_CPL_HDR_DEFAULT (161) -#define AL_PCIE_REV_3_EP_NOF_NP_HDR_DEFAULT (38) -#define AL_PCIE_REV_3_EP_NOF_P_HDR_DEFAULT (60) - -/** - * MACROS - */ -#define AL_PCIE_PARSE_LANES(v) (((1 << v) - 1) << \ - PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT) - -/** - * Static functions - */ -static void -al_pcie_port_wr_to_ro_set(struct al_pcie_port *pcie_port, al_bool enable) -{ - /* when disabling writes to RO, make sure any previous writes to - * config space were committed - */ - if (enable == AL_FALSE) - al_local_data_memory_barrier(); - - al_reg_write32(&pcie_port->regs->port_regs->rd_only_wr_en, - (enable == AL_TRUE) ? 1 : 0); - - /* when enabling writes to RO, make sure it is committed before trying - * to write to RO config space - */ - if (enable == AL_TRUE) - al_local_data_memory_barrier(); -} - -/** helper function to access dbi_cs2 registers */ -static void -al_reg_write32_dbi_cs2( - struct al_pcie_port *pcie_port, - uint32_t *offset, - uint32_t val) -{ - uintptr_t cs2_bit = - (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? 0x4000 : 0x1000; - - al_reg_write32((uint32_t *)((uintptr_t)offset | cs2_bit), val); -} - -static unsigned int -al_pcie_speed_gen_code(enum al_pcie_link_speed speed) -{ - if (speed == AL_PCIE_LINK_SPEED_GEN1) - return 1; - if (speed == AL_PCIE_LINK_SPEED_GEN2) - return 2; - if (speed == AL_PCIE_LINK_SPEED_GEN3) - return 3; - /* must not be reached */ - return 0; -} - -static inline void -al_pcie_port_link_speed_ctrl_set( - struct al_pcie_port *pcie_port, - enum al_pcie_link_speed max_speed) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); - - if (max_speed != AL_PCIE_LINK_SPEED_DEFAULT) { - uint16_t max_speed_val = (uint16_t)al_pcie_speed_gen_code(max_speed); - al_reg_write32_masked( - (uint32_t __iomem *)(regs->core_space[0].pcie_link_cap_base), - 0xF, max_speed_val); - al_reg_write32_masked( - (uint32_t __iomem *)(regs->core_space[0].pcie_cap_base - + (AL_PCI_EXP_LNKCTL2 >> 2)), - 0xF, max_speed_val); - } - - al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); -} - -static int -al_pcie_port_link_config( - struct al_pcie_port *pcie_port, - const struct al_pcie_link_params *link_params) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint8_t max_lanes = pcie_port->max_lanes; - - if ((link_params->max_payload_size != AL_PCIE_MPS_DEFAULT) && - (link_params->max_payload_size != AL_PCIE_MPS_128) && - (link_params->max_payload_size != AL_PCIE_MPS_256)) { - al_err("PCIe %d: unsupported Max Payload Size (%u)\n", - pcie_port->port_id, link_params->max_payload_size); - return -EINVAL; - } - - al_dbg("PCIe %d: link config: max speed gen %d, max lanes %d, reversal %s\n", - pcie_port->port_id, link_params->max_speed, - pcie_port->max_lanes, link_params->enable_reversal? "enable" : "disable"); - - al_pcie_port_link_speed_ctrl_set(pcie_port, link_params->max_speed); - - /* Change Max Payload Size, if needed. - * The Max Payload Size is only valid for PF0. - */ - if (link_params->max_payload_size != AL_PCIE_MPS_DEFAULT) - al_reg_write32_masked(regs->core_space[0].pcie_dev_ctrl_status, - PCIE_PORT_DEV_CTRL_STATUS_MPS_MASK, - link_params->max_payload_size << - PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT); - - /** Snap from PCIe core spec: - * Link Mode Enable. Sets the number of lanes in the link that you want - * to connect to the link partner. When you have unused lanes in your - * system, then you must change the value in this register to reflect - * the number of lanes. You must also change the value in the - * "Predetermined Number of Lanes" field of the "Link Width and Speed - * Change Control Register". - * 000001: x1 - * 000011: x2 - * 000111: x4 - * 001111: x8 - * 011111: x16 - * 111111: x32 (not supported) - */ - al_reg_write32_masked(®s->port_regs->gen2_ctrl, - PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_MASK, - max_lanes << PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_SHIFT); - al_reg_write32_masked(®s->port_regs->port_link_ctrl, - PCIE_PORT_LINK_CTRL_LINK_CAPABLE_MASK, - (max_lanes + (max_lanes-1)) - << PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT); - - /* TODO: add support for reversal mode */ - if (link_params->enable_reversal) { - al_err("PCIe %d: enabling reversal mode not implemented\n", - pcie_port->port_id); - return -ENOSYS; - } - return 0; -} - -static void -al_pcie_port_ram_parity_int_config( - struct al_pcie_port *pcie_port, - al_bool enable) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_reg_write32(®s->app.parity->en_core, - (enable == AL_TRUE) ? 0xffffffff : 0x0); - - al_reg_write32_masked(®s->app.int_grp_b->mask, - PCIE_W_INT_GRP_B_CAUSE_B_PARITY_ERROR_CORE, - (enable != AL_TRUE) ? - PCIE_W_INT_GRP_B_CAUSE_B_PARITY_ERROR_CORE : 0); - -} - -static void -al_pcie_port_axi_parity_int_config( - struct al_pcie_port *pcie_port, - al_bool enable) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t parity_enable_mask = 0xffffffff; - - /** - * Addressing RMN: 5603 - * - * RMN description: - * u4_ram2p signal false parity error - * - * Software flow: - * Disable parity check for this memory - */ - if (pcie_port->rev_id >= AL_PCIE_REV_ID_3) - parity_enable_mask &= ~PCIE_AXI_PARITY_EN_AXI_U4_RAM2P; - - al_reg_write32(regs->axi.parity.en_axi, - (enable == AL_TRUE) ? parity_enable_mask : 0x0); - - if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - al_reg_write32_masked(regs->axi.ctrl.global, - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR | - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD | - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV | - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR, - (enable == AL_TRUE) ? - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR | - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD | - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV | - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR : - PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV); - } else { - al_reg_write32_masked(regs->axi.ctrl.global, - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR | - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD | - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV | - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR, - (enable == AL_TRUE) ? - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR | - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD | - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV | - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR : - PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV); - } - - al_reg_write32_masked(®s->axi.int_grp_a->mask, - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_DATA_PATH_RD | - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_RD | - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_WR | - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_DATA_WR | - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERROR_AXI, - (enable != AL_TRUE) ? - (PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_DATA_PATH_RD | - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_RD | - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_WR | - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_DATA_WR | - PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERROR_AXI) : 0); -} - -static void -al_pcie_port_relaxed_pcie_ordering_config( - struct al_pcie_port *pcie_port, - struct al_pcie_relaxed_ordering_params *relaxed_ordering_params) -{ - struct al_pcie_regs *regs = pcie_port->regs; - enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); - /** - * Default: - * - RC: Rx relaxed ordering only - * - EP: TX relaxed ordering only - */ - al_bool tx_relaxed_ordering = (op_mode == AL_PCIE_OPERATING_MODE_RC ? AL_FALSE : AL_TRUE); - al_bool rx_relaxed_ordering = (op_mode == AL_PCIE_OPERATING_MODE_RC ? AL_TRUE : AL_FALSE); - - if (relaxed_ordering_params) { - tx_relaxed_ordering = relaxed_ordering_params->enable_tx_relaxed_ordering; - rx_relaxed_ordering = relaxed_ordering_params->enable_rx_relaxed_ordering; - } - - /** PCIe ordering: - * - disable outbound completion must be stalled behind outbound write - * ordering rule enforcement is disabled for root-port - * - disables read completion on the master port push slave writes for end-point - */ - al_reg_write32_masked( - regs->axi.ordering.pos_cntl, - PCIE_AXI_POS_ORDER_BYPASS_CMPL_AFTER_WR_FIX | - PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_DIS | - PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_SUPPORT_INTERLV_DIS | - PCIE_AXI_POS_ORDER_SEGMENT_BUFFER_DONT_WAIT_FOR_P_WRITES, - (tx_relaxed_ordering ? - (PCIE_AXI_POS_ORDER_BYPASS_CMPL_AFTER_WR_FIX | - PCIE_AXI_POS_ORDER_SEGMENT_BUFFER_DONT_WAIT_FOR_P_WRITES) : 0) | - (rx_relaxed_ordering ? - (PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_DIS | - PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_SUPPORT_INTERLV_DIS) : 0)); -} - -static int -al_pcie_rev_id_get( - void __iomem *pbs_reg_base, - void __iomem *pcie_reg_base) -{ - uint32_t chip_id; - uint16_t chip_id_dev; - uint8_t rev_id; - struct al_pbs_regs *pbs_regs = pbs_reg_base; - - /* get revision ID from PBS' chip_id register */ - chip_id = al_reg_read32(&pbs_regs->unit.chip_id); - chip_id_dev = AL_REG_FIELD_GET(chip_id, - PBS_UNIT_CHIP_ID_DEV_ID_MASK, - PBS_UNIT_CHIP_ID_DEV_ID_SHIFT); - - if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_ALPINE) { - rev_id = AL_REG_FIELD_GET( - chip_id, - PBS_UNIT_CHIP_ID_DEV_REV_ID_MASK, - PBS_UNIT_CHIP_ID_DEV_REV_ID_SHIFT); - } else if (chip_id_dev == PBS_UNIT_CHIP_ID_DEV_ID_PEAKROCK) { - struct al_pcie_revx_regs __iomem *regs = - (struct al_pcie_revx_regs __iomem *)pcie_reg_base; - uint32_t dev_id; - - dev_id = al_reg_read32(®s->axi.device_id.device_rev_id) & - PCIE_AXI_DEVICE_ID_REG_DEV_ID_MASK; - if (dev_id == PCIE_AXI_DEVICE_ID_REG_DEV_ID_X4) { - rev_id = AL_PCIE_REV_ID_2; - } else if (dev_id == PCIE_AXI_DEVICE_ID_REG_DEV_ID_X8) { - rev_id = AL_PCIE_REV_ID_3; - } else { - al_warn("%s: Revision ID is unknown\n", - __func__); - return -EINVAL; - } - } else { - al_warn("%s: Revision ID is unknown\n", - __func__); - return -EINVAL; - } - return rev_id; -} - -static int -al_pcie_port_lat_rply_timers_config( - struct al_pcie_port *pcie_port, - const struct al_pcie_latency_replay_timers *lat_rply_timers) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t reg = 0; - - AL_REG_FIELD_SET(reg, 0xFFFF, 0, lat_rply_timers->round_trip_lat_limit); - AL_REG_FIELD_SET(reg, 0xFFFF0000, 16, lat_rply_timers->replay_timer_limit); - - al_reg_write32(®s->port_regs->ack_lat_rply_timer, reg); - return 0; -} - -static void -al_pcie_ib_hcrd_os_ob_reads_config_default( - struct al_pcie_port *pcie_port) -{ - - struct al_pcie_ib_hcrd_os_ob_reads_config ib_hcrd_os_ob_reads_config; - - switch (al_pcie_operating_mode_get(pcie_port)) { - case AL_PCIE_OPERATING_MODE_RC: - if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads = - AL_PCIE_REV_3_RC_OB_OS_READS_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_cpl_hdr = - AL_PCIE_REV_3_RC_NOF_CPL_HDR_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_np_hdr = - AL_PCIE_REV_3_RC_NOF_NP_HDR_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_p_hdr = - AL_PCIE_REV_3_RC_NOF_P_HDR_DEFAULT; - } else { - ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads = - AL_PCIE_REV_1_2_RC_OB_OS_READS_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_cpl_hdr = - AL_PCIE_REV_1_2_RC_NOF_CPL_HDR_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_np_hdr = - AL_PCIE_REV_1_2_RC_NOF_NP_HDR_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_p_hdr = - AL_PCIE_REV_1_2_RC_NOF_P_HDR_DEFAULT; - } - break; - - case AL_PCIE_OPERATING_MODE_EP: - if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads = - AL_PCIE_REV_3_EP_OB_OS_READS_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_cpl_hdr = - AL_PCIE_REV_3_EP_NOF_CPL_HDR_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_np_hdr = - AL_PCIE_REV_3_EP_NOF_NP_HDR_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_p_hdr = - AL_PCIE_REV_3_EP_NOF_P_HDR_DEFAULT; - } else { - ib_hcrd_os_ob_reads_config.nof_outstanding_ob_reads = - AL_PCIE_REV_1_2_EP_OB_OS_READS_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_cpl_hdr = - AL_PCIE_REV_1_2_EP_NOF_CPL_HDR_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_np_hdr = - AL_PCIE_REV_1_2_EP_NOF_NP_HDR_DEFAULT; - ib_hcrd_os_ob_reads_config.nof_p_hdr = - AL_PCIE_REV_1_2_EP_NOF_P_HDR_DEFAULT; - } - break; - - default: - al_err("PCIe %d: outstanding outbound transactions could not be configured - unknown operating mode\n", - pcie_port->port_id); - al_assert(0); - } - - al_pcie_port_ib_hcrd_os_ob_reads_config(pcie_port, &ib_hcrd_os_ob_reads_config); -}; - -/** return AL_TRUE is link started (LTSSM enabled) and AL_FALSE otherwise */ -static al_bool -al_pcie_is_link_started(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; - - uint32_t port_init = al_reg_read32(regs->app.global_ctrl.port_init); - uint8_t ltssm_en = AL_REG_FIELD_GET(port_init, - PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK, - PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT); - - return ltssm_en; -} - -/** return AL_TRUE if link is up, AL_FALSE otherwise */ -static al_bool -al_pcie_check_link( - struct al_pcie_port *pcie_port, - uint8_t *ltssm_ret) -{ - struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; - uint32_t info_0; - uint8_t ltssm_state; - - info_0 = al_reg_read32(®s->app.debug->info_0); - - ltssm_state = AL_REG_FIELD_GET(info_0, - PCIE_W_DEBUG_INFO_0_LTSSM_STATE_MASK, - PCIE_W_DEBUG_INFO_0_LTSSM_STATE_SHIFT); - - al_dbg("PCIe %d: Port Debug 0: 0x%08x. LTSSM state :0x%x\n", - pcie_port->port_id, info_0, ltssm_state); - - if (ltssm_ret) - *ltssm_ret = ltssm_state; - - if ((ltssm_state == AL_PCIE_LTSSM_STATE_L0) || - (ltssm_state == AL_PCIE_LTSSM_STATE_L0S)) - return AL_TRUE; - return AL_FALSE; -} - -static int -al_pcie_port_gen2_params_config(struct al_pcie_port *pcie_port, - const struct al_pcie_gen2_params *gen2_params) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t gen2_ctrl; - - al_dbg("PCIe %d: Gen2 params config: Tx Swing %s, interrupt on link Eq %s, set Deemphasis %s\n", - pcie_port->port_id, - gen2_params->tx_swing_low ? "Low" : "Full", - gen2_params->tx_compliance_receive_enable? "enable" : "disable", - gen2_params->set_deemphasis? "enable" : "disable"); - - gen2_ctrl = al_reg_read32(®s->port_regs->gen2_ctrl); - - if (gen2_params->tx_swing_low) - AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT); - else - AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT); - - if (gen2_params->tx_compliance_receive_enable) - AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT); - else - AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT); - - if (gen2_params->set_deemphasis) - AL_REG_BIT_SET(gen2_ctrl, PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT); - else - AL_REG_BIT_CLEAR(gen2_ctrl, PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT); - - al_reg_write32(®s->port_regs->gen2_ctrl, gen2_ctrl); - - return 0; -} - - -static uint16_t -gen3_lane_eq_param_to_val(const struct al_pcie_gen3_lane_eq_params *eq_params) -{ - uint16_t eq_control = 0; - - eq_control = eq_params->downstream_port_transmitter_preset & 0xF; - eq_control |= (eq_params->downstream_port_receiver_preset_hint & 0x7) << 4; - eq_control |= (eq_params->upstream_port_transmitter_preset & 0xF) << 8; - eq_control |= (eq_params->upstream_port_receiver_preset_hint & 0x7) << 12; - - return eq_control; -} - -static int -al_pcie_port_gen3_params_config(struct al_pcie_port *pcie_port, - const struct al_pcie_gen3_params *gen3_params) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t reg = 0; - uint16_t __iomem *lanes_eq_base = (uint16_t __iomem *)(regs->core_space[0].pcie_sec_ext_cap_base + (0xC >> 2)); - int i; - - al_dbg("PCIe %d: Gen3 params config: Equalization %s, interrupt on link Eq %s\n", - pcie_port->port_id, - gen3_params->perform_eq ? "enable" : "disable", - gen3_params->interrupt_enable_on_link_eq_request? "enable" : "disable"); - - if (gen3_params->perform_eq) - AL_REG_BIT_SET(reg, 0); - if (gen3_params->interrupt_enable_on_link_eq_request) - AL_REG_BIT_SET(reg, 1); - - al_reg_write32(regs->core_space[0].pcie_sec_ext_cap_base + (4 >> 2), - reg); - - al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); - - for (i = 0; i < gen3_params->eq_params_elements; i += 2) { - uint32_t eq_control = - (uint32_t)gen3_lane_eq_param_to_val(gen3_params->eq_params + i) | - (uint32_t)gen3_lane_eq_param_to_val(gen3_params->eq_params + i + 1) << 16; - - al_dbg("PCIe %d: Set EQ (0x%08x) for lane %d, %d\n", pcie_port->port_id, eq_control, i, i + 1); - al_reg_write32((uint32_t *)(lanes_eq_base + i), eq_control); - } - - al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); - - reg = al_reg_read32(®s->port_regs->gen3_ctrl); - if (gen3_params->eq_disable) - AL_REG_BIT_SET(reg, PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT); - else - AL_REG_BIT_CLEAR(reg, PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT); - - if (gen3_params->eq_phase2_3_disable) - AL_REG_BIT_SET(reg, PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT); - else - AL_REG_BIT_CLEAR(reg, PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT); - - al_reg_write32(®s->port_regs->gen3_ctrl, reg); - - reg = 0; - AL_REG_FIELD_SET(reg, PCIE_PORT_GEN3_EQ_LF_MASK, - PCIE_PORT_GEN3_EQ_LF_SHIFT, - gen3_params->local_lf); - AL_REG_FIELD_SET(reg, PCIE_PORT_GEN3_EQ_FS_MASK, - PCIE_PORT_GEN3_EQ_FS_SHIFT, - gen3_params->local_fs); - - al_reg_write32(®s->port_regs->gen3_eq_fs_lf, reg); - - reg = 0; - AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_MASK, - PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_SHIFT, - gen3_params->local_lf); - AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_MASK, - PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_SHIFT, - gen3_params->local_fs); - al_reg_write32(regs->axi.conf.zero_lane0, reg); - al_reg_write32(regs->axi.conf.zero_lane1, reg); - al_reg_write32(regs->axi.conf.zero_lane2, reg); - al_reg_write32(regs->axi.conf.zero_lane3, reg); - if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - al_reg_write32(regs->axi.conf.zero_lane4, reg); - al_reg_write32(regs->axi.conf.zero_lane5, reg); - al_reg_write32(regs->axi.conf.zero_lane6, reg); - al_reg_write32(regs->axi.conf.zero_lane7, reg); - } - - /* - * Gen3 EQ Control Register: - * - Preset Request Vector - request 9 - * - Behavior After 24 ms Timeout (when optimal settings are not - * found): Recovery.Equalization.RcvrLock - * - Phase2_3 2 ms Timeout Disable - * - Feedback Mode - Figure Of Merit - */ - reg = 0x00020031; - al_reg_write32(®s->port_regs->gen3_eq_ctrl, reg); - - return 0; -} - -static int -al_pcie_port_tl_credits_config( - struct al_pcie_port *pcie_port, - const struct al_pcie_tl_credits_params *tl_credits __attribute__((__unused__))) -{ - al_err("PCIe %d: transport layer credits config not implemented\n", - pcie_port->port_id); - - return -ENOSYS; - -} - -static int -al_pcie_port_pf_params_config(struct al_pcie_pf *pcie_pf, - const struct al_pcie_pf_config_params *pf_params) -{ - struct al_pcie_port *pcie_port = pcie_pf->pcie_port; - struct al_pcie_regs *regs = pcie_port->regs; - unsigned int pf_num = pcie_pf->pf_num; - int bar_idx; - int ret; - - al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); - - /* Disable D1 and D3hot capabilities */ - if (pf_params->cap_d1_d3hot_dis) - al_reg_write32_masked( - regs->core_space[pf_num].pcie_pm_cap_base, - AL_FIELD_MASK(26, 25) | AL_FIELD_MASK(31, 28), 0); - - /* Disable FLR capability */ - if (pf_params->cap_flr_dis) - al_reg_write32_masked( - regs->core_space[pf_num].pcie_dev_cap_base, - AL_BIT(28), 0); - - /* Disable ASPM capability */ - if (pf_params->cap_aspm_dis) { - al_reg_write32_masked( - regs->core_space[pf_num].pcie_cap_base + (AL_PCI_EXP_LNKCAP >> 2), - AL_PCI_EXP_LNKCAP_ASPMS, 0); - } else if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { - al_warn("%s: ASPM support is enabled, please disable it\n", - __func__); - ret = -EINVAL; - goto done; - } - - if (!pf_params->bar_params_valid) { - ret = 0; - goto done; - } - - for (bar_idx = 0; bar_idx < 6;){ /* bar_idx will be incremented depending on bar type */ - const struct al_pcie_ep_bar_params *params = pf_params->bar_params + bar_idx; - uint32_t mask = 0; - uint32_t ctrl = 0; - uint32_t __iomem *bar_addr = ®s->core_space[pf_num].config_header[(AL_PCI_BASE_ADDRESS_0 >> 2) + bar_idx]; - - if (params->enable) { - uint64_t size = params->size; - - if (params->memory_64_bit) { - const struct al_pcie_ep_bar_params *next_params = params + 1; - /* 64 bars start at even index (BAR0, BAR 2 or BAR 4) */ - if (bar_idx & 1) { - ret = -EINVAL; - goto done; - } - - /* next BAR must be disabled */ - if (next_params->enable) { - ret = -EINVAL; - goto done; - } - - /* 64 bar must be memory bar */ - if (!params->memory_space) { - ret = -EINVAL; - goto done; - } - } else { - if (size > AL_PCIE_MAX_32_MEMORY_BAR_SIZE) - return -EINVAL; - /* 32 bit space can't be prefetchable */ - if (params->memory_is_prefetchable) { - ret = -EINVAL; - goto done; - } - } - - if (params->memory_space) { - if (size < AL_PCIE_MIN_MEMORY_BAR_SIZE) { - al_err("PCIe %d: memory BAR %d: size (0x%llx) less that minimal allowed value\n", - pcie_port->port_id, bar_idx, size); - ret = -EINVAL; - goto done; - } - } else { - /* IO can't be prefetchable */ - if (params->memory_is_prefetchable) { - ret = -EINVAL; - goto done; - } - - if (size < AL_PCIE_MIN_IO_BAR_SIZE) { - al_err("PCIe %d: IO BAR %d: size (0x%llx) less that minimal allowed value\n", - pcie_port->port_id, bar_idx, size); - ret = -EINVAL; - goto done; - } - } - - /* size must be power of 2 */ - if (size & (size - 1)) { - al_err("PCIe %d: BAR %d:size (0x%llx) must be " - "power of 2\n", - pcie_port->port_id, bar_idx, size); - ret = -EINVAL; - goto done; - } - - /* If BAR is 64-bit, disable the next BAR before - * configuring this one - */ - if (params->memory_64_bit) - al_reg_write32_dbi_cs2(pcie_port, bar_addr + 1, 0); - - mask = 1; /* enable bit*/ - mask |= (params->size - 1) & 0xFFFFFFFF; - - al_reg_write32_dbi_cs2(pcie_port, bar_addr , mask); - - if (params->memory_space == AL_FALSE) - ctrl = AL_PCI_BASE_ADDRESS_SPACE_IO; - if (params->memory_64_bit) - ctrl |= AL_PCI_BASE_ADDRESS_MEM_TYPE_64; - if (params->memory_is_prefetchable) - ctrl |= AL_PCI_BASE_ADDRESS_MEM_PREFETCH; - al_reg_write32(bar_addr, ctrl); - - if (params->memory_64_bit) { - mask = ((params->size - 1) >> 32) & 0xFFFFFFFF; - al_reg_write32_dbi_cs2(pcie_port, bar_addr + 1, mask); - } - - } else { - al_reg_write32_dbi_cs2(pcie_port, bar_addr , mask); - } - if (params->enable && params->memory_64_bit) - bar_idx += 2; - else - bar_idx += 1; - } - - if (pf_params->exp_bar_params.enable) { - if (pcie_port->rev_id != AL_PCIE_REV_ID_3) { - al_err("PCIe %d: Expansion BAR enable not supported\n", pcie_port->port_id); - ret = -ENOSYS; - goto done; - } else { - /* Enable exp ROM */ - uint32_t __iomem *exp_rom_bar_addr = - ®s->core_space[pf_num].config_header[AL_PCI_EXP_ROM_BASE_ADDRESS >> 2]; - uint32_t mask = 1; /* enable bit*/ - mask |= (pf_params->exp_bar_params.size - 1) & 0xFFFFFFFF; - al_reg_write32_dbi_cs2(pcie_port, exp_rom_bar_addr , mask); - } - } else if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - /* Disable exp ROM */ - uint32_t __iomem *exp_rom_bar_addr = - ®s->core_space[pf_num].config_header[AL_PCI_EXP_ROM_BASE_ADDRESS >> 2]; - al_reg_write32_dbi_cs2(pcie_port, exp_rom_bar_addr , 0); - } - - /* Open CPU generated msi and legacy interrupts in pcie wrapper logic */ - if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || - (pcie_port->rev_id == AL_PCIE_REV_ID_1)) { - al_reg_write32(regs->app.soc_int[pf_num].mask_inta_leg_0, (1 << 21)); - } else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) || - (pcie_port->rev_id == AL_PCIE_REV_ID_3)) { - al_reg_write32(regs->app.soc_int[pf_num].mask_inta_leg_3, (1 << 18)); - } else { - al_assert(0); - ret = -ENOSYS; - goto done; - } - - /** - * Addressing RMN: 1547 - * - * RMN description: - * 1. Whenever writing to 0x2xx offset, the write also happens to - * 0x3xx address, meaning two registers are written instead of one. - * 2. Read and write from 0x3xx work ok. - * - * Software flow: - * Backup the value of the app.int_grp_a.mask_a register, because - * app.int_grp_a.mask_clear_a gets overwritten during the write to - * app.soc.mask_msi_leg_0 register. - * Restore the original value after the write to app.soc.mask_msi_leg_0 - * register. - */ - if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { - uint32_t backup; - - backup = al_reg_read32(®s->app.int_grp_a->mask); - al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22)); - al_reg_write32(®s->app.int_grp_a->mask, backup); - } else if (pcie_port->rev_id == AL_PCIE_REV_ID_1) { - al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_0, (1 << 22)); - } else if ((pcie_port->rev_id == AL_PCIE_REV_ID_2) || - (pcie_port->rev_id == AL_PCIE_REV_ID_3)) { - al_reg_write32(regs->app.soc_int[pf_num].mask_msi_leg_3, (1 << 19)); - } else { - al_assert(0); - ret = -ENOSYS; - goto done; - } - - ret = 0; - -done: - al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); - - return ret; -} - -static void -al_pcie_port_features_config( - struct al_pcie_port *pcie_port, - const struct al_pcie_features *features) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_assert(pcie_port->rev_id > AL_PCIE_REV_ID_0); - - al_reg_write32_masked( - ®s->app.ctrl_gen->features, - PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX, - features->sata_ep_msi_fix ? - PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX : 0); -} - -static int -al_pcie_port_sris_config( - struct al_pcie_port *pcie_port, - struct al_pcie_sris_params *sris_params, - enum al_pcie_link_speed link_speed) -{ - int rc = 0; - struct al_pcie_regs *regs = pcie_port->regs; - - if (sris_params->use_defaults) { - sris_params->kp_counter_gen3 = (pcie_port->rev_id > AL_PCIE_REV_ID_1) ? - PCIE_SRIS_KP_COUNTER_GEN3_DEFAULT_VAL : 0; - sris_params->kp_counter_gen21 = PCIE_SRIS_KP_COUNTER_GEN21_DEFAULT_VAL; - - al_dbg("PCIe %d: configuring SRIS with default values kp_gen3[%d] kp_gen21[%d]\n", - pcie_port->port_id, - sris_params->kp_counter_gen3, - sris_params->kp_counter_gen21); - } - - switch (pcie_port->rev_id) { - case AL_PCIE_REV_ID_3: - case AL_PCIE_REV_ID_2: - al_reg_write32_masked(regs->app.global_ctrl.sris_kp_counter, - PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_MASK | - PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_MASK | - PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_PCIE_X4_SRIS_EN, - (sris_params->kp_counter_gen3 << - PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_SHIFT) | - (sris_params->kp_counter_gen21 << - PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_SHIFT) | - PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_PCIE_X4_SRIS_EN); - break; - - case AL_PCIE_REV_ID_1: - if ((link_speed == AL_PCIE_LINK_SPEED_GEN3) && (sris_params->kp_counter_gen3)) { - al_err("PCIe %d: cannot config Gen%d SRIS with rev_id[%d]\n", - pcie_port->port_id, al_pcie_speed_gen_code(link_speed), - pcie_port->rev_id); - return -EINVAL; - } - - al_reg_write32_masked(®s->port_regs->filter_mask_reg_1, - PCIE_FLT_MASK_SKP_INT_VAL_MASK, - sris_params->kp_counter_gen21); - break; - - default: - al_err("PCIe %d: SRIS config is not supported in rev_id[%d]\n", - pcie_port->port_id, pcie_port->rev_id); - al_assert(0); - return -EINVAL; - } - - return rc; -} - -static void -al_pcie_port_ib_hcrd_config(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_reg_write32_masked( - ®s->port_regs->vc0_posted_rcv_q_ctrl, - RADM_PQ_HCRD_VC0_MASK, - (pcie_port->ib_hcrd_config.nof_p_hdr - 1) - << RADM_PQ_HCRD_VC0_SHIFT); - - al_reg_write32_masked( - ®s->port_regs->vc0_non_posted_rcv_q_ctrl, - RADM_NPQ_HCRD_VC0_MASK, - (pcie_port->ib_hcrd_config.nof_np_hdr - 1) - << RADM_NPQ_HCRD_VC0_SHIFT); -} - -static unsigned int -al_pcie_port_max_num_of_pfs_get(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t max_func_num; - uint32_t max_num_of_pfs; - - /** - * Only in REV3, when port is already enabled, max_num_of_pfs is already - * initialized, return it. Otherwise, return default: 1 PF - */ - if ((pcie_port->rev_id == AL_PCIE_REV_ID_3) - && al_pcie_port_is_enabled(pcie_port)) { - max_func_num = al_reg_read32(®s->port_regs->timer_ctrl_max_func_num); - max_num_of_pfs = AL_REG_FIELD_GET(max_func_num, PCIE_PORT_GEN3_MAX_FUNC_NUM, 0) + 1; - return max_num_of_pfs; - } - return 1; -} - -/******************************************************************************/ -/***************************** API Implementation *****************************/ -/******************************************************************************/ - -/*************************** PCIe Initialization API **************************/ - -/** - * Initializes a PCIe port handle structure - * Caution: this function should not read/write to any register except for - * reading RO register (REV_ID for example) - */ -int -al_pcie_port_handle_init( - struct al_pcie_port *pcie_port, - void __iomem *pcie_reg_base, - void __iomem *pbs_reg_base, - unsigned int port_id) -{ - int i, ret; - - pcie_port->pcie_reg_base = pcie_reg_base; - pcie_port->regs = &pcie_port->regs_ptrs; - pcie_port->ex_regs = NULL; - pcie_port->pbs_regs = pbs_reg_base; - pcie_port->port_id = port_id; - pcie_port->max_lanes = 0; - - ret = al_pcie_rev_id_get(pbs_reg_base, pcie_reg_base); - if (ret < 0) - return ret; - - pcie_port->rev_id = ret; - - /* Zero all regs */ - al_memset(pcie_port->regs, 0, sizeof(struct al_pcie_regs)); - - if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || - (pcie_port->rev_id == AL_PCIE_REV_ID_1)) { - struct al_pcie_rev1_regs __iomem *regs = - (struct al_pcie_rev1_regs __iomem *)pcie_reg_base; - - pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; - pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; - pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; - pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; - pcie_port->regs->axi.ob_ctrl.cfg_target_bus = ®s->axi.ob_ctrl.cfg_target_bus; - pcie_port->regs->axi.ob_ctrl.cfg_control = ®s->axi.ob_ctrl.cfg_control; - pcie_port->regs->axi.ob_ctrl.io_start_l = ®s->axi.ob_ctrl.io_start_l; - pcie_port->regs->axi.ob_ctrl.io_start_h = ®s->axi.ob_ctrl.io_start_h; - pcie_port->regs->axi.ob_ctrl.io_limit_l = ®s->axi.ob_ctrl.io_limit_l; - pcie_port->regs->axi.ob_ctrl.io_limit_h = ®s->axi.ob_ctrl.io_limit_h; - pcie_port->regs->axi.pcie_global.conf = ®s->axi.pcie_global.conf; - pcie_port->regs->axi.conf.zero_lane0 = ®s->axi.conf.zero_lane0; - pcie_port->regs->axi.conf.zero_lane1 = ®s->axi.conf.zero_lane1; - pcie_port->regs->axi.conf.zero_lane2 = ®s->axi.conf.zero_lane2; - pcie_port->regs->axi.conf.zero_lane3 = ®s->axi.conf.zero_lane3; - pcie_port->regs->axi.status.lane[0] = ®s->axi.status.lane0; - pcie_port->regs->axi.status.lane[1] = ®s->axi.status.lane1; - pcie_port->regs->axi.status.lane[2] = ®s->axi.status.lane2; - pcie_port->regs->axi.status.lane[3] = ®s->axi.status.lane3; - pcie_port->regs->axi.parity.en_axi = ®s->axi.parity.en_axi; - pcie_port->regs->axi.ordering.pos_cntl = ®s->axi.ordering.pos_cntl; - pcie_port->regs->axi.pre_configuration.pcie_core_setup = ®s->axi.pre_configuration.pcie_core_setup; - pcie_port->regs->axi.init_fc.cfg = ®s->axi.init_fc.cfg; - pcie_port->regs->axi.int_grp_a = ®s->axi.int_grp_a; - - pcie_port->regs->app.global_ctrl.port_init = ®s->app.global_ctrl.port_init; - pcie_port->regs->app.global_ctrl.pm_control = ®s->app.global_ctrl.pm_control; - pcie_port->regs->app.global_ctrl.events_gen[0] = ®s->app.global_ctrl.events_gen; - pcie_port->regs->app.debug = ®s->app.debug; - pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = ®s->app.soc_int.mask_inta_leg_0; - pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = ®s->app.soc_int.mask_msi_leg_0; - pcie_port->regs->app.ctrl_gen = ®s->app.ctrl_gen; - pcie_port->regs->app.parity = ®s->app.parity; - pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair; - pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair; - - if (pcie_port->rev_id == AL_PCIE_REV_ID_0) { - pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a_m0; - pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b_m0; - } else { - pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a; - pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b; - } - - pcie_port->regs->core_space[0].config_header = regs->core_space.config_header; - pcie_port->regs->core_space[0].pcie_pm_cap_base = ®s->core_space.pcie_pm_cap_base; - pcie_port->regs->core_space[0].pcie_cap_base = ®s->core_space.pcie_cap_base; - pcie_port->regs->core_space[0].pcie_dev_cap_base = ®s->core_space.pcie_dev_cap_base; - pcie_port->regs->core_space[0].pcie_dev_ctrl_status = ®s->core_space.pcie_dev_ctrl_status; - pcie_port->regs->core_space[0].pcie_link_cap_base = ®s->core_space.pcie_link_cap_base; - pcie_port->regs->core_space[0].msix_cap_base = ®s->core_space.msix_cap_base; - pcie_port->regs->core_space[0].aer = ®s->core_space.aer; - pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = ®s->core_space.pcie_sec_ext_cap_base; - - pcie_port->regs->port_regs = ®s->core_space.port_regs; - - } else if (pcie_port->rev_id == AL_PCIE_REV_ID_2) { - struct al_pcie_rev2_regs __iomem *regs = - (struct al_pcie_rev2_regs __iomem *)pcie_reg_base; - - pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; - pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; - pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; - pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; - pcie_port->regs->axi.ob_ctrl.cfg_target_bus = ®s->axi.ob_ctrl.cfg_target_bus; - pcie_port->regs->axi.ob_ctrl.cfg_control = ®s->axi.ob_ctrl.cfg_control; - pcie_port->regs->axi.ob_ctrl.io_start_l = ®s->axi.ob_ctrl.io_start_l; - pcie_port->regs->axi.ob_ctrl.io_start_h = ®s->axi.ob_ctrl.io_start_h; - pcie_port->regs->axi.ob_ctrl.io_limit_l = ®s->axi.ob_ctrl.io_limit_l; - pcie_port->regs->axi.ob_ctrl.io_limit_h = ®s->axi.ob_ctrl.io_limit_h; - pcie_port->regs->axi.pcie_global.conf = ®s->axi.pcie_global.conf; - pcie_port->regs->axi.conf.zero_lane0 = ®s->axi.conf.zero_lane0; - pcie_port->regs->axi.conf.zero_lane1 = ®s->axi.conf.zero_lane1; - pcie_port->regs->axi.conf.zero_lane2 = ®s->axi.conf.zero_lane2; - pcie_port->regs->axi.conf.zero_lane3 = ®s->axi.conf.zero_lane3; - pcie_port->regs->axi.status.lane[0] = ®s->axi.status.lane0; - pcie_port->regs->axi.status.lane[1] = ®s->axi.status.lane1; - pcie_port->regs->axi.status.lane[2] = ®s->axi.status.lane2; - pcie_port->regs->axi.status.lane[3] = ®s->axi.status.lane3; - pcie_port->regs->axi.parity.en_axi = ®s->axi.parity.en_axi; - pcie_port->regs->axi.ordering.pos_cntl = ®s->axi.ordering.pos_cntl; - pcie_port->regs->axi.pre_configuration.pcie_core_setup = ®s->axi.pre_configuration.pcie_core_setup; - pcie_port->regs->axi.init_fc.cfg = ®s->axi.init_fc.cfg; - pcie_port->regs->axi.int_grp_a = ®s->axi.int_grp_a; - - pcie_port->regs->app.global_ctrl.port_init = ®s->app.global_ctrl.port_init; - pcie_port->regs->app.global_ctrl.pm_control = ®s->app.global_ctrl.pm_control; - pcie_port->regs->app.global_ctrl.events_gen[0] = ®s->app.global_ctrl.events_gen; - pcie_port->regs->app.global_ctrl.corr_err_sts_int = ®s->app.global_ctrl.pended_corr_err_sts_int; - pcie_port->regs->app.global_ctrl.uncorr_err_sts_int = ®s->app.global_ctrl.pended_uncorr_err_sts_int; - pcie_port->regs->app.debug = ®s->app.debug; - pcie_port->regs->app.ap_user_send_msg = ®s->app.ap_user_send_msg; - pcie_port->regs->app.soc_int[0].mask_inta_leg_0 = ®s->app.soc_int.mask_inta_leg_0; - pcie_port->regs->app.soc_int[0].mask_inta_leg_3 = ®s->app.soc_int.mask_inta_leg_3; - pcie_port->regs->app.soc_int[0].mask_msi_leg_0 = ®s->app.soc_int.mask_msi_leg_0; - pcie_port->regs->app.soc_int[0].mask_msi_leg_3 = ®s->app.soc_int.mask_msi_leg_3; - pcie_port->regs->app.ctrl_gen = ®s->app.ctrl_gen; - pcie_port->regs->app.parity = ®s->app.parity; - pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair; - pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair; - pcie_port->regs->app.status_per_func[0] = ®s->app.status_per_func; - pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a; - pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b; - - pcie_port->regs->core_space[0].config_header = regs->core_space.config_header; - pcie_port->regs->core_space[0].pcie_pm_cap_base = ®s->core_space.pcie_pm_cap_base; - pcie_port->regs->core_space[0].pcie_cap_base = ®s->core_space.pcie_cap_base; - pcie_port->regs->core_space[0].pcie_dev_cap_base = ®s->core_space.pcie_dev_cap_base; - pcie_port->regs->core_space[0].pcie_dev_ctrl_status = ®s->core_space.pcie_dev_ctrl_status; - pcie_port->regs->core_space[0].pcie_link_cap_base = ®s->core_space.pcie_link_cap_base; - pcie_port->regs->core_space[0].msix_cap_base = ®s->core_space.msix_cap_base; - pcie_port->regs->core_space[0].aer = ®s->core_space.aer; - pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = ®s->core_space.pcie_sec_ext_cap_base; - - pcie_port->regs->port_regs = ®s->core_space.port_regs; - - } else if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - struct al_pcie_rev3_regs __iomem *regs = - (struct al_pcie_rev3_regs __iomem *)pcie_reg_base; - pcie_port->regs->axi.ctrl.global = ®s->axi.ctrl.global; - pcie_port->regs->axi.ctrl.master_arctl = ®s->axi.ctrl.master_arctl; - pcie_port->regs->axi.ctrl.master_awctl = ®s->axi.ctrl.master_awctl; - pcie_port->regs->axi.ctrl.slv_ctl = ®s->axi.ctrl.slv_ctl; - pcie_port->regs->axi.ob_ctrl.cfg_target_bus = ®s->axi.ob_ctrl.cfg_target_bus; - pcie_port->regs->axi.ob_ctrl.cfg_control = ®s->axi.ob_ctrl.cfg_control; - pcie_port->regs->axi.ob_ctrl.io_start_l = ®s->axi.ob_ctrl.io_start_l; - pcie_port->regs->axi.ob_ctrl.io_start_h = ®s->axi.ob_ctrl.io_start_h; - pcie_port->regs->axi.ob_ctrl.io_limit_l = ®s->axi.ob_ctrl.io_limit_l; - pcie_port->regs->axi.ob_ctrl.io_limit_h = ®s->axi.ob_ctrl.io_limit_h; - pcie_port->regs->axi.pcie_global.conf = ®s->axi.pcie_global.conf; - pcie_port->regs->axi.conf.zero_lane0 = ®s->axi.conf.zero_lane0; - pcie_port->regs->axi.conf.zero_lane1 = ®s->axi.conf.zero_lane1; - pcie_port->regs->axi.conf.zero_lane2 = ®s->axi.conf.zero_lane2; - pcie_port->regs->axi.conf.zero_lane3 = ®s->axi.conf.zero_lane3; - pcie_port->regs->axi.conf.zero_lane4 = ®s->axi.conf.zero_lane4; - pcie_port->regs->axi.conf.zero_lane5 = ®s->axi.conf.zero_lane5; - pcie_port->regs->axi.conf.zero_lane6 = ®s->axi.conf.zero_lane6; - pcie_port->regs->axi.conf.zero_lane7 = ®s->axi.conf.zero_lane7; - pcie_port->regs->axi.status.lane[0] = ®s->axi.status.lane0; - pcie_port->regs->axi.status.lane[1] = ®s->axi.status.lane1; - pcie_port->regs->axi.status.lane[2] = ®s->axi.status.lane2; - pcie_port->regs->axi.status.lane[3] = ®s->axi.status.lane3; - pcie_port->regs->axi.status.lane[4] = ®s->axi.status.lane4; - pcie_port->regs->axi.status.lane[5] = ®s->axi.status.lane5; - pcie_port->regs->axi.status.lane[6] = ®s->axi.status.lane6; - pcie_port->regs->axi.status.lane[7] = ®s->axi.status.lane7; - pcie_port->regs->axi.parity.en_axi = ®s->axi.parity.en_axi; - pcie_port->regs->axi.ordering.pos_cntl = ®s->axi.ordering.pos_cntl; - pcie_port->regs->axi.pre_configuration.pcie_core_setup = ®s->axi.pre_configuration.pcie_core_setup; - pcie_port->regs->axi.init_fc.cfg = ®s->axi.init_fc.cfg; - pcie_port->regs->axi.int_grp_a = ®s->axi.int_grp_a; - pcie_port->regs->axi.axi_attr_ovrd.write_msg_ctrl_0 = ®s->axi.axi_attr_ovrd.write_msg_ctrl_0; - pcie_port->regs->axi.axi_attr_ovrd.write_msg_ctrl_1 = ®s->axi.axi_attr_ovrd.write_msg_ctrl_1; - pcie_port->regs->axi.axi_attr_ovrd.pf_sel = ®s->axi.axi_attr_ovrd.pf_sel; - - for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_0 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_0; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_1 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_1; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_2 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_2; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_3 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_3; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_4 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_4; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_5 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_5; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_6 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_6; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_7 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_7; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_8 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_8; - pcie_port->regs->axi.pf_axi_attr_ovrd[i].func_ctrl_9 = ®s->axi.pf_axi_attr_ovrd[i].func_ctrl_9; - } - - pcie_port->regs->axi.msg_attr_axuser_table.entry_vec = ®s->axi.msg_attr_axuser_table.entry_vec; - - pcie_port->regs->app.global_ctrl.port_init = ®s->app.global_ctrl.port_init; - pcie_port->regs->app.global_ctrl.pm_control = ®s->app.global_ctrl.pm_control; - pcie_port->regs->app.global_ctrl.corr_err_sts_int = ®s->app.global_ctrl.pended_corr_err_sts_int; - pcie_port->regs->app.global_ctrl.uncorr_err_sts_int = ®s->app.global_ctrl.pended_uncorr_err_sts_int; - - for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { - pcie_port->regs->app.global_ctrl.events_gen[i] = ®s->app.events_gen_per_func[i].events_gen; - } - - pcie_port->regs->app.global_ctrl.sris_kp_counter = ®s->app.global_ctrl.sris_kp_counter_value; - pcie_port->regs->app.debug = ®s->app.debug; - - for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { - pcie_port->regs->app.soc_int[i].mask_inta_leg_0 = ®s->app.soc_int_per_func[i].mask_inta_leg_0; - pcie_port->regs->app.soc_int[i].mask_inta_leg_3 = ®s->app.soc_int_per_func[i].mask_inta_leg_3; - pcie_port->regs->app.soc_int[i].mask_msi_leg_0 = ®s->app.soc_int_per_func[i].mask_msi_leg_0; - pcie_port->regs->app.soc_int[i].mask_msi_leg_3 = ®s->app.soc_int_per_func[i].mask_msi_leg_3; - } - - pcie_port->regs->app.ap_user_send_msg = ®s->app.ap_user_send_msg; - pcie_port->regs->app.ctrl_gen = ®s->app.ctrl_gen; - pcie_port->regs->app.parity = ®s->app.parity; - pcie_port->regs->app.atu.in_mask_pair = regs->app.atu.in_mask_pair; - pcie_port->regs->app.atu.out_mask_pair = regs->app.atu.out_mask_pair; - - for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) - pcie_port->regs->app.status_per_func[i] = ®s->app.status_per_func[i]; - - pcie_port->regs->app.int_grp_a = ®s->app.int_grp_a; - pcie_port->regs->app.int_grp_b = ®s->app.int_grp_b; - pcie_port->regs->app.int_grp_c = ®s->app.int_grp_c; - pcie_port->regs->app.int_grp_d = ®s->app.int_grp_d; - - for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { - pcie_port->regs->core_space[i].config_header = regs->core_space.func[i].config_header; - pcie_port->regs->core_space[i].pcie_pm_cap_base = ®s->core_space.func[i].pcie_pm_cap_base; - pcie_port->regs->core_space[i].pcie_cap_base = ®s->core_space.func[i].pcie_cap_base; - pcie_port->regs->core_space[i].pcie_dev_cap_base = ®s->core_space.func[i].pcie_dev_cap_base; - pcie_port->regs->core_space[i].pcie_dev_ctrl_status = ®s->core_space.func[i].pcie_dev_ctrl_status; - pcie_port->regs->core_space[i].pcie_link_cap_base = ®s->core_space.func[i].pcie_link_cap_base; - pcie_port->regs->core_space[i].msix_cap_base = ®s->core_space.func[i].msix_cap_base; - pcie_port->regs->core_space[i].aer = ®s->core_space.func[i].aer; - pcie_port->regs->core_space[i].tph_cap_base = ®s->core_space.func[i].tph_cap_base; - - } - - /* secondary extension capability only for PF0 */ - pcie_port->regs->core_space[0].pcie_sec_ext_cap_base = ®s->core_space.func[0].pcie_sec_ext_cap_base; - - pcie_port->regs->port_regs = ®s->core_space.func[0].port_regs; - - } else { - al_warn("%s: Revision ID is unknown\n", - __func__); - return -EINVAL; - } - - /* set maximum number of physical functions */ - pcie_port->max_num_of_pfs = al_pcie_port_max_num_of_pfs_get(pcie_port); - - al_dbg("pcie port handle initialized. port id: %d, rev_id %d, regs base %p\n", - port_id, pcie_port->rev_id, pcie_reg_base); - return 0; -} - -/** - * Initializes a PCIe Physical function handle structure - * Caution: this function should not read/write to any register except for - * reading RO register (REV_ID for example) - */ -int -al_pcie_pf_handle_init( - struct al_pcie_pf *pcie_pf, - struct al_pcie_port *pcie_port, - unsigned int pf_num) -{ - enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); - al_assert(pf_num < pcie_port->max_num_of_pfs); - - if (op_mode != AL_PCIE_OPERATING_MODE_EP) { - al_err("PCIe %d: can't init PF handle with operating mode [%d]\n", - pcie_port->port_id, op_mode); - return -EINVAL; - } - - pcie_pf->pf_num = pf_num; - pcie_pf->pcie_port = pcie_port; - - al_dbg("PCIe %d: pf handle initialized. pf number: %d, rev_id %d, regs %p\n", - pcie_port->port_id, pcie_pf->pf_num, pcie_port->rev_id, - pcie_port->regs); - return 0; -} - -/************************** Pre PCIe Port Enable API **************************/ - -/** configure pcie operating mode (root complex or endpoint) */ -int -al_pcie_port_operating_mode_config( - struct al_pcie_port *pcie_port, - enum al_pcie_operating_mode mode) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t reg, device_type, new_device_type; - - if (al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: already enabled, cannot set operating mode\n", - pcie_port->port_id); - return -EINVAL; - } - - reg = al_reg_read32(regs->axi.pcie_global.conf); - - device_type = AL_REG_FIELD_GET(reg, - PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK, - PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT); - if (mode == AL_PCIE_OPERATING_MODE_EP) { - new_device_type = PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP; - } else if (mode == AL_PCIE_OPERATING_MODE_RC) { - new_device_type = PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC; - - if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - /* config 1 PF in RC mode */ - al_reg_write32_masked(regs->axi.axi_attr_ovrd.pf_sel, - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_AXUSER | - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_REG | - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_ADDR_OFFSET_MASK | - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT0_OVRD | - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_AXUSER | - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_REG | - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_ADDR_OFFSET_MASK | - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT1_OVRD, - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_REG | - PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_REG); - } - } else { - al_err("PCIe %d: unknown operating mode: %d\n", pcie_port->port_id, mode); - return -EINVAL; - } - - if (new_device_type == device_type) { - al_dbg("PCIe %d: operating mode already set to %s\n", - pcie_port->port_id, (mode == AL_PCIE_OPERATING_MODE_EP) ? - "EndPoint" : "Root Complex"); - return 0; - } - al_info("PCIe %d: set operating mode to %s\n", - pcie_port->port_id, (mode == AL_PCIE_OPERATING_MODE_EP) ? - "EndPoint" : "Root Complex"); - AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK, - PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT, - new_device_type); - - al_reg_write32(regs->axi.pcie_global.conf, reg); - - return 0; -} - -int -al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - if (al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: already enabled, cannot set max lanes\n", - pcie_port->port_id); - return -EINVAL; - } - - /* convert to bitmask format (4 ->'b1111, 2 ->'b11, 1 -> 'b1) */ - uint32_t active_lanes_val = AL_PCIE_PARSE_LANES(lanes); - - al_reg_write32_masked(regs->axi.pcie_global.conf, - (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? - PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK : - PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK, - active_lanes_val); - - pcie_port->max_lanes = lanes; - return 0; -} - -int -al_pcie_port_max_num_of_pfs_set( - struct al_pcie_port *pcie_port, - uint8_t max_num_of_pfs) -{ - if (al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: already enabled, cannot set max num of PFs\n", - pcie_port->port_id); - return -EINVAL; - } - - if (pcie_port->rev_id == AL_PCIE_REV_ID_3) - al_assert(max_num_of_pfs <= REV3_MAX_NUM_OF_PFS); - else - al_assert(max_num_of_pfs == REV1_2_MAX_NUM_OF_PFS); - - pcie_port->max_num_of_pfs = max_num_of_pfs; - - return 0; -} - -/* Inbound header credits and outstanding outbound reads configuration */ -int -al_pcie_port_ib_hcrd_os_ob_reads_config( - struct al_pcie_port *pcie_port, - struct al_pcie_ib_hcrd_os_ob_reads_config *ib_hcrd_os_ob_reads_config) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - if (al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: already enabled, cannot configure IB credits and OB OS reads\n", - pcie_port->port_id); - return -EINVAL; - } - - al_assert(ib_hcrd_os_ob_reads_config->nof_np_hdr > 0); - - al_assert(ib_hcrd_os_ob_reads_config->nof_p_hdr > 0); - - al_assert(ib_hcrd_os_ob_reads_config->nof_cpl_hdr > 0); - - if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - al_assert( - (ib_hcrd_os_ob_reads_config->nof_cpl_hdr + - ib_hcrd_os_ob_reads_config->nof_np_hdr + - ib_hcrd_os_ob_reads_config->nof_p_hdr) == - AL_PCIE_REV3_IB_HCRD_SUM); - - al_reg_write32_masked( - regs->axi.init_fc.cfg, - PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_MASK | - PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_MASK | - PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_MASK, - (ib_hcrd_os_ob_reads_config->nof_p_hdr << - PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_SHIFT) | - (ib_hcrd_os_ob_reads_config->nof_np_hdr << - PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_SHIFT) | - (ib_hcrd_os_ob_reads_config->nof_cpl_hdr << - PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_SHIFT)); - } else { - al_assert( - (ib_hcrd_os_ob_reads_config->nof_cpl_hdr + - ib_hcrd_os_ob_reads_config->nof_np_hdr + - ib_hcrd_os_ob_reads_config->nof_p_hdr) == - AL_PCIE_REV_1_2_IB_HCRD_SUM); - - al_reg_write32_masked( - regs->axi.init_fc.cfg, - PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_MASK | - PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_MASK | - PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_MASK, - (ib_hcrd_os_ob_reads_config->nof_p_hdr << - PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_SHIFT) | - (ib_hcrd_os_ob_reads_config->nof_np_hdr << - PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_SHIFT) | - (ib_hcrd_os_ob_reads_config->nof_cpl_hdr << - PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_SHIFT)); - } - - al_reg_write32_masked( - regs->axi.pre_configuration.pcie_core_setup, - PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_MASK, - ib_hcrd_os_ob_reads_config->nof_outstanding_ob_reads << - PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_SHIFT); - - /* Store 'nof_p_hdr' and 'nof_np_hdr' to be set in the core later */ - pcie_port->ib_hcrd_config.nof_np_hdr = - ib_hcrd_os_ob_reads_config->nof_np_hdr; - pcie_port->ib_hcrd_config.nof_p_hdr = - ib_hcrd_os_ob_reads_config->nof_p_hdr; - - return 0; -} - -enum al_pcie_operating_mode -al_pcie_operating_mode_get( - struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t reg, device_type; - - al_assert(pcie_port); - - reg = al_reg_read32(regs->axi.pcie_global.conf); - - device_type = AL_REG_FIELD_GET(reg, - PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK, - PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT); - - switch (device_type) { - case PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP: - return AL_PCIE_OPERATING_MODE_EP; - case PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC: - return AL_PCIE_OPERATING_MODE_RC; - default: - al_err("PCIe %d: unknown device type (%d) in global conf register.\n", - pcie_port->port_id, device_type); - } - return AL_PCIE_OPERATING_MODE_UNKNOWN; -} - -/**************************** PCIe Port Enable API ****************************/ - -/** Enable PCIe port (deassert reset) */ -int -al_pcie_port_enable(struct al_pcie_port *pcie_port) -{ - struct al_pbs_regs *pbs_reg_base = - (struct al_pbs_regs *)pcie_port->pbs_regs; - struct al_pcie_regs *regs = pcie_port->regs; - unsigned int port_id = pcie_port->port_id; - - /* pre-port-enable default functionality should be here */ - - /** - * Set inbound header credit and outstanding outbound reads defaults - * Must be called before port enable (PCIE_EXIST) - */ - al_pcie_ib_hcrd_os_ob_reads_config_default(pcie_port); - - /* - * Disable ATS capability - * - must be done before core reset deasserted - * - rev_id 0 - no effect, but no harm - */ - if ((pcie_port->rev_id == AL_PCIE_REV_ID_0) || - (pcie_port->rev_id == AL_PCIE_REV_ID_1) || - (pcie_port->rev_id == AL_PCIE_REV_ID_2)) { - al_reg_write32_masked( - regs->axi.ordering.pos_cntl, - PCIE_AXI_CORE_SETUP_ATS_CAP_DIS, - PCIE_AXI_CORE_SETUP_ATS_CAP_DIS); - } - - /* Deassert core reset */ - al_reg_write32_masked( - &pbs_reg_base->unit.pcie_conf_1, - 1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT), - 1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT)); - - return 0; -} - -/** Disable PCIe port (assert reset) */ -void -al_pcie_port_disable(struct al_pcie_port *pcie_port) -{ - struct al_pbs_regs *pbs_reg_base = - (struct al_pbs_regs *)pcie_port->pbs_regs; - unsigned int port_id = pcie_port->port_id; - - if (!al_pcie_port_is_enabled(pcie_port)) { - al_warn("PCIe %d: trying to disable a non-enabled port\n", - pcie_port->port_id); - } - - /* Assert core reset */ - al_reg_write32_masked( - &pbs_reg_base->unit.pcie_conf_1, - 1 << (port_id + PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT), - 0); -} - -int -al_pcie_port_memory_shutdown_set( - struct al_pcie_port *pcie_port, - al_bool enable) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? - PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN : - PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN; - - if (!al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: not enabled, cannot shutdown memory\n", - pcie_port->port_id); - return -EINVAL; - } - - al_reg_write32_masked(regs->axi.pcie_global.conf, - mask, enable == AL_TRUE ? mask : 0); - - return 0; -} - -al_bool -al_pcie_port_is_enabled(struct al_pcie_port *pcie_port) -{ - struct al_pbs_regs *pbs_reg_base = (struct al_pbs_regs *)pcie_port->pbs_regs; - uint32_t pcie_exist = al_reg_read32(&pbs_reg_base->unit.pcie_conf_1); - - uint32_t ports_enabled = AL_REG_FIELD_GET(pcie_exist, - PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_MASK, - PBS_UNIT_PCIE_CONF_1_PCIE_EXIST_SHIFT); - - return (AL_REG_FIELD_GET(ports_enabled, AL_BIT(pcie_port->port_id), - pcie_port->port_id) == 1); -} - -/*************************** PCIe Configuration API ***************************/ - -/** configure pcie port (link params, etc..) */ -int -al_pcie_port_config(struct al_pcie_port *pcie_port, - const struct al_pcie_port_config_params *params) -{ - struct al_pcie_regs *regs = pcie_port->regs; - enum al_pcie_operating_mode op_mode; - int status = 0; - int i; - - if (!al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: port not enabled, cannot configure port\n", - pcie_port->port_id); - return -EINVAL; - } - - if (al_pcie_is_link_started(pcie_port)) { - al_err("PCIe %d: link already started, cannot configure port\n", - pcie_port->port_id); - return -EINVAL; - } - - al_assert(pcie_port); - al_assert(params); - - al_dbg("PCIe %d: port config\n", pcie_port->port_id); - - op_mode = al_pcie_operating_mode_get(pcie_port); - - /* if max lanes not specifies, read it from register */ - if (pcie_port->max_lanes == 0) { - uint32_t global_conf = al_reg_read32(regs->axi.pcie_global.conf); - uint32_t act_lanes = AL_REG_FIELD_GET(global_conf, - (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? - PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK : - PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK, - PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT); - - switch(act_lanes) { - case 0x1: - pcie_port->max_lanes = 1; - break; - case 0x3: - pcie_port->max_lanes = 2; - break; - case 0xf: - pcie_port->max_lanes = 4; - break; - case 0xff: - pcie_port->max_lanes = 8; - break; - default: - pcie_port->max_lanes = 0; - al_err("PCIe %d: invalid max lanes val (0x%x)\n", pcie_port->port_id, act_lanes); - break; - } - } - - if (params->link_params) - status = al_pcie_port_link_config(pcie_port, params->link_params); - if (status) - goto done; - - /* Change max read request size to 256 bytes - * Max Payload Size is remained untouched- it is the responsibility of - * the host to change the MPS, if needed. - */ - for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { - al_reg_write32_masked(regs->core_space[i].pcie_dev_ctrl_status, - PCIE_PORT_DEV_CTRL_STATUS_MRRS_MASK, - PCIE_PORT_DEV_CTRL_STATUS_MRRS_VAL_256); - if (pcie_port->rev_id != AL_PCIE_REV_ID_3) - break; - } - - if (pcie_port->rev_id == AL_PCIE_REV_ID_3) { - /* Set maximum physical function numbers */ - al_reg_write32_masked( - ®s->port_regs->timer_ctrl_max_func_num, - PCIE_PORT_GEN3_MAX_FUNC_NUM, - pcie_port->max_num_of_pfs - 1); - - al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); - - /** - * in EP mode, when we have more than 1 PF we need to assert - * multi-pf support so the host scan all PFs - */ - if ((op_mode == AL_PCIE_OPERATING_MODE_EP) && (pcie_port->max_num_of_pfs > 1)) { - al_reg_write32_masked((uint32_t __iomem *) - (®s->core_space[0].config_header[0] + - (PCIE_BIST_HEADER_TYPE_BASE >> 2)), - PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK, - PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK); - } - - /* Disable TPH next pointer */ - for (i = 0; i < AL_MAX_NUM_OF_PFS; i++) { - al_reg_write32_masked(regs->core_space[i].tph_cap_base, - PCIE_TPH_NEXT_POINTER, 0); - } - - al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); - } - - - status = al_pcie_port_snoop_config(pcie_port, params->enable_axi_snoop); - if (status) - goto done; - - al_pcie_port_ram_parity_int_config(pcie_port, params->enable_ram_parity_int); - - al_pcie_port_axi_parity_int_config(pcie_port, params->enable_axi_parity_int); - - al_pcie_port_relaxed_pcie_ordering_config(pcie_port, params->relaxed_ordering_params); - - if (params->lat_rply_timers) - status = al_pcie_port_lat_rply_timers_config(pcie_port, params->lat_rply_timers); - if (status) - goto done; - - if (params->gen2_params) - status = al_pcie_port_gen2_params_config(pcie_port, params->gen2_params); - if (status) - goto done; - - if (params->gen3_params) - status = al_pcie_port_gen3_params_config(pcie_port, params->gen3_params); - if (status) - goto done; - - if (params->tl_credits) - status = al_pcie_port_tl_credits_config(pcie_port, params->tl_credits); - if (status) - goto done; - - if (params->features) - al_pcie_port_features_config(pcie_port, params->features); - - if (params->sris_params) - status = al_pcie_port_sris_config(pcie_port, params->sris_params, - params->link_params->max_speed); - if (status) - goto done; - - al_pcie_port_ib_hcrd_config(pcie_port); - - if (params->fast_link_mode) { - al_reg_write32_masked(®s->port_regs->port_link_ctrl, - 1 << PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT, - 1 << PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT); - } - - if (params->enable_axi_slave_err_resp) - al_reg_write32_masked(®s->port_regs->axi_slave_err_resp, - 1 << PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT, - 1 << PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT); - - /** - * Addressing RMN: 5477 - * - * RMN description: - * address-decoder logic performs sub-target decoding even for transactions - * which undergo target enforcement. thus, in case transaction's address is - * inside any ECAM bar, the sub-target decoding will be set to ECAM, which - * causes wrong handling by PCIe unit - * - * Software flow: - * on EP mode only, turning on the iATU-enable bit (with the relevant mask - * below) allows the PCIe unit to discard the ECAM bit which was asserted - * by-mistake in the address-decoder - */ - if (op_mode == AL_PCIE_OPERATING_MODE_EP) { - al_reg_write32_masked(regs->axi.ob_ctrl.cfg_target_bus, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK, - (0) << PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT); - al_reg_write32_masked(regs->axi.ob_ctrl.cfg_control, - PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_IATU_EN, - PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_IATU_EN); - } - - if (op_mode == AL_PCIE_OPERATING_MODE_RC) { - /** - * enable memory and I/O access from port when in RC mode - * in RC mode, only core_space[0] is valid. - */ - al_reg_write16_masked( - (uint16_t __iomem *)(®s->core_space[0].config_header[0] + (0x4 >> 2)), - 0x7, /* Mem, MSE, IO */ - 0x7); - - /* change the class code to match pci bridge */ - al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); - - al_reg_write32_masked( - (uint32_t __iomem *)(®s->core_space[0].config_header[0] - + (PCI_CLASS_REVISION >> 2)), - 0xFFFFFF00, - 0x06040000); - - al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); - - /** - * Addressing RMN: 5702 - * - * RMN description: - * target bus mask default value in HW is: 0xFE, this enforces - * setting the target bus for ports 1 and 3 when running on RC - * mode since bit[20] in ECAM address in these cases is set - * - * Software flow: - * on RC mode only, set target-bus value to 0xFF to prevent this - * enforcement - */ - al_reg_write32_masked(regs->axi.ob_ctrl.cfg_target_bus, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK); - } -done: - al_dbg("PCIe %d: port config %s\n", pcie_port->port_id, status? "failed": "done"); - - return status; -} - -int -al_pcie_pf_config( - struct al_pcie_pf *pcie_pf, - const struct al_pcie_pf_config_params *params) -{ - struct al_pcie_port *pcie_port; - int status = 0; - - al_assert(pcie_pf); - al_assert(params); - - pcie_port = pcie_pf->pcie_port; - - if (!al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: port not enabled, cannot configure port\n", pcie_port->port_id); - return -EINVAL; - } - - al_dbg("PCIe %d: pf %d config\n", pcie_port->port_id, pcie_pf->pf_num); - - if (params) - status = al_pcie_port_pf_params_config(pcie_pf, params); - if (status) - goto done; - -done: - al_dbg("PCIe %d: pf %d config %s\n", - pcie_port->port_id, pcie_pf->pf_num, status ? "failed" : "done"); - - return status; -} - -/************************** PCIe Link Operations API **************************/ - -/* start pcie link */ -int -al_pcie_link_start(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; - - if (!al_pcie_port_is_enabled(pcie_port)) { - al_err("PCIe %d: port not enabled, cannot start link\n", - pcie_port->port_id); - return -EINVAL; - } - - al_dbg("PCIe_%d: start port link.\n", pcie_port->port_id); - - al_reg_write32_masked( - regs->app.global_ctrl.port_init, - PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK, - PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK); - - return 0; -} - -/* stop pcie link */ -int -al_pcie_link_stop(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; - - if (!al_pcie_is_link_started(pcie_port)) { - al_warn("PCIe %d: trying to stop a non-started link\n", - pcie_port->port_id); - } - - al_dbg("PCIe_%d: stop port link.\n", pcie_port->port_id); - - al_reg_write32_masked( - regs->app.global_ctrl.port_init, - PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK, - ~PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK); - - return 0; -} - -/* wait for link up indication */ -int -al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms) -{ - int wait_count = timeout_ms * AL_PCIE_LINKUP_WAIT_INTERVALS_PER_SEC; - - while (wait_count-- > 0) { - if (al_pcie_check_link(pcie_port, NULL)) { - al_info("PCIe_%d: <<<<<<<<< Link up >>>>>>>>>\n", pcie_port->port_id); - return 0; - } else - al_dbg("PCIe_%d: No link up, %d attempts remaining\n", - pcie_port->port_id, wait_count); - - al_udelay(AL_PCIE_LINKUP_WAIT_INTERVAL); - } - al_info("PCIE_%d: link is not established in time\n", - pcie_port->port_id); - - return ETIMEDOUT; -} - -/** get link status */ -int -al_pcie_link_status(struct al_pcie_port *pcie_port, - struct al_pcie_link_status *status) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint16_t pcie_lnksta; - - al_assert(status); - - status->link_up = al_pcie_check_link(pcie_port, &status->ltssm_state); - - if (!status->link_up) { - status->speed = AL_PCIE_LINK_SPEED_DEFAULT; - status->lanes = 0; - return 0; - } - - pcie_lnksta = al_reg_read16((uint16_t __iomem *)regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKSTA >> 1)); - - switch(pcie_lnksta & AL_PCI_EXP_LNKSTA_CLS) { - case AL_PCI_EXP_LNKSTA_CLS_2_5GB: - status->speed = AL_PCIE_LINK_SPEED_GEN1; - break; - case AL_PCI_EXP_LNKSTA_CLS_5_0GB: - status->speed = AL_PCIE_LINK_SPEED_GEN2; - break; - case AL_PCI_EXP_LNKSTA_CLS_8_0GB: - status->speed = AL_PCIE_LINK_SPEED_GEN3; - break; - default: - status->speed = AL_PCIE_LINK_SPEED_DEFAULT; - al_err("PCIe %d: unknown link speed indication. PCIE LINK STATUS %x\n", - pcie_port->port_id, pcie_lnksta); - } - status->lanes = (pcie_lnksta & AL_PCI_EXP_LNKSTA_NLW) >> AL_PCI_EXP_LNKSTA_NLW_SHIFT; - al_info("PCIe %d: Link up. speed gen%d negotiated width %d\n", - pcie_port->port_id, status->speed, status->lanes); - - return 0; -} - -/** get lane status */ -void -al_pcie_lane_status_get( - struct al_pcie_port *pcie_port, - unsigned int lane, - struct al_pcie_lane_status *status) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t lane_status; - uint32_t *reg_ptr; - - al_assert(pcie_port); - al_assert(status); - al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_1) || (lane < REV1_2_MAX_NUM_LANES)); - al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_2) || (lane < REV1_2_MAX_NUM_LANES)); - al_assert((pcie_port->rev_id != AL_PCIE_REV_ID_3) || (lane < REV3_MAX_NUM_LANES)); - - reg_ptr = regs->axi.status.lane[lane]; - - /* Reset field is valid only when same value is read twice */ - do { - lane_status = al_reg_read32(reg_ptr); - status->is_reset = !!(lane_status & PCIE_AXI_STATUS_LANE_IS_RESET); - } while (status->is_reset != (!!(al_reg_read32(reg_ptr) & PCIE_AXI_STATUS_LANE_IS_RESET))); - - status->requested_speed = - (lane_status & PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_MASK) >> - PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_SHIFT; -} - -/** trigger hot reset */ -int -al_pcie_link_hot_reset(struct al_pcie_port *pcie_port, al_bool enable) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t events_gen; - al_bool app_reset_state; - enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); - - if (op_mode != AL_PCIE_OPERATING_MODE_RC) { - al_err("PCIe %d: hot-reset is applicable only for RC mode\n", pcie_port->port_id); - return -EINVAL; - } - - if (!al_pcie_is_link_started(pcie_port)) { - al_err("PCIe %d: link not started, cannot trigger hot-reset\n", pcie_port->port_id); - return -EINVAL; - } - - events_gen = al_reg_read32(regs->app.global_ctrl.events_gen[0]); - app_reset_state = events_gen & PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT; - - if (enable && app_reset_state) { - al_err("PCIe %d: link is already in hot-reset state\n", pcie_port->port_id); - return -EINVAL; - } else if ((!enable) && (!(app_reset_state))) { - al_err("PCIe %d: link is already in non-hot-reset state\n", pcie_port->port_id); - return -EINVAL; - } else { - al_dbg("PCIe %d: %s hot-reset\n", pcie_port->port_id, - (enable ? "enabling" : "disabling")); - /* hot-reset functionality is implemented only for function 0 */ - al_reg_write32_masked(regs->app.global_ctrl.events_gen[0], - PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT, - (enable ? PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT - : ~PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT)); - return 0; - } -} - -/** disable port link */ -int -al_pcie_link_disable(struct al_pcie_port *pcie_port, al_bool disable) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t pcie_lnkctl; - al_bool link_disable_state; - enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); - - if (op_mode != AL_PCIE_OPERATING_MODE_RC) { - al_err("PCIe %d: hot-reset is applicable only for RC mode\n", pcie_port->port_id); - return -EINVAL; - } - - if (!al_pcie_is_link_started(pcie_port)) { - al_err("PCIe %d: link not started, cannot disable link\n", pcie_port->port_id); - return -EINVAL; - } - - pcie_lnkctl = al_reg_read32(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1)); - link_disable_state = pcie_lnkctl & AL_PCI_EXP_LNKCTL_LNK_DIS; - - if (disable && link_disable_state) { - al_err("PCIe %d: link is already in disable state\n", pcie_port->port_id); - return -EINVAL; - } else if ((!disable) && (!(link_disable_state))) { - al_err("PCIe %d: link is already in enable state\n", pcie_port->port_id); - return -EINVAL; - } - - al_dbg("PCIe %d: %s port\n", pcie_port->port_id, (disable ? "disabling" : "enabling")); - al_reg_write32_masked(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1), - AL_PCI_EXP_LNKCTL_LNK_DIS, - (disable ? AL_PCI_EXP_LNKCTL_LNK_DIS : ~AL_PCI_EXP_LNKCTL_LNK_DIS)); - return 0; -} - -/** retrain link */ -int -al_pcie_link_retrain(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = pcie_port->regs; - enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); - - if (op_mode != AL_PCIE_OPERATING_MODE_RC) { - al_err("PCIe %d: link-retrain is applicable only for RC mode\n", - pcie_port->port_id); - return -EINVAL; - } - - if (!al_pcie_is_link_started(pcie_port)) { - al_err("PCIe %d: link not started, cannot link-retrain\n", pcie_port->port_id); - return -EINVAL; - } - - al_reg_write32_masked(regs->core_space[0].pcie_cap_base + (AL_PCI_EXP_LNKCTL >> 1), - AL_PCI_EXP_LNKCTL_LNK_RTRN, AL_PCI_EXP_LNKCTL_LNK_RTRN); - - return 0; -} - -/* trigger speed change */ -int -al_pcie_link_change_speed(struct al_pcie_port *pcie_port, - enum al_pcie_link_speed new_speed) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - if (!al_pcie_is_link_started(pcie_port)) { - al_err("PCIe %d: link not started, cannot change speed\n", pcie_port->port_id); - return -EINVAL; - } - - al_dbg("PCIe %d: changing speed to %d\n", pcie_port->port_id, new_speed); - - al_pcie_port_link_speed_ctrl_set(pcie_port, new_speed); - - al_reg_write32_masked(®s->port_regs->gen2_ctrl, - PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE, - PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE); - - return 0; -} - -/* TODO: check if this function needed */ -int -al_pcie_link_change_width(struct al_pcie_port *pcie_port, - uint8_t width __attribute__((__unused__))) -{ - al_err("PCIe %d: link change width not implemented\n", - pcie_port->port_id); - - return -ENOSYS; -} - -/**************************** Post Link Start API *****************************/ - -/************************** Snoop Configuration API ***************************/ - -int -al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, al_bool enable_axi_snoop) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - /* Set snoop mode */ - al_info("PCIE_%d: snoop mode %s\n", - pcie_port->port_id, enable_axi_snoop ? "enable" : "disable"); - - if (enable_axi_snoop) { - al_reg_write32_masked(regs->axi.ctrl.master_arctl, - PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP, - PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP); - - al_reg_write32_masked(regs->axi.ctrl.master_awctl, - PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP, - PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP); - } else { - al_reg_write32_masked(regs->axi.ctrl.master_arctl, - PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP, - PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP); - - al_reg_write32_masked(regs->axi.ctrl.master_awctl, - PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP | PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP, - PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP); - } - return 0; -} - -/************************** Configuration Space API ***************************/ - -/** get base address of pci configuration space header */ -int -al_pcie_config_space_get(struct al_pcie_pf *pcie_pf, - uint8_t __iomem **addr) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - - *addr = (uint8_t __iomem *)®s->core_space[pcie_pf->pf_num].config_header[0]; - return 0; -} - -/* Read data from the local configuration space */ -uint32_t -al_pcie_local_cfg_space_read( - struct al_pcie_pf *pcie_pf, - unsigned int reg_offset) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - uint32_t data; - - data = al_reg_read32(®s->core_space[pcie_pf->pf_num].config_header[reg_offset]); - - return data; -} - -/* Write data to the local configuration space */ -void -al_pcie_local_cfg_space_write( - struct al_pcie_pf *pcie_pf, - unsigned int reg_offset, - uint32_t data, - al_bool cs2, - al_bool allow_ro_wr) -{ - struct al_pcie_port *pcie_port = pcie_pf->pcie_port; - struct al_pcie_regs *regs = pcie_port->regs; - unsigned int pf_num = pcie_pf->pf_num; - uint32_t *offset = ®s->core_space[pf_num].config_header[reg_offset]; - - if (allow_ro_wr) - al_pcie_port_wr_to_ro_set(pcie_port, AL_TRUE); - - if (cs2 == AL_FALSE) - al_reg_write32(offset, data); - else - al_reg_write32_dbi_cs2(pcie_port, offset, data); - - if (allow_ro_wr) - al_pcie_port_wr_to_ro_set(pcie_port, AL_FALSE); -} - -/** set target_bus and mask_target_bus */ -int -al_pcie_target_bus_set( - struct al_pcie_port *pcie_port, - uint8_t target_bus, - uint8_t mask_target_bus) -{ - struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; - uint32_t reg; - - reg = al_reg_read32(regs->axi.ob_ctrl.cfg_target_bus); - AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT, - mask_target_bus); - AL_REG_FIELD_SET(reg, PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_MASK, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_SHIFT, - target_bus); - al_reg_write32(regs->axi.ob_ctrl.cfg_target_bus, reg); - return 0; -} - -/** get target_bus and mask_target_bus */ -int -al_pcie_target_bus_get( - struct al_pcie_port *pcie_port, - uint8_t *target_bus, - uint8_t *mask_target_bus) -{ - struct al_pcie_regs *regs = (struct al_pcie_regs *)pcie_port->regs; - uint32_t reg; - - al_assert(target_bus); - al_assert(mask_target_bus); - - reg = al_reg_read32(regs->axi.ob_ctrl.cfg_target_bus); - - *mask_target_bus = AL_REG_FIELD_GET(reg, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT); - *target_bus = AL_REG_FIELD_GET(reg, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_MASK, - PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_SHIFT); - return 0; -} - -/** Set secondary bus number */ -int -al_pcie_secondary_bus_set(struct al_pcie_port *pcie_port, uint8_t secbus) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - uint32_t secbus_val = (secbus << - PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_SHIFT); - - al_reg_write32_masked( - regs->axi.ob_ctrl.cfg_control, - PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_MASK, - secbus_val); - return 0; -} - -/** Set sub-ordinary bus number */ -int -al_pcie_subordinary_bus_set(struct al_pcie_port *pcie_port, uint8_t subbus) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - uint32_t subbus_val = (subbus << - PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_SHIFT); - - al_reg_write32_masked( - regs->axi.ob_ctrl.cfg_control, - PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_MASK, - subbus_val); - return 0; -} - -/* Enable/disable deferring incoming configuration requests */ -void -al_pcie_app_req_retry_set( - struct al_pcie_port *pcie_port, - al_bool en) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint32_t mask = (pcie_port->rev_id == AL_PCIE_REV_ID_3) ? - PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN : - PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN; - - al_reg_write32_masked(regs->app.global_ctrl.pm_control, - mask, (en == AL_TRUE) ? mask : 0); -} - -/*************** Internal Address Translation Unit (ATU) API ******************/ - -/** program internal ATU region entry */ -int -al_pcie_atu_region_set( - struct al_pcie_port *pcie_port, - struct al_pcie_atu_region *atu_region) -{ - struct al_pcie_regs *regs = pcie_port->regs; - enum al_pcie_operating_mode op_mode = al_pcie_operating_mode_get(pcie_port); - uint32_t reg = 0; - - /** - * Addressing RMN: 5384 - * - * RMN description: - * From SNPS (also included in the data book) Dynamic iATU Programming - * With AHB/AXI Bridge Module When the bridge slave interface clock - * (hresetn or slv_aclk) is asynchronous to the PCIe native core clock - * (core_clk), you must not update the iATU registers while operations - * are in progress on the AHB/AXI bridge slave interface. The iATU - * registers are in the core_clk clock domain. The register outputs are - * used in the AHB/AXI bridge slave interface clock domain. There is no - * synchronization logic between these registers and the AHB/AXI bridge - * slave interface. - * - * Software flow: - * Do not allow configuring Outbound iATU after link is started - */ - if ((atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) - && (al_pcie_is_link_started(pcie_port))) { - if (!atu_region->enforce_ob_atu_region_set) { - al_err("PCIe %d: setting OB iATU after link is started is not allowed\n", - pcie_port->port_id); - return -EINVAL; - } else { - al_info("PCIe %d: setting OB iATU even after link is started\n", - pcie_port->port_id); - } - } - - /*TODO : add sanity check */ - AL_REG_FIELD_SET(reg, 0xF, 0, atu_region->index); - AL_REG_BIT_VAL_SET(reg, 31, atu_region->direction); - al_reg_write32(®s->port_regs->iatu.index, reg); - - al_reg_write32(®s->port_regs->iatu.lower_base_addr, - (uint32_t)(atu_region->base_addr & 0xFFFFFFFF)); - al_reg_write32(®s->port_regs->iatu.upper_base_addr, - (uint32_t)((atu_region->base_addr >> 32)& 0xFFFFFFFF)); - al_reg_write32(®s->port_regs->iatu.lower_target_addr, - (uint32_t)(atu_region->target_addr & 0xFFFFFFFF)); - al_reg_write32(®s->port_regs->iatu.upper_target_addr, - (uint32_t)((atu_region->target_addr >> 32)& 0xFFFFFFFF)); - - /* configure the limit, not needed when working in BAR match mode */ - if (atu_region->match_mode == 0) { - uint32_t limit_reg_val; - if (pcie_port->rev_id > AL_PCIE_REV_ID_0) { - uint32_t *limit_ext_reg = - (atu_region->direction == AL_PCIE_ATU_DIR_OUTBOUND) ? - ®s->app.atu.out_mask_pair[atu_region->index / 2] : - ®s->app.atu.in_mask_pair[atu_region->index / 2]; - uint32_t limit_ext_reg_mask = - (atu_region->index % 2) ? - PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_MASK : - PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_MASK; - unsigned int limit_ext_reg_shift = - (atu_region->index % 2) ? - PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT : - PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT; - uint64_t limit_sz_msk = - atu_region->limit - atu_region->base_addr; - uint32_t limit_ext_reg_val = (uint32_t)(((limit_sz_msk) >> - 32) & 0xFFFFFFFF); - - if (limit_ext_reg_val) { - limit_reg_val = (uint32_t)((limit_sz_msk) & 0xFFFFFFFF); - al_assert(limit_reg_val == 0xFFFFFFFF); - } else { - limit_reg_val = (uint32_t)(atu_region->limit & - 0xFFFFFFFF); - } - - al_reg_write32_masked( - limit_ext_reg, - limit_ext_reg_mask, - limit_ext_reg_val << limit_ext_reg_shift); - } else { - limit_reg_val = (uint32_t)(atu_region->limit & 0xFFFFFFFF); - } - - al_reg_write32(®s->port_regs->iatu.limit_addr, - limit_reg_val); - } - - reg = 0; - AL_REG_FIELD_SET(reg, 0x1F, 0, atu_region->tlp_type); - AL_REG_FIELD_SET(reg, 0x3 << 9, 9, atu_region->attr); - - - if ((pcie_port->rev_id == AL_PCIE_REV_ID_3) - && (op_mode == AL_PCIE_OPERATING_MODE_EP) - && (atu_region->function_match_bypass_mode)) { - AL_REG_FIELD_SET(reg, - PCIE_IATU_CR1_FUNC_NUM_MASK, - PCIE_IATU_CR1_FUNC_NUM_SHIFT, - atu_region->function_match_bypass_mode_number); - } - - al_reg_write32(®s->port_regs->iatu.cr1, reg); - - /* Enable/disable the region. */ - reg = 0; - AL_REG_FIELD_SET(reg, 0xFF, 0, atu_region->msg_code); - AL_REG_FIELD_SET(reg, 0x700, 8, atu_region->bar_number); - AL_REG_FIELD_SET(reg, 0x3 << 24, 24, atu_region->response); - AL_REG_BIT_VAL_SET(reg, 16, atu_region->enable_attr_match_mode == AL_TRUE); - AL_REG_BIT_VAL_SET(reg, 21, atu_region->enable_msg_match_mode == AL_TRUE); - AL_REG_BIT_VAL_SET(reg, 28, atu_region->cfg_shift_mode == AL_TRUE); - AL_REG_BIT_VAL_SET(reg, 29, atu_region->invert_matching == AL_TRUE); - if (atu_region->tlp_type == AL_PCIE_TLP_TYPE_MEM || atu_region->tlp_type == AL_PCIE_TLP_TYPE_IO) - AL_REG_BIT_VAL_SET(reg, 30, !!atu_region->match_mode); - AL_REG_BIT_VAL_SET(reg, 31, !!atu_region->enable); - - /* In outbound, enable function bypass - * In inbound, enable function match mode - * Note: this is the same bit, has different meanings in ob/ib ATUs - */ - if (op_mode == AL_PCIE_OPERATING_MODE_EP) - AL_REG_FIELD_SET(reg, - PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_MASK, - PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_SHIFT, - atu_region->function_match_bypass_mode ? 0x1 : 0x0); - - al_reg_write32(®s->port_regs->iatu.cr2, reg); - - return 0; -} - -/** obtains internal ATU region base/target addresses */ -void -al_pcie_atu_region_get_fields( - struct al_pcie_port *pcie_port, - enum al_pcie_atu_dir direction, uint8_t index, - al_bool *enable, uint64_t *base_addr, uint64_t *target_addr) -{ - struct al_pcie_regs *regs = pcie_port->regs; - uint64_t high_addr; - uint32_t reg = 0; - - AL_REG_FIELD_SET(reg, 0xF, 0, index); - AL_REG_BIT_VAL_SET(reg, 31, direction); - al_reg_write32(®s->port_regs->iatu.index, reg); - - *base_addr = al_reg_read32(®s->port_regs->iatu.lower_base_addr); - high_addr = al_reg_read32(®s->port_regs->iatu.upper_base_addr); - high_addr <<= 32; - *base_addr |= high_addr; - - *target_addr = al_reg_read32(®s->port_regs->iatu.lower_target_addr); - high_addr = al_reg_read32(®s->port_regs->iatu.upper_target_addr); - high_addr <<= 32; - *target_addr |= high_addr; - - reg = al_reg_read32(®s->port_regs->iatu.cr1); - *enable = AL_REG_BIT_GET(reg, 31) ? AL_TRUE : AL_FALSE; -} - -void -al_pcie_axi_io_config( - struct al_pcie_port *pcie_port, - al_phys_addr_t start, - al_phys_addr_t end) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_reg_write32(regs->axi.ob_ctrl.io_start_h, - (uint32_t)((start >> 32) & 0xFFFFFFFF)); - - al_reg_write32(regs->axi.ob_ctrl.io_start_l, - (uint32_t)(start & 0xFFFFFFFF)); - - al_reg_write32(regs->axi.ob_ctrl.io_limit_h, - (uint32_t)((end >> 32) & 0xFFFFFFFF)); - - al_reg_write32(regs->axi.ob_ctrl.io_limit_l, - (uint32_t)(end & 0xFFFFFFFF)); - - al_reg_write32_masked(regs->axi.ctrl.slv_ctl, - PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN, - PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN); -} - -/************** Interrupt generation (Endpoint mode Only) API *****************/ - -/** generate INTx Assert/DeAssert Message */ -int -al_pcie_legacy_int_gen( - struct al_pcie_pf *pcie_pf, - al_bool assert, - enum al_pcie_legacy_int_type type) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - unsigned int pf_num = pcie_pf->pf_num; - uint32_t reg; - - al_assert(type == AL_PCIE_LEGACY_INTA); /* only INTA supported */ - reg = al_reg_read32(regs->app.global_ctrl.events_gen[pf_num]); - AL_REG_BIT_VAL_SET(reg, 3, !!assert); - al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg); - - return 0; -} - -/** generate MSI interrupt */ -int -al_pcie_msi_int_gen(struct al_pcie_pf *pcie_pf, uint8_t vector) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - unsigned int pf_num = pcie_pf->pf_num; - uint32_t reg; - - /* set msi vector and clear MSI request */ - reg = al_reg_read32(regs->app.global_ctrl.events_gen[pf_num]); - AL_REG_BIT_CLEAR(reg, 4); - AL_REG_FIELD_SET(reg, - PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_MASK, - PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_SHIFT, - vector); - al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg); - /* set MSI request */ - AL_REG_BIT_SET(reg, 4); - al_reg_write32(regs->app.global_ctrl.events_gen[pf_num], reg); - - return 0; -} - -/** configure MSIX capability */ -int -al_pcie_msix_config( - struct al_pcie_pf *pcie_pf, - struct al_pcie_msix_params *msix_params) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - unsigned int pf_num = pcie_pf->pf_num; - uint32_t msix_reg0; - - al_pcie_port_wr_to_ro_set(pcie_pf->pcie_port, AL_TRUE); - - msix_reg0 = al_reg_read32(regs->core_space[pf_num].msix_cap_base); - - msix_reg0 &= ~(AL_PCI_MSIX_MSGCTRL_TBL_SIZE << AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT); - msix_reg0 |= ((msix_params->table_size - 1) & AL_PCI_MSIX_MSGCTRL_TBL_SIZE) << - AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT; - al_reg_write32(regs->core_space[pf_num].msix_cap_base, msix_reg0); - - /* Table offset & BAR */ - al_reg_write32(regs->core_space[pf_num].msix_cap_base + (AL_PCI_MSIX_TABLE >> 2), - (msix_params->table_offset & AL_PCI_MSIX_TABLE_OFFSET) | - (msix_params->table_bar & AL_PCI_MSIX_TABLE_BAR)); - /* PBA offset & BAR */ - al_reg_write32(regs->core_space[pf_num].msix_cap_base + (AL_PCI_MSIX_PBA >> 2), - (msix_params->pba_offset & AL_PCI_MSIX_PBA_OFFSET) | - (msix_params->pba_bar & AL_PCI_MSIX_PBA_BAR)); - - al_pcie_port_wr_to_ro_set(pcie_pf->pcie_port, AL_FALSE); - - return 0; -} - -/** check whether MSIX is enabled */ -al_bool -al_pcie_msix_enabled(struct al_pcie_pf *pcie_pf) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - uint32_t msix_reg0 = al_reg_read32(regs->core_space[pcie_pf->pf_num].msix_cap_base); - - if (msix_reg0 & AL_PCI_MSIX_MSGCTRL_EN) - return AL_TRUE; - return AL_FALSE; -} - -/** check whether MSIX is masked */ -al_bool -al_pcie_msix_masked(struct al_pcie_pf *pcie_pf) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - uint32_t msix_reg0 = al_reg_read32(regs->core_space[pcie_pf->pf_num].msix_cap_base); - - if (msix_reg0 & AL_PCI_MSIX_MSGCTRL_MASK) - return AL_TRUE; - return AL_FALSE; -} - -/******************** Advanced Error Reporting (AER) API **********************/ - -/** configure AER capability */ -int -al_pcie_aer_config( - struct al_pcie_pf *pcie_pf, - struct al_pcie_aer_params *params) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; - uint32_t reg_val; - - reg_val = al_reg_read32(&aer_regs->header); - - if (((reg_val & PCIE_AER_CAP_ID_MASK) >> PCIE_AER_CAP_ID_SHIFT) != - PCIE_AER_CAP_ID_VAL) - return -EIO; - - if (((reg_val & PCIE_AER_CAP_VER_MASK) >> PCIE_AER_CAP_VER_SHIFT) != - PCIE_AER_CAP_VER_VAL) - return -EIO; - - al_reg_write32(&aer_regs->corr_err_mask, ~params->enabled_corr_err); - - al_reg_write32(&aer_regs->uncorr_err_mask, - (~params->enabled_uncorr_non_fatal_err) | - (~params->enabled_uncorr_fatal_err)); - - al_reg_write32(&aer_regs->uncorr_err_severity, - params->enabled_uncorr_fatal_err); - - al_reg_write32(&aer_regs->cap_and_ctrl, - (params->ecrc_gen_en ? PCIE_AER_CTRL_STAT_ECRC_GEN_EN : 0) | - (params->ecrc_chk_en ? PCIE_AER_CTRL_STAT_ECRC_CHK_EN : 0)); - - al_reg_write32_masked( - regs->core_space[pcie_pf->pf_num].pcie_dev_ctrl_status, - PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN | - PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN | - PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN | - PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN, - (params->enabled_corr_err ? - PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN : 0) | - (params->enabled_uncorr_non_fatal_err ? - PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN : 0) | - (params->enabled_uncorr_fatal_err ? - PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN : 0) | - ((params->enabled_uncorr_non_fatal_err & - AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR) ? - PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN : 0) | - ((params->enabled_uncorr_fatal_err & - AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR) ? - PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN : 0)); - - return 0; -} - -/** AER uncorretable errors get and clear */ -unsigned int -al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; - uint32_t reg_val; - - reg_val = al_reg_read32(&aer_regs->uncorr_err_stat); - al_reg_write32(&aer_regs->uncorr_err_stat, reg_val); - - return reg_val; -} - -/** AER corretable errors get and clear */ -unsigned int -al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; - uint32_t reg_val; - - reg_val = al_reg_read32(&aer_regs->corr_err_stat); - al_reg_write32(&aer_regs->corr_err_stat, reg_val); - - return reg_val; -} - -#if (AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS != 4) -#error Wrong assumption! -#endif - -/** AER get the header for the TLP corresponding to a detected error */ -void -al_pcie_aer_err_tlp_hdr_get( - struct al_pcie_pf *pcie_pf, - uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]) -{ - struct al_pcie_regs *regs = pcie_pf->pcie_port->regs; - struct al_pcie_core_aer_regs *aer_regs = regs->core_space[pcie_pf->pf_num].aer; - int i; - - for (i = 0; i < AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS; i++) - hdr[i] = al_reg_read32(&aer_regs->header_log[i]); -} - -/********************** Loopback mode (RC and Endpoint modes) ************/ - -/** enter local pipe loopback mode */ -int -al_pcie_local_pipe_loopback_enter(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_dbg("PCIe %d: Enter LOCAL PIPE Loopback mode", pcie_port->port_id); - - al_reg_write32_masked(®s->port_regs->pipe_loopback_ctrl, - 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT, - 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT); - - al_reg_write32_masked(®s->port_regs->port_link_ctrl, - 1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT, - 1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT); - - return 0; -} - -/** - * @brief exit local pipe loopback mode - * - * @param pcie_port pcie port handle - * @return 0 if no error found - */ -int -al_pcie_local_pipe_loopback_exit(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_dbg("PCIe %d: Exit LOCAL PIPE Loopback mode", pcie_port->port_id); - - al_reg_write32_masked(®s->port_regs->pipe_loopback_ctrl, - 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT, - 0); - - al_reg_write32_masked(®s->port_regs->port_link_ctrl, - 1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT, - 0); - return 0; -} - -/** enter remote loopback mode */ -int -al_pcie_remote_loopback_enter(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_dbg("PCIe %d: Enter REMOTE Loopback mode", pcie_port->port_id); - - al_reg_write32_masked(®s->port_regs->port_link_ctrl, - 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT, - 1 << PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT); - - return 0; -} - -/** - * @brief exit remote loopback mode - * - * @param pcie_port pcie port handle - * @return 0 if no error found - */ -int -al_pcie_remote_loopback_exit(struct al_pcie_port *pcie_port) -{ - struct al_pcie_regs *regs = pcie_port->regs; - - al_dbg("PCIe %d: Exit REMOTE Loopback mode", pcie_port->port_id); - - al_reg_write32_masked(®s->port_regs->port_link_ctrl, - 1 << PCIE_PORT_LINK_CTRL_LB_EN_SHIFT, - 0); - return 0; -} diff --git a/sys/arm/annapurna/alpine/hal/al_hal_pcie.h b/sys/arm/annapurna/alpine/hal/al_hal_pcie.h deleted file mode 100644 index 1ddc8eb70749..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_pcie.h +++ /dev/null @@ -1,1157 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @defgroup grouppcie PCI Express Controller - * @{ - * @section overview Overview - * This header file provide API for the HAL driver of the pcie port, the driver - * provides the following functionalities: - * - Port initialization - * - Link operation - * - Interrupts transactions generation (Endpoint mode). - * - Configuration Access management functions - * - Internal Translation Unit programming - * - * This API does not provide the following: - * - PCIe transactions generation and reception (except interrupts as mentioned - * above) as this functionality is done by the port without need for sw - * intervention. - * - Configuration Access: those transactions are generated automatically by - * the port (ECAM or ATU mode) when the CPU issues memory transaction - * through the fabric toward the PCIe port. This API provides management - * function for controlling the Configuration Access type and bus destination - * - Interrupt Handling. - * - Message Generation: common used messages are automatically generated, also, - * the ATU generic mechanism for generating various kind of messages. - * - PCIe Port Management: both link and port power management features can be - * managed using the PCI/PCIe standard power management and PCIe capabilities - * registers. - * - PCIe link and protocol error handling: the feature can be managed using - * the Advanced Error Handling PCIe capability registers. - * - * @section flows Software Flows - * @subsection init Initialization - * - allocation and set zeros al_pcie_port and al_pcie_pf structures handles - * - call al_pcie_port_handle_init() with pointer to the allocated - * al_pcie_port handle, address of the port internal registers space, and - * port id. - * - call al_pcie_pf_handle_init() with pointer to the al_pcie_port handle - * and pf_number. - * - set the port mode, End-Point or Root-Compex (default). - * - set number of lanes connected to the controller. - * - enable the controller using the al_pcie_port_enable(). note that this - * function expect the virtual address of the PBS Functional Registers. - * - wait for 2000 South-bridge cycles. - * - prepare al_pcie_port_config_params and al_pcie_pf_config_params - * structures depending on chip, board and system configuration. - * for example, when using the port as root complex, the operating_mode - * field should be set to AL_PCIE_OPERATING_MODE_RC. In this example we - * prepare the following configuration: - * For port configuration - * - Root Complex mode - * - Set the Max Link Speed to Gen2 - * - Set the max lanes width to 2 (x2) - * - Disable reversal mode - * - Enable Snoops to support I/O Hardware cache coherency - * - Enable pcie core RAM parity - * - Enable pcie core AXI parity - * - Keep transaction layer default credits - * For pf configuration - * - No EP parameters - * - No SR-IOV parameters - * so the structures we prepare: - * @code - * - struct al_pcie_link_params link_params = { - * AL_PCIE_LINK_SPEED_GEN2, - * AL_FALSE, // disable reversal mode - * AL_PCIE_MPS_DEFAULT}; - * - * - struct al_pcie_port_config_params config_params = { - * &link_params, - * AL_TRUE, // enable Snoop for inbound memory transactions - * AL_TRUE, // enable pcie port RAM parity - * AL_TRUE, // enable pcie port AXI parity - * NULL, // use default latency/replay timers - * NULL, // use default gen2 pipe params - * NULL, // gen3_params not needed when max speed set to Gen2 - * NULL, // don't change TL credits - * NULL, // end point params not needed - * AL_FALSE, //no fast link - * AL_FALSE}; //return 0xFFFFFFFF for read transactions with - * //pci target error - * @endcode - * - now call al_pcie_port_config() with pcie_port and port_config_params - * @subsection link-init Link Initialization - * - once the port configured, we can start PCIe link: - * - call al_pcie_link_start() - * - call al_pcie_link_up_wait() - * - allocate al_pcie_link_status struct and call al_pcie_link_status() and - * check the link is established. - * - * @subsection cap Configuration Access Preparation - * - Once the link is established, we can prepare the port for pci - * configuration access, this stage requires system knowledge about the PCI - * buses enumeration. For example, if 5 buses were discovered on previously - * scanned root complex port, then we should start enumeration from bus 5 (PCI - * secondary bus), the sub-ordinary bus will be temporarily set to maximum - * value (255) until the scan process under this bus is finished, then it will - * updated to the maximum bus value found. So we use the following sequence: - * - call al_pcie_secondary_bus_set() with sec-bus = 5 - * - call al_pcie_subordinary_bus_set() with sub-bus = 255 - * - * @subsection cfg Configuration (Cfg) Access Generation - * - we assume using ECAM method, in this method, the software issues pcie Cfg - * access by accessing the ECAM memory space of the pcie port. For example, to - * issue 4 byte Cfg Read from bus B, Device D, Function F and register R, the - * software issues 4 byte read access to the following physical address - * ECAM base address of the port + (B << 20) + (D << 15) + (F << 12) + R. - * But, as the default size of the ECAM address space is less than - * needed full range (256MB), we modify the target_bus value prior to Cfg - * access in order make the port generate Cfg access with bus value set to the - * value of the target_bus rather than bits 27:20 of the physical address. - * - call al_pcie_target_bus_set() with target_bus set to the required bus of - * the next Cfg access to be issued, mask_target_bus will be set to 0xff. - * no need to call that function if the next Cfg access bus equals to the last - * value set to target_bus. - * - * @file al_hal_pcie.h - * @brief HAL Driver Header for the Annapurna Labs PCI Express port. - */ - -#ifndef _AL_HAL_PCIE_H_ -#define _AL_HAL_PCIE_H_ - -#include "al_hal_common.h" -#include "al_hal_pcie_regs.h" - -/******************************************************************************/ -/********************************* Constants **********************************/ -/******************************************************************************/ - -/** Inbound header credits sum - rev 0/1/2 */ -#define AL_PCIE_REV_1_2_IB_HCRD_SUM 97 -/** Inbound header credits sum - rev 3 */ -#define AL_PCIE_REV3_IB_HCRD_SUM 259 - -/** Number of extended registers */ -#define AL_PCIE_EX_REGS_NUM 40 - -/******************************************************************************* - * PCIe AER uncorrectable error bits - * To be used with the following functions: - * - al_pcie_aer_config - * - al_pcie_aer_uncorr_get_and_clear - ******************************************************************************/ -/** Data Link Protocol Error */ -#define AL_PCIE_AER_UNCORR_DLP_ERR AL_BIT(4) -/** Poisoned TLP */ -#define AL_PCIE_AER_UNCORR_POISIONED_TLP AL_BIT(12) -/** Flow Control Protocol Error */ -#define AL_PCIE_AER_UNCORR_FLOW_CTRL_ERR AL_BIT(13) -/** Completion Timeout */ -#define AL_PCIE_AER_UNCORR_COMPL_TO AL_BIT(14) -/** Completer Abort */ -#define AL_PCIE_AER_UNCORR_COMPL_ABT AL_BIT(15) -/** Unexpected Completion */ -#define AL_PCIE_AER_UNCORR_UNEXPCTED_COMPL AL_BIT(16) -/** Receiver Overflow */ -#define AL_PCIE_AER_UNCORR_RCV_OVRFLW AL_BIT(17) -/** Malformed TLP */ -#define AL_PCIE_AER_UNCORR_MLFRM_TLP AL_BIT(18) -/** ECRC Error */ -#define AL_PCIE_AER_UNCORR_ECRC_ERR AL_BIT(19) -/** Unsupported Request Error */ -#define AL_PCIE_AER_UNCORR_UNSUPRT_REQ_ERR AL_BIT(20) -/** Uncorrectable Internal Error */ -#define AL_PCIE_AER_UNCORR_INT_ERR AL_BIT(22) -/** AtomicOp Egress Blocked */ -#define AL_PCIE_AER_UNCORR_ATOMIC_EGRESS_BLK AL_BIT(24) - -/******************************************************************************* - * PCIe AER correctable error bits - * To be used with the following functions: - * - al_pcie_aer_config - * - al_pcie_aer_corr_get_and_clear - ******************************************************************************/ -/** Receiver Error */ -#define AL_PCIE_AER_CORR_RCV_ERR AL_BIT(0) -/** Bad TLP */ -#define AL_PCIE_AER_CORR_BAD_TLP AL_BIT(6) -/** Bad DLLP */ -#define AL_PCIE_AER_CORR_BAD_DLLP AL_BIT(7) -/** REPLAY_NUM Rollover */ -#define AL_PCIE_AER_CORR_RPLY_NUM_ROLL_OVR AL_BIT(8) -/** Replay Timer Timeout */ -#define AL_PCIE_AER_CORR_RPLY_TMR_TO AL_BIT(12) -/** Advisory Non-Fatal Error */ -#define AL_PCIE_AER_CORR_ADVISORY_NON_FTL_ERR AL_BIT(13) -/** Corrected Internal Error */ -#define AL_PCIE_AER_CORR_INT_ERR AL_BIT(14) - -/** The AER erroneous TLP header length [num DWORDs] */ -#define AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS 4 - -/******************************************************************************/ -/************************* Data Structures and Types **************************/ -/******************************************************************************/ - -/** - * al_pcie_ib_hcrd_config: data structure internally used in order to config - * inbound posted/non-posted parameters. - * Note: it's required to have this structure in pcie_port handle since it has - * a state (required/not-required) which is determined by outbound - * outstanding configuration - */ -struct al_pcie_ib_hcrd_config { - /* Internally used - see 'al_pcie_ib_hcrd_os_ob_reads_config' */ - unsigned int nof_np_hdr; - - /* Internally used - see 'al_pcie_ib_hcrd_os_ob_reads_config' */ - unsigned int nof_p_hdr; -}; - -/* The Max Payload Size. Measured in bytes. - * DEFAULT: do not change the current MPS - */ -enum al_pcie_max_payload_size { - AL_PCIE_MPS_DEFAULT, - AL_PCIE_MPS_128 = 0, - AL_PCIE_MPS_256 = 1, - AL_PCIE_MPS_512 = 2, - AL_PCIE_MPS_1024 = 3, - AL_PCIE_MPS_2048 = 4, - AL_PCIE_MPS_4096 = 5, -}; - -/** - * al_pcie_port: data structure used by the HAL to handle a specific pcie port. - * this structure is allocated and set to zeros by the upper layer, then it is - * initialized by the al_pcie_port_handle_init() that should be called before any - * other function of this API. later, this handle passed to the API functions. - */ -struct al_pcie_port { - void __iomem *pcie_reg_base; - struct al_pcie_regs regs_ptrs; - struct al_pcie_regs *regs; - uint32_t *ex_regs_ptrs[AL_PCIE_EX_REGS_NUM]; - void *ex_regs; - void __iomem *pbs_regs; - - /* Revision ID */ - uint8_t rev_id; - unsigned int port_id; - uint8_t max_lanes; - uint8_t max_num_of_pfs; - - /* Internally used */ - struct al_pcie_ib_hcrd_config ib_hcrd_config; -}; - -/** - * al_pcie_pf: the pf handle, a data structure used to handle PF specific - * functionality. Initialized using "al_pcie_pf_handle_init()" - */ -struct al_pcie_pf { - unsigned int pf_num; - struct al_pcie_port *pcie_port; -}; - -/** Operating mode (endpoint, root complex) */ -enum al_pcie_operating_mode { - AL_PCIE_OPERATING_MODE_EP, - AL_PCIE_OPERATING_MODE_RC, - AL_PCIE_OPERATING_MODE_UNKNOWN -}; - -/* The maximum link speed, measured GT/s (Giga transfer / second) - * DEFAULT: do not change the current speed - * GEN1: 2.5 GT/s - * GEN2: 5 GT/s - * GEN3: 8GT/s - * - * Note: The values of this enumerator are important for proper behavior - */ -enum al_pcie_link_speed { - AL_PCIE_LINK_SPEED_DEFAULT, - AL_PCIE_LINK_SPEED_GEN1 = 1, - AL_PCIE_LINK_SPEED_GEN2 = 2, - AL_PCIE_LINK_SPEED_GEN3 = 3 -}; - -/** PCIe capabilities that supported by a specific port */ -struct al_pcie_max_capability { - al_bool end_point_mode_supported; - al_bool root_complex_mode_supported; - enum al_pcie_link_speed max_speed; - uint8_t max_lanes; - al_bool reversal_supported; - uint8_t atu_regions_num; - uint32_t atu_min_size; -}; - -/** PCIe link related parameters */ -struct al_pcie_link_params { - enum al_pcie_link_speed max_speed; - al_bool enable_reversal; - enum al_pcie_max_payload_size max_payload_size; - -}; - -/** PCIe gen2 link parameters */ -struct al_pcie_gen2_params { - al_bool tx_swing_low; /* set tx swing low when true, and tx swing full when false */ - al_bool tx_compliance_receive_enable; - al_bool set_deemphasis; -}; - -/** PCIe gen 3 standard per lane equalization parameters */ -struct al_pcie_gen3_lane_eq_params { - uint8_t downstream_port_transmitter_preset; - uint8_t downstream_port_receiver_preset_hint; - uint8_t upstream_port_transmitter_preset; - uint8_t upstream_port_receiver_preset_hint; -}; - -/** PCIe gen 3 equalization parameters */ -struct al_pcie_gen3_params { - al_bool perform_eq; - al_bool interrupt_enable_on_link_eq_request; - struct al_pcie_gen3_lane_eq_params *eq_params; /* array of lanes params */ - int eq_params_elements; /* number of elements in the eq_params array */ - - al_bool eq_disable; /* disables the equalization feature */ - al_bool eq_phase2_3_disable; /* Equalization Phase 2 and Phase 3 */ - /* Disable (RC mode only) */ - uint8_t local_lf; /* Full Swing (FS) Value for Gen3 Transmit Equalization */ - /* Value Range: 12 through 63 (decimal).*/ - - uint8_t local_fs; /* Low Frequency (LF) Value for Gen3 Transmit Equalization */ -}; - -/** Transport Layer credits parameters */ -struct al_pcie_tl_credits_params { -}; - -/** Various configuration features */ -struct al_pcie_features { - /** - * Enable MSI fix from the SATA to the PCIe EP - * Only valid for port 0, when enabled as EP - */ - al_bool sata_ep_msi_fix; -}; - -/** - * Inbound posted/non-posted header credits and outstanding outbound reads - * completion header configuration - * - * Constraints: - * - nof_cpl_hdr + nof_np_hdr + nof_p_hdr == - * AL_PCIE_REV_1_2_IB_HCRD_SUM/AL_PCIE_REV3_IB_HCRD_SUM - * - nof_cpl_hdr > 0 - * - nof_p_hdr > 0 - * - nof_np_hdr > 0 - */ -struct al_pcie_ib_hcrd_os_ob_reads_config { - /** Max number of outstanding outbound reads */ - uint8_t nof_outstanding_ob_reads; - - /** - * This value set the possible outstanding headers CMPLs , the core - * can get (the core always advertise infinite credits for CMPLs). - */ - unsigned int nof_cpl_hdr; - - /** - * This value set the possible outstanding headers reads (non-posted - * transactions), the core can get (it set the value in the init FC - * process). - */ - unsigned int nof_np_hdr; - - /** - * This value set the possible outstanding headers writes (posted - * transactions), the core can get (it set the value in the init FC - * process). - */ - unsigned int nof_p_hdr; -}; - -/** PCIe Ack/Nak Latency and Replay timers */ -struct al_pcie_latency_replay_timers { - uint16_t round_trip_lat_limit; - uint16_t replay_timer_limit; -}; - -/* SRIS KP counter values */ -struct al_pcie_sris_params { - /** set to AL_TRUE to use defaults and ignore the other parameters */ - al_bool use_defaults; - uint16_t kp_counter_gen3; /* only for Gen3 */ - uint16_t kp_counter_gen21; -}; - -/** Relaxed ordering params */ -struct al_pcie_relaxed_ordering_params { - al_bool enable_tx_relaxed_ordering; - al_bool enable_rx_relaxed_ordering; -}; - -/** PCIe port configuration parameters - * This structure includes the parameters that the HAL should apply to the port - * (by al_pcie_port_config()). - * The fields that are pointers (e.g. link_params) can be set to NULL, in that - * case, the al_pcie_port_config() will keep the current HW settings. - */ -struct al_pcie_port_config_params { - struct al_pcie_link_params *link_params; - al_bool enable_axi_snoop; - al_bool enable_ram_parity_int; - al_bool enable_axi_parity_int; - struct al_pcie_latency_replay_timers *lat_rply_timers; - struct al_pcie_gen2_params *gen2_params; - struct al_pcie_gen3_params *gen3_params; - struct al_pcie_tl_credits_params *tl_credits; - struct al_pcie_features *features; - /* Sets all internal timers to Fast Mode for speeding up simulation.*/ - al_bool fast_link_mode; - /* - * when true, the PCI unit will return Slave Error/Decoding Error to the master unit in case - * of error. when false, the value 0xFFFFFFFF will be returned without error indication. - */ - al_bool enable_axi_slave_err_resp; - struct al_pcie_sris_params *sris_params; - struct al_pcie_relaxed_ordering_params *relaxed_ordering_params; -}; - -/** BAR register configuration parameters (Endpoint Mode only) */ -struct al_pcie_ep_bar_params { - al_bool enable; - al_bool memory_space; /**< memory or io */ - al_bool memory_64_bit; /**< is memory space is 64 bit */ - al_bool memory_is_prefetchable; - uint64_t size; /* the bar size in bytes */ -}; - -/** PF config params (EP mode only) */ -struct al_pcie_pf_config_params { - al_bool cap_d1_d3hot_dis; - al_bool cap_flr_dis; - al_bool cap_aspm_dis; - al_bool bar_params_valid; - struct al_pcie_ep_bar_params bar_params[6]; - struct al_pcie_ep_bar_params exp_bar_params;/* expansion ROM BAR*/ -}; - -/** PCIe link status */ -struct al_pcie_link_status { - al_bool link_up; - enum al_pcie_link_speed speed; - uint8_t lanes; - uint8_t ltssm_state; -}; - -/** PCIe lane status */ -struct al_pcie_lane_status { - al_bool is_reset; - enum al_pcie_link_speed requested_speed; -}; - -/** PCIe MSIX capability configuration parameters */ -struct al_pcie_msix_params { - uint16_t table_size; - uint16_t table_offset; - uint8_t table_bar; - uint16_t pba_offset; - uint16_t pba_bar; -}; - -/** PCIE AER capability parameters */ -struct al_pcie_aer_params { - /** ECRC Generation Enable */ - al_bool ecrc_gen_en; - /** ECRC Check Enable */ - al_bool ecrc_chk_en; - - /** - * Enabled reporting of correctable errors (bit mask) - * See 'AL_PCIE_AER_CORR_*' for details - * 0 - no reporting at all - */ - unsigned int enabled_corr_err; - /** - * Enabled reporting of non-fatal uncorrectable errors (bit mask) - * See 'AL_PCIE_AER_UNCORR_*' for details - * 0 - no reporting at all - */ - unsigned int enabled_uncorr_non_fatal_err; - /** - * Enabled reporting of fatal uncorrectable errors (bit mask) - * See 'AL_PCIE_AER_UNCORR_*' for details - * 0 - no reporting at all - */ - unsigned int enabled_uncorr_fatal_err; -}; - -/******************************************************************************/ -/********************************** PCIe API **********************************/ -/******************************************************************************/ - -/*************************** PCIe Initialization API **************************/ - -/** - * Initializes a PCIe port handle structure. - * - * @param pcie_port an allocated, non-initialized instance. - * @param pcie_reg_base the virtual base address of the port internal - * registers - * @param pbs_reg_base the virtual base address of the pbs functional - * registers - * @param port_id the port id (used mainly for debug messages) - * - * @return 0 if no error found. - */ -int al_pcie_port_handle_init(struct al_pcie_port *pcie_port, - void __iomem *pcie_reg_base, - void __iomem *pbs_reg_base, - unsigned int port_id); - -/** - * Initializes a PCIe pf handle structure - * @param pcie_pf an allocated, non-initialized instance of pf handle - * @param pcie_port pcie port handle - * @param pf_num physical function number - * @return 0 if no error found - */ -int al_pcie_pf_handle_init( - struct al_pcie_pf *pcie_pf, - struct al_pcie_port *pcie_port, - unsigned int pf_num); - -/************************** Pre PCIe Port Enable API **************************/ - -/** - * @brief set current pcie operating mode (root complex or endpoint) - * This function can be called only before enabling the controller using - * al_pcie_port_enable(). - * - * @param pcie_port pcie port handle - * @param mode pcie operating mode - * - * @return 0 if no error found. - */ -int al_pcie_port_operating_mode_config(struct al_pcie_port *pcie_port, - enum al_pcie_operating_mode mode); - -/** - * Configure number of lanes connected to this port. - * This function can be called only before enabling the controller using al_pcie_port_enable(). - * - * @param pcie_port pcie port handle - * @param lanes number of lanes - * Note: this function must be called before any al_pcie_port_config() calls - * - * @return 0 if no error found. - */ -int al_pcie_port_max_lanes_set(struct al_pcie_port *pcie_port, uint8_t lanes); - -/** - * Set maximum physical function numbers - * @param pcie_port pcie port handle - * @param max_num_of_pfs number of physical functions - * Note: this function must be called before any al_pcie_pf_config() calls - */ -int al_pcie_port_max_num_of_pfs_set( - struct al_pcie_port *pcie_port, - uint8_t max_num_of_pfs); - -/** - * @brief Inbound posted/non-posted header credits and outstanding outbound - * reads completion header configuration - * - * @param pcie_port pcie port handle - * @param ib_hcrd_os_ob_reads_config - * Inbound header credits and outstanding outbound reads - * configuration - */ -int al_pcie_port_ib_hcrd_os_ob_reads_config( - struct al_pcie_port *pcie_port, - struct al_pcie_ib_hcrd_os_ob_reads_config *ib_hcrd_os_ob_reads_config); - -/** return PCIe operating mode - * @param pcie_port pcie port handle - * @return operating mode - */ -enum al_pcie_operating_mode al_pcie_operating_mode_get( - struct al_pcie_port *pcie_port); - -/**************************** PCIe Port Enable API ****************************/ - -/** Enable PCIe unit (deassert reset) - * - * @param pcie_port pcie port handle - * - * @return 0 if no error found. - */ -int al_pcie_port_enable(struct al_pcie_port *pcie_port); - -/** Disable PCIe unit (assert reset) - * - * @param pcie_port pcie port handle - */ -void al_pcie_port_disable(struct al_pcie_port *pcie_port); - -/** - * Port memory shutdown/up - * Caution: This function can be called only when the controller is disabled - * - * @param pcie_port pcie port handle - * @param enable memory shutdown enable or disable - * - */ -int al_pcie_port_memory_shutdown_set( - struct al_pcie_port *pcie_port, - al_bool enable); - -/** - * Check if port enabled or not - * @param pcie_port pcie port handle - * @return AL_TRUE of port enabled and AL_FALSE otherwise - */ -al_bool al_pcie_port_is_enabled(struct al_pcie_port *pcie_port); - -/*************************** PCIe Configuration API ***************************/ - -/** - * @brief configure pcie port (mode, link params, etc..) - * this function must be called before initializing the link - * - * @param pcie_port pcie port handle - * @param params configuration structure. - * - * @return 0 if no error found - */ -int al_pcie_port_config(struct al_pcie_port *pcie_port, - const struct al_pcie_port_config_params *params); - -/** - * @brief Configure a specific PF (EP params, sriov params, ...) - * this function must be called before any datapath transactions - * - * @param pcie_pf pcie pf handle - * @param params configuration structure. - * - * @return 0 if no error found - */ -int al_pcie_pf_config( - struct al_pcie_pf *pcie_pf, - const struct al_pcie_pf_config_params *params); - -/************************** PCIe Link Operations API **************************/ - -/** - * @brief start pcie link - * - * @param pcie_port pcie port handle - * - * @return 0 if no error found - */ -int al_pcie_link_start(struct al_pcie_port *pcie_port); - -/** - * @brief stop pcie link - * - * @param pcie_port pcie port handle - * - * @return 0 if no error found - */ -int al_pcie_link_stop(struct al_pcie_port *pcie_port); - -/** - * @brief trigger link-disable - * - * @param pcie_port pcie port handle - * @param disable AL_TRUE to disable the link and AL_FALSE to enable it - * - * Note: this functionality differs from "al_pcie_link_stop" as it's a spec - * functionality where both sides of the PCIe agrees to disable the link - * @return 0 if no error found - */ -int al_pcie_link_disable(struct al_pcie_port *pcie_port, al_bool disable); - -/** - * @brief wait for link up indication - * this function waits for link up indication, it polls LTSSM state until link is ready - * - * @param pcie_port pcie port handle - * @param timeout_ms maximum timeout in milli-seconds to wait for link up - * - * @return 0 if link up indication detected - * -ETIME if not. - */ -int al_pcie_link_up_wait(struct al_pcie_port *pcie_port, uint32_t timeout_ms); - -/** - * @brief get link status - * - * @param pcie_port pcie port handle - * @param status structure for link status - * - * @return 0 if no error found - */ -int al_pcie_link_status(struct al_pcie_port *pcie_port, struct al_pcie_link_status *status); - -/** - * @brief get lane status - * - * @param pcie_port - * pcie port handle - * @param lane - * PCIe lane - * @param status - * Pointer to returned structure for lane status - * - */ -void al_pcie_lane_status_get( - struct al_pcie_port *pcie_port, - unsigned int lane, - struct al_pcie_lane_status *status); - -/** - * @brief trigger hot reset - * - * @param pcie_port pcie port handle - * @param enable AL_TRUE to enable hot-reset and AL_FALSE to disable it - * - * @return 0 if no error found - */ -int al_pcie_link_hot_reset(struct al_pcie_port *pcie_port, al_bool enable); - -/** - * @brief trigger link-retain - * this function initiates Link retraining by directing the Physical Layer LTSSM - * to the Recovery state. If the LTSSM is already in Recovery or Configuration, - * re-entering Recovery is permitted but not required. - - * @param pcie_port pcie port handle - * - * Note: there's no need to disable initiating link-retrain - * @return 0 if no error found - */ -int al_pcie_link_retrain(struct al_pcie_port *pcie_port); - -/** - * @brief change port speed - * this function changes the port speed, it doesn't wait for link re-establishment - * - * @param pcie_port pcie port handle - * @param new_speed the new speed gen to set - * - * @return 0 if no error found - */ -int al_pcie_link_change_speed(struct al_pcie_port *pcie_port, enum al_pcie_link_speed new_speed); - -/* TODO: check if this function needed */ -int al_pcie_link_change_width(struct al_pcie_port *pcie_port, uint8_t width); - -/**************************** Post Link Start API *****************************/ - -/************************** Snoop Configuration API ***************************/ - -/** - * @brief configure pcie port axi snoop - * - * @param pcie_port pcie port handle - * @param enable_axi_snoop enable snoop. - * - * @return 0 if no error found - */ -/* TODO: Can this API be called after port enable? */ -int al_pcie_port_snoop_config(struct al_pcie_port *pcie_port, - al_bool enable_axi_snoop); - -/************************** Configuration Space API ***************************/ - -/** - * Configuration Space Access Through PCI-E_ECAM_Ext PASW (RC mode only) - */ - -/** - * @brief get base address of pci configuration space header - * @param pcie_pf pcie pf handle - * @param addr pointer for returned address; - * @return 0 if no error found - */ -int al_pcie_config_space_get( - struct al_pcie_pf *pcie_pf, - uint8_t __iomem **addr); - -/** - * Read data from the local configuration space - * - * @param pcie_pf pcie pf handle - * @param reg_offset Configuration space register offset - * @return Read data - */ -uint32_t al_pcie_local_cfg_space_read( - struct al_pcie_pf *pcie_pf, - unsigned int reg_offset); - -/** - * Write data to the local configuration space - * - * @param pcie_pf PCIe pf handle - * @param reg_offset Configuration space register offset - * @param data Data to write - * @param cs2 Should be AL_TRUE if dbi_cs2 must be asserted - * to enable writing to this register, according to - * the PCIe Core specifications - * @param allow_ro_wr AL_TRUE to allow writing into read-only regs - * - */ -void al_pcie_local_cfg_space_write( - struct al_pcie_pf *pcie_pf, - unsigned int reg_offset, - uint32_t data, - al_bool cs2, - al_bool allow_ro_wr); - -/** - * @brief set target_bus and mask_target_bus - * @param pcie_port pcie port handle - * @param target_bus - * @param mask_target_bus - * @return 0 if no error found - */ -int al_pcie_target_bus_set(struct al_pcie_port *pcie_port, - uint8_t target_bus, - uint8_t mask_target_bus); - -/** - * @brief get target_bus and mask_target_bus - * @param pcie_port pcie port handle - * @param target_bus - * @param mask_target_bus - * @return 0 if no error found - */ -int al_pcie_target_bus_get(struct al_pcie_port *pcie_port, - uint8_t *target_bus, - uint8_t *mask_target_bus); - -/** - * Set secondary bus number - * - * @param pcie_port pcie port handle - * @param secbus pci secondary bus number - * - * @return 0 if no error found. - */ -int al_pcie_secondary_bus_set(struct al_pcie_port *pcie_port, uint8_t secbus); - -/** - * Set subordinary bus number - * - * @param pcie_port pcie port handle - * @param subbus the highest bus number of all of the buses that can be reached - * downstream of the PCIE instance. - * - * @return 0 if no error found. - */ -int al_pcie_subordinary_bus_set(struct al_pcie_port *pcie_port,uint8_t subbus); - -/** - * @brief Enable/disable deferring incoming configuration requests until - * initialization is complete. When enabled, the core completes incoming - * configuration requests with a Configuration Request Retry Status. - * Other incoming Requests complete with Unsupported Request status. - * - * @param pcie_port pcie port handle - * @param en enable/disable - */ -void al_pcie_app_req_retry_set(struct al_pcie_port *pcie_port, al_bool en); - -/*************** Internal Address Translation Unit (ATU) API ******************/ - -enum al_pcie_atu_dir { - AL_PCIE_ATU_DIR_OUTBOUND = 0, - AL_PCIE_ATU_DIR_INBOUND = 1, -}; - -enum al_pcie_atu_tlp { - AL_PCIE_TLP_TYPE_MEM = 0, - AL_PCIE_TLP_TYPE_IO = 2, - AL_PCIE_TLP_TYPE_CFG0 = 4, - AL_PCIE_TLP_TYPE_CFG1 = 5, - AL_PCIE_TLP_TYPE_MSG = 0x10, - AL_PCIE_TLP_TYPE_RESERVED = 0x1f -}; - -enum al_pcie_atu_response { - AL_PCIE_RESPONSE_NORMAL = 0, - AL_PCIE_RESPONSE_UR = 1, - AL_PCIE_RESPONSE_CA = 2 -}; - -struct al_pcie_atu_region { - al_bool enable; - /* outbound or inbound */ - enum al_pcie_atu_dir direction; - /* region index */ - uint8_t index; - uint64_t base_addr; - /** limit marks the region's end address. only bits [39:0] are valid - * given the Alpine PoC maximum physical address space - */ - uint64_t limit; - /** the address that matches will be translated to this address + offset - */ - uint64_t target_addr; - al_bool invert_matching; - /* pcie tlp type*/ - enum al_pcie_atu_tlp tlp_type; - /* pcie frame header attr field*/ - uint8_t attr; - /** - * outbound specific params - */ - /* pcie message code */ - uint8_t msg_code; - al_bool cfg_shift_mode; - /** - * inbound specific params - */ - uint8_t bar_number; - /* BAR match mode, used in EP for MEM and IO tlps*/ - uint8_t match_mode; - /** - * For outbound: enables taking the function number of the translated - * TLP from the PCIe core. For inbound: enables ATU function match mode - * Note: this boolean is ignored in RC mode - */ - al_bool function_match_bypass_mode; - /** - * The function number to match/bypass (see previous parameter) - * Note: this parameter is ignored when previous param is FALSE - */ - uint8_t function_match_bypass_mode_number; - /* response code */ - enum al_pcie_atu_response response; - al_bool enable_attr_match_mode; - al_bool enable_msg_match_mode; - /** - * USE WITH CAUTION: setting this boolean to AL_TRUE allows setting the - * outbound ATU even after link is already started. DO NOT SET this - * boolean to AL_TRUE unless there have been NO traffic before calling - * al_pcie_atu_region_set function - */ - al_bool enforce_ob_atu_region_set; -}; - -/** - * @brief program internal ATU region entry - * @param pcie_port pcie port handle - * @param atu_region data structure that contains the region index and the - * translation parameters - * @return 0 if no error - */ -int al_pcie_atu_region_set( - struct al_pcie_port *pcie_port, - struct al_pcie_atu_region *atu_region); - -/** - * @brief get internal ATU is enabled and base/target addresses - * @param pcie_port pcie port handle - * @param direction input: iATU direction (IB/OB) - * @param index input: iATU index - * @param enable output: AL_TRUE if the iATU is enabled - * @param base_addr output: the iATU base address - * @param target_addr output: the iATU target address - */ -void al_pcie_atu_region_get_fields( - struct al_pcie_port *pcie_port, - enum al_pcie_atu_dir direction, uint8_t index, - al_bool *enable, uint64_t *base_addr, uint64_t *target_addr); - -/** - * @brief Configure axi io bar. - * every hit to this bar will override size to 4 bytes. - * @param pcie_port pcie port handle - * @param start the first address of the memory - * @param end the last address of the memory - * @return - */ -void al_pcie_axi_io_config( - struct al_pcie_port *pcie_port, - al_phys_addr_t start, - al_phys_addr_t end); - -/************** Interrupt generation (Endpoint mode Only) API *****************/ - -enum al_pcie_legacy_int_type{ - AL_PCIE_LEGACY_INTA = 0, - AL_PCIE_LEGACY_INTB, - AL_PCIE_LEGACY_INTC, - AL_PCIE_LEGACY_INTD -}; - -/** - * @brief generate INTx Assert/DeAssert Message - * @param pcie_pf pcie pf handle - * @param assert when true, Assert Message is sent - * @param type type of message (INTA, INTB, etc) - * @return 0 if no error found - */ -int al_pcie_legacy_int_gen( - struct al_pcie_pf *pcie_pf, - al_bool assert, - enum al_pcie_legacy_int_type type); - -/** - * @brief generate MSI interrupt - * @param pcie_pf pcie pf handle - * @param vector the vector index to send interrupt for. - * @return 0 if no error found - */ -int al_pcie_msi_int_gen(struct al_pcie_pf *pcie_pf, uint8_t vector); - -/** - * @brief configure MSIX capability - * @param pcie_pf pcie pf handle - * @param msix_params MSIX capability configuration parameters - * @return 0 if no error found - */ -int al_pcie_msix_config( - struct al_pcie_pf *pcie_pf, - struct al_pcie_msix_params *msix_params); - -/** - * @brief check whether MSIX capability is enabled - * @param pcie_pf pcie pf handle - * @return AL_TRUE if MSIX capability is enabled, AL_FALSE otherwise - */ -al_bool al_pcie_msix_enabled(struct al_pcie_pf *pcie_pf); - -/** - * @brief check whether MSIX capability is masked - * @param pcie_pf pcie pf handle - * @return AL_TRUE if MSIX capability is masked, AL_FALSE otherwise - */ -al_bool al_pcie_msix_masked(struct al_pcie_pf *pcie_pf); - -/******************** Advanced Error Reporting (AER) API **********************/ - -/** - * @brief configure AER capability - * @param pcie_pf pcie pf handle - * @param params AER capability configuration parameters - * @return 0 if no error found - */ -int al_pcie_aer_config( - struct al_pcie_pf *pcie_pf, - struct al_pcie_aer_params *params); - -/** - * @brief AER uncorretable errors get and clear - * @param pcie_pf pcie pf handle - * @return bit mask of uncorrectable errors - see 'AL_PCIE_AER_UNCORR_*' for - * details - */ -unsigned int al_pcie_aer_uncorr_get_and_clear(struct al_pcie_pf *pcie_pf); - -/** - * @brief AER corretable errors get and clear - * @param pcie_pf pcie pf handle - * @return bit mask of correctable errors - see 'AL_PCIE_AER_CORR_*' for - * details - */ -unsigned int al_pcie_aer_corr_get_and_clear(struct al_pcie_pf *pcie_pf); - -/** - * @brief AER get the header for the TLP corresponding to a detected error - * @param pcie_pf pcie pf handle - * @param hdr pointer to an array for getting the header - */ -void al_pcie_aer_err_tlp_hdr_get( - struct al_pcie_pf *pcie_pf, - uint32_t hdr[AL_PCIE_AER_ERR_TLP_HDR_NUM_DWORDS]); - -/******************** Loop-Back mode (RC and Endpoint modes) ******************/ - -/** - * @brief enter local pipe loop-back mode - * This mode will connect the pipe RX signals to TX. - * no need to start link when using this mode. - * Gen3 equalization must be disabled before enabling this mode - * The caller must make sure the port is ready to accept the TLPs it sends to - * itself. for example, BARs should be initialized before sending memory TLPs. - * - * @param pcie_port pcie port handle - * @return 0 if no error found - */ -int al_pcie_local_pipe_loopback_enter(struct al_pcie_port *pcie_port); - -/** - * @brief exit local pipe loopback mode - * - * @param pcie_port pcie port handle - * @return 0 if no error found - */ -int al_pcie_local_pipe_loopback_exit(struct al_pcie_port *pcie_port); - -/** - * @brief enter master remote loopback mode - * No need to configure the link partner to enter slave remote loopback mode - * as this should be done as response to special training sequence directives - * when master works in remote loopback mode. - * The caller must make sure the port is ready to accept the TLPs it sends to - * itself. for example, BARs should be initialized before sending memory TLPs. - * - * @param pcie_port pcie port handle - * @return 0 if no error found - */ -int al_pcie_remote_loopback_enter(struct al_pcie_port *pcie_port); - -/** - * @brief exit remote loopback mode - * - * @param pcie_port pcie port handle - * @return 0 if no error found - */ -int al_pcie_remote_loopback_exit(struct al_pcie_port *pcie_port); - -#endif -/** @} end of grouppcie group */ diff --git a/sys/arm/annapurna/alpine/hal/al_hal_pcie_axi_reg.h b/sys/arm/annapurna/alpine/hal/al_hal_pcie_axi_reg.h deleted file mode 100644 index 04d4bfdbca3f..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_pcie_axi_reg.h +++ /dev/null @@ -1,1501 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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 __AL_PCIE_HAL_AXI_REG_H__ -#define __AL_PCIE_HAL_AXI_REG_H__ - -#include "al_hal_plat_types.h" - -#ifdef __cplusplus -extern "C" { -#endif -/* -* Unit Registers -*/ - - - -struct al_pcie_rev1_2_axi_ctrl { - /* [0x0] */ - uint32_t global; - uint32_t rsrvd_0; - /* [0x8] */ - uint32_t master_bctl; - /* [0xc] */ - uint32_t master_rctl; - /* [0x10] */ - uint32_t master_ctl; - /* [0x14] */ - uint32_t master_arctl; - /* [0x18] */ - uint32_t master_awctl; - /* [0x1c] */ - uint32_t slave_rctl; - /* [0x20] */ - uint32_t slv_wctl; - /* [0x24] */ - uint32_t slv_ctl; - /* [0x28] */ - uint32_t dbi_ctl; - /* [0x2c] */ - uint32_t vmid_mask; - uint32_t rsrvd[4]; -}; -struct al_pcie_rev3_axi_ctrl { - /* [0x0] */ - uint32_t global; - uint32_t rsrvd_0; - /* [0x8] */ - uint32_t master_bctl; - /* [0xc] */ - uint32_t master_rctl; - /* [0x10] */ - uint32_t master_ctl; - /* [0x14] */ - uint32_t master_arctl; - /* [0x18] */ - uint32_t master_awctl; - /* [0x1c] */ - uint32_t slave_rctl; - /* [0x20] */ - uint32_t slv_wctl; - /* [0x24] */ - uint32_t slv_ctl; - /* [0x28] */ - uint32_t dbi_ctl; - /* [0x2c] */ - uint32_t vmid_mask; -}; -struct al_pcie_rev1_axi_ob_ctrl { - /* [0x0] */ - uint32_t cfg_target_bus; - /* [0x4] */ - uint32_t cfg_control; - /* [0x8] */ - uint32_t io_start_l; - /* [0xc] */ - uint32_t io_start_h; - /* [0x10] */ - uint32_t io_limit_l; - /* [0x14] */ - uint32_t io_limit_h; - /* [0x18] */ - uint32_t msg_start_l; - /* [0x1c] */ - uint32_t msg_start_h; - /* [0x20] */ - uint32_t msg_limit_l; - /* [0x24] */ - uint32_t msg_limit_h; - uint32_t rsrvd[6]; -}; -struct al_pcie_rev2_axi_ob_ctrl { - /* [0x0] */ - uint32_t cfg_target_bus; - /* [0x4] */ - uint32_t cfg_control; - /* [0x8] */ - uint32_t io_start_l; - /* [0xc] */ - uint32_t io_start_h; - /* [0x10] */ - uint32_t io_limit_l; - /* [0x14] */ - uint32_t io_limit_h; - /* [0x18] */ - uint32_t msg_start_l; - /* [0x1c] */ - uint32_t msg_start_h; - /* [0x20] */ - uint32_t msg_limit_l; - /* [0x24] */ - uint32_t msg_limit_h; - /* - * [0x28] this register override the VMID field in the AXUSER [19:4], - * for the AXI master port. - */ - uint32_t vmid_reg_ovrd; - /* [0x2c] this register override the ADDR[63:32] AXI master port. */ - uint32_t addr_high_reg_ovrd_value; - /* [0x30] this register override the ADDR[63:32] AXI master port. */ - uint32_t addr_high_reg_ovrd_sel; - /* - * [0x34] Define the size to replace in the master axi address bits - * [63:32] - */ - uint32_t addr_size_replace; - uint32_t rsrvd[2]; -}; -struct al_pcie_rev3_axi_ob_ctrl { - /* [0x0] */ - uint32_t cfg_target_bus; - /* [0x4] */ - uint32_t cfg_control; - /* [0x8] */ - uint32_t io_start_l; - /* [0xc] */ - uint32_t io_start_h; - /* [0x10] */ - uint32_t io_limit_l; - /* [0x14] */ - uint32_t io_limit_h; - /* [0x18] */ - uint32_t aw_msg_start_l; - /* [0x1c] */ - uint32_t aw_msg_start_h; - /* [0x20] */ - uint32_t aw_msg_limit_l; - /* [0x24] */ - uint32_t aw_msg_limit_h; - /* [0x28] */ - uint32_t ar_msg_start_l; - /* [0x2c] */ - uint32_t ar_msg_start_h; - /* [0x30] */ - uint32_t ar_msg_limit_l; - /* [0x34] */ - uint32_t ar_msg_limit_h; - /* [0x38] */ - uint32_t io_addr_mask_h; - /* [0x3c] */ - uint32_t ar_msg_addr_mask_h; - /* [0x40] */ - uint32_t aw_msg_addr_mask_h; - /* - * [0x44] this register override the VMID field in the AXUSER [19:4], - * for the AXI master port. - */ - uint32_t vmid_reg_ovrd; - /* [0x48] this register override the ADDR[63:32] AXI master port. */ - uint32_t addr_high_reg_ovrd_value; - /* [0x4c] this register override the ADDR[63:32] AXI master port. */ - uint32_t addr_high_reg_ovrd_sel; - /* - * [0x50] Define the size to replace in the master axi address bits - * [63:32] - */ - uint32_t addr_size_replace; - uint32_t rsrvd[3]; -}; -struct al_pcie_revx_axi_msg { - /* [0x0] */ - uint32_t addr_high; - /* [0x4] */ - uint32_t addr_low; - /* [0x8] */ - uint32_t type; -}; -struct al_pcie_revx_axi_pcie_status { - /* [0x0] */ - uint32_t debug; -}; -struct al_pcie_revx_axi_rd_parity { - /* [0x0] */ - uint32_t log_high; - /* [0x4] */ - uint32_t log_low; -}; -struct al_pcie_revx_axi_rd_cmpl { - /* [0x0] */ - uint32_t cmpl_log_high; - /* [0x4] */ - uint32_t cmpl_log_low; -}; -struct al_pcie_revx_axi_rd_to { - /* [0x0] */ - uint32_t to_log_high; - /* [0x4] */ - uint32_t to_log_low; -}; -struct al_pcie_revx_axi_wr_cmpl { - /* [0x0] */ - uint32_t wr_cmpl_log_high; - /* [0x4] */ - uint32_t wr_cmpl_log_low; -}; -struct al_pcie_revx_axi_wr_to { - /* [0x0] */ - uint32_t wr_to_log_high; - /* [0x4] */ - uint32_t wr_to_log_low; -}; -struct al_pcie_revx_axi_pcie_global { - /* [0x0] */ - uint32_t conf; -}; -struct al_pcie_rev1_2_axi_status { - /* [0x0] */ - uint32_t lane0; - /* [0x4] */ - uint32_t lane1; - /* [0x8] */ - uint32_t lane2; - /* [0xc] */ - uint32_t lane3; -}; -struct al_pcie_rev3_axi_status { - /* [0x0] */ - uint32_t lane0; - /* [0x4] */ - uint32_t lane1; - /* [0x8] */ - uint32_t lane2; - /* [0xc] */ - uint32_t lane3; - /* [0x10] */ - uint32_t lane4; - /* [0x14] */ - uint32_t lane5; - /* [0x18] */ - uint32_t lane6; - /* [0x1c] */ - uint32_t lane7; - uint32_t rsrvd[8]; -}; -struct al_pcie_rev1_2_axi_conf { - /* [0x0] */ - uint32_t zero_lane0; - /* [0x4] */ - uint32_t zero_lane1; - /* [0x8] */ - uint32_t zero_lane2; - /* [0xc] */ - uint32_t zero_lane3; - /* [0x10] */ - uint32_t one_lane0; - /* [0x14] */ - uint32_t one_lane1; - /* [0x18] */ - uint32_t one_lane2; - /* [0x1c] */ - uint32_t one_lane3; -}; -struct al_pcie_rev3_axi_conf { - /* [0x0] */ - uint32_t zero_lane0; - /* [0x4] */ - uint32_t zero_lane1; - /* [0x8] */ - uint32_t zero_lane2; - /* [0xc] */ - uint32_t zero_lane3; - /* [0x10] */ - uint32_t zero_lane4; - /* [0x14] */ - uint32_t zero_lane5; - /* [0x18] */ - uint32_t zero_lane6; - /* [0x1c] */ - uint32_t zero_lane7; - /* [0x20] */ - uint32_t one_lane0; - /* [0x24] */ - uint32_t one_lane1; - /* [0x28] */ - uint32_t one_lane2; - /* [0x2c] */ - uint32_t one_lane3; - /* [0x30] */ - uint32_t one_lane4; - /* [0x34] */ - uint32_t one_lane5; - /* [0x38] */ - uint32_t one_lane6; - /* [0x3c] */ - uint32_t one_lane7; - uint32_t rsrvd[16]; -}; - -struct al_pcie_revx_axi_msg_attr_axuser_table { - /* [0x0] 4 option, the index comes from */ - uint32_t entry_vec; -}; - -struct al_pcie_revx_axi_parity { - /* [0x0] */ - uint32_t en_axi; - /* [0x4] */ - uint32_t status_axi; -}; -struct al_pcie_revx_axi_pos_logged { - /* [0x0] */ - uint32_t error_low; - /* [0x4] */ - uint32_t error_high; -}; -struct al_pcie_revx_axi_ordering { - /* [0x0] */ - uint32_t pos_cntl; -}; -struct al_pcie_revx_axi_link_down { - /* [0x0] */ - uint32_t reset_extend; -}; -struct al_pcie_revx_axi_pre_configuration { - /* [0x0] */ - uint32_t pcie_core_setup; -}; -struct al_pcie_revx_axi_init_fc { - /* - * Revision 1/2: - * [0x0] The sum of all the fields below must be 97 - * Revision 3: - * [0x0] The sum of all the fields below must be 259 - * */ - uint32_t cfg; -}; -struct al_pcie_revx_axi_int_grp_a_axi { - /* - * [0x0] Interrupt Cause Register - * Set by hardware. - * - If MSI-X is enabled, and auto_clear control bit =TRUE, - * automatically cleared after MSI-X message associated with this - * specific interrupt bit is sent (MSI-X acknowledge is received). - * - Software can set a bit in this register by writing 1 to the - * associated bit in the Interrupt Cause Set register. - * Write-0 clears a bit. Write-1 has no effect. - * - On CPU Read -- If clear_on_read control bit =TRUE, automatically - * cleared (all bits are cleared). - * When there is a conflict, and on the same clock cycle hardware tries - * to set a bit in the Interrupt Cause register, the specific bit is set - * to ensure the interrupt indication is not lost. - */ - uint32_t cause; - uint32_t rsrvd_0; - /* - * [0x8] Interrupt Cause Set Register - * Writing 1 to a bit in this register sets its corresponding cause bit, - * enabling software to generate a hardware interrupt. Write 0 has no - * effect. - */ - uint32_t cause_set; - uint32_t rsrvd_1; - /* - * [0x10] Interrupt Mask Register - * If Auto-mask control bit =TRUE, automatically set to 1 after MSI-X - * message associate to the associate interrupt bit is sent (AXI write - * acknowledge is received) - */ - uint32_t mask; - uint32_t rsrvd_2; - /* - * [0x18] Interrupt Mask Clear Register - * Used when auto-mask control bit=True. It enables the CPU to clear a - * specific bit, preventing a scenario in which the CPU overrides - * another bit with 1 (old value) that hardware has just cleared to 0. - * Writing 0 to this register clears its corresponding mask bit. Write 1 - * has no effect. - */ - uint32_t mask_clear; - uint32_t rsrvd_3; - /* - * [0x20] Interrupt Status Register - * This register latches the status of the interrupt source. - */ - uint32_t status; - uint32_t rsrvd_4; - /* [0x28] Interrupt Control Register */ - uint32_t control; - uint32_t rsrvd_5; - /* - * [0x30] Interrupt Mask Register - * Each bit in this register masks the corresponding cause bit for - * generating an Abort signal. Its default value is determined by unit - * instantiation. - * Abort = Wire-OR of Cause & !Interrupt_Abort_Mask). - * This register provides an error handling configuration for error - * interrupts. - */ - uint32_t abort_mask; - uint32_t rsrvd_6; - /* - * [0x38] Interrupt Log Register - * Each bit in this register masks the corresponding cause bit for - * capturing the log registers. Its default value is determined by unit - * instantiatio.n - * Log_capture = Wire-OR of Cause & !Interrupt_Log_Mask). - * This register provides an error handling configuration for error - * interrupts. - */ - uint32_t log_mask; - uint32_t rsrvd; -}; - -struct al_pcie_rev3_axi_eq_ovrd_tx_rx_values { - /* [0x0] */ - uint32_t cfg_0; - /* [0x4] */ - uint32_t cfg_1; - /* [0x8] */ - uint32_t cfg_2; - /* [0xc] */ - uint32_t cfg_3; - /* [0x10] */ - uint32_t cfg_4; - /* [0x14] */ - uint32_t cfg_5; - /* [0x18] */ - uint32_t cfg_6; - /* [0x1c] */ - uint32_t cfg_7; - /* [0x20] */ - uint32_t cfg_8; - /* [0x24] */ - uint32_t cfg_9; - /* [0x28] */ - uint32_t cfg_10; - /* [0x2c] */ - uint32_t cfg_11; - uint32_t rsrvd[12]; -}; -struct al_pcie_rev3_axi_dbg_outstading_trans_axi { - /* [0x0] */ - uint32_t read_master_counter; - /* [0x4] */ - uint32_t write_master_counter; - /* [0x8] */ - uint32_t read_slave_counter; -}; -struct al_pcie_revx_axi_device_id { - /* [0x0] */ - uint32_t device_rev_id; -}; -struct al_pcie_revx_axi_power_mang_ovrd_cntl { - /* [0x0] */ - uint32_t cfg_static_nof_elidle; - /* [0x4] */ - uint32_t cfg_l0s_wait_ovrd; - /* [0x8] */ - uint32_t cfg_l12_wait_ovrd; - /* [0xc] */ - uint32_t cfg_l0s_delay_in_p0s; - /* [0x10] */ - uint32_t cfg_l12_delay_in_p12; - /* [0x14] */ - uint32_t cfg_l12_delay_in_p12_clk_rst; - /* [0x18] */ - uint32_t cfg_delay_powerdown_bus; - uint32_t rsrvd; -}; -struct al_pcie_rev3_axi_dbg_outstading_trans_axi_write { - /* [0x0] */ - uint32_t slave_counter; -}; -struct al_pcie_rev3_axi_attr_ovrd { - /* - * [0x0] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t write_msg_ctrl_0; - /* [0x4] in case of message this register set the below attributes */ - uint32_t write_msg_ctrl_1; - /* - * [0x8] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t read_msg_ctrl_0; - /* [0xc] in case of message this register set the below attributes */ - uint32_t read_msg_ctrl_1; - /* [0x10] in case of message this register set the below attributes */ - uint32_t pf_sel; - uint32_t rsrvd[3]; -}; -struct al_pcie_rev3_axi_pf_axi_attr_ovrd { - /* - * [0x0] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_0; - /* [0x4] in case of message this register set the below attributes */ - uint32_t func_ctrl_1; - /* - * [0x8] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_2; - /* - * [0xc] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_3; - /* - * [0x10] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_4; - /* - * [0x14] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_5; - /* - * [0x18] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_6; - /* - * [0x1c] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_7; - /* - * [0x20] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_8; - /* - * [0x24] In case of hit on the io message bar and - * a*_cfg_outbound_msg_no_snoop_n, the message attributes come from this - * register - */ - uint32_t func_ctrl_9; - uint32_t rsrvd[6]; -}; - -struct al_pcie_revx_axi_regs { - uint32_t rsrvd_0[91]; - struct al_pcie_revx_axi_device_id device_id; /* [0x16c] */ -}; - -struct al_pcie_rev1_axi_regs { - struct al_pcie_rev1_2_axi_ctrl ctrl; /* [0x0] */ - struct al_pcie_rev1_axi_ob_ctrl ob_ctrl; /* [0x40] */ - uint32_t rsrvd_0[4]; - struct al_pcie_revx_axi_msg msg; /* [0x90] */ - struct al_pcie_revx_axi_pcie_status pcie_status; /* [0x9c] */ - struct al_pcie_revx_axi_rd_parity rd_parity; /* [0xa0] */ - struct al_pcie_revx_axi_rd_cmpl rd_cmpl; /* [0xa8] */ - struct al_pcie_revx_axi_rd_to rd_to; /* [0xb0] */ - struct al_pcie_revx_axi_wr_cmpl wr_cmpl; /* [0xb8] */ - struct al_pcie_revx_axi_wr_to wr_to; /* [0xc0] */ - struct al_pcie_revx_axi_pcie_global pcie_global; /* [0xc8] */ - struct al_pcie_rev1_2_axi_status status; /* [0xcc] */ - struct al_pcie_rev1_2_axi_conf conf; /* [0xdc] */ - struct al_pcie_revx_axi_parity parity; /* [0xfc] */ - struct al_pcie_revx_axi_pos_logged pos_logged; /* [0x104] */ - struct al_pcie_revx_axi_ordering ordering; /* [0x10c] */ - struct al_pcie_revx_axi_link_down link_down; /* [0x110] */ - struct al_pcie_revx_axi_pre_configuration pre_configuration; /* [0x114] */ - struct al_pcie_revx_axi_init_fc init_fc; /* [0x118] */ - uint32_t rsrvd_1[20]; - struct al_pcie_revx_axi_device_id device_id; /* [0x16c] */ - uint32_t rsrvd_2[36]; - struct al_pcie_revx_axi_int_grp_a_axi int_grp_a; /* [0x200] */ -}; - -struct al_pcie_rev2_axi_regs { - struct al_pcie_rev1_2_axi_ctrl ctrl; /* [0x0] */ - struct al_pcie_rev2_axi_ob_ctrl ob_ctrl; /* [0x40] */ - uint32_t rsrvd_0[4]; - struct al_pcie_revx_axi_msg msg; /* [0x90] */ - struct al_pcie_revx_axi_pcie_status pcie_status; /* [0x9c] */ - struct al_pcie_revx_axi_rd_parity rd_parity; /* [0xa0] */ - struct al_pcie_revx_axi_rd_cmpl rd_cmpl; /* [0xa8] */ - struct al_pcie_revx_axi_rd_to rd_to; /* [0xb0] */ - struct al_pcie_revx_axi_wr_cmpl wr_cmpl; /* [0xb8] */ - struct al_pcie_revx_axi_wr_to wr_to; /* [0xc0] */ - struct al_pcie_revx_axi_pcie_global pcie_global; /* [0xc8] */ - struct al_pcie_rev1_2_axi_status status; /* [0xcc] */ - struct al_pcie_rev1_2_axi_conf conf; /* [0xdc] */ - struct al_pcie_revx_axi_parity parity; /* [0xfc] */ - struct al_pcie_revx_axi_pos_logged pos_logged; /* [0x104] */ - struct al_pcie_revx_axi_ordering ordering; /* [0x10c] */ - struct al_pcie_revx_axi_link_down link_down; /* [0x110] */ - struct al_pcie_revx_axi_pre_configuration pre_configuration; /* [0x114] */ - struct al_pcie_revx_axi_init_fc init_fc; /* [0x118] */ - uint32_t rsrvd_1[20]; - struct al_pcie_revx_axi_device_id device_id; /* [0x16c] */ - uint32_t rsrvd_2[36]; - struct al_pcie_revx_axi_int_grp_a_axi int_grp_a; /* [0x200] */ -}; - -struct al_pcie_rev3_axi_regs { - struct al_pcie_rev3_axi_ctrl ctrl; /* [0x0] */ - struct al_pcie_rev3_axi_ob_ctrl ob_ctrl;/* [0x30] */ - struct al_pcie_revx_axi_msg msg; /* [0x90] */ - struct al_pcie_revx_axi_pcie_status pcie_status; /* [0x9c] */ - struct al_pcie_revx_axi_rd_parity rd_parity; /* [0xa0] */ - struct al_pcie_revx_axi_rd_cmpl rd_cmpl; /* [0xa8] */ - struct al_pcie_revx_axi_rd_to rd_to; /* [0xb0] */ - struct al_pcie_revx_axi_wr_cmpl wr_cmpl; /* [0xb8] */ - struct al_pcie_revx_axi_wr_to wr_to; /* [0xc0] */ - struct al_pcie_revx_axi_pcie_global pcie_global; /* [0xc8] */ - uint32_t rsrvd_0; - struct al_pcie_revx_axi_parity parity; /* [0xd0] */ - struct al_pcie_revx_axi_pos_logged pos_logged; /* [0xd8] */ - struct al_pcie_revx_axi_ordering ordering; /* [0xe0] */ - struct al_pcie_revx_axi_link_down link_down; /* [0xe4] */ - struct al_pcie_revx_axi_pre_configuration pre_configuration;/* [0xe8] */ - struct al_pcie_revx_axi_init_fc init_fc; /* [0xec] */ - uint32_t rsrvd_1[4]; - struct al_pcie_rev3_axi_eq_ovrd_tx_rx_values eq_ovrd_tx_rx_values;/* [0x100] */ - struct al_pcie_rev3_axi_dbg_outstading_trans_axi dbg_outstading_trans_axi;/* [0x160] */ - struct al_pcie_revx_axi_device_id device_id; /* [0x16c] */ - struct al_pcie_revx_axi_power_mang_ovrd_cntl power_mang_ovrd_cntl;/* [0x170] */ - struct al_pcie_rev3_axi_dbg_outstading_trans_axi_write dbg_outstading_trans_axi_write;/* [0x190] */ - uint32_t rsrvd_2[3]; - struct al_pcie_rev3_axi_attr_ovrd axi_attr_ovrd; /* [0x1a0] */ - struct al_pcie_rev3_axi_pf_axi_attr_ovrd pf_axi_attr_ovrd[REV3_MAX_NUM_OF_PFS];/* [0x1c0] */ - uint32_t rsrvd_3[64]; - struct al_pcie_rev3_axi_status status; /* [0x3c0] */ - struct al_pcie_rev3_axi_conf conf; /* [0x400] */ - uint32_t rsrvd_4[32]; - struct al_pcie_revx_axi_msg_attr_axuser_table msg_attr_axuser_table; /* [0x500] */ - uint32_t rsrvd_5[191]; - struct al_pcie_revx_axi_int_grp_a_axi int_grp_a; /* [0x800] */ -}; - -/* -* Registers Fields -*/ - -/**** Device ID register ****/ -#define PCIE_AXI_DEVICE_ID_REG_DEV_ID_MASK AL_FIELD_MASK(31, 16) -#define PCIE_AXI_DEVICE_ID_REG_DEV_ID_SHIFT 16 -#define PCIE_AXI_DEVICE_ID_REG_DEV_ID_X4 (0 << PCIE_AXI_DEVICE_ID_REG_DEV_ID_SHIFT) -#define PCIE_AXI_DEVICE_ID_REG_DEV_ID_X8 (2 << PCIE_AXI_DEVICE_ID_REG_DEV_ID_SHIFT) -#define PCIE_AXI_DEVICE_ID_REG_REV_ID_MASK AL_FIELD_MASK(15, 0) -#define PCIE_AXI_DEVICE_ID_REG_REV_ID_SHIFT 0 - -/**** Global register ****/ -/* - * Not in use. - * Disable completion after inbound posted ordering enforcement to AXI bridge. - */ -#define PCIE_AXI_CTRL_GLOBAL_CPL_AFTER_P_ORDER_DIS (1 << 0) -/* - * Not in use. - * Enforce completion after write ordering on AXI bridge. Only for CPU read - * requests. - */ -#define PCIE_AXI_CTRL_GLOBAL_CPU_CPL_ONLY_EN (1 << 1) -/* When linked down, map all transactions to PCIe to DEC ERR. */ -#define PCIE_AXI_CTRL_GLOBAL_BLOCK_PCIE_SLAVE_EN (1 << 2) -/* - * Wait for the NIC to flush before enabling reset to the PCIe core, on a link - * down event. - */ -#define PCIE_AXI_CTRL_GLOBAL_WAIT_SLV_FLUSH_EN (1 << 3) -/* - * When the BME is cleared and this bit is set, it causes all transactions that - * do not get to the PCIe to be returned with DECERR. - */ -#define PCIE_REV1_2_AXI_CTRL_GLOBAL_MEM_BAR_MAP_TO_ERR (1 << 4) -#define PCIE_REV3_AXI_CTRL_GLOBAL_MEM_BAR_MAP_TO_ERR_MASK 0x00000FF0 -#define PCIE_REV3_AXI_CTRL_GLOBAL_MEM_BAR_MAP_TO_ERR_SHIFT 4 -/* - * Wait for the DBI port (the port that enables access to the internal PCIe core - * registers) to flush before enabling reset to the PCIe core on link down - * event. - */ -#define PCIE_REV1_2_AXI_CTRL_GLOBAL_WAIT_DBI_FLUSH_EN (1 << 5) -#define PCIE_REV3_AXI_CTRL_GLOBAL_WAIT_DBI_FLUSH_EN (1 << 12) -/* Reserved. Read undefined; must read as zeros. */ -#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_FLUSH_DBI_AXI (1 << 13) -/* Reserved. Read undefined; must read as zeros. */ -#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_HOLD_LNKDWN_RESET_SW (1 << 14) -/* Reserved. Read undefined; must read as zeros. */ -#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_MASK_CORECLK_ACT_CLK_RST (1 << 15) -/* Reserved. Read undefined; must read as zeros. */ -#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_MASK_RXELECIDLE_CLK_RST (1 << 16) -/* Reserved. Read undefined; must read as zeros. */ -#define PCIE_REV3_AXI_CTRL_GLOBAL_CFG_ALLOW_NONSTICKY_RESET_WHEN_LNKDOWN_CLK_RST (1 << 17) - -/* - * When set, adds parity on the write and read address channels, and write data - * channel. - */ -#define PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR (1 << 16) -#define PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_MSTR (1 << 18) -/* When set, enables parity check on the read data. */ -#define PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD (1 << 17) -#define PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_RD (1 << 19) -/* - * When set, adds parity on the RD data channel. - */ -#define PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV (1 << 18) -#define PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_CALC_EN_SLV (1 << 20) -/* - * When set, enables parity check on the write data. - */ -#define PCIE_REV1_2_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR (1 << 19) -#define PCIE_REV3_AXI_CTRL_GLOBAL_PARITY_ERR_EN_WR (1 << 21) -/* - * When set, error track for timeout and parity is disabled, i.e., the logged - * address for parity/timeout/cmpl errors on the AXI master port is not valid, - * and timeout and completion errors check are disabled. - */ -#define PCIE_REV1_2_AXI_CTRL_GLOBAL_ERROR_TRACK_DIS (1 << 20) -#define PCIE_REV3_AXI_CTRL_GLOBAL_ERROR_TRACK_DIS (1 << 22) - -/**** Master_Arctl register ****/ -/* override arcache */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_OVR_ARCACHE (1 << 0) -/* arache value */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_ARACHE_VA_MASK 0x0000001E -#define PCIE_AXI_CTRL_MASTER_ARCTL_ARACHE_VA_SHIFT 1 -/* arprot override */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_OVR (1 << 5) -/* arprot value */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_VALUE_MASK 0x000001C0 -#define PCIE_AXI_CTRL_MASTER_ARCTL_ARPROT_VALUE_SHIFT 6 -/* vmid val */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_VMID_VAL_MASK 0x01FFFE00 -#define PCIE_AXI_CTRL_MASTER_ARCTL_VMID_VAL_SHIFT 9 -/* IPA value */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_IPA_VAL (1 << 25) -/* overide snoop inidcation, if not set take it from mstr_armisc ... */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_OVR_SNOOP (1 << 26) -/* -snoop indication value when override */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_SNOOP (1 << 27) -/* -arqos value */ -#define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_MASK 0xF0000000 -#define PCIE_AXI_CTRL_MASTER_ARCTL_ARQOS_SHIFT 28 - -/**** Master_Awctl register ****/ -/* override arcache */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_OVR_ARCACHE (1 << 0) -/* awache value */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_AWACHE_VA_MASK 0x0000001E -#define PCIE_AXI_CTRL_MASTER_AWCTL_AWACHE_VA_SHIFT 1 -/* awprot override */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_OVR (1 << 5) -/* awprot value */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_VALUE_MASK 0x000001C0 -#define PCIE_AXI_CTRL_MASTER_AWCTL_AWPROT_VALUE_SHIFT 6 -/* vmid val */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_VMID_VAL_MASK 0x01FFFE00 -#define PCIE_AXI_CTRL_MASTER_AWCTL_VMID_VAL_SHIFT 9 -/* IPA value */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_IPA_VAL (1 << 25) -/* overide snoop inidcation, if not set take it from mstr_armisc ... */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_OVR_SNOOP (1 << 26) -/* -snoop indication value when override */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_SNOOP (1 << 27) -/* -awqos value */ -#define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_MASK 0xF0000000 -#define PCIE_AXI_CTRL_MASTER_AWCTL_AWQOS_SHIFT 28 - -/**** slv_ctl register ****/ -#define PCIE_AXI_CTRL_SLV_CTRL_IO_BAR_EN (1 << 6) - -/**** Cfg_Target_Bus register ****/ -/* - * Defines which MSBs to complete the number of the bust that arrived from ECAM. - * If set to 0, take the bit from the ECAM bar, otherwise from the busnum of - * this register. - * The LSB for the bus number comes on the addr[*:20]. - */ -#define PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_MASK 0x000000FF -#define PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_MASK_SHIFT 0 -/* Target bus number for outbound configuration type0 and type1 access */ -#define PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_MASK 0x0000FF00 -#define PCIE_AXI_MISC_OB_CTRL_CFG_TARGET_BUS_BUSNUM_SHIFT 8 - -/**** Cfg_Control register ****/ -/* Primary bus number */ -#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_PBUS_MASK 0x000000FF -#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_PBUS_SHIFT 0 -/* - * - * Subordinate bus number - */ -#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_MASK 0x0000FF00 -#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SUBBUS_SHIFT 8 -/* Secondary bus nnumber */ -#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_MASK 0x00FF0000 -#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_SEC_BUS_SHIFT 16 -/* Enable outbound configuration access through iATU. */ -#define PCIE_AXI_MISC_OB_CTRL_CFG_CONTROL_IATU_EN (1 << 31) - -/**** IO_Start_H register ****/ -/* - * - * Outbound ATIU I/O start address high - */ -#define PCIE_AXI_MISC_OB_CTRL_IO_START_H_ADDR_MASK 0x000003FF -#define PCIE_AXI_MISC_OB_CTRL_IO_START_H_ADDR_SHIFT 0 - -/**** IO_Limit_H register ****/ -/* - * - * Outbound ATIU I/O limit address high - */ -#define PCIE_AXI_MISC_OB_CTRL_IO_LIMIT_H_ADDR_MASK 0x000003FF -#define PCIE_AXI_MISC_OB_CTRL_IO_LIMIT_H_ADDR_SHIFT 0 - -/**** Msg_Start_H register ****/ -/* - * - * Outbound ATIU msg-no-data start address high - */ -#define PCIE_AXI_MISC_OB_CTRL_MSG_START_H_ADDR_MASK 0x000003FF -#define PCIE_AXI_MISC_OB_CTRL_MSG_START_H_ADDR_SHIFT 0 - -/**** Msg_Limit_H register ****/ -/* - * - * Outbound ATIU msg-no-data limit address high - */ -#define PCIE_AXI_MISC_OB_CTRL_MSG_LIMIT_H_ADDR_MASK 0x000003FF -#define PCIE_AXI_MISC_OB_CTRL_MSG_LIMIT_H_ADDR_SHIFT 0 - -/**** vmid_reg_ovrd register ****/ -/* - * select if to take the value from register or from address[63:48]: - * 1'b1: register value. - * 1'b0: from address[63:48] - */ -#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_SEL_MASK 0x0000FFFF -#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_SEL_SHIFT 0 -/* vmid override value. */ -#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_VALUE_MASK 0xFFFF0000 -#define PCIE_AXI_MISC_OB_CTRL_VMID_REG_OVRD_VALUE_SHIFT 16 - -/**** addr_size_replace register ****/ -/* - * Size in bits to replace from bit [63:64-N], when equal zero no replace is - * done. - */ -#define PCIE_AXI_MISC_OB_CTRL_ADDR_SIZE_REPLACE_VALUE_MASK 0x0000FFFF -#define PCIE_AXI_MISC_OB_CTRL_ADDR_SIZE_REPLACE_VALUE_SHIFT 0 -/* Reserved. */ -#define PCIE_AXI_MISC_OB_CTRL_ADDR_SIZE_REPLACE_RSRVD_MASK 0xFFFF0000 -#define PCIE_AXI_MISC_OB_CTRL_ADDR_SIZE_REPLACE_RSRVD_SHIFT 16 - -/**** type register ****/ -/* Type of message */ -#define PCIE_AXI_MISC_MSG_TYPE_TYPE_MASK 0x00FFFFFF -#define PCIE_AXI_MISC_MSG_TYPE_TYPE_SHIFT 0 -/* Reserved */ -#define PCIE_AXI_MISC_MSG_TYPE_RSRVD_MASK 0xFF000000 -#define PCIE_AXI_MISC_MSG_TYPE_RSRVD_SHIFT 24 - -/**** debug register ****/ -/* Causes ACI PCIe reset, including ,master/slave/DBI (registers). */ -#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_AXI_BRIDGE_RESET (1 << 0) -/* - * Causes reset of the entire PCIe core (including the AXI bridge). - * When set, the software must not address the PCI core (through the MEM space - * and REG space). - */ -#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_CORE_RESET (1 << 1) -/* - * Indicates that the SB is empty from the request to the PCIe (not including - * registers). - */ -#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_SB_FLUSH_OB_STATUS (1 << 2) -/* MAP and transaction to the PCIe core to ERROR. */ -#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_SB_MAP_TO_ERR (1 << 3) -/* Indicates that the pcie_core clock is gated off */ -#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_CORE_CLK_GATE_OFF (1 << 4) -/* Reserved */ -#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_RSRVD_MASK 0xFFFFFFE0 -#define PCIE_AXI_MISC_PCIE_STATUS_DEBUG_RSRVD_SHIFT 5 - -/**** conf register ****/ -/* - * Device Type - * Indicates the specific type of this PCI Express Function. It is also used to - * set the - * Device/Port Type field. - * - * 4'b0000: PCI Express Endpoint - * 4'b0001: Legacy PCI Express Endpoint - * 4'b0100: Root Port of PCI Express Root Complex - * - * Must be programmed before link training sequence, according to the reset - * strap. - * Change this register should be when the pci_exist (in the PBS regfile) is - * zero. - */ -#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_MASK 0x0000000F -#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_SHIFT 0 -/* - * [i] - Lane i active - * Change this register should be when the pci_exist (in the PBS regfile) is - * zero. - */ -#define PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK 0x000000F0 -#define PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_RESERVED_MASK 0xFFFFFF00 -#define PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_RESERVED_SHIFT 8 -#define PCIE_REVX_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_SHIFT 4 -#define PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_NOF_ACT_LANES_MASK 0x000FFFF0 -#define PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_RESERVED_MASK 0xFFF00000 -#define PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_RESERVED_SHIFT 20 - -#define PCIE_REV1_2_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN 0x100 -#define PCIE_REV3_AXI_MISC_PCIE_GLOBAL_CONF_MEM_SHUTDOWN 0x100000 - -/**** laneX register ****/ -#define PCIE_AXI_STATUS_LANE_IS_RESET AL_BIT(13) -#define PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_MASK AL_FIELD_MASK(2, 0) -#define PCIE_AXI_STATUS_LANE_REQUESTED_SPEED_SHIFT 0 - -/**** zero_laneX register ****/ -/* phy_mac_local_fs */ -#define PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_MASK 0x0000003f -#define PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_FS_SHIFT 0 -/* phy_mac_local_lf */ -#define PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_MASK 0x00000fc0 -#define PCIE_AXI_MISC_ZERO_LANEX_PHY_MAC_LOCAL_LF_SHIFT 6 - -/**** en_axi register ****/ -/* u4_ram2p */ -#define PCIE_AXI_PARITY_EN_AXI_U4_RAM2P AL_BIT(1) - -/**** pos_cntl register ****/ -/* Disables POS. */ -#define PCIE_AXI_POS_ORDER_AXI_POS_BYPASS (1 << 0) -/* Clear the POS data structure. */ -#define PCIE_AXI_POS_ORDER_AXI_POS_CLEAR (1 << 1) -/* Read push all write. */ -#define PCIE_AXI_POS_ORDER_AXI_POS_RSO_ENABLE (1 << 2) -/* - * Causes the PCIe core to wait for all the BRESPs before issuing a read - * request. - */ -#define PCIE_AXI_POS_ORDER_AXI_DW_RD_FLUSH_WR (1 << 3) -/* - * When set, to 1'b1 supports interleaving data return from the PCIe core. Valid - * only when cfg_bypass_cmpl_after_write_fix is set. - */ -#define PCIE_AXI_POS_ORDER_RD_CMPL_AFTER_WR_SUPPORT_RD_INTERLV (1 << 4) -/* When set, to 1'b1 disables read completion after write ordering. */ -#define PCIE_AXI_POS_ORDER_BYPASS_CMPL_AFTER_WR_FIX (1 << 5) -/* - * When set, disables EP mode read cmpl on the master port push slave writes, - * when each read response from the master is not interleaved. - */ -#define PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_DIS (1 << 6) -/* When set, disables EP mode read cmpl on the master port push slave writes. */ -#define PCIE_AXI_POS_ORDER_EP_CMPL_AFTER_WR_SUPPORT_INTERLV_DIS (1 << 7) -/* should be zero */ -#define PCIE_AXI_POS_ORDER_9_8 AL_FIELD_MASK(9, 8) -/* Give the segmentation buffer not to wait for P writes to end in the AXI - * bridge before releasing the CMPL. - */ -#define PCIE_AXI_POS_ORDER_SEGMENT_BUFFER_DONT_WAIT_FOR_P_WRITES AL_BIT(10) -/* should be zero */ -#define PCIE_AXI_POS_ORDER_11 AL_BIT(11) -/** - * When set cause pcie core to send ready in the middle of the read data - * burst returning from the DRAM to the PCIe core - */ -#define PCIE_AXI_POS_ORDER_SEND_READY_ON_READ_DATA_BURST AL_BIT(12) -/* When set disable the ATS CAP. */ -#define PCIE_AXI_CORE_SETUP_ATS_CAP_DIS AL_BIT(13) -/* When set disable D3/D2/D1 PME support */ -#define PCIE_AXI_POS_ORDER_DISABLE_DX_PME AL_BIT(14) -/* When set enable nonsticky reset when linkdown hot reset */ -#define PCIE_AXI_POS_ORDER_ENABLE_NONSTICKY_RESET_ON_HOT_RESET AL_BIT(15) -/* When set, terminate message with data as UR request */ -#define PCIE_AXI_TERMINATE_DATA_MSG_AS_UR_REQ AL_BIT(16) - -/**** pcie_core_setup register ****/ -/* - * This Value delay the rate change to the serdes, until the EIOS is sent by the - * serdes. Should be program before the pcie_exist, is asserted. - */ -#define PCIE_AXI_CORE_SETUP_DELAY_MAC_PHY_RATE_MASK 0x000000FF -#define PCIE_AXI_CORE_SETUP_DELAY_MAC_PHY_RATE_SHIFT 0 -/* - * Limit the number of outstanding AXI reads that the PCIe core can get. Should - * be program before the pcie_exist, is asserted. - */ -#define PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_MASK 0x0000FF00 -#define PCIE_AXI_CORE_SETUP_NOF_READS_ONSLAVE_INTRF_PCIE_CORE_SHIFT 8 -/* Enable the sriov feature. */ -#define PCIE_AXI_REV1_2_CORE_SETUP_SRIOV_ENABLE AL_BIT(16) -/* not in use */ -#define PCIE_AXI_REV3_CORE_SETUP_NOT_IN_USE (1 << 16) -/* Reserved. Read undefined; must read as zeros. */ -#define PCIE_AXI_REV3_CORE_SETUP_CFG_DELAY_AFTER_PCIE_EXIST_MASK 0x0FFE0000 -#define PCIE_AXI_REV3_CORE_SETUP_CFG_DELAY_AFTER_PCIE_EXIST_SHIFT 17 - -/**** cfg register ****/ -/* This value set the possible out standing headers writes (post ... */ -#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_MASK 0x0000007F -#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_P_HDR_SHIFT 0 -/* This value set the possible out standing headers reads (non-p ... */ -#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_MASK 0x00003F80 -#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_NP_HDR_SHIFT 7 -/* This value set the possible out standing headers CMPLs , the ... */ -#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_MASK 0x001FC000 -#define PCIE_AXI_REV1_2_INIT_FC_CFG_NOF_CPL_HDR_SHIFT 14 - -#define PCIE_AXI_REV1_2_INIT_FC_CFG_RSRVD_MASK 0xFFE00000 -#define PCIE_AXI_REV1_2_INIT_FC_CFG_RSRVD_SHIFT 21 - -/* This value set the possible out standing headers writes (post ... */ -#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_MASK 0x000001FF -#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_P_HDR_SHIFT 0 -/* This value set the possible out standing headers reads (non-p ... */ -#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_MASK 0x0003FE00 -#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_NP_HDR_SHIFT 9 -/* This value set the possible out standing headers CMPLs , the ... */ -#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_MASK 0x07FC0000 -#define PCIE_AXI_REV3_INIT_FC_CFG_NOF_CPL_HDR_SHIFT 18 - /* - * [27] cfg_cpl_p_rr: do round robin on the SB output btw Posted and CPL. - * [28] cfg_np_pass_p_rr, in case RR between CPL AND P, allow to pass NP in case - * p is empty. - * [29] cfg_np_part_of_rr_arb: NP also is a part of the round robin arbiter. - */ -#define PCIE_AXI_REV3_INIT_FC_CFG_RSRVD_MASK 0xF8000000 -#define PCIE_AXI_REV3_INIT_FC_CFG_RSRVD_SHIFT 27 - -/**** write_msg_ctrl_0 register ****/ -/* - * choose if 17 in the AXUSER indicate message hint (1'b1) or no snoop - * indication (1'b0) - */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_OUTBOUND_MSG_NO_SNOOP_N (1 << 0) -/* this bit define if the message is with data or without */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_WITH_DATA (1 << 1) -/* message code for message with data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_CODE_DATA_MASK 0x000003FC -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_CODE_DATA_SHIFT 2 -/* message code for message without data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_CODE_MASK 0x0003FC00 -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_CODE_SHIFT 10 -/* message ST value */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_ST_MASK 0x03FC0000 -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_ST_SHIFT 18 -/* message NO-SNOOP */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_NO_SNOOP (1 << 26) -/* message TH bit */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_TH (1 << 27) -/* message PH bits */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_PH_MASK 0x30000000 -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_AW_CFG_MSG_PH_SHIFT 28 -/* Rsrvd */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_RSRVD_MASK 0xC0000000 -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_0_RSRVD_SHIFT 30 - -/**** write_msg_ctrl_1 register ****/ -/* message type */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MISC_MSG_TYPE_VALUE_MASK 0x0000001F -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MISC_MSG_TYPE_VALUE_SHIFT 0 -/* this bit define if the message is with data or without */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_TYPE_VALUE_MASK 0x000003E0 -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_TYPE_VALUE_SHIFT 5 -/* override axi size for message with no data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_NO_DATA_AXI_SIZE_OVRD (1 << 10) -/* override the AXI size to the pcie core for message with no data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_NO_DATA_AXI_SIZE_MSG_MASK 0x00003800 -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_NO_DATA_AXI_SIZE_MSG_SHIFT 11 -/* override axi size for message with data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_AXI_SIZE_OVRD (1 << 14) -/* override the AXI size to the pcie core for message with data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_AXI_SIZE_MSG_MASK 0x00038000 -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_AW_CFG_MSG_DATA_AXI_SIZE_MSG_SHIFT 15 -/* Rsrvd */ -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_RSRVD_MASK 0xFFFC0000 -#define PCIE_AXI_AXI_ATTR_OVRD_WR_MSG_CTRL_1_RSRVD_SHIFT 18 - -/**** read_msg_ctrl_0 register ****/ -/* - * choose if 17 in the AXUSER indicate message hint (1'b1) or no snoop - * indication (1'b0) - */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_OUTBOUND_MSG_NO_SNOOP_N (1 << 0) -/* this bit define if the message is with data or without */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_WITH_DATA (1 << 1) -/* message code for message with data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_CODE_DATA_MASK 0x000003FC -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_CODE_DATA_SHIFT 2 -/* message code for message without data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_CODE_MASK 0x0003FC00 -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_CODE_SHIFT 10 -/* message ST value */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_ST_MASK 0x03FC0000 -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_ST_SHIFT 18 -/* message NO-SNOOP */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_NO_SNOOP (1 << 26) -/* message TH bit */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_TH (1 << 27) -/* message PH bits */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_PH_MASK 0x30000000 -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_AR_CFG_MSG_PH_SHIFT 28 -/* Rsrvd */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_RSRVD_MASK 0xC0000000 -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_0_RSRVD_SHIFT 30 - -/**** read_msg_ctrl_1 register ****/ -/* message type */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MISC_MSG_TYPE_VALUE_MASK 0x0000001F -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MISC_MSG_TYPE_VALUE_SHIFT 0 -/* this bit define if the message is with data or without */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_TYPE_VALUE_MASK 0x000003E0 -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_TYPE_VALUE_SHIFT 5 -/* override axi size for message with no data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_NO_DATA_AXI_SIZE_OVRD (1 << 10) -/* override the AXI size to the pcie core for message with no data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_NO_DATA_AXI_SIZE_MSG_MASK 0x00003800 -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_NO_DATA_AXI_SIZE_MSG_SHIFT 11 -/* override axi size for message with data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_AXI_SIZE_OVRD (1 << 14) -/* override the AXI size to the pcie core for message with data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_AXI_SIZE_MSG_MASK 0x00038000 -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_AR_CFG_MSG_DATA_AXI_SIZE_MSG_SHIFT 15 -/* Rsrvd */ -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_RSRVD_MASK 0xFFFC0000 -#define PCIE_AXI_AXI_ATTR_OVRD_READ_MSG_CTRL_1_RSRVD_SHIFT 18 - -/**** pf_sel register ****/ -/* message type */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_AXUSER (1 << 0) -/* this bit define if the message is with data or without */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_OVRD_FROM_REG (1 << 1) -/* override axi size for message with no data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_ADDR_OFFSET_MASK 0x0000003C -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT0_ADDR_OFFSET_SHIFT 2 -/* override the AXI size to the pcie core for message with no data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT0_OVRD (1 << 6) -/* Rsrvd */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_RSRVD_7 (1 << 7) -/* message type */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_AXUSER (1 << 8) -/* this bit define if the message is with data or without */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_OVRD_FROM_REG (1 << 9) -/* override axi size for message with no data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_ADDR_OFFSET_MASK 0x00003C00 -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_PF_BIT1_ADDR_OFFSET_SHIFT 10 -/* override the AXI size to the pcie core for message with no data. */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_CFG_PF_BIT1_OVRD (1 << 14) -/* Rsrvd */ -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_RSRVD_MASK 0xFFFF8000 -#define PCIE_AXI_AXI_ATTR_OVRD_PF_SEL_RSRVD_SHIFT 15 - - /**** func_ctrl_0 register ****/ -/* choose the field from the axuser */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_TH_OVRD_FROM_AXUSER (1 << 0) -/* choose the field from register */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_TH_OVRD_FROM_REG (1 << 1) -/* field offset from the address portions according to the spec */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_TH_ADDR_OFFSET_MASK 0x0000003C -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_TH_ADDR_OFFSET_SHIFT 2 -/* register value override */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_CFG_TH_OVRD (1 << 6) -/* choose the field from the axuser */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_ST_VEC_OVRD_FROM_AXUSER_MASK 0x00007F80 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_ST_VEC_OVRD_FROM_AXUSER_SHIFT 7 -/* choose the field from register */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_ST_VEC_OVRD_FROM_REG_MASK 0x007F8000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_PF_VEC_ST_VEC_OVRD_FROM_REG_SHIFT 15 -/* register value override */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_CFG_ST_VEC_OVRD_MASK 0x7F800000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_CFG_ST_VEC_OVRD_SHIFT 23 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_0_RSRVD (1 << 31) - -/**** func_ctrl_2 register ****/ -/* choose the field from the axuser */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_OVRD_FROM_AXUSER_MASK 0x00000003 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_OVRD_FROM_AXUSER_SHIFT 0 -/* choose the field from register */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_OVRD_FROM_REG_MASK 0x0000000C -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_OVRD_FROM_REG_SHIFT 2 -/* in case the field take from the address, offset field for each bit. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_ADDR_OFFSET_MASK 0x00000FF0 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_PH_VEC_ADDR_OFFSET_SHIFT 4 -/* register value override */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_PH_VEC_OVRD_MASK 0x00003000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_PH_VEC_OVRD_SHIFT 12 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_14_15_MASK 0x0000C000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_14_15_SHIFT 14 -/* choose the field from the axuser */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_AXUSER_MASK 0x00030000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_AXUSER_SHIFT 16 -/* choose the field from register */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_REG_MASK 0x000C0000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_OVRD_FROM_REG_SHIFT 18 -/* in case the field take from the address, offset field for each bit. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_ADDR_OFFSET_MASK 0x0FF00000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_PF_VEC_VMID89_VEC_ADDR_OFFSET_SHIFT 20 -/* register value override */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_VMID89_VEC_OVRD_MASK 0x30000000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_CFG_VMID89_VEC_OVRD_SHIFT 28 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_MASK 0xC0000000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_2_RSRVD_SHIFT 30 - -/**** func_ctrl_3 register ****/ -/* - * When set take the corresponding bit address from register - * pf_vec_mem_addr44_53_ovrd - */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR44_53_SEL_MASK 0x000003FF -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR44_53_SEL_SHIFT 0 -/* override value. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR44_53_OVRD_MASK 0x000FFC00 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR44_53_OVRD_SHIFT 10 -/* - * When set take the corresponding bit address from register - * pf_vec_mem_addr54_63_ovrd - */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR54_63_SEL_MASK 0x3FF00000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_PF_VEC_MEM_ADDR54_63_SEL_SHIFT 20 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_RSRVD_MASK 0xC0000000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_3_RSRVD_SHIFT 30 - -/**** func_ctrl_4 register ****/ -/* When set take the corresponding bit address from vmid value. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_VMID_MASK 0x000003FF -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_SEL_VMID_SHIFT 0 -/* override value. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_OVRD_MASK 0x000FFC00 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_PF_VEC_MEM_ADDR54_63_OVRD_SHIFT 10 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_RSRVD_MASK 0xFFF00000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_4_RSRVD_SHIFT 20 - -/**** func_ctrl_5 register ****/ -/* - * When set take the corresponding bit address [63:44] from - * aw_pf_vec_msg_addr_ovrd - */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_5_AW_PF_VEC_MSG_ADDR_SEL_MASK 0x000FFFFF -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_5_AW_PF_VEC_MSG_ADDR_SEL_SHIFT 0 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_5_RSRVD_MASK 0xFFF00000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_5_RSRVD_SHIFT 20 - -/**** func_ctrl_6 register ****/ -/* override value. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_6_AW_PF_VEC_MSG_ADDR_OVRD_MASK 0x000FFFFF -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_6_AW_PF_VEC_MSG_ADDR_OVRD_SHIFT 0 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_6_RSRVD_MASK 0xFFF00000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_6_RSRVD_SHIFT 20 - -/**** func_ctrl_7 register ****/ -/* - * When set take the corresponding bit address [63:44] from - * ar_pf_vec_msg_addr_ovrd - */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_7_AR_PF_VEC_MSG_ADDR_SEL_MASK 0x000FFFFF -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_7_AR_PF_VEC_MSG_ADDR_SEL_SHIFT 0 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_7_RSRVD_MASK 0xFFF00000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_7_RSRVD_SHIFT 20 - -/**** func_ctrl_8 register ****/ -/* override value. */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_8_AR_PF_VEC_MSG_ADDR_OVRD_MASK 0x000FFFFF -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_8_AR_PF_VEC_MSG_ADDR_OVRD_SHIFT 0 -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_8_RSRVD_MASK 0xFFF00000 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_8_RSRVD_SHIFT 20 - -/**** func_ctrl_9 register ****/ -/* no snoop override */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_PF_VEC_NO_SNOOP_OVRD (1 << 0) -/* no snoop override value */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_PF_VEC_NO_SNOOP_OVRD_VALUE (1 << 1) -/* atu bypass override */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_PF_VEC_ATU_BYPASS_OVRD (1 << 2) -/* atu bypass override value */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_PF_VEC_ATU_BYPASS_OVRD_VALUE (1 << 3) -/* Rsrvd */ -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_RSRVD_MASK 0xFFFFFFF0 -#define PCIE_AXI_PF_AXI_ATTR_OVRD_FUNC_CTRL_9_RSRVD_SHIFT 4 - -/**** entry_vec register ****/ -/* entry0 */ -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_0_MASK 0x0000001F -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_0_SHIFT 0 -/* entry1 */ -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_1_MASK 0x000003E0 -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_1_SHIFT 5 -/* entry2 */ -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_2_MASK 0x00007C00 -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_2_SHIFT 10 -/* entry3 */ -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_3_MASK 0x000F8000 -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_ENTRY_3_SHIFT 15 -/* atu bypass for message "write" */ -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_AW_MSG_ATU_BYPASS (1 << 20) -/* atu bypass for message "read" */ -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_AR_MSG_ATU_BYPASS (1 << 21) -/* Rsrvd */ -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_RSRVD_MASK 0xFFC00000 -#define PCIE_AXI_MSG_ATTR_AXUSER_TABLE_ENTRY_VEC_RSRVD_SHIFT 22 - -/**** int_cause_grp_A_axi register ****/ -/* - * Master Response Composer Lookup Error - * Overflow that occurred in a lookup table of the Outbound responses. This - * indicates that there was a violation for the number of outstanding NP - * requests issued for the Inbound direction. - * Write zero to clear. - */ -#define PCIE_AXI_INT_GRP_A_CAUSE_GM_COMPOSER_LOOKUP_ERR (1 << 0) -/* - * Indicates a PARITY ERROR on the master data read channel. - * Write zero to clear. - */ -#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_DATA_PATH_RD (1 << 2) -/* - * Indicates a PARITY ERROR on the slave addr read channel. - * Write zero to clear. - */ -#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_RD (1 << 3) -/* - * Indicates a PARITY ERROR on the slave addr write channel. - * Write zero to clear. - */ -#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_ADDR_WR (1 << 4) -/* - * Indicates a PARITY ERROR on the slave data write channel. - * Write zero to clear. - */ -#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERR_OUT_DATA_WR (1 << 5) -/* Reserved */ -#define PCIE_AXI_INT_GRP_A_CAUSE_RESERVED_6 (1 << 6) -/* - * Software error: ECAM write request with invalid bus number. - * Write Zero to clear - */ -#define PCIE_AXI_INT_GRP_A_CAUSE_SW_ECAM_ERR_RD (1 << 7) -/* - * Software error: ECAM read request with invalid bus number. - * Write Zero to clear. - */ -#define PCIE_AXI_INT_GRP_A_CAUSE_SW_ECAM_ERR_WR (1 << 8) -/* Indicates an ERROR in the PCIe application cause register. */ -#define PCIE_AXI_INT_GRP_A_CAUSE_PCIE_CORE_INT (1 << 9) -/* - * Whenever the Master AXI finishes writing a message, it sets this bit. - * Whenever the int is cleared, the message information MSG_* regs are no longer - * valid. - */ -#define PCIE_AXI_INT_GRP_A_CAUSE_MSTR_AXI_GETOUT_MSG (1 << 10) -/* Read AXI compilation has ERROR. */ -#define PCIE_AXI_INT_GRP_A_CAUSE_RD_CMPL_ERR (1 << 11) -/* Write AXI compilation has ERROR. */ -#define PCIE_AXI_INT_GRP_A_CAUSE_WR_CMPL_ERR (1 << 12) -/* Read AXI compilation has timed out. */ -#define PCIE_AXI_INT_GRP_A_CAUSE_RD_CMPL_TO (1 << 13) -/* Write AXI compilation has timed out. */ -#define PCIE_AXI_INT_GRP_A_CAUSE_WR_CMPL_TO (1 << 14) -/* Parity error AXI domain */ -#define PCIE_AXI_INT_GRP_A_CAUSE_PARITY_ERROR_AXI (1 << 15) -/* POS error interrupt */ -#define PCIE_AXI_INT_GRP_A_CAUSE_POS_AXI_BRESP (1 << 16) -/* The outstanding write counter become full should never happen */ -#define PCIE_AXI_INT_GRP_A_CAUSE_WRITE_CNT_FULL_ERR (1 << 17) -/* BRESP received before the write counter increment. */ -#define PCIE_AXI_INT_GRP_A_CAUSE_BRESP_BEFORE_WR_CNT_INC_ERR (1 << 18) - -/**** int_control_grp_A_axi register ****/ -/* When Clear_on_Read =1, all bits of the Cause register are cleared on read. */ -#define PCIE_AXI_INT_GRP_A_CTRL_CLEAR_ON_READ (1 << 0) -/* - * (Must be set only when MSIX is enabled.) - * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its - * corresponding bit in the mask register is set, masking future interrupts. - */ -#define PCIE_AXI_INT_GRP_A_CTRL_AUTO_MASK (1 << 1) -/* - * Auto_Clear (RW) - * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared - * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. - */ -#define PCIE_AXI_INT_GRP_A_CTRL_AUTO_CLEAR (1 << 2) -/* - * When set,_on_Posedge =1, the bits in the Interrupt Cause register are set on - * the posedge of the interrupt source, i.e., when interrupt source =1 and - * Interrupt Status = 0. - * When set,_on_Posedge =0, the bits in the Interrupt Cause register are set - * when interrupt source =1. - */ -#define PCIE_AXI_INT_GRP_A_CTRL_SET_ON_POS (1 << 3) -/* - * When Moderation_Reset =1, all Moderation timers associated with the interrupt - * cause bits are cleared to 0, enabling immediate interrupt assertion if any - * unmasked cause bit is set to 1. This bit is self-negated. - */ -#define PCIE_AXI_INT_GRP_A_CTRL_MOD_RST (1 << 4) -/* - * When mask_msi_x =1, no MSI-X from this group is sent. This bit is set to 1 - * when the associate summary bit in this group is used to generate a single - * MSI-X for this group. - */ -#define PCIE_AXI_INT_GRP_A_CTRL_MASK_MSI_X (1 << 5) -/* MSI-X AWID value. Same ID for all cause bits. */ -#define PCIE_AXI_INT_GRP_A_CTRL_AWID_MASK 0x00000F00 -#define PCIE_AXI_INT_GRP_A_CTRL_AWID_SHIFT 8 -/* - * This value determines the interval between interrupts. Writing ZERO disables - * Moderation. - */ -#define PCIE_AXI_INT_GRP_A_CTRL_MOD_INTV_MASK 0x00FF0000 -#define PCIE_AXI_INT_GRP_A_CTRL_MOD_INTV_SHIFT 16 -/* - * This value determines the Moderation_Timer_Clock speed. - * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. - * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. - * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. - */ -#define PCIE_AXI_INT_GRP_A_CTRL_MOD_RES_MASK 0x0F000000 -#define PCIE_AXI_INT_GRP_A_CTRL_MOD_RES_SHIFT 24 - -#ifdef __cplusplus -} -#endif - -#endif /* __AL_HAL_pcie_axi_REG_H */ - -/** @} end of ... group */ diff --git a/sys/arm/annapurna/alpine/hal/al_hal_pcie_interrupts.h b/sys/arm/annapurna/alpine/hal/al_hal_pcie_interrupts.h deleted file mode 100644 index 357971ca63cb..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_pcie_interrupts.h +++ /dev/null @@ -1,271 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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 _AL_HAL_PCIE_INTERRUPTS_H_ -#define _AL_HAL_PCIE_INTERRUPTS_H_ - -#include "al_hal_common.h" -#include "al_hal_pcie.h" -#include "al_hal_iofic.h" - -/** - * @defgroup group_pcie_interrupts PCIe interrupts - * @ingroup grouppcie - * @{ - * The PCIe interrupts HAL can be used to control PCIe unit interrupts. - * There are 5 groups of interrupts: app group A, B, C, D and AXI. - * Only 2 interrupts go from the pcie unit to the GIC: - * 1. Summary for all the int groups (AXI+APP CORE). - * 2. INTA assert/deassert (RC only). - * For the specific GIC interrupt line, please check the architecture reference - * manual. - * The reset mask state of all interrupts is: Masked - * - * @file al_hal_pcie_interrupts.h - * - */ - -/** - * PCIe interrupt groups - */ -enum al_pcie_int_group { - AL_PCIE_INT_GRP_A, - AL_PCIE_INT_GRP_B, - AL_PCIE_INT_GRP_C, /* Rev3 only */ - AL_PCIE_INT_GRP_D, /* Rev3 only */ - AL_PCIE_INT_GRP_AXI_A, -}; - -/** - * App group A interrupts mask - don't change - * All interrupts not listed below should be masked - */ -enum al_pcie_app_int_grp_a { - /** [RC only] Deassert_INTD received */ - AL_PCIE_APP_INT_DEASSERT_INTD = AL_BIT(0), - /** [RC only] Deassert_INTC received */ - AL_PCIE_APP_INT_DEASSERT_INTC = AL_BIT(1), - /** [RC only] Deassert_INTB received */ - AL_PCIE_APP_INT_DEASSERT_INTB = AL_BIT(2), - /** - * [RC only] Deassert_INTA received - there's a didcated GIC interrupt - * line that reflects the status of ASSERT/DEASSERT of INTA - */ - AL_PCIE_APP_INT_DEASSERT_INTA = AL_BIT(3), - /** [RC only] Assert_INTD received */ - AL_PCIE_APP_INT_ASSERT_INTD = AL_BIT(4), - /** [RC only] Assert_INTC received */ - AL_PCIE_APP_INT_ASSERT_INTC = AL_BIT(5), - /** [RC only] Assert_INTB received */ - AL_PCIE_APP_INT_ASSERT_INTB = AL_BIT(6), - /** - * [RC only] Assert_INTA received - there's a didcated GIC interrupt - * line that reflects the status of ASSERT/DEASSERT of INTA - */ - AL_PCIE_APP_INT_ASSERT_INTA = AL_BIT(7), - /** [RC only] MSI Controller Interrupt */ - AL_PCIE_APP_INT_MSI_CNTR_RCV_INT = AL_BIT(8), - /** [EP only] MSI sent grant */ - AL_PCIE_APP_INT_MSI_TRNS_GNT = AL_BIT(9), - /** [RC only] System error detected (ERR_COR, ERR_FATAL, ERR_NONFATAL) */ - AL_PCIE_APP_INT_SYS_ERR_RC = AL_BIT(10), - /** [EP only] Software initiates FLR on a Physical Function */ - AL_PCIE_APP_INT_FLR_PF_ACTIVE = AL_BIT(11), - /** [RC only] Root Error Command register assertion notification */ - AL_PCIE_APP_INT_AER_RC_ERR = AL_BIT(12), - /** [RC only] Root Error Command register assertion notification With MSI or MSIX enabled */ - AL_PCIE_APP_INT_AER_RC_ERR_MSI = AL_BIT(13), - /** [RC only] PME Status bit assertion in the Root Status register With INTA */ - AL_PCIE_APP_INT_PME_INT = AL_BIT(15), - /** [RC only] PME Status bit assertion in the Root Status register With MSI or MSIX enabled */ - AL_PCIE_APP_INT_PME_MSI = AL_BIT(16), - /** [RC/EP] The core assert link down event, whenever the link is going down */ - AL_PCIE_APP_INT_LINK_DOWN = AL_BIT(21), - /** [EP only] When the EP gets a command to shut down, signal the software to block any new TLP. */ - AL_PCIE_APP_INT_PM_XTLH_BLOCK_TLP = AL_BIT(22), - /** [RC/EP] PHY/MAC link up */ - AL_PCIE_APP_INT_XMLH_LINK_UP = AL_BIT(23), - /** [RC/EP] Data link up */ - AL_PCIE_APP_INT_RDLH_LINK_UP = AL_BIT(24), - /** [RC/EP] The LTSSM is in RCVRY_LOCK state. */ - AL_PCIE_APP_INT_LTSSM_RCVRY_STATE = AL_BIT(25), - /** - * [RC/EP] CFG write transaction to the configuration space by the RC peer - * For RC the int/ will be set from DBI write (internal SoC write)] - */ - AL_PCIE_APP_INT_CFG_WR = AL_BIT(26), - /** [EP only] CFG access in EP mode */ - AL_PCIE_APP_INT_CFG_ACCESS = AL_BIT(31), -}; - -/** - * App group B interrupts mask - don't change - * All interrupts not listed below should be masked - */ -enum al_pcie_app_int_grp_b { - /** [RC only] PM_PME Message received */ - AL_PCIE_APP_INT_GRP_B_PM_PME_MSG_RCVD = AL_BIT(0), - /** [RC only] PME_TO_Ack Message received */ - AL_PCIE_APP_INT_GRP_B_PME_TO_ACK_MSG_RCVD = AL_BIT(1), - /** [EP only] PME_Turn_Off Message received */ - AL_PCIE_APP_INT_GRP_B_PME_TURN_OFF_MSG_RCVD = AL_BIT(2), - /** [RC only] ERR_CORR Message received */ - AL_PCIE_APP_INT_GRP_B_CORR_ERR_MSG_RCVD = AL_BIT(3), - /** [RC only] ERR_NONFATAL Message received */ - AL_PCIE_APP_INT_GRP_B_NON_FTL_ERR_MSG_RCVD = AL_BIT(4), - /** [RC only] ERR_FATAL Message received */ - AL_PCIE_APP_INT_GRP_B_FTL_ERR_MSG_RCVD = AL_BIT(5), - /** - * [RC/EP] Vendor Defined Message received - * Asserted when a vevdor message is received (with no data), buffers 2 - * messages only, and latch the headers in registers - */ - AL_PCIE_APP_INT_GRP_B_VNDR_MSG_A_RCVD = AL_BIT(6), - /** - * [RC/EP] Vendor Defined Message received - * Asserted when a vevdor message is received (with no data), buffers 2 - * messages only, and latch the headers in registers - */ - AL_PCIE_APP_INT_GRP_B_VNDR_MSG_B_RCVD = AL_BIT(7), - /** [EP only] Link Autonomous Bandwidth Status is updated */ - AL_PCIE_APP_INT_GRP_B_LNK_BW_UPD = AL_BIT(12), - /** [EP only] Link Equalization Request bit in the Link Status 2 Register has been set */ - AL_PCIE_APP_INT_GRP_B_LNK_EQ_REQ = AL_BIT(13), - /** [RC/EP] OB Vendor message request is granted by the PCIe core */ - AL_PCIE_APP_INT_GRP_B_OB_VNDR_MSG_REQ_GRNT = AL_BIT(14), - /** [RC only] CPL timeout from the PCIe core indiication */ - AL_PCIE_APP_INT_GRP_B_CPL_TO = AL_BIT(15), - /** [RC/EP] Slave Response Composer Lookup Error */ - AL_PCIE_APP_INT_GRP_B_SLV_RESP_COMP_LKUP_ERR = AL_BIT(16), - /** [RC/EP] Parity Error */ - AL_PCIE_APP_INT_GRP_B_PARITY_ERR = AL_BIT(17), - /** [EP only] Speed change request */ - AL_PCIE_APP_INT_GRP_B_SPEED_CHANGE = AL_BIT(31), -}; - -/** - * AXI interrupts mask - don't change - * These are internal errors that can happen on the internal chip interface - * between the PCIe port and the I/O Fabric over the AXI bus. The notion of - * master and slave refer to the PCIe port master interface towards the I/O - * Fabric (i.e. for inbound PCIe writes/reads toward the I/O Fabric), while the - * slave interface refer to the I/O Fabric to PCIe port interface where the - * internal chip DMAs and CPU cluster is initiating transactions. - * All interrupts not listed below should be masked. - */ -enum al_pcie_axi_int { - /** [RC/EP] Master Response Composer Lookup Error */ - AL_PCIE_AXI_INT_MSTR_RESP_COMP_LKUP_ERR = AL_BIT(0), - /** [RC/EP] PARITY ERROR on the master data read channel */ - AL_PCIE_AXI_INT_PARITY_ERR_MSTR_DATA_RD_CHNL = AL_BIT(2), - /** [RC/EP] PARITY ERROR on the slave addr read channel */ - AL_PCIE_AXI_INT_PARITY_ERR_SLV_ADDR_RD_CHNL = AL_BIT(3), - /** [RC/EP] PARITY ERROR on the slave addr write channel */ - AL_PCIE_AXI_INT_PARITY_ERR_SLV_ADDR_WR_CHNL = AL_BIT(4), - /** [RC/EP] PARITY ERROR on the slave data write channel */ - AL_PCIE_AXI_INT_PARITY_ERR_SLV_DATA_WR_CHNL = AL_BIT(5), - /** [RC only] Software error: ECAM write request with invalid bus number */ - AL_PCIE_AXI_INT_ECAM_WR_REQ_INVLD_BUS_NUM = AL_BIT(7), - /** [RC only] Software error: ECAM read request with invalid bus number */ - AL_PCIE_AXI_INT_ECAM_RD_REQ_INVLD_BUS_NUM = AL_BIT(8), - /** [RC/EP] Read AXI completion has ERROR */ - AL_PCIE_AXI_INT_RD_AXI_COMPL_ERR = AL_BIT(11), - /** [RC/EP] Write AXI completion has ERROR */ - AL_PCIE_AXI_INT_WR_AXI_COMPL_ERR = AL_BIT(12), - /** [RC/EP] Read AXI completion has timed out */ - AL_PCIE_AXI_INT_RD_AXI_COMPL_TO = AL_BIT(13), - /** [RC/EP] Write AXI completion has timed out */ - AL_PCIE_AXI_INT_WR_AXI_COMPL_TO = AL_BIT(14), - /** [RC/EP] Parity error AXI domain */ - AL_PCIE_AXI_INT_AXI_DOM_PARITY_ERR = AL_BIT(15), - /** [RC/EP] POS error interrupt */ - AL_PCIE_AXI_INT_POS_ERR = AL_BIT(16), -}; - -/** - * @brief Initialize and configure PCIe controller interrupts - * Doesn't change the mask state of the interrupts - * The reset mask state of all interrupts is: Masked - * - * @param pcie_port pcie port handle - */ -void al_pcie_ints_config(struct al_pcie_port *pcie_port); - -/** - * Unmask PCIe app group interrupts - * @param pcie_port pcie_port pcie port handle - * @param int_group interrupt group - * @param int_mask int_mask interrupts to unmask ('1' to unmask) - */ -void al_pcie_app_int_grp_unmask( - struct al_pcie_port *pcie_port, - enum al_pcie_int_group int_group, - uint32_t int_mask); - -/** - * Mask PCIe app group interrupts - * @param pcie_port pcie_port pcie port handle - * @param int_group interrupt group - * @param int_mask int_mask interrupts to unmask ('1' to mask) - */ -void al_pcie_app_int_grp_mask( - struct al_pcie_port *pcie_port, - enum al_pcie_int_group int_group, - uint32_t int_mask); - -/** - * Clear the PCIe app group interrupt cause - * @param pcie_port pcie port handle - * @param int_group interrupt group - * @param int_cause interrupt cause - */ -void al_pcie_app_int_grp_cause_clear( - struct al_pcie_port *pcie_port, - enum al_pcie_int_group int_group, - uint32_t int_cause); - -/** - * Read PCIe app group interrupt cause - * @param pcie_port pcie port handle - * @param int_group interrupt group - * @return interrupt cause or 0 in case the group is not supported - */ -uint32_t al_pcie_app_int_grp_cause_read( - struct al_pcie_port *pcie_port, - enum al_pcie_int_group int_group); - -#endif -/** @} end of group_pcie_interrupts group */ diff --git a/sys/arm/annapurna/alpine/hal/al_hal_pcie_regs.h b/sys/arm/annapurna/alpine/hal/al_hal_pcie_regs.h deleted file mode 100644 index 15c5735e279f..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_pcie_regs.h +++ /dev/null @@ -1,594 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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 __AL_HAL_PCIE_REGS_H__ -#define __AL_HAL_PCIE_REGS_H__ - -/* Note: Definitions before the includes so axi/wrapper regs sees them */ - -/** Maximum physical functions supported */ -#define REV1_2_MAX_NUM_OF_PFS 1 -#define REV3_MAX_NUM_OF_PFS 4 -#define AL_MAX_NUM_OF_PFS 4 /* the maximum between all Revisions */ - -#include "al_hal_pcie_axi_reg.h" -#ifndef AL_PCIE_EX -#include "al_hal_pcie_w_reg.h" -#else -#include "al_hal_pcie_w_reg_ex.h" -#endif - -/** - * Revision IDs: - * ID_0: SlickRock M0 - * ID_1: SlickRock A0 - * ID_2: PeakRock x4 - * ID_3: PeakRock x8 - */ -#define AL_PCIE_REV_ID_0 0 -#define AL_PCIE_REV_ID_1 1 -#define AL_PCIE_REV_ID_2 2 -#define AL_PCIE_REV_ID_3 3 - -#define AL_PCIE_AXI_REGS_OFFSET 0x0 -#define AL_PCIE_REV_1_2_APP_REGS_OFFSET 0x1000 -#define AL_PCIE_REV_3_APP_REGS_OFFSET 0x2000 -#define AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET 0x2000 -#define AL_PCIE_REV_3_CORE_CONF_BASE_OFFSET 0x10000 - -/** Maximum number of lanes supported */ -#define REV1_2_MAX_NUM_LANES 4 -#define REV3_MAX_NUM_LANES 8 -#define AL_MAX_NUM_OF_LANES 8 /* the maximum between all Revisions */ - -struct al_pcie_core_iatu_regs { - uint32_t index; - uint32_t cr1; - uint32_t cr2; - uint32_t lower_base_addr; - uint32_t upper_base_addr; - uint32_t limit_addr; - uint32_t lower_target_addr; - uint32_t upper_target_addr; - uint32_t cr3; - uint32_t rsrvd[(0x270 - 0x224) >> 2]; -}; - -struct al_pcie_core_port_regs { - uint32_t ack_lat_rply_timer; - uint32_t reserved1[(0x10 - 0x4) >> 2]; - uint32_t port_link_ctrl; - uint32_t reserved2[(0x18 - 0x14) >> 2]; - uint32_t timer_ctrl_max_func_num; - uint32_t filter_mask_reg_1; - uint32_t reserved3[(0x48 - 0x20) >> 2]; - uint32_t vc0_posted_rcv_q_ctrl; - uint32_t vc0_non_posted_rcv_q_ctrl; - uint32_t vc0_comp_rcv_q_ctrl; - uint32_t reserved4[(0x10C - 0x54) >> 2]; - uint32_t gen2_ctrl; - uint32_t reserved5[(0x190 - 0x110) >> 2]; - uint32_t gen3_ctrl; - uint32_t gen3_eq_fs_lf; - uint32_t gen3_eq_preset_to_coef_map; - uint32_t gen3_eq_preset_idx; - uint32_t reserved6; - uint32_t gen3_eq_status; - uint32_t gen3_eq_ctrl; - uint32_t reserved7[(0x1B8 - 0x1AC) >> 2]; - uint32_t pipe_loopback_ctrl; - uint32_t rd_only_wr_en; - uint32_t reserved8[(0x1D0 - 0x1C0) >> 2]; - uint32_t axi_slave_err_resp; - uint32_t reserved9[(0x200 - 0x1D4) >> 2]; - struct al_pcie_core_iatu_regs iatu; - uint32_t reserved10[(0x448 - 0x270) >> 2]; -}; - -struct al_pcie_core_aer_regs { - /* 0x0 - PCI Express Extended Capability Header */ - uint32_t header; - /* 0x4 - Uncorrectable Error Status Register */ - uint32_t uncorr_err_stat; - /* 0x8 - Uncorrectable Error Mask Register */ - uint32_t uncorr_err_mask; - /* 0xc - Uncorrectable Error Severity Register */ - uint32_t uncorr_err_severity; - /* 0x10 - Correctable Error Status Register */ - uint32_t corr_err_stat; - /* 0x14 - Correctable Error Mask Register */ - uint32_t corr_err_mask; - /* 0x18 - Advanced Error Capabilities and Control Register */ - uint32_t cap_and_ctrl; - /* 0x1c - Header Log Registers */ - uint32_t header_log[4]; - /* 0x2c - Root Error Command Register */ - uint32_t root_err_cmd; - /* 0x30 - Root Error Status Register */ - uint32_t root_err_stat; - /* 0x34 - Error Source Identification Register */ - uint32_t err_src_id; -}; - -struct al_pcie_core_reg_space_rev_1_2 { - uint32_t config_header[0x40 >> 2]; - uint32_t pcie_pm_cap_base; - uint32_t reserved1[(0x70 - 0x44) >> 2]; - uint32_t pcie_cap_base; - uint32_t pcie_dev_cap_base; - uint32_t pcie_dev_ctrl_status; - uint32_t pcie_link_cap_base; - uint32_t reserved2[(0xB0 - 0x80) >> 2]; - uint32_t msix_cap_base; - uint32_t reserved3[(0x100 - 0xB4) >> 2]; - struct al_pcie_core_aer_regs aer; - uint32_t reserved4[(0x150 - - (0x100 + - sizeof(struct al_pcie_core_aer_regs))) >> 2]; - uint32_t pcie_sec_ext_cap_base; - uint32_t reserved5[(0x700 - 0x154) >> 2]; - struct al_pcie_core_port_regs port_regs; - uint32_t reserved6[(0x1000 - - (0x700 + - sizeof(struct al_pcie_core_port_regs))) >> 2]; -}; - -struct al_pcie_core_reg_space_rev_3 { - uint32_t config_header[0x40 >> 2]; - uint32_t pcie_pm_cap_base; - uint32_t reserved1[(0x70 - 0x44) >> 2]; - uint32_t pcie_cap_base; - uint32_t pcie_dev_cap_base; - uint32_t pcie_dev_ctrl_status; - uint32_t pcie_link_cap_base; - uint32_t reserved2[(0xB0 - 0x80) >> 2]; - uint32_t msix_cap_base; - uint32_t reserved3[(0x100 - 0xB4) >> 2]; - struct al_pcie_core_aer_regs aer; - uint32_t reserved4[(0x158 - - (0x100 + - sizeof(struct al_pcie_core_aer_regs))) >> 2]; - /* pcie_sec_cap is only applicable for function 0 */ - uint32_t pcie_sec_ext_cap_base; - uint32_t reserved5[(0x178 - 0x15C) >> 2]; - /* tph capability is only applicable for rev3 */ - uint32_t tph_cap_base; - uint32_t reserved6[(0x700 - 0x17C) >> 2]; - /* port_regs is only applicable for function 0 */ - struct al_pcie_core_port_regs port_regs; - uint32_t reserved7[(0x1000 - - (0x700 + - sizeof(struct al_pcie_core_port_regs))) >> 2]; -}; - -struct al_pcie_rev3_core_reg_space { - struct al_pcie_core_reg_space_rev_3 func[REV3_MAX_NUM_OF_PFS]; -}; - -struct al_pcie_core_reg_space { - uint32_t *config_header; - uint32_t *pcie_pm_cap_base; - uint32_t *pcie_cap_base; - uint32_t *pcie_dev_cap_base; - uint32_t *pcie_dev_ctrl_status; - uint32_t *pcie_link_cap_base; - uint32_t *msix_cap_base; - struct al_pcie_core_aer_regs *aer; - uint32_t *pcie_sec_ext_cap_base; - uint32_t *tph_cap_base; -}; - -struct al_pcie_revx_regs { - struct al_pcie_revx_axi_regs __iomem axi; -}; - -struct al_pcie_rev1_regs { - struct al_pcie_rev1_axi_regs __iomem axi; - uint32_t reserved1[(AL_PCIE_REV_1_2_APP_REGS_OFFSET - - (AL_PCIE_AXI_REGS_OFFSET + - sizeof(struct al_pcie_rev1_axi_regs))) >> 2]; - struct al_pcie_rev1_w_regs __iomem app; - uint32_t reserved2[(AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET - - (AL_PCIE_REV_1_2_APP_REGS_OFFSET + - sizeof(struct al_pcie_rev1_w_regs))) >> 2]; - struct al_pcie_core_reg_space_rev_1_2 core_space; -}; - -struct al_pcie_rev2_regs { - struct al_pcie_rev2_axi_regs __iomem axi; - uint32_t reserved1[(AL_PCIE_REV_1_2_APP_REGS_OFFSET - - (AL_PCIE_AXI_REGS_OFFSET + - sizeof(struct al_pcie_rev2_axi_regs))) >> 2]; - struct al_pcie_rev2_w_regs __iomem app; - uint32_t reserved2[(AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET - - (AL_PCIE_REV_1_2_APP_REGS_OFFSET + - sizeof(struct al_pcie_rev2_w_regs))) >> 2]; - struct al_pcie_core_reg_space_rev_1_2 core_space; -}; - -struct al_pcie_rev3_regs { - struct al_pcie_rev3_axi_regs __iomem axi; - uint32_t reserved1[(AL_PCIE_REV_3_APP_REGS_OFFSET - - (AL_PCIE_AXI_REGS_OFFSET + - sizeof(struct al_pcie_rev3_axi_regs))) >> 2]; - struct al_pcie_rev3_w_regs __iomem app; - uint32_t reserved2[(AL_PCIE_REV_3_CORE_CONF_BASE_OFFSET - - (AL_PCIE_REV_3_APP_REGS_OFFSET + - sizeof(struct al_pcie_rev3_w_regs))) >> 2]; - struct al_pcie_rev3_core_reg_space core_space; -}; - -struct al_pcie_axi_ctrl { - uint32_t *global; - uint32_t *master_arctl; - uint32_t *master_awctl; - uint32_t *slv_ctl; -}; - -struct al_pcie_axi_ob_ctrl { - uint32_t *cfg_target_bus; - uint32_t *cfg_control; - uint32_t *io_start_l; - uint32_t *io_start_h; - uint32_t *io_limit_l; - uint32_t *io_limit_h; -}; - -struct al_pcie_axi_pcie_global { - uint32_t *conf; -}; - -struct al_pcie_axi_conf { - uint32_t *zero_lane0; - uint32_t *zero_lane1; - uint32_t *zero_lane2; - uint32_t *zero_lane3; - uint32_t *zero_lane4; - uint32_t *zero_lane5; - uint32_t *zero_lane6; - uint32_t *zero_lane7; -}; - -struct al_pcie_axi_status { - uint32_t *lane[AL_MAX_NUM_OF_LANES]; -}; - -struct al_pcie_axi_parity { - uint32_t *en_axi; -}; - -struct al_pcie_axi_ordering { - uint32_t *pos_cntl; -}; - -struct al_pcie_axi_pre_configuration { - uint32_t *pcie_core_setup; -}; - -struct al_pcie_axi_init_fc { - uint32_t *cfg; -}; - -struct al_pcie_axi_attr_ovrd { - uint32_t *write_msg_ctrl_0; - uint32_t *write_msg_ctrl_1; - uint32_t *pf_sel; -}; - -struct al_pcie_axi_pf_axi_attr_ovrd { - uint32_t *func_ctrl_0; - uint32_t *func_ctrl_1; - uint32_t *func_ctrl_2; - uint32_t *func_ctrl_3; - uint32_t *func_ctrl_4; - uint32_t *func_ctrl_5; - uint32_t *func_ctrl_6; - uint32_t *func_ctrl_7; - uint32_t *func_ctrl_8; - uint32_t *func_ctrl_9; -}; - -struct al_pcie_axi_msg_attr_axuser_table { - uint32_t *entry_vec; -}; - -struct al_pcie_axi_regs { - struct al_pcie_axi_ctrl ctrl; - struct al_pcie_axi_ob_ctrl ob_ctrl; - struct al_pcie_axi_pcie_global pcie_global; - struct al_pcie_axi_conf conf; - struct al_pcie_axi_status status; - struct al_pcie_axi_parity parity; - struct al_pcie_axi_ordering ordering; - struct al_pcie_axi_pre_configuration pre_configuration; - struct al_pcie_axi_init_fc init_fc; - struct al_pcie_revx_axi_int_grp_a_axi *int_grp_a; - /* Rev3 only */ - struct al_pcie_axi_attr_ovrd axi_attr_ovrd; - struct al_pcie_axi_pf_axi_attr_ovrd pf_axi_attr_ovrd[REV3_MAX_NUM_OF_PFS]; - struct al_pcie_axi_msg_attr_axuser_table msg_attr_axuser_table; -}; - -struct al_pcie_w_global_ctrl { - uint32_t *port_init; - uint32_t *pm_control; - uint32_t *events_gen[REV3_MAX_NUM_OF_PFS]; - uint32_t *corr_err_sts_int; - uint32_t *uncorr_err_sts_int; - uint32_t *sris_kp_counter; -}; - -struct al_pcie_w_soc_int { - uint32_t *mask_inta_leg_0; - uint32_t *mask_inta_leg_3; /* Rev 2/3 only */ - uint32_t *mask_msi_leg_0; - uint32_t *mask_msi_leg_3; /* Rev 2/3 only */ -}; -struct al_pcie_w_atu { - uint32_t *in_mask_pair; - uint32_t *out_mask_pair; -}; - -struct al_pcie_w_regs { - struct al_pcie_w_global_ctrl global_ctrl; - struct al_pcie_revx_w_debug *debug; - struct al_pcie_revx_w_ap_user_send_msg *ap_user_send_msg; - struct al_pcie_w_soc_int soc_int[REV3_MAX_NUM_OF_PFS]; - struct al_pcie_revx_w_cntl_gen *ctrl_gen; - struct al_pcie_revx_w_parity *parity; - struct al_pcie_w_atu atu; - struct al_pcie_revx_w_status_per_func *status_per_func[REV3_MAX_NUM_OF_PFS]; - struct al_pcie_revx_w_int_grp *int_grp_a; - struct al_pcie_revx_w_int_grp *int_grp_b; - struct al_pcie_revx_w_int_grp *int_grp_c; - struct al_pcie_revx_w_int_grp *int_grp_d; -}; - -struct al_pcie_regs { - struct al_pcie_axi_regs axi; - struct al_pcie_w_regs app; - struct al_pcie_core_port_regs *port_regs; - struct al_pcie_core_reg_space core_space[REV3_MAX_NUM_OF_PFS]; -}; - -#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP 0 -#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC 4 - -#define PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE AL_BIT(17) -#define PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT 18 -#define PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT 19 -#define PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT 20 -#define PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_MASK AL_FIELD_MASK(12, 8) -#define PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_SHIFT 8 - -#define PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT 9 -#define PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT 16 - -#define PCIE_PORT_GEN3_EQ_LF_SHIFT 0 -#define PCIE_PORT_GEN3_EQ_LF_MASK 0x3f -#define PCIE_PORT_GEN3_EQ_FS_SHIFT 6 -#define PCIE_PORT_GEN3_EQ_FS_MASK (0x3f << PCIE_PORT_GEN3_EQ_FS_SHIFT) - -#define PCIE_PORT_LINK_CTRL_LB_EN_SHIFT 2 -#define PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT 7 -#define PCIE_PORT_LINK_CTRL_LINK_CAPABLE_MASK AL_FIELD_MASK(21, 16) -#define PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT 16 - -#define PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT 31 - -#define PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT 0 - -/** timer_ctrl_max_func_num register - * Max physical function number (for example: 0 for 1PF, 3 for 4PFs) - */ -#define PCIE_PORT_GEN3_MAX_FUNC_NUM AL_FIELD_MASK(7, 0) - -/* filter_mask_reg_1 register */ -/** - * SKP Interval Value. - * The number of symbol times to wait between transmitting SKP ordered sets - */ -#define PCIE_FLT_MASK_SKP_INT_VAL_MASK AL_FIELD_MASK(10, 0) - -/* - * 0: Treat Function MisMatched TLPs as UR - * 1: Treat Function MisMatched TLPs as Supported - */ -#define CX_FLT_MASK_UR_FUNC_MISMATCH AL_BIT(16) - -/* - * 0: Treat CFG type1 TLPs as UR for EP; Supported for RC - * 1: Treat CFG type1 TLPs as Supported for EP; UR for RC - */ -#define CX_FLT_MASK_CFG_TYPE1_RE_AS_UR AL_BIT(19) - -/* - * 0: Enforce requester id match for received CPL TLPs. - * A violation results in cpl_abort, and possibly AER of unexp_cpl_err, - * cpl_rcvd_ur, cpl_rcvd_ca - * 1: Mask requester id match for received CPL TLPs - */ -#define CX_FLT_MASK_CPL_REQID_MATCH AL_BIT(22) - -/* - * 0: Enforce function match for received CPL TLPs. - * A violation results in cpl_abort, and possibly AER of unexp_cpl_err, - * cpl_rcvd_ur, cpl_rcvd_ca - * 1: Mask function match for received CPL TLPs - */ -#define CX_FLT_MASK_CPL_FUNC_MATCH AL_BIT(23) - -/* vc0_posted_rcv_q_ctrl register */ -#define RADM_PQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12) -#define RADM_PQ_HCRD_VC0_SHIFT 12 - -/* vc0_non_posted_rcv_q_ctrl register */ -#define RADM_NPQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12) -#define RADM_NPQ_HCRD_VC0_SHIFT 12 - -/* vc0_comp_rcv_q_ctrl register */ -#define RADM_CPLQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12) -#define RADM_CPLQ_HCRD_VC0_SHIFT 12 - -/**** iATU, Control Register 1 ****/ - -/** - * When the Address and BAR matching logic in the core indicate that a MEM-I/O - * transaction matches a BAR in the function corresponding to this value, then - * address translation proceeds. This check is only performed if the "Function - * Number Match Enable" bit of the "iATU Control 2 Register" is set - */ -#define PCIE_IATU_CR1_FUNC_NUM_MASK AL_FIELD_MASK(24, 20) -#define PCIE_IATU_CR1_FUNC_NUM_SHIFT 20 - -/**** iATU, Control Register 2 ****/ -/** For outbound regions, the Function Number Translation Bypass mode enables - * taking the function number of the translated TLP from the PCIe core - * interface and not from the "Function Number" field of CR1. - * For inbound regions, this bit should be asserted when physical function - * match mode needs to be enabled - */ -#define PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_MASK AL_BIT(19) -#define PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_SHIFT 19 - -/* pcie_dev_ctrl_status register */ -#define PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN AL_BIT(0) -#define PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN AL_BIT(1) -#define PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN AL_BIT(2) -#define PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN AL_BIT(3) - -#define PCIE_PORT_DEV_CTRL_STATUS_MPS_MASK AL_FIELD_MASK(7, 5) -#define PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT 5 -#define PCIE_PORT_DEV_CTRL_STATUS_MPS_VAL_256 (1 << PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT) - -#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_MASK AL_FIELD_MASK(14, 12) -#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_SHIFT 12 -#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_VAL_256 (1 << PCIE_PORT_DEV_CTRL_STATUS_MRRS_SHIFT) - -/****************************************************************************** - * AER registers - ******************************************************************************/ -/* PCI Express Extended Capability ID */ -#define PCIE_AER_CAP_ID_MASK AL_FIELD_MASK(15, 0) -#define PCIE_AER_CAP_ID_SHIFT 0 -#define PCIE_AER_CAP_ID_VAL 1 -/* Capability Version */ -#define PCIE_AER_CAP_VER_MASK AL_FIELD_MASK(19, 16) -#define PCIE_AER_CAP_VER_SHIFT 16 -#define PCIE_AER_CAP_VER_VAL 2 - -/* First Error Pointer */ -#define PCIE_AER_CTRL_STAT_FIRST_ERR_PTR_MASK AL_FIELD_MASK(4, 0) -#define PCIE_AER_CTRL_STAT_FIRST_ERR_PTR_SHIFT 0 -/* ECRC Generation Capability */ -#define PCIE_AER_CTRL_STAT_ECRC_GEN_SUPPORTED AL_BIT(5) -/* ECRC Generation Enable */ -#define PCIE_AER_CTRL_STAT_ECRC_GEN_EN AL_BIT(6) -/* ECRC Check Capable */ -#define PCIE_AER_CTRL_STAT_ECRC_CHK_SUPPORTED AL_BIT(7) -/* ECRC Check Enable */ -#define PCIE_AER_CTRL_STAT_ECRC_CHK_EN AL_BIT(8) - -/* Correctable Error Reporting Enable */ -#define PCIE_AER_ROOT_ERR_CMD_CORR_ERR_RPRT_EN AL_BIT(0) -/* Non-Fatal Error Reporting Enable */ -#define PCIE_AER_ROOT_ERR_CMD_NON_FTL_ERR_RPRT_EN AL_BIT(1) -/* Fatal Error Reporting Enable */ -#define PCIE_AER_ROOT_ERR_CMD_FTL_ERR_RPRT_EN AL_BIT(2) - -/* ERR_COR Received */ -#define PCIE_AER_ROOT_ERR_STAT_CORR_ERR AL_BIT(0) -/* Multiple ERR_COR Received */ -#define PCIE_AER_ROOT_ERR_STAT_CORR_ERR_MULTI AL_BIT(1) -/* ERR_FATAL/NONFATAL Received */ -#define PCIE_AER_ROOT_ERR_STAT_FTL_NON_FTL_ERR AL_BIT(2) -/* Multiple ERR_FATAL/NONFATAL Received */ -#define PCIE_AER_ROOT_ERR_STAT_FTL_NON_FTL_ERR_MULTI AL_BIT(3) -/* First Uncorrectable Fatal */ -#define PCIE_AER_ROOT_ERR_STAT_FIRST_UNCORR_FTL AL_BIT(4) -/* Non-Fatal Error Messages Received */ -#define PCIE_AER_ROOT_ERR_STAT_NON_FTL_RCVD AL_BIT(5) -/* Fatal Error Messages Received */ -#define PCIE_AER_ROOT_ERR_STAT_FTL_RCVD AL_BIT(6) -/* Advanced Error Interrupt Message Number */ -#define PCIE_AER_ROOT_ERR_STAT_ERR_INT_MSG_NUM_MASK AL_FIELD_MASK(31, 27) -#define PCIE_AER_ROOT_ERR_STAT_ERR_INT_MSG_NUM_SHIFT 27 - -/* ERR_COR Source Identification */ -#define PCIE_AER_SRC_ID_CORR_ERR_MASK AL_FIELD_MASK(15, 0) -#define PCIE_AER_SRC_ID_CORR_ERR_SHIFT 0 -/* ERR_FATAL/NONFATAL Source Identification */ -#define PCIE_AER_SRC_ID_CORR_ERR_FTL_NON_FTL_MASK AL_FIELD_MASK(31, 16) -#define PCIE_AER_SRC_ID_CORR_ERR_FTL_NON_FTL_SHIFT 16 - -/* AER message */ -#define PCIE_AER_MSG_REQID_MASK AL_FIELD_MASK(31, 16) -#define PCIE_AER_MSG_REQID_SHIFT 16 -#define PCIE_AER_MSG_TYPE_MASK AL_FIELD_MASK(15, 8) -#define PCIE_AER_MSG_TYPE_SHIFT 8 -#define PCIE_AER_MSG_RESERVED AL_FIELD_MASK(7, 1) -#define PCIE_AER_MSG_VALID AL_BIT(0) -/* AER message ack */ -#define PCIE_AER_MSG_ACK AL_BIT(0) -/* AER errors definitions */ -#define AL_PCIE_AER_TYPE_CORR (0x30) -#define AL_PCIE_AER_TYPE_NON_FATAL (0x31) -#define AL_PCIE_AER_TYPE_FATAL (0x33) -/* Requester ID Bus */ -#define AL_PCIE_REQID_BUS_NUM_SHIFT (8) - -/****************************************************************************** - * TPH registers - ******************************************************************************/ -#define PCIE_TPH_NEXT_POINTER AL_FIELD_MASK(31, 20) - -/****************************************************************************** - * Config Header registers - ******************************************************************************/ -/** - * see BIST_HEADER_TYPE_LATENCY_CACHE_LINE_SIZE_REG in core spec - * Note: valid only for EP mode - */ -#define PCIE_BIST_HEADER_TYPE_BASE 0xc -#define PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK AL_BIT(23) - -/****************************************************************************** - * SRIS KP counters default values - ******************************************************************************/ -#define PCIE_SRIS_KP_COUNTER_GEN3_DEFAULT_VAL (0x24) -#define PCIE_SRIS_KP_COUNTER_GEN21_DEFAULT_VAL (0x4B) - -#endif diff --git a/sys/arm/annapurna/alpine/hal/al_hal_pcie_w_reg.h b/sys/arm/annapurna/alpine/hal/al_hal_pcie_w_reg.h deleted file mode 100644 index 44e9d952655d..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_pcie_w_reg.h +++ /dev/null @@ -1,1505 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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 __AL_HAL_PCIE_W_REG_H__ -#define __AL_HAL_PCIE_W_REG_H__ - -#ifdef __cplusplus -extern "C" { -#endif -/* -* Unit Registers -*/ - - - -struct al_pcie_rev1_w_global_ctrl { - /* [0x0] */ - uint32_t port_init; - /* [0x4] */ - uint32_t port_status; - /* [0x8] */ - uint32_t pm_control; - uint32_t rsrvd_0; - /* [0x10] */ - uint32_t events_gen; - uint32_t rsrvd[3]; -}; -struct al_pcie_rev2_w_global_ctrl { - /* [0x0] */ - uint32_t port_init; - /* [0x4] */ - uint32_t port_status; - /* [0x8] */ - uint32_t pm_control; - uint32_t rsrvd_0; - /* [0x10] */ - uint32_t events_gen; - /* [0x14] */ - uint32_t pended_corr_err_sts_int; - /* [0x18] */ - uint32_t pended_uncorr_err_sts_int; - /* [0x1c] */ - uint32_t sris_kp_counter_value; -}; -struct al_pcie_rev3_w_global_ctrl { - /* [0x0] */ - uint32_t port_init; - /* [0x4] */ - uint32_t port_status; - /* [0x8] */ - uint32_t pm_control; - /* [0xc] */ - uint32_t pended_corr_err_sts_int; - /* [0x10] */ - uint32_t pended_uncorr_err_sts_int; - /* [0x14] */ - uint32_t sris_kp_counter_value; - uint32_t rsrvd[2]; -}; - -struct al_pcie_rev3_w_events_gen_per_func { - /* [0x0] */ - uint32_t events_gen; -}; -struct al_pcie_rev3_w_pm_state_per_func { - /* [0x0] */ - uint32_t pm_state_per_func; -}; -struct al_pcie_rev3_w_cfg_bars_ovrd { - /* [0x0] */ - uint32_t bar0_mask_lsb; - /* [0x4] */ - uint32_t bar0_mask_msb; - /* [0x8] */ - uint32_t bar0_limit_lsb; - /* [0xc] */ - uint32_t bar0_limit_msb; - /* [0x10] */ - uint32_t bar0_start_lsb; - /* [0x14] */ - uint32_t bar0_start_msb; - /* [0x18] */ - uint32_t bar0_ctrl; - /* [0x1c] */ - uint32_t bar1_mask_lsb; - /* [0x20] */ - uint32_t bar1_mask_msb; - /* [0x24] */ - uint32_t bar1_limit_lsb; - /* [0x28] */ - uint32_t bar1_limit_msb; - /* [0x2c] */ - uint32_t bar1_start_lsb; - /* [0x30] */ - uint32_t bar1_start_msb; - /* [0x34] */ - uint32_t bar1_ctrl; - /* [0x38] */ - uint32_t bar2_mask_lsb; - /* [0x3c] */ - uint32_t bar2_mask_msb; - /* [0x40] */ - uint32_t bar2_limit_lsb; - /* [0x44] */ - uint32_t bar2_limit_msb; - /* [0x48] */ - uint32_t bar2_start_lsb; - /* [0x4c] */ - uint32_t bar2_start_msb; - /* [0x50] */ - uint32_t bar2_ctrl; - /* [0x54] */ - uint32_t bar3_mask_lsb; - /* [0x58] */ - uint32_t bar3_mask_msb; - /* [0x5c] */ - uint32_t bar3_limit_lsb; - /* [0x60] */ - uint32_t bar3_limit_msb; - /* [0x64] */ - uint32_t bar3_start_lsb; - /* [0x68] */ - uint32_t bar3_start_msb; - /* [0x6c] */ - uint32_t bar3_ctrl; - /* [0x70] */ - uint32_t bar4_mask_lsb; - /* [0x74] */ - uint32_t bar4_mask_msb; - /* [0x78] */ - uint32_t bar4_limit_lsb; - /* [0x7c] */ - uint32_t bar4_limit_msb; - /* [0x80] */ - uint32_t bar4_start_lsb; - /* [0x84] */ - uint32_t bar4_start_msb; - /* [0x88] */ - uint32_t bar4_ctrl; - /* [0x8c] */ - uint32_t bar5_mask_lsb; - /* [0x90] */ - uint32_t bar5_mask_msb; - /* [0x94] */ - uint32_t bar5_limit_lsb; - /* [0x98] */ - uint32_t bar5_limit_msb; - /* [0x9c] */ - uint32_t bar5_start_lsb; - /* [0xa0] */ - uint32_t bar5_start_msb; - /* [0xa4] */ - uint32_t bar5_ctrl; - uint32_t rsrvd[2]; -}; - -struct al_pcie_revx_w_debug { - /* [0x0] */ - uint32_t info_0; - /* [0x4] */ - uint32_t info_1; - /* [0x8] */ - uint32_t info_2; - /* [0xc] */ - uint32_t info_3; -}; -struct al_pcie_revx_w_ob_ven_msg { - /* [0x0] */ - uint32_t control; - /* [0x4] */ - uint32_t param_1; - /* [0x8] */ - uint32_t param_2; - /* [0xc] */ - uint32_t data_high; - uint32_t rsrvd_0; - /* [0x14] */ - uint32_t data_low; -}; -struct al_pcie_revx_w_ap_user_send_msg { - /* [0x0] */ - uint32_t req_info; - /* [0x4] */ - uint32_t ack_info; -}; -struct al_pcie_revx_w_link_down { - /* [0x0] */ - uint32_t reset_delay; - /* [0x4] */ - uint32_t reset_extend_rsrvd; -}; -struct al_pcie_revx_w_cntl_gen { - /* [0x0] */ - uint32_t features; -}; -struct al_pcie_revx_w_parity { - /* [0x0] */ - uint32_t en_core; - /* [0x4] */ - uint32_t status_core; -}; -struct al_pcie_revx_w_last_wr { - /* [0x0] */ - uint32_t cfg_addr; -}; -struct al_pcie_rev1_2_w_atu { - /* [0x0] */ - uint32_t in_mask_pair[6]; - /* [0x18] */ - uint32_t out_mask_pair[6]; -}; -struct al_pcie_rev3_w_atu { - /* [0x0] */ - uint32_t in_mask_pair[12]; - /* [0x30] */ - uint32_t out_mask_pair[8]; - /* [0x50] */ - uint32_t reg_out_mask; - uint32_t rsrvd[11]; -}; -struct al_pcie_rev3_w_cfg_func_ext { - /* [0x0] */ - uint32_t cfg; -}; -struct al_pcie_rev3_w_app_hdr_interface_send { - /* [0x0] */ - uint32_t app_hdr_31_0; - /* [0x4] */ - uint32_t app_hdr_63_32; - /* [0x8] */ - uint32_t app_hdr_95_64; - /* [0xc] */ - uint32_t app_hdr_127_96; - /* [0x10] */ - uint32_t app_err_bus; - /* [0x14] */ - uint32_t app_func_num_advisory; - /* [0x18] */ - uint32_t app_hdr_cmd; -}; -struct al_pcie_rev3_w_diag_command { - /* [0x0] */ - uint32_t diag_ctrl; -}; -struct al_pcie_rev1_w_soc_int { - /* [0x0] */ - uint32_t status_0; - /* [0x4] */ - uint32_t status_1; - /* [0x8] */ - uint32_t status_2; - /* [0xc] */ - uint32_t mask_inta_leg_0; - /* [0x10] */ - uint32_t mask_inta_leg_1; - /* [0x14] */ - uint32_t mask_inta_leg_2; - /* [0x18] */ - uint32_t mask_msi_leg_0; - /* [0x1c] */ - uint32_t mask_msi_leg_1; - /* [0x20] */ - uint32_t mask_msi_leg_2; - /* [0x24] */ - uint32_t msi_leg_cntl; -}; -struct al_pcie_rev2_w_soc_int { - /* [0x0] */ - uint32_t status_0; - /* [0x4] */ - uint32_t status_1; - /* [0x8] */ - uint32_t status_2; - /* [0xc] */ - uint32_t status_3; - /* [0x10] */ - uint32_t mask_inta_leg_0; - /* [0x14] */ - uint32_t mask_inta_leg_1; - /* [0x18] */ - uint32_t mask_inta_leg_2; - /* [0x1c] */ - uint32_t mask_inta_leg_3; - /* [0x20] */ - uint32_t mask_msi_leg_0; - /* [0x24] */ - uint32_t mask_msi_leg_1; - /* [0x28] */ - uint32_t mask_msi_leg_2; - /* [0x2c] */ - uint32_t mask_msi_leg_3; - /* [0x30] */ - uint32_t msi_leg_cntl; -}; -struct al_pcie_rev3_w_soc_int_per_func { - /* [0x0] */ - uint32_t status_0; - /* [0x4] */ - uint32_t status_1; - /* [0x8] */ - uint32_t status_2; - /* [0xc] */ - uint32_t status_3; - /* [0x10] */ - uint32_t mask_inta_leg_0; - /* [0x14] */ - uint32_t mask_inta_leg_1; - /* [0x18] */ - uint32_t mask_inta_leg_2; - /* [0x1c] */ - uint32_t mask_inta_leg_3; - /* [0x20] */ - uint32_t mask_msi_leg_0; - /* [0x24] */ - uint32_t mask_msi_leg_1; - /* [0x28] */ - uint32_t mask_msi_leg_2; - /* [0x2c] */ - uint32_t mask_msi_leg_3; - /* [0x30] */ - uint32_t msi_leg_cntl; -}; - -struct al_pcie_revx_w_ap_err { - /* - * [0x0] latch the header in case of any error occur in the core, read - * on clear of the last register in the bind. - */ - uint32_t hdr_log; -}; -struct al_pcie_revx_w_status_per_func { - /* - * [0x0] latch the header in case of any error occure in the core, read - * on clear of the last register in the bind. - */ - uint32_t status_per_func; -}; -struct al_pcie_revx_w_int_grp { - /* - * [0x0] Interrupt Cause Register - * Set by hardware - * - If MSI-X is enabled and auto_clear control bit =TRUE, automatically - * cleared after MSI-X message associated with this specific interrupt - * bit is sent (MSI-X acknowledge is received). - * - Software can set a bit in this register by writing 1 to the - * associated bit in the Interrupt Cause Set register - * Write-0 clears a bit. Write-1 has no effect. - * - On CPU Read - If clear_on_read control bit =TRUE, automatically - * cleared (all bits are cleared). - * When there is a conflict and on the same clock cycle, hardware tries - * to set a bit in the Interrupt Cause register, the specific bit is set - * to ensure the interrupt indication is not lost. - */ - uint32_t cause; - uint32_t rsrvd_0; - /* - * [0x8] Interrupt Cause Set Register - * Writing 1 to a bit in this register sets its corresponding cause bit, - * enabling software to generate a hardware interrupt. Write 0 has no - * effect. - */ - uint32_t cause_set; - uint32_t rsrvd_1; - /* - * [0x10] Interrupt Mask Register - * If Auto-mask control bit =TRUE, automatically set to 1 after MSI-X - * message associatd with the associated interrupt bit is sent (AXI - * write acknowledge is received). - */ - uint32_t mask; - uint32_t rsrvd_2; - /* - * [0x18] Interrupt Mask Clear Register - * Used when auto-mask control bit=True. Enables CPU to clear a specific - * bit. It prevents a scenario in which the CPU overrides another bit - * with 1 (old value) that hardware has just cleared to 0. - * Write 0 to this register clears its corresponding mask bit. Write 1 - * has no effect. - */ - uint32_t mask_clear; - uint32_t rsrvd_3; - /* - * [0x20] Interrupt Status Register - * This register latches the status of the interrupt source. - */ - uint32_t status; - uint32_t rsrvd_4; - /* [0x28] Interrupt Control Register */ - uint32_t control; - uint32_t rsrvd_5; - /* - * [0x30] Interrupt Mask Register - * Each bit in this register masks the corresponding cause bit for - * generating an Abort signal. Its default value is determined by unit - * instantiation. - * (Abort = Wire-OR of Cause & !Interrupt_Abort_Mask) - * This register provides error handling configuration for error - * interrupts - */ - uint32_t abort_mask; - uint32_t rsrvd_6; - /* - * [0x38] Interrupt Log Register - * Each bit in this register masks the corresponding cause bit for - * capturing the log registers. Its default value is determined by unit - * instantiation. - * (Log_capture = Wire-OR of Cause & !Interrupt_Log_Mask) - * This register provides error handling configuration for error - * interrupts. - */ - uint32_t log_mask; - uint32_t rsrvd; -}; - -struct al_pcie_rev1_w_regs { - struct al_pcie_rev1_w_global_ctrl global_ctrl; /* [0x0] */ - uint32_t rsrvd_0[24]; - struct al_pcie_revx_w_debug debug; /* [0x80] */ - struct al_pcie_revx_w_ob_ven_msg ob_ven_msg; /* [0x90] */ - uint32_t rsrvd_1[86]; - struct al_pcie_rev1_w_soc_int soc_int; /* [0x200] */ - struct al_pcie_revx_w_link_down link_down; /* [0x228] */ - struct al_pcie_revx_w_cntl_gen ctrl_gen; /* [0x230] */ - struct al_pcie_revx_w_parity parity; /* [0x234] */ - struct al_pcie_revx_w_last_wr last_wr; /* [0x23c] */ - struct al_pcie_rev1_2_w_atu atu; /* [0x240] */ - uint32_t rsrvd_2[36]; - struct al_pcie_revx_w_int_grp int_grp_a_m0; /* [0x300] */ - struct al_pcie_revx_w_int_grp int_grp_b_m0; /* [0x340] */ - uint32_t rsrvd_3[32]; - struct al_pcie_revx_w_int_grp int_grp_a; /* [0x400] */ - struct al_pcie_revx_w_int_grp int_grp_b; /* [0x440] */ -}; - -struct al_pcie_rev2_w_regs { - struct al_pcie_rev2_w_global_ctrl global_ctrl; /* [0x0] */ - uint32_t rsrvd_0[24]; - struct al_pcie_revx_w_debug debug; /* [0x80] */ - struct al_pcie_revx_w_ob_ven_msg ob_ven_msg; /* [0x90] */ - struct al_pcie_revx_w_ap_user_send_msg ap_user_send_msg; /* [0xa8] */ - uint32_t rsrvd_1[20]; - struct al_pcie_rev2_w_soc_int soc_int; /* [0x100] */ - uint32_t rsrvd_2[61]; - struct al_pcie_revx_w_link_down link_down; /* [0x228] */ - struct al_pcie_revx_w_cntl_gen ctrl_gen; /* [0x230] */ - struct al_pcie_revx_w_parity parity; /* [0x234] */ - struct al_pcie_revx_w_last_wr last_wr; /* [0x23c] */ - struct al_pcie_rev1_2_w_atu atu; /* [0x240] */ - uint32_t rsrvd_3[6]; - struct al_pcie_revx_w_ap_err ap_err[4]; /* [0x288] */ - uint32_t rsrvd_4[26]; - struct al_pcie_revx_w_status_per_func status_per_func; /* [0x300] */ - uint32_t rsrvd_5[63]; - struct al_pcie_revx_w_int_grp int_grp_a; /* [0x400] */ - struct al_pcie_revx_w_int_grp int_grp_b; /* [0x440] */ -}; - -struct al_pcie_rev3_w_regs { - struct al_pcie_rev3_w_global_ctrl global_ctrl; /* [0x0] */ - uint32_t rsrvd_0[24]; - struct al_pcie_revx_w_debug debug; /* [0x80] */ - struct al_pcie_revx_w_ob_ven_msg ob_ven_msg; /* [0x90] */ - struct al_pcie_revx_w_ap_user_send_msg ap_user_send_msg; /* [0xa8] */ - uint32_t rsrvd_1[94]; - struct al_pcie_revx_w_link_down link_down; /* [0x228] */ - struct al_pcie_revx_w_cntl_gen ctrl_gen; /* [0x230] */ - struct al_pcie_revx_w_parity parity; /* [0x234] */ - struct al_pcie_revx_w_last_wr last_wr; /* [0x23c] */ - struct al_pcie_rev3_w_atu atu; /* [0x240] */ - uint32_t rsrvd_2[8]; - struct al_pcie_rev3_w_cfg_func_ext cfg_func_ext; /* [0x2e0] */ - struct al_pcie_rev3_w_app_hdr_interface_send app_hdr_interface_send;/* [0x2e4] */ - struct al_pcie_rev3_w_diag_command diag_command; /* [0x300] */ - uint32_t rsrvd_3[3]; - struct al_pcie_rev3_w_soc_int_per_func soc_int_per_func[REV3_MAX_NUM_OF_PFS]; /* [0x310] */ - uint32_t rsrvd_4[44]; - struct al_pcie_rev3_w_events_gen_per_func events_gen_per_func[REV3_MAX_NUM_OF_PFS]; /* [0x490] */ - uint32_t rsrvd_5[4]; - struct al_pcie_rev3_w_pm_state_per_func pm_state_per_func[REV3_MAX_NUM_OF_PFS];/* [0x4b0] */ - uint32_t rsrvd_6[16]; - struct al_pcie_rev3_w_cfg_bars_ovrd cfg_bars_ovrd[REV3_MAX_NUM_OF_PFS]; /* [0x500] */ - uint32_t rsrvd_7[176]; - uint32_t rsrvd_8[16]; - struct al_pcie_revx_w_ap_err ap_err[5]; /* [0xac0] */ - uint32_t rsrvd_9[11]; - struct al_pcie_revx_w_status_per_func status_per_func[4]; /* [0xb00] */ - uint32_t rsrvd_10[316]; - struct al_pcie_revx_w_int_grp int_grp_a; /* [0x1000] */ - struct al_pcie_revx_w_int_grp int_grp_b; /* [0x1040] */ - struct al_pcie_revx_w_int_grp int_grp_c; /* [0x1080] */ - struct al_pcie_revx_w_int_grp int_grp_d; /* [0x10c0] */ -}; - -/* -* Registers Fields -*/ - - -/**** Port_Init register ****/ -/* Enable port to start LTSSM Link Training */ -#define PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_MASK (1 << 0) -#define PCIE_W_GLOBAL_CTRL_PORT_INIT_APP_LTSSM_EN_SHIFT (0) -/* - * Device Type - * Indicates the specific type of this PCIe Function. It is also used to set the - * Device/Port Type field. - * 4'b0000: PCIe Endpoint - * 4'b0001: Legacy PCIe Endpoint - * 4'b0100: Root Port of PCIe Root Complex - * Must be programmed before link training sequence. According to the reset - * strap - */ -#define PCIE_W_GLOBAL_CTRL_PORT_INIT_DEVICE_TYPE_MASK 0x000000F0 -#define PCIE_W_GLOBAL_CTRL_PORT_INIT_DEVICE_TYPE_SHIFT 4 -/* - * Performs Manual Lane reversal for transmit Lanes. - * Must be programmed before link training sequence. - */ -#define PCIE_W_GLOBAL_CTRL_PORT_INIT_TX_LANE_FLIP_EN (1 << 8) -/* - * Performs Manual Lane reversal for receive Lanes. - * Must be programmed before link training sequence. - */ -#define PCIE_W_GLOBAL_CTRL_PORT_INIT_RX_LANE_FLIP_EN (1 << 9) -/* - * Auxiliary Power Detected - * Indicates that auxiliary power (Vaux) is present. This one move to reset - * strap from - */ -#define PCIE_W_GLOBAL_CTRL_PORT_INIT_SYS_AUX_PWR_DET_NOT_USE (1 << 10) - -/**** Port_Status register ****/ -/* PHY Link up/down indicator */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_PHY_LINK_UP (1 << 0) -/* - * Data Link Layer up/down indicator - * This status from the Flow Control Initialization State Machine indicates that - * Flow Control has been initiated and the Data Link Layer is ready to transmit - * and receive packets. - */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_DL_LINK_UP (1 << 1) -/* Reset request due to link down status. */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_LINK_REQ_RST (1 << 2) -/* Power management is in L0s state.. */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_LINKST_IN_L0S (1 << 3) -/* Power management is in L1 state. */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_LINKST_IN_L1 (1 << 4) -/* Power management is in L2 state. */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_LINKST_IN_L2 (1 << 5) -/* Power management is exiting L2 state. */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_LINKST_L2_EXIT (1 << 6) -/* Power state of the device. */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_DSTATE_MASK 0x00000380 -#define PCIE_W_GLOBAL_CTRL_PORT_STS_PM_DSTATE_SHIFT 7 -/* tie to zero. */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_XMLH_IN_RL0S (1 << 10) -/* Timeout count before flush */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_LINK_TOUT_FLUSH_NOT (1 << 11) -/* Segmentation buffer not empty */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_RADM_Q_NOT_EMPTY (1 << 12) -/* - * Clock Turnoff Request - * Allows clock generation module to turn off core_clk based on the current - * power management state: - * 0: core_clk is required to be active for the current power state. - * 1: The current power state allows core_clk to be shut down. - * This does not indicate the clock requirement for the PHY. - */ -#define PCIE_W_GLOBAL_CTRL_PORT_STS_CORE_CLK_REQ_N (1 << 31) - -/**** PM_Control register ****/ -/* - * Wake Up. Used by application logic to wake up the PMC state machine from a - * D1, D2, or D3 power state. EP mode only. Change the value from 0 to 1 to send - * the message. Per function the upper bits are not use for ocie core less than - * 8 functions - */ -#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_PM_XMT_PME (1 << 0) -#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_PM_XMT_PME_FUNC_MASK 0x000000FF -#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_PM_XMT_PME_FUNC_SHIFT 0 -/* - * Request to Enter ASPM L1. - * The core ignores the L1 entry request on app_req_entr_l1 when it is busy - * processing a transaction. - */ -#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_REQ_ENTR_L1 (1 << 3) -#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_REQ_ENTR_L1 (1 << 8) -/* - * Request to exit ASPM L1. - * Only effective if L1 is enabled. - */ -#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_REQ_EXIT_L1 (1 << 4) -#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_REQ_EXIT_L1 (1 << 9) -/* - * Indication that component is ready to enter the L23 state. The core delays - * sending PM_Enter_L23 (in response to PM_Turn_Off) until this signal becomes - * active. - * EP mode - */ -#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_READY_ENTR_L23 (1 << 5) -#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_READY_ENTR_L23 (1 << 10) -/* - * Request to generate a PM_Turn_Off Message to communicate transition to L2/L3 - * Ready state to downstream components. Host must wait PM_Turn_Off_Ack messages - * acceptance RC mode. - */ -#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_PM_XMT_TURNOFF (1 << 6) -#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_PM_XMT_TURNOFF (1 << 11) -/* - * Provides a capability to defer incoming Configuration Requests until - * initialization is complete. When app_req_retry_en is asserted, the core - * completes incoming Configuration Requests with a Configuration Request Retry - * Status. Other incoming Requests complete with Unsupported Request status. - */ -#define PCIE_W_REV1_2_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN (1 << 7) -#define PCIE_W_REV3_GLOBAL_CTRL_PM_CONTROL_APP_REQ_RETRY_EN (1 << 12) -/* - * Core core gate enable - * If set, core_clk is gated off whenever a clock turnoff request allows the - * clock generation module to turn off core_clk (Port_Status.core_clk_req_n - * field), and the PHY supports a request to disable clock gating. If not, the - * core clock turns off in P2 mode in any case (PIPE). - */ -#define PCIE_W_GLOBAL_CTRL_PM_CONTROL_CORE_CLK_GATE (1 << 31) - -/**** sris_kp_counter_value register ****/ -/* skp counter when SRIS disable */ -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_NO_SRIS_MASK 0x000001FF -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_NO_SRIS_SHIFT 0 -/* skp counter when SRIS enable */ -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_MASK 0x0003FE00 -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN3_SRIS_SHIFT 9 -/* skp counter when SRIS enable for gen3 */ -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_MASK 0x1FFC0000 -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_GEN21_SRIS_SHIFT 18 -/* mask the interrupt to the soc in case correctable error occur in the ARI. */ -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_RSRVD_MASK 0x60000000 -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_RSRVD_SHIFT 29 -/* not in use in the pcie_x8 core. */ -#define PCIE_W_GLOBAL_CTRL_SRIS_KP_COUNTER_VALUE_PCIE_X4_SRIS_EN (1 << 31) - -/**** Events_Gen register ****/ -/* INT_D. Not supported */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTD (1 << 0) -/* INT_C. Not supported */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTC (1 << 1) -/* INT_B. Not supported */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTB (1 << 2) -/* Transmit INT_A Interrupt ControlEvery transition from 0 to 1 ... */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTA (1 << 3) -/* A request to generate an outbound MSI interrupt when MSI is e ... */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_TRNS_REQ (1 << 4) -/* Set the MSI vector before issuing msi_trans_req. */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_MASK 0x000003E0 -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_SHIFT 5 -/* The application requests hot reset to a downstream device */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT (1 << 10) -/* The application request unlock message to be sent */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_UNLOCK_GEN (1 << 30) -/* Indicates that FLR on a Physical Function has been completed */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE (1 << 31) - -/**** Cpl_TO_Info register ****/ -/* The Traffic Class of the timed out CPL */ -#define PCIE_W_LCL_LOG_CPL_TO_INFO_TC_MASK 0x00000003 -#define PCIE_W_LCL_LOG_CPL_TO_INFO_TC_SHIFT 0 -/* Indicates which Virtual Function (VF) had a CPL timeout */ -#define PCIE_W_LCL_LOG_CPL_TO_INFO_FUN_NUM_MASK 0x000000FC -#define PCIE_W_LCL_LOG_CPL_TO_INFO_FUN_NUM_SHIFT 2 -/* The Tag field of the timed out CPL */ -#define PCIE_W_LCL_LOG_CPL_TO_INFO_TAG_MASK 0x0000FF00 -#define PCIE_W_LCL_LOG_CPL_TO_INFO_TAG_SHIFT 8 -/* The Attributes field of the timed out CPL */ -#define PCIE_W_LCL_LOG_CPL_TO_INFO_ATTR_MASK 0x00030000 -#define PCIE_W_LCL_LOG_CPL_TO_INFO_ATTR_SHIFT 16 -/* The Len field of the timed out CPL */ -#define PCIE_W_LCL_LOG_CPL_TO_INFO_LEN_MASK 0x3FFC0000 -#define PCIE_W_LCL_LOG_CPL_TO_INFO_LEN_SHIFT 18 -/* - * Write 1 to this field to clear the information logged in the register. New - * logged information will only be valid when the interrupt is cleared . - */ -#define PCIE_W_LCL_LOG_CPL_TO_INFO_VALID (1 << 31) -#define PCIE_W_LCL_LOG_CPL_TO_INFO_VALID_SHIFT (31) - -/**** Rcv_Msg0_0 register ****/ -/* The Requester ID of the received message */ -#define PCIE_W_LCL_LOG_RCV_MSG0_0_REQ_ID_MASK 0x0000FFFF -#define PCIE_W_LCL_LOG_RCV_MSG0_0_REQ_ID_SHIFT 0 -/* - * Valid logged message - * Writing 1 to this bit enables new message capturing. Write one to clear - */ -#define PCIE_W_LCL_LOG_RCV_MSG0_0_VALID (1 << 31) - -/**** Rcv_Msg1_0 register ****/ -/* The Requester ID of the received message */ -#define PCIE_W_LCL_LOG_RCV_MSG1_0_REQ_ID_MASK 0x0000FFFF -#define PCIE_W_LCL_LOG_RCV_MSG1_0_REQ_ID_SHIFT 0 -/* - * Valid logged message - * Writing 1 to this bit enables new message capturing. Write one to clear - */ -#define PCIE_W_LCL_LOG_RCV_MSG1_0_VALID (1 << 31) - -/**** Core_Queues_Status register ****/ -/* - * Indicates which entries in the CPL lookup table - * have valid entries stored. NOT supported. - */ -#define PCIE_W_LCL_LOG_CORE_Q_STATUS_CPL_LUT_VALID_MASK 0x0000FFFF -#define PCIE_W_LCL_LOG_CORE_Q_STATUS_CPL_LUT_VALID_SHIFT 0 - -/**** Cpl_to register ****/ -#define PCIE_W_LCL_LOG_CPL_TO_REQID_MASK 0x0000FFFF -#define PCIE_W_LCL_LOG_CPL_TO_REQID_SHIFT 0 - -/**** Debug_Info_0 register ****/ -/* Indicates the current power state */ -#define PCIE_W_DEBUG_INFO_0_PM_CURRENT_STATE_MASK 0x00000007 -#define PCIE_W_DEBUG_INFO_0_PM_CURRENT_STATE_SHIFT 0 -/* Current state of the LTSSM */ -#define PCIE_W_DEBUG_INFO_0_LTSSM_STATE_MASK 0x000001F8 -#define PCIE_W_DEBUG_INFO_0_LTSSM_STATE_SHIFT 3 -/* Decode of the Recovery. Equalization LTSSM state */ -#define PCIE_W_DEBUG_INFO_0_LTSSM_STATE_RCVRY_EQ (1 << 9) -/* State of selected internal signals, for debug purposes only */ -#define PCIE_W_DEBUG_INFO_0_CXPL_DEBUG_INFO_EI_MASK 0x03FFFC00 -#define PCIE_W_DEBUG_INFO_0_CXPL_DEBUG_INFO_EI_SHIFT 10 - -/**** control register ****/ -/* Indication to send vendor message; when clear the message was sent. */ -#define PCIE_W_OB_VEN_MSG_CONTROL_REQ (1 << 0) - -/**** param_1 register ****/ -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_1_FMT_MASK 0x00000003 -#define PCIE_W_OB_VEN_MSG_PARAM_1_FMT_SHIFT 0 -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_1_TYPE_MASK 0x0000007C -#define PCIE_W_OB_VEN_MSG_PARAM_1_TYPE_SHIFT 2 -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_1_TC_MASK 0x00000380 -#define PCIE_W_OB_VEN_MSG_PARAM_1_TC_SHIFT 7 -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_1_TD (1 << 10) -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_1_EP (1 << 11) -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_1_ATTR_MASK 0x00003000 -#define PCIE_W_OB_VEN_MSG_PARAM_1_ATTR_SHIFT 12 -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_1_LEN_MASK 0x00FFC000 -#define PCIE_W_OB_VEN_MSG_PARAM_1_LEN_SHIFT 14 -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_1_TAG_MASK 0xFF000000 -#define PCIE_W_OB_VEN_MSG_PARAM_1_TAG_SHIFT 24 - -/**** param_2 register ****/ -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_2_REQ_ID_MASK 0x0000FFFF -#define PCIE_W_OB_VEN_MSG_PARAM_2_REQ_ID_SHIFT 0 -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_2_CODE_MASK 0x00FF0000 -#define PCIE_W_OB_VEN_MSG_PARAM_2_CODE_SHIFT 16 -/* Vendor message parameters */ -#define PCIE_W_OB_VEN_MSG_PARAM_2_RSVD_31_24_MASK 0xFF000000 -#define PCIE_W_OB_VEN_MSG_PARAM_2_RSVD_31_24_SHIFT 24 - -/**** ack_info register ****/ -/* Vendor message parameters */ -#define PCIE_W_AP_USER_SEND_MSG_ACK_INFO_ACK (1 << 0) - -/**** features register ****/ -/* Enable MSI fix from the SATA to the PCIe EP - Only valid for port zero */ -#define PCIE_W_CTRL_GEN_FEATURES_SATA_EP_MSI_FIX AL_BIT(16) - -/**** in/out_mask_x_y register ****/ -/* When bit [i] set to 1 it maks the compare in the atu_in/out wind ... */ -#define PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_MASK 0x0000FFFF -#define PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_EVEN_SHIFT 0 -/* When bit [i] set to 1 it maks the compare in the atu_in/out wind ... */ -#define PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_MASK 0xFFFF0000 -#define PCIE_W_ATU_MASK_EVEN_ODD_ATU_MASK_40_32_ODD_SHIFT 16 - -/**** cfg register ****/ -/* - * The 2-bit TPH Requester Enabled field of each TPH - * Requester Control register. - */ -#define PCIE_W_CFG_FUNC_EXT_CFG_CFG_TPH_REQ_EN_MASK 0x000000FF -#define PCIE_W_CFG_FUNC_EXT_CFG_CFG_TPH_REQ_EN_SHIFT 0 -/* SRIS mode enable. */ -#define PCIE_W_CFG_FUNC_EXT_CFG_APP_SRIS_MODE (1 << 8) -/* - * - */ -#define PCIE_W_CFG_FUNC_EXT_CFG_RSRVD_MASK 0xFFFFFE00 -#define PCIE_W_CFG_FUNC_EXT_CFG_RSRVD_SHIFT 9 - -/**** app_func_num_advisory register ****/ -/* - * The number of the function that is reporting the error - * indicated app_err_bus, valid when app_hdr_valid is asserted. - * Correctable and Uncorrected Internal errors (app_err_bus[10:9]) are - * not function specific, and are recorded for all physical functions, - * regardless of the value this bus. Function numbering starts at '0'. - */ -#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_APP_ERR_FUNC_NUM_MASK 0x0000FFFF -#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_APP_ERR_FUNC_NUM_SHIFT 0 -/* - * Description: Indicates that your application error is an advisory - * error. Your application should assert app_err_advisory under either - * of the following conditions: - * - The core is configured to mask completion timeout errors, your - * application is reporting a completion timeout error app_err_bus, - * and your application intends to resend the request. In such cases - * the error is an advisory error, as described in PCI Express 3.0 - * Specification. When your application does not intend to resend - * the request, then your application must keep app_err_advisory - * de-asserted when reporting a completion timeout error. - * - The core is configured to forward poisoned TLPs to your - * application and your application is going to treat the poisoned - * TLP as a normal TLP, as described in PCI Express 3.0 - * Specification. Upon receipt of a poisoned TLP, your application - * must report the error app_err_bus, and either assert - * app_err_advisory (to indicate an advisory error) or de-assert - * app_err_advisory (to indicate that your application is dropping the - * TLP). - * For more details, see the PCI Express 3.0 Specification to determine - * when an application error is an advisory error. - */ -#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_APP_ERR_ADVISORY (1 << 16) -/* - * Rsrvd. - */ -#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_RSRVD_MASK 0xFFFE0000 -#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_FUNC_NUM_ADVISORY_RSRVD_SHIFT 17 - -/**** app_hdr_cmd register ****/ -/* - * When set the header is send (need to clear before sending the next message). - */ -#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_HDR_CMD_APP_HDR_VALID (1 << 0) -/* - * Rsrvd. - */ -#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_HDR_CMD_RSRVD_MASK 0xFFFFFFFE -#define PCIE_W_APP_HDR_INTERFACE_SEND_APP_HDR_CMD_RSRVD_SHIFT 1 - -/**** diag_ctrl register ****/ -/* - * The 2-bit TPH Requester Enabled field of each TPH - * Requester Control register. - */ -#define PCIE_W_DIAG_COMMAND_DIAG_CTRL_DIAG_CTRL_BUS_MASK 0x00000007 -#define PCIE_W_DIAG_COMMAND_DIAG_CTRL_DIAG_CTRL_BUS_SHIFT 0 -/* - * - */ -#define PCIE_W_DIAG_COMMAND_DIAG_CTRL_RSRVD_MASK 0xFFFFFFF8 -#define PCIE_W_DIAG_COMMAND_DIAG_CTRL_RSRVD_SHIFT 3 - - -/**** Events_Gen register ****/ -/* INT_D. Not supported */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTD (1 << 0) -/* INT_C. Not supported */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTC (1 << 1) -/* INT_B. Not supported */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTB (1 << 2) -/* - * Transmit INT_A Interrupt Control - * Every transition from 0 to 1 schedules an Assert_ INT interrupt message for - * transmit. - * Every transition from 1 to 0, schedules a Deassert_INT interrupt message for - * transmit. Which interrupt, the PCIe only use INTA message. - */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_ASSERT_INTA (1 << 3) -/* - * A request to generate an outbound MSI interrupt when MSI is enabled. Change - * from 1'b0 to 1'b1 to create an MSI write to be sent. - */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_TRNS_REQ (1 << 4) -/* Set the MSI vector before issuing msi_trans_req. */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_MASK 0x000003E0 -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_MSI_VECTOR_SHIFT 5 -/* - * The application requests hot reset to a downstream device. Change the value - * from 0 to 1 to send hot reset. Only func 0 is supported. - */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_APP_RST_INIT (1 << 10) -/* - * The application request unlock message to be sent. Change the value from 0 to - * 1 to send the message. Only func 0 is supported. - */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_UNLOCK_GEN (1 << 30) -/* Indicates that FLR on a Physical Function has been completed. */ -#define PCIE_W_GLOBAL_CTRL_EVENTS_GEN_FLR_PF_DONE (1 << 31) - -/**** pm_state_per_func register ****/ -/* - * Description: The current power management D-state of the - * function: - * \u25a0 000b: D0 - * \u25a0 001b: D1 - * \u25a0 010b: D2 - * \u25a0 011b: D3 - * \u25a0 100b: Uninitialized - * \u25a0 Other values: Not applicable - * There are 3 bits of pm_dstate for each configured function. - */ -#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_PM_DSTATE_MASK 0x0000000F -#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_PM_DSTATE_SHIFT 0 -/* - * PME Status bit from the PMCSR. There is 1 bit of - * pm_status for each configured function - */ -#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_PM_STATUS (1 << 4) -/* - * PME Enable bit in the PMCSR. There is 1 bit of - * pm_pme_en for each configured function. - */ -#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_PM_PME_EN (1 << 5) -/* - * Auxiliary Power Enable bit in the Device Control - * register. There is 1 bit of aux_pm_en for each configured function. - */ -#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_AUX_PME_EN (1 << 6) -/* - * This field should be set according to the MAX_FUNC_NUM set in the PCIe core, - * it uses as mask (bit per function) to the dsate when set to zero. - */ -#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_ASPM_PF_ENABLE_MAX_FUNC_NUMBER (1 << 7) -/* - * This field should be set according to the MAX_FUNC_NUM set in the PCIe core, - * it uses as mask (bit per function) to the ASPM contrl bit, when set to zero. - */ -#define PCIE_W_PM_STATE_PER_FUNC_PM_STATE_PER_FUNC_DSATE_PF_ENABLE_MAX_FUNC_NUMBER (1 << 8) - -/**** bar0_ctrl register ****/ -/* bar is en and override the internal PF bar. */ -#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_BAR_EN_MASK 0x00000003 -#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_BAR_EN_SHIFT 0 -/* bar is io */ -#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_BAR_IO_MASK 0x0000000C -#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_BAR_IO_SHIFT 2 -/* Reserved. */ -#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_RSRVS_MASK 0xFFFFFFF0 -#define PCIE_W_CFG_BARS_OVRD_BAR0_CTRL_RSRVS_SHIFT 4 - -/**** bar1_ctrl register ****/ -/* bar is en and override the internal PF bar. */ -#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_BAR_EN_MASK 0x00000003 -#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_BAR_EN_SHIFT 0 -/* bar is io */ -#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_BAR_IO_MASK 0x0000000C -#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_BAR_IO_SHIFT 2 -/* Reserved. */ -#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_RSRVS_MASK 0xFFFFFFF0 -#define PCIE_W_CFG_BARS_OVRD_BAR1_CTRL_RSRVS_SHIFT 4 - -/**** bar2_ctrl register ****/ -/* bar is en and override the internal PF bar. */ -#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_BAR_EN_MASK 0x00000003 -#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_BAR_EN_SHIFT 0 -/* bar is io */ -#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_BAR_IO_MASK 0x0000000C -#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_BAR_IO_SHIFT 2 -/* Reserved. */ -#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_RSRVS_MASK 0xFFFFFFF0 -#define PCIE_W_CFG_BARS_OVRD_BAR2_CTRL_RSRVS_SHIFT 4 - -/**** bar3_ctrl register ****/ -/* bar is en and override the internal PF bar. */ -#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_BAR_EN_MASK 0x00000003 -#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_BAR_EN_SHIFT 0 -/* bar is io */ -#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_BAR_IO_MASK 0x0000000C -#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_BAR_IO_SHIFT 2 -/* Reserved. */ -#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_RSRVS_MASK 0xFFFFFFF0 -#define PCIE_W_CFG_BARS_OVRD_BAR3_CTRL_RSRVS_SHIFT 4 - -/**** bar4_ctrl register ****/ -/* bar is en and override the internal PF bar. */ -#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_BAR_EN_MASK 0x00000003 -#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_BAR_EN_SHIFT 0 -/* bar is io */ -#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_BAR_IO_MASK 0x0000000C -#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_BAR_IO_SHIFT 2 -/* Reserved. */ -#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_RSRVS_MASK 0xFFFFFFF0 -#define PCIE_W_CFG_BARS_OVRD_BAR4_CTRL_RSRVS_SHIFT 4 - -/**** bar5_ctrl register ****/ -/* bar is en and override the internal PF bar. */ -#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_BAR_EN_MASK 0x00000003 -#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_BAR_EN_SHIFT 0 -/* bar is io */ -#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_BAR_IO_MASK 0x0000000C -#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_BAR_IO_SHIFT 2 -/* Reserved. */ -#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_RSRVS_MASK 0xFFFFFFF0 -#define PCIE_W_CFG_BARS_OVRD_BAR5_CTRL_RSRVS_SHIFT 4 - -/**** cause_A register ****/ -/* Deassert_INTD received. Write zero to clear this bit. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_DEASSERT_INTD (1 << 0) -/* Deassert_INTC received. Write zero to clear this bit. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_DEASSERT_INTC (1 << 1) -/* Deassert_INTB received. Write zero to clear this bit. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_DEASSERT_INTB (1 << 2) -/* Deassert_INTA received. Write zero to clear this bit. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_DEASSERT_INTA (1 << 3) -/* Assert_INTD received. Write zero to clear this bit. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_ASSERT_INTD (1 << 4) -/* Assert_INTC received. Write zero to clear this bit. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_ASSERT_INTC (1 << 5) -/* Assert_INTC received. Write zero to clear this bit. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_ASSERT_INTB (1 << 6) -/* Assert_INTA received. Write zero to clear this bit. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_ASSERT_INTA (1 << 7) -/* - * MSI Controller Interrupt - * MSI interrupt is being received. Write zero to clear this bit - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_MSI_CNTR_RCV_INT (1 << 8) -/* - * MSI sent grant. Write zero to clear this bit. - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_MSI_TRNS_GNT (1 << 9) -/* - * System error detected - * Indicates if any device in the hierarchy reports any of the following errors - * and the associated enable bit is set in the Root Control register: - * ERR_COR - * ERR_FATAL - * ERR_NONFATAL - * Also asserted when an internal error is detected. Write zero to clear this - * bit. - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_SYS_ERR_RC (1 << 10) -/* - * Set when software initiates FLR on a Physical Function by writing to the - * Initiate FLR register bit of that function Write zero to clear this bit. - */ -#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_FLR_PF_ACTIVE (1 << 11) -#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_11 (1 << 11) -/* - * Reported error condition causes a bit to be set in the Root Error Status - * register and the associated error message reporting enable bit is set in the - * Root Error Command Register. Write zero to clear this bit. - */ -#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_AER_RC_ERR (1 << 12) -#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_12 (1 << 12) -/* - * The core asserts aer_rc_err_msi when all of the following conditions are - * true: - * - MSI or MSI-X is enabled. - * - A reported error condition causes a bit to be set in the Root Error Status - * register. - * - The associated error message reporting enable bit is set in the Root Error - * Command register Write zero to clear this bit - */ -#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_AER_RC_ERR_MSI (1 << 13) -#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_13 (1 << 13) -/* - * Wake Up. Wake up from power management unit. - * The core generates wake to request the system to restore power and clock when - * a beacon has been detected. wake is an active high signal and its rising edge - * should be detected to drive the WAKE# on the connector Write zero to clear - * this bit - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_WAKE (1 << 14) -/* - * The core asserts cfg_pme_int when all of the following conditions are true: - * - INTx Assertion Disable bit in the Command register is 0. - * - PME Interrupt Enable bit in the Root Control register is set to 1. - * - PME Status bit in the Root Status register is set to 1. Write zero to clear - * this bit - */ -#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_PME_INT (1 << 15) -#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_15 (1 << 15) -/* - * The core asserts cfg_pme_msi when all of the following conditions are true: - * - MSI or MSI-X is enabled. - * - PME Interrupt Enable bit in the Root Control register is set to 1. - * - PME Status bit in the Root Status register is set to 1. Write zero to clear - * this bit - */ -#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_PME_MSI (1 << 16) -#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_RSRVD_16 (1 << 16) -/* - * The core asserts hp_pme when all of the following conditions are true: - * - The PME Enable bit in the Power Management Control and Status register is - * set to 1. - * - Any bit in the Slot Status register transitions from 0 to 1 and the - * associated event notification is enabled in the Slot Control register. Write - * zero to clear this bit - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_HP_PME (1 << 17) -/* - * The core asserts hp_int when all of the following conditions are true: - * - INTx Assertion Disable bit in the Command register is 0. - * - Hot-Plug interrupts are enabled in the Slot Control register. - * - Any bit in the Slot Status register is equal to 1, and the associated event - * notification is enabled in the Slot Control register. Write zero to clear - * this bit - */ -#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_HP_INT (1 << 18) -/* The outstanding write counter become full should never happen */ -#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_WRITE_COUNTER_FULL_ERR (1 << 18) - - -/* - * The core asserts hp_msi when the logical AND of the following conditions - * transitions from false to true: - * - MSI or MSI-X is enabled. - * - Hot-Plug interrupts are enabled in the Slot Control register. - * - Any bit in the Slot Status register transitions from 0 to 1 and the - * associated event notification is enabled in the Slot Control register. - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_HP_MSI (1 << 19) -/* Read VPD registers notification */ -#define PCIE_W_REV1_2_INT_GRP_A_CAUSE_A_VPD_INT (1 << 20) -/* not use */ -#define PCIE_W_REV3_INT_GRP_A_CAUSE_A_NOT_USE (1 << 20) - -/* - * The core assert link down event, whenever the link is going down. Write zero - * to clear this bit, pulse signal - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_LINK_DOWN_EVENT (1 << 21) -/* - * When the EP gets a command to shut down, signal the software to block any new - * TLP. - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_PM_XTLH_BLOCK_TLP (1 << 22) -/* PHY/MAC link up */ -#define PCIE_W_INT_GRP_A_CAUSE_A_XMLH_LINK_UP (1 << 23) -/* Data link up */ -#define PCIE_W_INT_GRP_A_CAUSE_A_RDLH_LINK_UP (1 << 24) -/* The ltssm is in RCVRY_LOCK state. */ -#define PCIE_W_INT_GRP_A_CAUSE_A_LTSSM_RCVRY_STATE (1 << 25) -/* - * Config write transaction to the config space by the RC peer, enable this - * interrupt only for EP mode. - */ -#define PCIE_W_INT_GRP_A_CAUSE_A_CFG_WR_EVENT (1 << 26) -/* AER error */ -#define PCIE_W_INT_GRP_A_CAUSE_A_AP_PENDED_CORR_ERR_STS_INT (1 << 28) -/* AER error */ -#define PCIE_W_INT_GRP_A_CAUSE_A_AP_PENDED_UNCORR_ERR_STS_INT (1 << 29) - -/**** control_A register ****/ -/* When Clear_on_Read =1, all bits of Cause register are cleared on read. */ -#define PCIE_W_INT_GRP_A_CONTROL_A_CLEAR_ON_READ (1 << 0) -/* - * (Must be set only when MSIX is enabled.) - * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its - * corresponding bit in the Mask register is set, masking future interrupts. - */ -#define PCIE_W_INT_GRP_A_CONTROL_A_AUTO_MASK (1 << 1) -/* - * Auto_Clear (RW) - * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared - * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. - */ -#define PCIE_W_INT_GRP_A_CONTROL_A_AUTO_CLEAR (1 << 2) -/* - * When Set_on_Posedge =1, the bits in the Interrupt Cause register are set on - * the posedge of the interrupt source, i.e., when interrupt source =1 and - * Interrupt Status = 0. - * When Set_on_Posedge =0, the bits in the Interrupt Cause register are set when - * interrupt source =1. - */ -#define PCIE_W_INT_GRP_A_CONTROL_A_SET_ON_POSEDGE (1 << 3) -/* - * When Moderation_Reset =1, all Moderation timers associated with the interrupt - * cause bits are cleared to 0, enabling immediate interrupt assertion if any - * unmasked cause bit is set to 1. This bit is self-negated. - */ -#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_RST (1 << 4) -/* - * When mask_msi_x =1, no MSI-X from this group is sent. This bit must be set to - * 1 when the associated summary bit in this group is used to generate a single - * MSI-X for this group. - */ -#define PCIE_W_INT_GRP_A_CONTROL_A_MASK_MSI_X (1 << 5) -/* MSI-X AWID value. Same ID for all cause bits. */ -#define PCIE_W_INT_GRP_A_CONTROL_A_AWID_MASK 0x00000F00 -#define PCIE_W_INT_GRP_A_CONTROL_A_AWID_SHIFT 8 -/* - * This value determines the interval between interrupts; writing ZERO disables - * Moderation. - */ -#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_INTV_MASK 0x00FF0000 -#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_INTV_SHIFT 16 -/* - * This value determines the Moderation_Timer_Clock speed. - * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. - * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. - * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. - */ -#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_RES_MASK 0x0F000000 -#define PCIE_W_INT_GRP_A_CONTROL_A_MOD_RES_SHIFT 24 - -/**** cause_B register ****/ -/* Indicates that the core received a PM_PME Message. Write Zero to clear. */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_PM_PME (1 << 0) -/* - * Indicates that the core received a PME_TO_Ack Message. Write Zero to clear. - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_PM_TO_ACK (1 << 1) -/* - * Indicates that the core received an PME_Turn_Off Message. Write Zero to - * clear. - * EP mode only - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_PM_TURNOFF (1 << 2) -/* Indicates that the core received an ERR_CORR Message. Write Zero to clear. */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_CORRECTABLE_ERR (1 << 3) -/* - * Indicates that the core received an ERR_NONFATAL Message. Write Zero to - * clear. - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_NONFATAL_ERR (1 << 4) -/* - * Indicates that the core received an ERR_FATAL Message. Write Zero to clear. - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_FATAL_ERR (1 << 5) -/* - * Indicates that the core received a Vendor Defined Message. Write Zero to - * clear. - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_VENDOR_0 (1 << 6) -/* - * Indicates that the core received a Vendor Defined Message. Write Zero to - * clear. - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_VENDOR_1 (1 << 7) -/* Indicates that the core received an Unlock Message. Write Zero to clear. */ -#define PCIE_W_INT_GRP_B_CAUSE_B_MSG_UNLOCK (1 << 8) -/* - * Notification when the Link Autonomous Bandwidth Status register (Link Status - * register bit 15) is updated and the Link Autonomous Bandwidth Interrupt - * Enable (Link Control register bit 11) is set. This bit is not applicable to, - * and is reserved, for Endpoint device. Write Zero to clear - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_LINK_AUTO_BW_INT (1 << 12) -/* - * Notification that the Link Equalization Request bit in the Link Status 2 - * Register has been set. Write Zero to clear. - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_LINK_EQ_REQ_INT (1 << 13) -/* - * OB Vendor message request is granted by the PCIe core Write Zero to clear. - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_VENDOR_MSG_GRANT (1 << 14) -/* CPL timeout from the PCIe core inidication. Write Zero to clear */ -#define PCIE_W_INT_GRP_B_CAUSE_B_CMP_TIME_OUT (1 << 15) -/* - * Slave Response Composer Lookup Error - * Indicates that an overflow occurred in a lookup table of the Inbound - * responses. This indicates that there was a violation of the number of - * outstanding NP requests issued for the Outbound direction. Write zero to - * clear - */ -#define PCIE_W_INT_GRP_B_CAUSE_B_RADMX_CMPOSER_LOOKUP_ERR (1 << 16) -/* Parity Error */ -#define PCIE_W_INT_GRP_B_CAUSE_B_PARITY_ERROR_CORE (1 << 17) - -/**** control_B register ****/ -/* When Clear_on_Read =1, all bits of the Cause register are cleared on read. */ -#define PCIE_W_INT_GRP_B_CONTROL_B_CLEAR_ON_READ (1 << 0) -/* - * (Must be set only when MSIX is enabled.) - * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its - * corresponding bit in the Mask register is set, masking future interrupts. - */ -#define PCIE_W_INT_GRP_B_CONTROL_B_AUTO_MASK (1 << 1) -/* - * Auto_Clear (RW) - * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared - * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. - */ -#define PCIE_W_INT_GRP_B_CONTROL_B_AUTO_CLEAR (1 << 2) -/* - * When Set_on_Posedge =1, the bits in the interrupt Cause register are set on - * the posedge of the interrupt source, i.e., when Interrupt Source =1 and - * Interrupt Status = 0. - * When Set_on_Posedge =0, the bits in the Interrupt Cause register are set when - * Interrupt Source =1. - */ -#define PCIE_W_INT_GRP_B_CONTROL_B_SET_ON_POSEDGE (1 << 3) -/* - * When Moderation_Reset =1, all Moderation timers associated with the interrupt - * cause bits are cleared to 0, enabling an immediate interrupt assertion if any - * unmasked cause bit is set to 1. This bit is self-negated. - */ -#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_RST (1 << 4) -/* - * When mask_msi_x =1, no MSI-X from this group is sent. This bit must be set to - * 1 when the associated summary bit in this group is used to generate a single - * MSI-X for this group. - */ -#define PCIE_W_INT_GRP_B_CONTROL_B_MASK_MSI_X (1 << 5) -/* MSI-X AWID value. Same ID for all cause bits. */ -#define PCIE_W_INT_GRP_B_CONTROL_B_AWID_MASK 0x00000F00 -#define PCIE_W_INT_GRP_B_CONTROL_B_AWID_SHIFT 8 -/* - * This value determines the interval between interrupts. Writing ZERO disables - * Moderation. - */ -#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_INTV_MASK 0x00FF0000 -#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_INTV_SHIFT 16 -/* - * This value determines the Moderation_Timer_Clock speed. - * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. - * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. - * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. - */ -#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_RES_MASK 0x0F000000 -#define PCIE_W_INT_GRP_B_CONTROL_B_MOD_RES_SHIFT 24 - -/**** cause_C register ****/ -/* VPD interrupt, ot read/write frpm EEPROM */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_VPD_INT_FUNC_MASK 0x0000000F -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_VPD_INT_FUNC_SHIFT 0 -/* flr PF active */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_FLR_PF_ACTIVE_MASK 0x000000F0 -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_FLR_PF_ACTIVE_SHIFT 4 -/* System ERR RC. */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_SYS_ERR_RC_MASK 0x00000F00 -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_SYS_ERR_RC_SHIFT 8 -/* AER RC INT */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_AER_RC_ERR_INT_MASK 0x0000F000 -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_AER_RC_ERR_INT_SHIFT 12 -/* AER RC MSI */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_AER_RC_ERR_MSI_MASK 0x000F0000 -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_AER_RC_ERR_MSI_SHIFT 16 -/* PME MSI */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_PME_MSI_MASK 0x00F00000 -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_PME_MSI_SHIFT 20 -/* PME int */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_PME_INT_MASK 0x0F000000 -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_CFG_PME_INT_SHIFT 24 -/* SB overflow */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_RADM_QOVERFLOW (1 << 28) -/* ecrc was injected through the diag_ctrl bus */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_ECRC_INJECTED (1 << 29) -/* lcrc was injected through the diag_ctrl bus */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_LCRC_INJECTED (1 << 30) -/* lcrc was injected through the diag_ctrl bus */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CAUSE_GRP_C_RSRVD (1 << 31) - -/**** control_C register ****/ -/* When Clear_on_Read =1, all bits of Cause register are cleared on read. */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_CLEAR_ON_READ (1 << 0) -/* - * (Must be set only when MSIX is enabled.) - * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its - * corresponding bit in the Mask register is set, masking future interrupts. - */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_AUTO_MASK (1 << 1) -/* - * Auto_Clear (RW) - * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared - * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. - */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_AUTO_CLEAR (1 << 2) -/* - * When Set_on_Posedge =1, the bits in the Interrupt Cause register are set on - * the posedge of the interrupt source, i.e., when interrupt source =1 and - * Interrupt Status = 0. - * When Set_on_Posedge =0, the bits in the Interrupt Cause register are set when - * interrupt source =1. - */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_SET_ON_POSEDGE (1 << 3) -/* - * When Moderation_Reset =1, all Moderation timers associated with the interrupt - * cause bits are cleared to 0, enabling immediate interrupt assertion if any - * unmasked cause bit is set to 1. This bit is self-negated. - */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_RST (1 << 4) -/* - * When mask_msi_x =1, no MSI-X from this group is sent. This bit must be set to - * 1 when the associated summary bit in this group is used to generate a single - * MSI-X for this group. - */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MASK_MSI_X (1 << 5) -/* MSI-X AWID value. Same ID for all cause bits. */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_AWID_MASK 0x00000F00 -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_AWID_SHIFT 8 -/* - * This value determines the interval between interrupts; writing ZERO disables - * Moderation. - */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_INTV_MASK 0x00FF0000 -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_INTV_SHIFT 16 -/* - * This value determines the Moderation_Timer_Clock speed. - * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. - * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. - * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. - */ -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_RES_MASK 0x0F000000 -#define PCIE_W_INTERRUPT_GRP_C_INT_CONTROL_GRP_C_MOD_RES_SHIFT 24 - -/**** control_D register ****/ -/* When Clear_on_Read =1, all bits of Cause register are cleared on read. */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_CLEAR_ON_READ (1 << 0) -/* - * (Must be set only when MSIX is enabled.) - * When Auto-Mask =1 and an MSI-X ACK for this bit is received, its - * corresponding bit in the Mask register is set, masking future interrupts. - */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_AUTO_MASK (1 << 1) -/* - * Auto_Clear (RW) - * When Auto-Clear =1, the bits in the Interrupt Cause register are auto-cleared - * after MSI-X is acknowledged. Must be used only if MSI-X is enabled. - */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_AUTO_CLEAR (1 << 2) -/* - * When Set_on_Posedge =1, the bits in the Interrupt Cause register are set on - * the posedge of the interrupt source, i.e., when interrupt source =1 and - * Interrupt Status = 0. - * When Set_on_Posedge =0, the bits in the Interrupt Cause register are set when - * interrupt source =1. - */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_SET_ON_POSEDGE (1 << 3) -/* - * When Moderation_Reset =1, all Moderation timers associated with the interrupt - * cause bits are cleared to 0, enabling immediate interrupt assertion if any - * unmasked cause bit is set to 1. This bit is self-negated. - */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_RST (1 << 4) -/* - * When mask_msi_x =1, no MSI-X from this group is sent. This bit must be set to - * 1 when the associated summary bit in this group is used to generate a single - * MSI-X for this group. - */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MASK_MSI_X (1 << 5) -/* MSI-X AWID value. Same ID for all cause bits. */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_AWID_MASK 0x00000F00 -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_AWID_SHIFT 8 -/* - * This value determines the interval between interrupts; writing ZERO disables - * Moderation. - */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_INTV_MASK 0x00FF0000 -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_INTV_SHIFT 16 -/* - * This value determines the Moderation_Timer_Clock speed. - * 0- Moderation-timer is decremented every 1x256 SB clock cycles ~1uS. - * 1- Moderation-timer is decremented every 2x256 SB clock cycles ~2uS. - * N- Moderation-timer is decremented every Nx256 SB clock cycles ~(N+1) uS. - */ -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_RES_MASK 0x0F000000 -#define PCIE_W_INTERRUPT_GRP_D_INT_CONTROL_GRP_D_MOD_RES_SHIFT 24 -#ifdef __cplusplus -} -#endif - -#endif /* __AL_HAL_PCIE_W_REG_H */ - -/** @} end of ... group */ - - diff --git a/sys/arm/annapurna/alpine/hal/al_hal_plat_services.h b/sys/arm/annapurna/alpine/hal/al_hal_plat_services.h deleted file mode 100644 index 217bb927f69f..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_plat_services.h +++ /dev/null @@ -1,419 +0,0 @@ -/*- -******************************************************************************* -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @defgroup group_services Platform Services API - * @{ - * The Platform Services API provides miscellaneous system services to HAL - * drivers, such as: - * - Registers read/write - * - Assertions - * - Memory barriers - * - Endianness conversions - * - * And more. - * @file plat_api/sample/al_hal_plat_services.h - * - * @brief API for Platform services provided for to HAL drivers - * - * - */ - -#ifndef __PLAT_SERVICES_H__ -#define __PLAT_SERVICES_H__ - -#include -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -/* Prototypes for all the bus_space structure functions */ -bs_protos(generic); -bs_protos(generic_armv4); - -#define __UNUSED __attribute__((unused)) - -/* *INDENT-OFF* */ -#ifdef __cplusplus -extern "C" { -#endif -/* *INDENT-ON* */ - -/* - * WMA: This is a hack which allows not modifying the __iomem accessing HAL code. - * On ARMv7, bus_handle holds the information about VA of accessed memory. It - * is possible to use direct load/store instruction instead of bus_dma machinery. - * WARNING: This is not guaranteed to stay that way forever, nor that - * on other architectures these variables behave similarly. Keep that - * in mind during porting to other systems. - */ -/** - * Read MMIO 8 bits register - * @param offset register offset - * - * @return register value - */ -static uint8_t al_reg_read8(uint8_t * offset); - -/** - * Read MMIO 16 bits register - * @param offset register offset - * - * @return register value - */ -static uint16_t al_reg_read16(uint16_t * offset); - -/** - * Read MMIO 32 bits register - * @param offset register offset - * - * @return register value - */ -static uint32_t al_reg_read32(uint32_t * offset); - -/** - * Read MMIO 64 bits register - * @param offset register offset - * - * @return register value - */ -uint64_t al_reg_read64(uint64_t * offset); - -/** - * Relaxed read MMIO 32 bits register - * - * Relaxed register read/write functions don't involve cpu instructions that - * force syncronization, nor ordering between the register access and memory - * data access. - * These instructions are used in performance critical code to avoid the - * overhead of the synchronization instructions. - * - * @param offset register offset - * - * @return register value - */ -#define al_bus_dma_to_va(bus_tag, bus_handle) ((void*)bus_handle) - -/** - * Relaxed read MMIO 32 bits register - * - * Relaxed register read/write functions don't involve cpu instructions that - * force syncronization, nor ordering between the register access and memory - * data access. - * These instructions are used in performance critical code to avoid the - * overhead of the synchronization instructions. - * - * @param offset register offset - * - * @return register value - */ -#define al_reg_read32_relaxed(l) generic_bs_r_4(NULL, (bus_space_handle_t)l, 0) - -/** - * Relaxed write to MMIO 32 bits register - * - * Relaxed register read/write functions don't involve cpu instructions that - * force syncronization, nor ordering between the register access and memory - * data access. - * These instructions are used in performance critical code to avoid the - * overhead of the synchronization instructions. - * - * @param offset register offset - * @param val value to write to the register - */ -#define al_reg_write32_relaxed(l,v) generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v) - -/** - * Write to MMIO 8 bits register - * @param offset register offset - * @param val value to write to the register - */ -#define al_reg_write8(l,v) do { dsb(); generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) - -/** - * Write to MMIO 16 bits register - * @param offset register offset - * @param val value to write to the register - */ -#define al_reg_write16(l,v) do { dsb(); generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) - -/** - * Write to MMIO 32 bits register - * @param offset register offset - * @param val value to write to the register - */ -#define al_reg_write32(l,v) do { dsb(); generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) - -/** - * Write to MMIO 64 bits register - * @param offset register offset - * @param val value to write to the register - */ -#define al_reg_write64(l,v) do { dsb(); generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0) - -static inline uint8_t -al_reg_read8(uint8_t *l) -{ - dsb(); - - return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0)); -} - -static inline uint16_t -al_reg_read16(uint16_t *l) -{ - dsb(); - - return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0)); -} - -static inline uint32_t -al_reg_read32(uint32_t *l) -{ - dsb(); - - return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0)); -} - -#define AL_DBG_LEVEL_NONE 0 -#define AL_DBG_LEVEL_ERR 1 -#define AL_DBG_LEVEL_WARN 2 -#define AL_DBG_LEVEL_INFO 3 -#define AL_DBG_LEVEL_DBG 4 - -#define AL_DBG_LEVEL AL_DBG_LEVEL_ERR - -extern struct mtx al_dbg_lock; - -#define AL_DBG_LOCK() mtx_lock_spin(&al_dbg_lock) -#define AL_DBG_UNLOCK() mtx_unlock_spin(&al_dbg_lock) - -/** - * print message - * - * @param format The format string - * @param ... Additional arguments - */ -#define al_print(type, fmt, ...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_NONE) { AL_DBG_LOCK(); printf(fmt, ##__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) - -/** - * print error message - * - * @param format - */ -#define al_err(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_ERR) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) - -/** - * print warning message - * - * @param format - */ -#define al_warn(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_WARN) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) - -/** - * print info message - * - * @param format - */ -#define al_info(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_INFO) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) - -/** - * print debug message - * - * @param format - */ -#define al_dbg(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_DBG) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0) - -/** - * Assertion - * - * @param condition - */ -#define al_assert(COND) \ - do { \ - if (!(COND)) \ - al_err( \ - "%s:%d:%s: Assertion failed! (%s)\n", \ - __FILE__, __LINE__, __func__, #COND); \ - } while(AL_FALSE) - -/** - * Make sure data will be visible by other masters (other CPUS and DMA). - * usually this is achieved by the ARM DMB instruction. - */ -static void al_data_memory_barrier(void); - -/** - * Make sure data will be visible by DMA masters, no restriction for other cpus - */ -static inline void -al_data_memory_barrier(void) -{ - dsb(); -} - -/** - * Make sure data will be visible in order by other cpus masters. - */ -static inline void -al_smp_data_memory_barrier(void) -{ - dsb(); -} - -/** - * Make sure write data will be visible in order by other cpus masters. - */ -static inline void -al_local_data_memory_barrier(void) -{ - dsb(); -} - -/** - * al_udelay - micro sec delay - */ -#define al_udelay(u) DELAY(u) - -/** - * al_msleep - mili sec delay - */ -#define al_msleep(m) DELAY((m) * 1000) - -/** - * swap half word to little endian - * - * @param x 16 bit value - * - * @return the value in little endian - */ -#define swap16_to_le(x) htole16(x) -/** - * swap word to little endian - * - * @param x 32 bit value - * - * @return the value in little endian - */ -#define swap32_to_le(x) htole32(x) - -/** - * swap 8 bytes to little endian - * - * @param x 64 bit value - * - * @return the value in little endian - */ -#define swap64_to_le(x) htole64(x) - -/** - * swap half word from little endian - * - * @param x 16 bit value - * - * @return the value in the cpu endianess - */ -#define swap16_from_le(x) le16toh(x) - -/** - * swap word from little endian - * - * @param x 32 bit value - * - * @return the value in the cpu endianess - */ -#define swap32_from_le(x) le32toh(x) - -/** - * swap 8 bytes from little endian - * - * @param x 64 bit value - * - * @return the value in the cpu endianess - */ -#define swap64_from_le(x) le64toh(x) - -/** - * Memory set - * - * @param p memory pointer - * @param val value for setting - * @param cnt number of bytes to set - */ -#define al_memset(p, val, cnt) memset(p, val, cnt) - -/** - * Memory copy - * - * @param p1 memory pointer - * @param p2 memory pointer - * @param cnt number of bytes to copy - */ -#define al_memcpy(p1, p2, cnt) memcpy(p1, p2, cnt) - -/** - * Memory compare - * - * @param p1 memory pointer - * @param p2 memory pointer - * @param cnt number of bytes to compare - */ -#define al_memcmp(p1, p2, cnt) memcmp(p1, p2, cnt) - -/** - * String compare - * - * @param s1 string pointer - * @param s2 string pointer - */ -#define al_strcmp(s1, s2) strcmp(s1, s2) - -#define al_get_cpu_id() 0 - -/* *INDENT-OFF* */ -#ifdef __cplusplus -} -#endif -/* *INDENT-ON* */ -/** @} end of Platform Services API group */ -#endif /* __PLAT_SERVICES_H__ */ diff --git a/sys/arm/annapurna/alpine/hal/al_hal_plat_types.h b/sys/arm/annapurna/alpine/hal/al_hal_plat_types.h deleted file mode 100644 index 43896ae08f71..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_plat_types.h +++ /dev/null @@ -1,94 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @defgroup group_services Platform Services API - * @{ - * @file plat_api/sample/al_hal_plat_types.h - * - */ - -#ifndef __PLAT_TYPES_H__ -#define __PLAT_TYPES_H__ - -#include -#include -#include -#include - -/* *INDENT-OFF* */ -#ifdef __cplusplus -extern "C" { -#endif -/* *INDENT-ON* */ - -/* Basic data types */ -typedef int al_bool; /** boolean */ -#define AL_TRUE 1 -#define AL_FALSE 0 - - -/* define types */ -#ifndef AL_HAVE_TYPES -typedef unsigned char uint8_t; /** unsigned 8 bits */ -typedef unsigned short uint16_t; /** unsigned 16 bits */ -typedef unsigned int uint32_t; /** unsigned 32 bits */ -typedef unsigned long long uint64_t; /** unsigned 64 bits */ - -typedef signed char int8_t; /** signed 8 bits */ -typedef short int int16_t; /** signed 16 bits */ -typedef signed int int32_t; /** signed 32 bits */ - -/** An unsigned int that is guaranteed to be the same size as a pointer */ -/** C99 standard */ -typedef unsigned long uintptr_t; -#endif - - -/** in LPAE mode, the address address is 40 bit, we extend it to 64 bit */ -typedef uint64_t al_phys_addr_t; - -/** this defines the cpu endiancess. */ -#define PLAT_ARCH_IS_LITTLE() AL_TRUE - -/* *INDENT-OFF* */ -#ifdef __cplusplus -} -#endif -/* *INDENT-ON* */ -/** @} end of Platform Services API group */ - -#endif /* __PLAT_TYPES_H__ */ diff --git a/sys/arm/annapurna/alpine/hal/al_hal_reg_utils.h b/sys/arm/annapurna/alpine/hal/al_hal_reg_utils.h deleted file mode 100644 index f29c3c5247b5..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_reg_utils.h +++ /dev/null @@ -1,188 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @defgroup group_common HAL Common Layer - * @{ - * @file al_hal_reg_utils.h - * - * @brief Register utilities used by HALs and platform layer - * - * - */ - -#ifndef __AL_HAL_REG_UTILS_H__ -#define __AL_HAL_REG_UTILS_H__ - -#include "al_hal_plat_types.h" -#include "al_hal_plat_services.h" - -/* *INDENT-OFF* */ -#ifdef __cplusplus -extern "C" { -#endif -/* *INDENT-ON* */ - -#define AL_BIT(b) (1UL << (b)) - -#define AL_ADDR_LOW(x) ((uint32_t)((al_phys_addr_t)(x))) -#define AL_ADDR_HIGH(x) ((uint32_t)((((al_phys_addr_t)(x)) >> 16) >> 16)) - -/** get field out of 32 bit register */ -#define AL_REG_FIELD_GET(reg, mask, shift) (((reg) & (mask)) >> (shift)) - -/** set field of 32 bit register */ -#define AL_REG_FIELD_SET(reg, mask, shift, val) \ - (reg) = \ - (((reg) & (~(mask))) | \ - ((((unsigned)(val)) << (shift)) & (mask))) - -/** set field of 64 bit register */ -#define AL_REG_FIELD_SET_64(reg, mask, shift, val) \ - ((reg) = \ - (((reg) & (~(mask))) | \ - ((((uint64_t)(val)) << (shift)) & (mask)))) - -/** get single bit out of 32 bit register */ -#define AL_REG_BIT_GET(reg, shift) \ - AL_REG_FIELD_GET(reg, AL_BIT(shift), shift) - -#define AL_REG_BITS_FIELD(shift, val) \ - (((unsigned)(val)) << (shift)) - -/** set single bit field of 32 bit register to a given value */ -#define AL_REG_BIT_VAL_SET(reg, shift, val) \ - AL_REG_FIELD_SET(reg, AL_BIT(shift), shift, val) - -/** set single bit of 32 bit register to 1 */ -#define AL_REG_BIT_SET(reg, shift) \ - AL_REG_BIT_VAL_SET(reg, shift, 1) - -/** clear single bit of 32 bit register */ -#define AL_REG_BIT_CLEAR(reg, shift) \ - AL_REG_BIT_VAL_SET(reg, shift, 0) - - -#define AL_BIT_MASK(n) \ - (AL_BIT(n) - 1) - -#define AL_FIELD_MASK(msb, lsb) \ - (AL_BIT(msb) + AL_BIT_MASK(msb) - AL_BIT_MASK(lsb)) - -/** clear bits specified by clear_mask */ -#define AL_REG_MASK_CLEAR(reg, clear_mask) \ - ((reg) = (((reg) & (~(clear_mask))))) - -/** set bits specified by clear_mask */ -#define AL_REG_MASK_SET(reg, clear_mask) \ - ((reg) = (((reg) | (clear_mask)))) - - -/** clear bits specified by clear_mask, and set bits specified by set_mask */ -#define AL_REG_CLEAR_AND_SET(reg, clear_mask, set_mask) \ - (reg) = (((reg) & (~(clear_mask))) | (set_mask)) - -#define AL_ALIGN_UP(val, size) \ - ((size) * (((val) + (size) - 1) / (size))) - -/** take bits selected by mask from one data, the rest from background */ -#define AL_MASK_VAL(mask, data, background) \ - (((mask) & (data)) | ((~mask) & (background))) - -/** - * 8 bits register masked write - * - * @param reg - * register address - * @param mask - * bits not selected (1) by mask will be left unchanged - * @param data - * data to write. bits not selected by mask ignored. - */ -static inline void -al_reg_write8_masked(uint8_t __iomem *reg, uint8_t mask, uint8_t data) -{ - uint8_t temp; - temp = al_reg_read8(reg); - al_reg_write8(reg, AL_MASK_VAL(mask, data, temp)); -} - - -/** - * 16 bits register masked write - * - * @param reg - * register address - * @param mask - * bits not selected (1) by mask will be left unchanged - * @param data - * data to write. bits not selected by mask ignored. - */ -static inline void -al_reg_write16_masked(uint16_t __iomem *reg, uint16_t mask, uint16_t data) -{ - uint16_t temp; - temp = al_reg_read16(reg); - al_reg_write16(reg, AL_MASK_VAL(mask, data, temp)); -} - - -/** - * 32 bits register masked write - * - * @param reg - * register address - * @param mask - * bits not selected (1) by mask will be left unchanged - * @param data - * data to write. bits not selected by mask ignored. - */ -static inline void -al_reg_write32_masked(uint32_t __iomem *reg, uint32_t mask, uint32_t data) -{ - uint32_t temp; - temp = al_reg_read32(reg); - al_reg_write32(reg, AL_MASK_VAL(mask, data, temp)); -} - -/* *INDENT-OFF* */ -#ifdef __cplusplus -} -#endif -/* *INDENT-ON* */ -/** @} end of Common group */ -#endif - diff --git a/sys/arm/annapurna/alpine/hal/al_hal_types.h b/sys/arm/annapurna/alpine/hal/al_hal_types.h deleted file mode 100644 index cea839dcfdcc..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_types.h +++ /dev/null @@ -1,117 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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. - -*******************************************************************************/ - -/** - * @defgroup group_common HAL Common Layer - * @{ - * @file al_hal_types.h - * - * @brief macros used by HALs and platform layer - * - */ - -#ifndef __AL_HAL_TYPES_H__ -#define __AL_HAL_TYPES_H__ - -#include "al_hal_plat_types.h" -#include "al_hal_plat_services.h" - -/* *INDENT-OFF* */ -#ifdef __cplusplus -extern "C" { -#endif -/* *INDENT-ON* */ - -/* Common defines */ - -#if (!AL_TRUE) || (AL_FALSE) -#error "AL_TRUE must be non zero and AL_FALSE must be zero" -#endif - -typedef int AL_RETURN; - -#if !defined(NULL) -#define NULL (void *)0 -#endif - -#if !defined(likely) -#define likely(x) (__builtin_expect(!!(x), 1)) -#define unlikely(x) (__builtin_expect(!!(x), 0)) -#endif - - -#ifdef __GNUC__ -#if !defined(__packed) -#define __packed __attribute__ ((packed)) -#endif - /* packed and alinged types */ -#define __packed_a4 __attribute__ ((packed, aligned(4))) -#define __packed_a8 __attribute__ ((packed, aligned(8))) -#define __packed_a16 __attribute__ ((packed, aligned(16))) - -#else -#if !defined(__packed) -#error "__packed is not defined!!" -#endif -#endif - -#if !defined(__iomem) -#define __iomem -#endif - -#if !defined(__cache_aligned) -#ifdef __GNUC__ -#define __cache_aligned __attribute__ ((__aligned__(64))) -#else -#define __cache_aligned -#endif -#endif - -#if !defined(INLINE) -#ifdef __GNUC__ -#define INLINE inline -#else -#define INLINE -#endif -#endif - -/* *INDENT-OFF* */ -#ifdef __cplusplus -} -#endif -/* *INDENT-ON* */ -/** @} end of Common group */ -#endif /* __TYPES_H__ */ diff --git a/sys/arm/annapurna/alpine/hal/al_hal_unit_adapter_regs.h b/sys/arm/annapurna/alpine/hal/al_hal_unit_adapter_regs.h deleted file mode 100644 index 740b959ab43e..000000000000 --- a/sys/arm/annapurna/alpine/hal/al_hal_unit_adapter_regs.h +++ /dev/null @@ -1,314 +0,0 @@ -/*- -******************************************************************************** -Copyright (C) 2015 Annapurna Labs Ltd. - -This file may be licensed under the terms of the Annapurna Labs Commercial -License Agreement. - -Alternatively, this file can be distributed under the terms of the GNU General -Public License V2 as published by the Free Software Foundation and can be -found at http://www.gnu.org/licenses/gpl-2.0.html - -Alternatively, 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. - -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 __AL_HAL_UNIT_ADAPTER_REGS_H__ -#define __AL_HAL_UNIT_ADAPTER_REGS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define AL_PCI_COMMAND 0x04 /* 16 bits */ -#define AL_PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ -#define AL_PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ -#define AL_PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ - -#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */ - -#define AL_PCI_BASE_ADDRESS_SPACE_IO 0x01 -#define AL_PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ -#define AL_PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ -#define AL_PCI_BASE_ADDRESS_DEVICE_ID 0x0c - -#define AL_PCI_BASE_ADDRESS_0 0x10 -#define AL_PCI_BASE_ADDRESS_0_HI 0x14 -#define AL_PCI_BASE_ADDRESS_2 0x18 -#define AL_PCI_BASE_ADDRESS_2_HI 0x1c -#define AL_PCI_BASE_ADDRESS_4 0x20 -#define AL_PCI_BASE_ADDRESS_4_HI 0x24 - -#define AL_PCI_EXP_ROM_BASE_ADDRESS 0x30 - -#define AL_PCI_AXI_CFG_AND_CTR_0 0x110 -#define AL_PCI_AXI_CFG_AND_CTR_1 0x130 -#define AL_PCI_AXI_CFG_AND_CTR_2 0x150 -#define AL_PCI_AXI_CFG_AND_CTR_3 0x170 - -#define AL_PCI_APP_CONTROL 0x220 - -#define AL_PCI_SRIOV_TOTAL_AND_INITIAL_VFS 0x30c - -#define AL_PCI_VF_BASE_ADDRESS_0 0x324 - - -#define AL_PCI_EXP_CAP_BASE 0x40 -#define AL_PCI_EXP_DEVCAP 4 /* Device capabilities */ -#define AL_PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */ -#define AL_PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */ -#define AL_PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */ -#define AL_PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */ -#define AL_PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */ -#define AL_PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ -#define AL_PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ -#define AL_PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ -#define AL_PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */ -#define AL_PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ -#define AL_PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ -#define AL_PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ -#define AL_PCI_EXP_DEVCTL 8 /* Device Control */ -#define AL_PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ -#define AL_PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ -#define AL_PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */ -#define AL_PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */ -#define AL_PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */ -#define AL_PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */ -#define AL_PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */ -#define AL_PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */ -#define AL_PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ -#define AL_PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ -#define AL_PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ -#define AL_PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ -#define AL_PCI_EXP_DEVSTA 0xA /* Device Status */ -#define AL_PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ -#define AL_PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */ -#define AL_PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */ -#define AL_PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */ -#define AL_PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ -#define AL_PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ -#define AL_PCI_EXP_LNKCAP 0xC /* Link Capabilities */ -#define AL_PCI_EXP_LNKCAP_SLS 0xf /* Supported Link Speeds */ -#define AL_PCI_EXP_LNKCAP_SLS_2_5GB 0x1 /* LNKCAP2 SLS Vector bit 0 (2.5GT/s) */ -#define AL_PCI_EXP_LNKCAP_SLS_5_0GB 0x2 /* LNKCAP2 SLS Vector bit 1 (5.0GT/s) */ -#define AL_PCI_EXP_LNKCAP_MLW 0x3f0 /* Maximum Link Width */ -#define AL_PCI_EXP_LNKCAP_ASPMS 0xc00 /* ASPM Support */ -#define AL_PCI_EXP_LNKCAP_L0SEL 0x7000 /* L0s Exit Latency */ -#define AL_PCI_EXP_LNKCAP_L1EL 0x38000 /* L1 Exit Latency */ -#define AL_PCI_EXP_LNKCAP_CLKPM 0x40000 /* L1 Clock Power Management */ -#define AL_PCI_EXP_LNKCAP_SDERC 0x80000 /* Surprise Down Error Reporting Capable */ -#define AL_PCI_EXP_LNKCAP_DLLLARC 0x100000 /* Data Link Layer Link Active Reporting Capable */ -#define AL_PCI_EXP_LNKCAP_LBNC 0x200000 /* Link Bandwidth Notification Capability */ -#define AL_PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */ - -#define AL_PCI_EXP_LNKCTL 0x10 /* Link Control */ -#define AL_PCI_EXP_LNKCTL_LNK_DIS 0x4 /* Link Disable Status */ -#define AL_PCI_EXP_LNKCTL_LNK_RTRN 0x5 /* Link Retrain Status */ - -#define AL_PCI_EXP_LNKSTA 0x12 /* Link Status */ -#define AL_PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */ -#define AL_PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */ -#define AL_PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */ -#define AL_PCI_EXP_LNKSTA_CLS_8_0GB 0x03 /* Current Link Speed 8.0GT/s */ -#define AL_PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */ -#define AL_PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */ -#define AL_PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */ -#define AL_PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */ -#define AL_PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ -#define AL_PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */ -#define AL_PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */ - -#define AL_PCI_EXP_LNKCTL2 0x30 /* Link Control 2 */ - -#define AL_PCI_MSIX_MSGCTRL 0 /* MSIX message control reg */ -#define AL_PCI_MSIX_MSGCTRL_TBL_SIZE 0x7ff /* MSIX table size */ -#define AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT 16 /* MSIX table size shift */ -#define AL_PCI_MSIX_MSGCTRL_EN 0x80000000 /* MSIX enable */ -#define AL_PCI_MSIX_MSGCTRL_MASK 0x40000000 /* MSIX mask */ - -#define AL_PCI_MSIX_TABLE 0x4 /* MSIX table offset and bar reg */ -#define AL_PCI_MSIX_TABLE_OFFSET 0xfffffff8 /* MSIX table offset */ -#define AL_PCI_MSIX_TABLE_BAR 0x7 /* MSIX table BAR */ - -#define AL_PCI_MSIX_PBA 0x8 /* MSIX pba offset and bar reg */ -#define AL_PCI_MSIX_PBA_OFFSET 0xfffffff8 /* MSIX pba offset */ -#define AL_PCI_MSIX_PBA_BAR 0x7 /* MSIX pba BAR */ - - -/* Adapter power management register 0 */ -#define AL_ADAPTER_PM_0 0x80 -#define AL_ADAPTER_PM_0_PM_NEXT_CAP_MASK 0xff00 -#define AL_ADAPTER_PM_0_PM_NEXT_CAP_SHIFT 8 -#define AL_ADAPTER_PM_0_PM_NEXT_CAP_VAL_MSIX 0x90 - -/* Adapter power management register 1 */ -#define AL_ADAPTER_PM_1 0x84 -#define AL_ADAPTER_PM_1_PME_EN 0x100 /* PM enable */ -#define AL_ADAPTER_PM_1_PWR_STATE_MASK 0x3 /* PM state mask */ -#define AL_ADAPTER_PM_1_PWR_STATE_D3 0x3 /* PM D3 state */ - -/* Sub Master Configuration & Control */ -#define AL_ADAPTER_SMCC 0x110 -#define AL_ADAPTER_SMCC_CONF_2 0x114 - -/* Interrupt_Cause register */ -#define AL_ADAPTER_INT_CAUSE 0x1B0 -#define AL_ADAPTER_INT_CAUSE_WR_ERR AL_BIT(1) -#define AL_ADAPTER_INT_CAUSE_RD_ERR AL_BIT(0) - -/* AXI_Master_Write_Error_Attribute_Latch register */ -/* AXI_Master_Read_Error_Attribute_Latch register */ -#define AL_ADAPTER_AXI_MSTR_WR_ERR_ATTR 0x1B4 -#define AL_ADAPTER_AXI_MSTR_RD_ERR_ATTR 0x1B8 - -#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_STAT_MASK AL_FIELD_MASK(1, 0) -#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_STAT_SHIFT 0 -#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_MSTR_ID_MASK AL_FIELD_MASK(4, 2) -#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_MSTR_ID_SHIFT 2 -#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_ADDR_TO AL_BIT(8) -#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_ERR AL_BIT(9) -#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_TO AL_BIT(10) -#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_ERR_BLK AL_BIT(11) -#define AL_ADAPTER_AXI_MSTR_RD_ERR_ATTR_RD_PARITY_ERR AL_BIT(12) - -/* Interrupt_Cause_mask register */ -#define AL_ADAPTER_INT_CAUSE_MASK 0x1BC -#define AL_ADAPTER_INT_CAUSE_MASK_WR_ERR AL_BIT(1) -#define AL_ADAPTER_INT_CAUSE_MASK_RD_ERR AL_BIT(0) - -/* AXI_Master_write_error_address_Latch register */ -#define AL_ADAPTER_AXI_MSTR_WR_ERR_LO_LATCH 0x1C0 - -/* AXI_Master_write_error_address_high_Latch register */ -#define AL_ADAPTER_AXI_MSTR_WR_ERR_HI_LATCH 0x1C4 - -/* AXI_Master_read_error_address_Latch register */ -#define AL_ADAPTER_AXI_MSTR_RD_ERR_LO_LATCH 0x1C8 - -/* AXI_Master_read_error_address_high_Latch register */ -#define AL_ADAPTER_AXI_MSTR_RD_ERR_HI_LATCH 0x1CC - -/* AXI_Master_Timeout register */ -#define AL_ADAPTER_AXI_MSTR_TO 0x1D0 -#define AL_ADAPTER_AXI_MSTR_TO_WR_MASK AL_FIELD_MASK(31, 16) -#define AL_ADAPTER_AXI_MSTR_TO_WR_SHIFT 16 -#define AL_ADAPTER_AXI_MSTR_TO_RD_MASK AL_FIELD_MASK(15, 0) -#define AL_ADAPTER_AXI_MSTR_TO_RD_SHIFT 0 - -/* - * Generic control registers - */ - -/* Control 0 */ -#define AL_ADAPTER_GENERIC_CONTROL_0 0x1E0 -/* Control 2 */ -#define AL_ADAPTER_GENERIC_CONTROL_2 0x1E8 -/* Control 3 */ -#define AL_ADAPTER_GENERIC_CONTROL_3 0x1EC -/* Control 9 */ -#define AL_ADAPTER_GENERIC_CONTROL_9 0x218 -/* Control 10 */ -#define AL_ADAPTER_GENERIC_CONTROL_10 0x21C -/* Control 11 */ -#define AL_ADAPTER_GENERIC_CONTROL_11 0x220 -/* Control 12 */ -#define AL_ADAPTER_GENERIC_CONTROL_12 0x224 -/* Control 13 */ -#define AL_ADAPTER_GENERIC_CONTROL_13 0x228 -/* Control 14 */ -#define AL_ADAPTER_GENERIC_CONTROL_14 0x22C -/* Control 15 */ -#define AL_ADAPTER_GENERIC_CONTROL_15 0x230 -/* Control 16 */ -#define AL_ADAPTER_GENERIC_CONTROL_16 0x234 -/* Control 17 */ -#define AL_ADAPTER_GENERIC_CONTROL_17 0x238 -/* Control 18 */ -#define AL_ADAPTER_GENERIC_CONTROL_18 0x23C -/* Control 19 */ -#define AL_ADAPTER_GENERIC_CONTROL_19 0x240 - -/* Enable clock gating */ -#define AL_ADAPTER_GENERIC_CONTROL_0_CLK_GATE_EN 0x01 -/* When set, all transactions through the PCI conf & mem BARs get timeout */ -#define AL_ADAPTER_GENERIC_CONTROL_0_ADAPTER_DIS 0x40 -#define AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC AL_BIT(18) -#define AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC_ON_FLR AL_BIT(26) - -/* - * SATA registers only - */ -/* Select 125MHz free running clock from IOFAB main PLL as SATA OOB clock - * instead of using power management ref clock - */ -#define AL_ADAPTER_GENERIC_CONTROL_10_SATA_OOB_CLK_SEL AL_BIT(26) -/* AXUSER selection and value per bit (1 = address, 0 = register) */ -/* Rx */ -#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_VAL_MASK AL_FIELD_MASK(15, 0) -#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_VAL_SHIFT 0 -#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_SEL_MASK AL_FIELD_MASK(31, 16) -#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_SEL_SHIFT 16 -/* Tx */ -#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_MASK AL_FIELD_MASK(15, 0) -#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_SHIFT 0 -#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_MASK AL_FIELD_MASK(31, 16) -#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_SHIFT 16 -/* Central VMID enabler. If set, then each entry will be used as programmed */ -#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_SEL AL_BIT(0) -/* Allow access to store VMID values per entry */ -#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_ACCESS_EN AL_BIT(1) -/* VMID Address select */ -/* Tx */ -#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_MASK AL_FIELD_MASK(13, 8) -#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_SHIFT 8 -/* Rx */ -#define AL_ADPTR_GEN_CTL_14_SATA_VM_AWADDR_SEL_MASK AL_FIELD_MASK(21, 16) -#define AL_ADPTR_GEN_CTL_14_SATA_VM_AWADDR_SEL_SHIFT 16 -/* Address Value */ -/* Rx */ -#define AL_ADPTR_GEN_CTL_15_SATA_VM_AWDDR_HI AL_FIELD_MASK(31, 0) -/* Tx */ -#define AL_ADPTR_GEN_CTL_16_SATA_VM_ARDDR_HI AL_FIELD_MASK(31, 0) - -/* - * ROB registers - */ -/* Read ROB_Enable, when disabled the read ROB is bypassed */ -#define AL_ADPTR_GEN_CTL_19_READ_ROB_EN AL_BIT(0) -/* Read force in-order of every read transaction */ -#define AL_ADPTR_GEN_CTL_19_READ_ROB_FORCE_INORDER AL_BIT(1) -/* Read software reset */ -#define AL_ADPTR_GEN_CTL_19_READ_ROB_SW_RESET AL_BIT(15) -/* Write ROB_Enable, when disabled_the_Write ROB is bypassed */ -#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_EN AL_BIT(16) -/* Write force in-order of every write transaction */ -#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_FORCE_INORDER AL_BIT(17) -/* Write software reset */ -#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_SW_RESET AL_BIT(31) - -#ifdef __cplusplus -} -#endif - -#endif From 9028b18f7587fe90a497f4762418a2cb3d478d4d Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Thu, 30 Jul 2015 13:59:38 +0000 Subject: [PATCH 082/314] Enable IRQ during syscalls on ARM64 FreeBSD provides a feature called Adaptive Mutexes, which allows a thread to spin for a while when the mutex is taken instead of immediately going to sleep. This causes issues when called from syscall handler if interrupts are masked. If every other core also attempts to access the same mutex there is a chance that all of them are spinning on the same lock at the same time. If interrupts are disabled, no kernel preemtion can occur and the system becomes unresponsive. This patch enables interrupts when syscall is being executed and masks them as soon as it is completed. Reviewed by: andrew Obtained from: Semihalf Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3246 --- sys/arm64/arm64/trap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index 89c104f214a1..a8a00d157dd1 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -319,6 +319,12 @@ do_el0_sync(struct trapframe *frame) #endif break; case EXCP_SVC: + /* + * Ensure the svc_handler is being run with interrupts enabled. + * They will be automatically restored when returning from + * exception handler. + */ + intr_enable(); svc_handler(frame); break; case EXCP_INSN_ABORT_L: From c547d650ebefb5692d077b7d30c7d27619768661 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 30 Jul 2015 14:20:36 +0000 Subject: [PATCH 083/314] Add ARM64TODO markers to unimplemented functionality Reviewed by: andrew Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D2389 --- sys/arm64/arm64/elf_machdep.c | 4 ++-- sys/arm64/arm64/machdep.c | 12 ++++++------ sys/arm64/arm64/mem.c | 2 +- sys/arm64/arm64/pmap.c | 14 +++++++------- sys/arm64/arm64/stack_machdep.c | 4 ++-- sys/arm64/arm64/trap.c | 4 ++-- sys/arm64/arm64/uio_machdep.c | 2 +- sys/arm64/arm64/vm_machdep.c | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sys/arm64/arm64/elf_machdep.c b/sys/arm64/arm64/elf_machdep.c index 5702e7f0670e..08a297bbec7e 100644 --- a/sys/arm64/arm64/elf_machdep.c +++ b/sys/arm64/arm64/elf_machdep.c @@ -137,7 +137,7 @@ elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, elf_lookup_fn lookup __unused) { - panic("elf_reloc_local"); + panic("ARM64TODO: elf_reloc_local"); } /* Process one elf relocation with addend. */ @@ -146,7 +146,7 @@ elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, elf_lookup_fn lookup) { - panic("elf_reloc"); + panic("ARM64TODO: elf_reloc"); } int diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index f67211f2ec12..f2a8a25dcbd8 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -209,21 +209,21 @@ int fill_dbregs(struct thread *td, struct dbreg *regs) { - panic("fill_dbregs"); + panic("ARM64TODO: fill_dbregs"); } int set_dbregs(struct thread *td, struct dbreg *regs) { - panic("set_dbregs"); + panic("ARM64TODO: set_dbregs"); } int ptrace_set_pc(struct thread *td, u_long addr) { - panic("ptrace_set_pc"); + panic("ARM64TODO: ptrace_set_pc"); return (0); } @@ -376,7 +376,7 @@ void cpu_halt(void) { - panic("cpu_halt"); + panic("ARM64TODO: cpu_halt"); } /* @@ -387,7 +387,7 @@ void cpu_flush_dcache(void *ptr, size_t len) { - /* TBD */ + /* ARM64TODO TBD */ } /* Get current clock frequency for the given CPU ID. */ @@ -395,7 +395,7 @@ int cpu_est_clockrate(int cpu_id, uint64_t *rate) { - panic("cpu_est_clockrate"); + panic("ARM64TODO: cpu_est_clockrate"); } void diff --git a/sys/arm64/arm64/mem.c b/sys/arm64/arm64/mem.c index 70c0f574450a..373d0bf18c6a 100644 --- a/sys/arm64/arm64/mem.c +++ b/sys/arm64/arm64/mem.c @@ -42,6 +42,6 @@ int memrw(struct cdev *dev, struct uio *uio, int flags) { - panic("memrw"); + panic("ARM64TODO: memrw"); } diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 7e4182052bd6..224fd23f9d48 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -1434,7 +1434,7 @@ static vm_page_t reclaim_pv_chunk(pmap_t locked_pmap, struct rwlock **lockp) { - panic("reclaim_pv_chunk"); + panic("ARM64TODO: reclaim_pv_chunk"); } /* @@ -2881,7 +2881,7 @@ pmap_ts_referenced(vm_page_t m) * at all. We need to be able to set it in * the exception handler. */ - panic("TODO: safe_to_clear_referenced\n"); + panic("ARM64TODO: safe_to_clear_referenced\n"); } else if ((pmap_load(l3) & ATTR_SW_WIRED) == 0) { /* * Wired pages cannot be paged out so @@ -2949,7 +2949,7 @@ pmap_clear_modify(vm_page_t m) if ((m->aflags & PGA_WRITEABLE) == 0) return; - /* TODO: We lack support for tracking if a page is modified */ + /* ARM64TODO: We lack support for tracking if a page is modified */ } void * @@ -2971,7 +2971,7 @@ void pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) { - panic("pmap_page_set_memattr"); + panic("ARM64TODO: pmap_page_set_memattr"); } /* @@ -2981,7 +2981,7 @@ int pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa) { - panic("pmap_mincore"); + panic("ARM64TODO: pmap_mincore"); } void @@ -3001,7 +3001,7 @@ void pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz) { - panic("pmap_sync_icache"); + panic("ARM64TODO: pmap_sync_icache"); } /* @@ -3085,7 +3085,7 @@ pmap_unmap_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count, for (i = 0; i < count; i++) { paddr = VM_PAGE_TO_PHYS(page[i]); if (paddr >= DMAP_MAX_PHYSADDR) { - panic("pmap_unmap_io_transient: TODO: Unmap data"); + panic("ARM64TODO: pmap_unmap_io_transient: Unmap data"); } } } diff --git a/sys/arm64/arm64/stack_machdep.c b/sys/arm64/arm64/stack_machdep.c index a640077b75fb..7449eaa2199e 100644 --- a/sys/arm64/arm64/stack_machdep.c +++ b/sys/arm64/arm64/stack_machdep.c @@ -49,12 +49,12 @@ stack_save_td(struct stack *st, struct thread *td) if (TD_IS_RUNNING(td)) panic("stack_save_td: running"); - stack_zero(st); + stack_zero(st); /* ARM64TODO */ } void stack_save(struct stack *st) { - stack_zero(st); + stack_zero(st); /* ARM64TODO */ } diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index a8a00d157dd1..fad842145871 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -119,7 +119,7 @@ cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) sa->narg = sa->callp->sy_narg; memcpy(sa->args, ap, nap * sizeof(register_t)); if (sa->narg > nap) - panic("TODO: Could we have more then 8 args?"); + panic("ARM64TODO: Could we have more then 8 args?"); td->td_retval[0] = 0; td->td_retval[1] = 0; @@ -341,6 +341,6 @@ void do_el0_error(struct trapframe *frame) { - panic("do_el0_error"); + panic("ARM64TODO: do_el0_error"); } diff --git a/sys/arm64/arm64/uio_machdep.c b/sys/arm64/arm64/uio_machdep.c index e6f6d39f02be..11ed239fa9dd 100644 --- a/sys/arm64/arm64/uio_machdep.c +++ b/sys/arm64/arm64/uio_machdep.c @@ -124,7 +124,7 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) } out: if (__predict_false(mapped)) { - panic("TODO 3"); + panic("ARM64TODO: uiomove_fromphys"); pmap_unmap_io_transient(&ma[offset >> PAGE_SHIFT], &vaddr, 1, TRUE); } diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c index bd6d980145ee..f32901aa10a9 100644 --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -263,13 +263,13 @@ void * uma_small_alloc(uma_zone_t zone, vm_size_t bytes, u_int8_t *flags, int wait) { - panic("uma_small_alloc"); + panic("ARM64TODO: uma_small_alloc"); } void uma_small_free(void *mem, vm_size_t size, u_int8_t flags) { - panic("uma_small_free"); + panic("ARM64TODO: uma_small_free"); } From bc384415792476ee1a5eb105be421c1dbd9234a9 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Thu, 30 Jul 2015 14:31:09 +0000 Subject: [PATCH 084/314] GCC: Add a new option "-fstack-protector-strong" This includes additional functions to be protected: those that have local array definitions, or have references to local frame addresses. This is a new option in GCC-4.9 that was relicensed by Han Shen from Google under GPLv2 for OpenBSD. Obtained from: OpenBSD (2014-01-14) MFC after: 2 weeks --- contrib/gcc/c-cppbuiltin.c | 4 +- contrib/gcc/cfgexpand.c | 82 +++++++++++++++++++++++++++++++++---- contrib/gcc/common.opt | 4 ++ contrib/gcc/doc/cpp.texi | 4 ++ contrib/gcc/doc/gcc.1 | 7 +++- contrib/gcc/doc/invoke.texi | 7 +++- contrib/gcc/gcc.c | 2 +- 7 files changed, 99 insertions(+), 11 deletions(-) diff --git a/contrib/gcc/c-cppbuiltin.c b/contrib/gcc/c-cppbuiltin.c index 6b65cdf55571..511104f2f954 100644 --- a/contrib/gcc/c-cppbuiltin.c +++ b/contrib/gcc/c-cppbuiltin.c @@ -553,7 +553,9 @@ c_cpp_builtins (cpp_reader *pfile) /* Make the choice of the stack protector runtime visible to source code. The macro names and values here were chosen for compatibility with an earlier implementation, i.e. ProPolice. */ - if (flag_stack_protect == 2) + if (flag_stack_protect == 3) + cpp_define (pfile, "__SSP_STRONG__=3"); + else if (flag_stack_protect == 2) cpp_define (pfile, "__SSP_ALL__=2"); else if (flag_stack_protect == 1) cpp_define (pfile, "__SSP__=1"); diff --git a/contrib/gcc/cfgexpand.c b/contrib/gcc/cfgexpand.c index b688917cc72b..ccb534f0e18c 100644 --- a/contrib/gcc/cfgexpand.c +++ b/contrib/gcc/cfgexpand.c @@ -810,6 +810,12 @@ clear_tree_used (tree block) clear_tree_used (t); } +enum { + SPCT_FLAG_DEFAULT = 1, + SPCT_FLAG_ALL = 2, + SPCT_FLAG_STRONG = 3 +}; + /* Examine TYPE and determine a bit mask of the following features. */ #define SPCT_HAS_LARGE_CHAR_ARRAY 1 @@ -879,7 +885,8 @@ stack_protect_decl_phase (tree decl) if (bits & SPCT_HAS_SMALL_CHAR_ARRAY) has_short_buffer = true; - if (flag_stack_protect == 2) + if (flag_stack_protect == SPCT_FLAG_ALL + || flag_stack_protect == SPCT_FLAG_STRONG) { if ((bits & (SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_LARGE_CHAR_ARRAY)) && !(bits & SPCT_HAS_AGGREGATE)) @@ -947,12 +954,36 @@ create_stack_guard (void) cfun->stack_protect_guard = guard; } +/* Helper routine to check if a record or union contains an array field. */ + +static int +record_or_union_type_has_array_p (tree tree_type) +{ + tree fields = TYPE_FIELDS (tree_type); + tree f; + + for (f = fields; f; f = TREE_CHAIN (f)) + if (TREE_CODE (f) == FIELD_DECL) + { + tree field_type = TREE_TYPE (f); + if ((TREE_CODE (field_type) == RECORD_TYPE + || TREE_CODE (field_type) == UNION_TYPE + || TREE_CODE (field_type) == QUAL_UNION_TYPE) + && record_or_union_type_has_array_p (field_type)) + return 1; + if (TREE_CODE (field_type) == ARRAY_TYPE) + return 1; + } + return 0; +} + /* Expand all variables used in the function. */ static void expand_used_vars (void) { tree t, outer_block = DECL_INITIAL (current_function_decl); + bool gen_stack_protect_signal = false; /* Compute the phase of the stack frame for this function. */ { @@ -972,6 +1003,29 @@ expand_used_vars (void) has_protected_decls = false; has_short_buffer = false; + if (flag_stack_protect == SPCT_FLAG_STRONG) + for (t = cfun->unexpanded_var_list; t; t = TREE_CHAIN (t)) + { + tree var = TREE_VALUE (t); + if (!is_global_var (var)) + { + tree var_type = TREE_TYPE (var); + /* Examine local referenced variables that have their addresses + * taken, contain an array, or are arrays. */ + if (TREE_CODE (var) == VAR_DECL + && (TREE_CODE (var_type) == ARRAY_TYPE + || TREE_ADDRESSABLE (var) + || ((TREE_CODE (var_type) == RECORD_TYPE + || TREE_CODE (var_type) == UNION_TYPE + || TREE_CODE (var_type) == QUAL_UNION_TYPE) + && record_or_union_type_has_array_p (var_type)))) + { + gen_stack_protect_signal = true; + break; + } + } + } + /* At this point all variables on the unexpanded_var_list with TREE_USED set are not associated with any block scope. Lay them out. */ for (t = cfun->unexpanded_var_list; t; t = TREE_CHAIN (t)) @@ -1032,12 +1086,26 @@ expand_used_vars (void) dump_stack_var_partition (); } - /* There are several conditions under which we should create a - stack guard: protect-all, alloca used, protected decls present. */ - if (flag_stack_protect == 2 - || (flag_stack_protect - && (current_function_calls_alloca || has_protected_decls))) - create_stack_guard (); + switch (flag_stack_protect) + { + case SPCT_FLAG_ALL: + create_stack_guard (); + break; + + case SPCT_FLAG_STRONG: + if (gen_stack_protect_signal + || current_function_calls_alloca || has_protected_decls) + create_stack_guard (); + break; + + case SPCT_FLAG_DEFAULT: + if (current_function_calls_alloca || has_protected_decls) + create_stack_guard(); + break; + + default: + ; + } /* Assign rtl to each variable based on these partitions. */ if (stack_vars_num > 0) diff --git a/contrib/gcc/common.opt b/contrib/gcc/common.opt index 7dd3909aa5b9..c185d1f6a45a 100644 --- a/contrib/gcc/common.opt +++ b/contrib/gcc/common.opt @@ -878,6 +878,10 @@ fstack-protector-all Common Report RejectNegative Var(flag_stack_protect, 2) VarExists Use a stack protection method for every function +fstack-protector-strong +Common Report RejectNegative Var(flag_stack_protect, 3) +Use a smart stack protection method for certain functions + fstrength-reduce Common Does nothing. Preserved for backward compatibility. diff --git a/contrib/gcc/doc/cpp.texi b/contrib/gcc/doc/cpp.texi index 7c21c56e4c2a..26bc6b70080c 100644 --- a/contrib/gcc/doc/cpp.texi +++ b/contrib/gcc/doc/cpp.texi @@ -2134,6 +2134,10 @@ use. This macro is defined, with value 2, when @option{-fstack-protector-all} is in use. +@item __SSP_STRONG__ +This macro is defined, with value 3, when @option{-fstack-protector-strong} is +in use. + @item __TIMESTAMP__ This macro expands to a string constant that describes the date and time of the last modification of the current source file. The string constant diff --git a/contrib/gcc/doc/gcc.1 b/contrib/gcc/doc/gcc.1 index 1879d76955cc..8afd6aa317f6 100644 --- a/contrib/gcc/doc/gcc.1 +++ b/contrib/gcc/doc/gcc.1 @@ -339,7 +339,7 @@ in the following sections. \&\fB\-fsched2\-use\-superblocks \&\-fsched2\-use\-traces \-fsee \-freschedule\-modulo\-scheduled\-loops \&\-fsection\-anchors \-fsignaling\-nans \-fsingle\-precision\-constant -\&\-fstack\-protector \-fstack\-protector\-all +\&\-fstack\-protector \-fstack\-protector\-all \-fstack\-protector\-strong \&\-fstrict\-aliasing \-fstrict\-overflow \-ftracer \-fthread\-jumps \&\-funroll\-all\-loops \-funroll\-loops \-fpeel\-loops \&\-fsplit\-ivs\-in\-unroller \-funswitch\-loops @@ -5193,6 +5193,11 @@ If a guard check fails, an error message is printed and the program exits. .IP "\fB\-fstack\-protector\-all\fR" 4 .IX Item "-fstack-protector-all" Like \fB\-fstack\-protector\fR except that all functions are protected. +.IP "\fB\-fstack\-protector\-strong\fR" 4 +.IX Item "-fstack-protector-strong" +Like \fB\-fstack\-protector\fR but includes additional functions to +be protected \-\-\- those that have local array definitions, or have +references to local frame addresses. .IP "\fB\-fsection\-anchors\fR" 4 .IX Item "-fsection-anchors" Try to reduce the number of symbolic address calculations by using diff --git a/contrib/gcc/doc/invoke.texi b/contrib/gcc/doc/invoke.texi index 4779bbd1f765..2bf48c3cb8aa 100644 --- a/contrib/gcc/doc/invoke.texi +++ b/contrib/gcc/doc/invoke.texi @@ -331,7 +331,7 @@ in the following sections. -fsched2-use-superblocks @gol -fsched2-use-traces -fsee -freschedule-modulo-scheduled-loops @gol -fsection-anchors -fsignaling-nans -fsingle-precision-constant @gol --fstack-protector -fstack-protector-all @gol +-fstack-protector -fstack-protector-all -fstack-protector-strong @gol -fstrict-aliasing -fstrict-overflow -ftracer -fthread-jumps @gol -funroll-all-loops -funroll-loops -fpeel-loops @gol -fsplit-ivs-in-unroller -funswitch-loops @gol @@ -5810,6 +5810,11 @@ If a guard check fails, an error message is printed and the program exits. @item -fstack-protector-all Like @option{-fstack-protector} except that all functions are protected. +@item -fstack-protector-strong +Like @option{-fstack-protector} but includes additional functions to +be protected --- those that have local array definitions, or have +references to local frame addresses. + @item -fsection-anchors @opindex fsection-anchors Try to reduce the number of symbolic address calculations by using diff --git a/contrib/gcc/gcc.c b/contrib/gcc/gcc.c index 5ed3a82727f3..91e750add240 100644 --- a/contrib/gcc/gcc.c +++ b/contrib/gcc/gcc.c @@ -680,7 +680,7 @@ proper position among the other output files. */ #ifdef TARGET_LIBC_PROVIDES_SSP #define LINK_SSP_SPEC "%{fstack-protector:}" #else -#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}" +#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-strong|fstack-protector-all:-lssp_nonshared -lssp}" #endif #endif From 8f89a299e2a0717ccbfbc8156ac3f2566dfab83f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Thu, 30 Jul 2015 15:28:06 +0000 Subject: [PATCH 085/314] vfs: fix off-by-one error in vfs_buf_check_mapped The check added in r285872 can trigger for valid buffers if the buffer space used happens to be just after unmapped_buf in KVA space. Discussed with: kib Sponsored by: Citrix Systems R&D --- sys/kern/vfs_bio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index d46432d0b16e..4f5a1d42efa7 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -955,7 +955,7 @@ vfs_buf_check_mapped(struct buf *bp) ("mapped buf: b_kvabase was not updated %p", bp)); KASSERT(bp->b_data != unmapped_buf, ("mapped buf: b_data was not updated %p", bp)); - KASSERT(bp->b_data < unmapped_buf || bp->b_data > unmapped_buf + + KASSERT(bp->b_data < unmapped_buf || bp->b_data => unmapped_buf + MAXPHYS, ("b_data + b_offset unmapped %p", bp)); } From c023d8234b2fef534ea2f0018ff393727a182ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Thu, 30 Jul 2015 15:43:26 +0000 Subject: [PATCH 086/314] vfs: fill fallout from r286076 This right operator is >= not =>. Reported by: cem --- sys/kern/vfs_bio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 4f5a1d42efa7..5f68bde8cd1c 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -955,7 +955,7 @@ vfs_buf_check_mapped(struct buf *bp) ("mapped buf: b_kvabase was not updated %p", bp)); KASSERT(bp->b_data != unmapped_buf, ("mapped buf: b_data was not updated %p", bp)); - KASSERT(bp->b_data < unmapped_buf || bp->b_data => unmapped_buf + + KASSERT(bp->b_data < unmapped_buf || bp->b_data >= unmapped_buf + MAXPHYS, ("b_data + b_offset unmapped %p", bp)); } From 0b6476ec5b6b6a20a75558295324b88bed76618f Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 30 Jul 2015 15:47:53 +0000 Subject: [PATCH 087/314] Improve comments. Submitted by: bde MFC after: 2 weeks --- sys/amd64/include/atomic.h | 8 ++++---- sys/i386/include/atomic.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h index 30f594c3f7fe..33d79b2cdfb6 100644 --- a/sys/amd64/include/atomic.h +++ b/sys/amd64/include/atomic.h @@ -272,10 +272,10 @@ atomic_testandset_long(volatile u_long *p, u_int v) * addresses, so we need a Store/Load barrier for sequentially * consistent fences in SMP kernels. We use "lock addl $0,mem" for a * Store/Load barrier, as recommended by the AMD Software Optimization - * Guide, and not mfence. In the kernel, we use a private per-cpu - * cache line as the target for the locked addition, to avoid - * introducing false data dependencies. In user space, we use a word - * in the stack's red zone (-8(%rsp)). + * Guide, and not mfence. To avoid false data dependencies, we use a + * special address for "mem". In the kernel, we use a private per-cpu + * cache line. In user space, we use a word in the stack's red zone + * (-8(%rsp)). * * For UP kernels, however, the memory of the single processor is * always consistent, so we only need to stop the compiler from diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h index 15742a51d2a9..3242d76dce80 100644 --- a/sys/i386/include/atomic.h +++ b/sys/i386/include/atomic.h @@ -259,9 +259,9 @@ atomic_testandset_int(volatile u_int *p, u_int v) * consistent fences in SMP kernels. We use "lock addl $0,mem" for a * Store/Load barrier, as recommended by the AMD Software Optimization * Guide, and not mfence. In the kernel, we use a private per-cpu - * cache line as the target for the locked addition, to avoid - * introducing false data dependencies. In userspace, a word at the - * top of the stack is utilized. + * cache line for "mem", to avoid introducing false data + * dependencies. In user space, we use the word at the top of the + * stack. * * For UP kernels, however, the memory of the single processor is * always consistent, so we only need to stop the compiler from From 8df0053b7a1373aa0cff6c0cfe001110c8b3df9b Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 30 Jul 2015 16:17:44 +0000 Subject: [PATCH 088/314] Add enough of pmap_page_set_memattr to run gstat. It still needs to split the DMAP 1G pages so we set the attributes only on the specified page. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/arm64/pmap.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 224fd23f9d48..2a2c37cc4814 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -2971,7 +2971,17 @@ void pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) { - panic("ARM64TODO: pmap_page_set_memattr"); + m->md.pv_memattr = ma; + + /* + * ARM64TODO: Implement the below (from the amd64 pmap) + * If "m" is a normal page, update its direct mapping. This update + * can be relied upon to perform any cache operations that are + * required for data coherence. + */ + if ((m->flags & PG_FICTITIOUS) == 0 && + PHYS_IN_DMAP(VM_PAGE_TO_PHYS(m))) + panic("ARM64TODO: pmap_page_set_memattr"); } /* From 91ed97ddd8b798a1ed7cb317a67c3211b0bc1bfc Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Thu, 30 Jul 2015 17:02:23 +0000 Subject: [PATCH 089/314] Updat the committers graph Approved by: marcel (mentor) Differential Revision: https://reviews.freebsd.org/D3251 --- share/misc/committers-src.dot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index cdf8bab71d59..53628b33e295 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -106,6 +106,7 @@ adrian [label="Adrian Chadd\nadrian@FreeBSD.org\n2000/07/03"] ae [label="Andrey V. Elsukov\nae@FreeBSD.org\n2010/06/03"] akiyama [label="Shunsuke Akiyama\nakiyama@FreeBSD.org\n2000/06/19"] alc [label="Alan Cox\nalc@FreeBSD.org\n1999/02/23"] +allanjude [label="Allan Jude\nallanjude@FreeBSD.org\n2015/07/30"] ambrisko [label="Doug Ambrisko\nambrisko@FreeBSD.org\n2001/12/19"] anchie [label="Ana Kukec\nanchie@FreeBSD.org\n2010/04/14"] andre [label="Andre Oppermann\nandre@FreeBSD.org\n2003/11/12"] @@ -346,6 +347,7 @@ avg -> art avg -> pluknet avg -> smh +bapt -> allanjude bapt -> bdrewery benno -> grehan @@ -572,6 +574,7 @@ kib -> zont kmacy -> lstewart +marcel -> allanjude marcel -> art marcel -> arun marcel -> marius From 2736982e9b666edea6244e05e3e3dda53b5640a7 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Thu, 30 Jul 2015 18:08:08 +0000 Subject: [PATCH 090/314] Make some variables and functions static. --- usr.bin/ipcrm/ipcrm.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/usr.bin/ipcrm/ipcrm.c b/usr.bin/ipcrm/ipcrm.c index 32887e058ab5..c255ef81e5d0 100644 --- a/usr.bin/ipcrm/ipcrm.c +++ b/usr.bin/ipcrm/ipcrm.c @@ -50,18 +50,11 @@ __FBSDID("$FreeBSD$"); #include "ipc.h" -int signaled; -int errflg; -int rmverbose = 0; +static int signaled; +static int errflg; +static int rmverbose = 0; -void usage(void); - -int msgrm(key_t, int); -int shmrm(key_t, int); -int semrm(key_t, int); -void not_configured(int); - -void +static void usage(void) { @@ -72,7 +65,7 @@ usage(void) exit(1); } -int +static int msgrm(key_t key, int id) { @@ -113,7 +106,7 @@ msgrm(key_t key, int id) return msgctl(id, IPC_RMID, NULL); } -int +static int shmrm(key_t key, int id) { @@ -154,7 +147,7 @@ shmrm(key_t key, int id) return shmctl(id, IPC_RMID, NULL); } -int +static int semrm(key_t key, int id) { union semun arg; @@ -196,7 +189,7 @@ semrm(key_t key, int id) return semctl(id, 0, IPC_RMID, arg); } -void +static void not_configured(int signo __unused) { From 6a875bf929d097f2bf55655da0d6fab553461936 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 30 Jul 2015 18:28:34 +0000 Subject: [PATCH 091/314] Do not pretend that vm_fault(9) supports unwiring the address. Rename the VM_FAULT_CHANGE_WIRING flag to VM_FAULT_WIRE. Assert that the flag is only passed when faulting on the wired map entry. Remove the vm_page_unwire() call, which should be never reachable. Since VM_FAULT_WIRE flag implies wired map entry, the TRYPAGER() macro is reduced to the testing of the fs.object having a default pager. Inline the check. Suggested and reviewed by: alc Tested by: pho (previous version) MFC after: 1 week --- sys/vm/vm_fault.c | 39 +++++++++++++++++---------------------- sys/vm/vm_map.c | 2 +- sys/vm/vm_map.h | 6 +++--- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 7391465cc3d2..0d8ceedf7b77 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -193,7 +193,7 @@ vm_fault_dirty(vm_map_entry_t entry, vm_page_t m, vm_prot_t prot, VM_OBJECT_ASSERT_LOCKED(m->object); need_dirty = ((fault_type & VM_PROT_WRITE) != 0 && - (fault_flags & VM_FAULT_CHANGE_WIRING) == 0) || + (fault_flags & VM_FAULT_WIRE) == 0) || (fault_flags & VM_FAULT_DIRTY) != 0; if (set_wd) @@ -243,15 +243,6 @@ vm_fault_dirty(vm_map_entry_t entry, vm_page_t m, vm_prot_t prot, vm_pager_page_unswapped(m); } -/* - * TRYPAGER - used by vm_fault to calculate whether the pager for the - * current object *might* contain the page. - * - * default objects are zero-fill, there is no real pager. - */ -#define TRYPAGER (fs.object->type != OBJT_DEFAULT && \ - ((fault_flags & VM_FAULT_CHANGE_WIRING) == 0 || wired)) - /* * vm_fault: * @@ -361,9 +352,12 @@ RetryFault:; if (wired) fault_type = prot | (fault_type & VM_PROT_COPY); + else + KASSERT((fault_flags & VM_FAULT_WIRE) == 0, + ("!wired && VM_FAULT_WIRE")); if (fs.vp == NULL /* avoid locked vnode leak */ && - (fault_flags & (VM_FAULT_CHANGE_WIRING | VM_FAULT_DIRTY)) == 0 && + (fault_flags & (VM_FAULT_WIRE | VM_FAULT_DIRTY)) == 0 && /* avoid calling vm_object_set_writeable_dirty() */ ((prot & VM_PROT_WRITE) == 0 || (fs.first_object->type != OBJT_VNODE && @@ -509,10 +503,12 @@ RetryFault:; } /* - * Page is not resident, If this is the search termination + * Page is not resident. If this is the search termination * or the pager might contain the page, allocate a new page. + * Default objects are zero-fill, there is no real pager. */ - if (TRYPAGER || fs.object == fs.first_object) { + if (fs.object->type != OBJT_DEFAULT || + fs.object == fs.first_object) { if (fs.pindex >= fs.object->size) { unlock_and_deallocate(&fs); return (KERN_PROTECTION_FAILURE); @@ -556,9 +552,10 @@ RetryFault:; * * Attempt to fault-in the page if there is a chance that the * pager has it, and potentially fault in additional pages - * at the same time. + * at the same time. For default objects simply provide + * zero-filled pages. */ - if (TRYPAGER) { + if (fs.object->type != OBJT_DEFAULT) { int rv; u_char behavior = vm_map_entry_behavior(fs.entry); @@ -873,7 +870,7 @@ RetryFault:; pmap_copy_page(fs.m, fs.first_m); fs.first_m->valid = VM_PAGE_BITS_ALL; if (wired && (fault_flags & - VM_FAULT_CHANGE_WIRING) == 0) { + VM_FAULT_WIRE) == 0) { vm_page_lock(fs.first_m); vm_page_wire(fs.first_m); vm_page_unlock(fs.first_m); @@ -994,7 +991,7 @@ RetryFault:; */ pmap_enter(fs.map->pmap, vaddr, fs.m, prot, fault_type | (wired ? PMAP_ENTER_WIRED : 0), 0); - if (faultcount != 1 && (fault_flags & VM_FAULT_CHANGE_WIRING) == 0 && + if (faultcount != 1 && (fault_flags & VM_FAULT_WIRE) == 0 && wired == 0) vm_fault_prefault(&fs, vaddr, faultcount, reqpage); VM_OBJECT_WLOCK(fs.object); @@ -1004,11 +1001,9 @@ RetryFault:; * If the page is not wired down, then put it where the pageout daemon * can find it. */ - if (fault_flags & VM_FAULT_CHANGE_WIRING) { - if (wired) - vm_page_wire(fs.m); - else - vm_page_unwire(fs.m, PQ_ACTIVE); + if ((fault_flags & VM_FAULT_WIRE) != 0) { + KASSERT(wired, ("VM_FAULT_WIRE && !wired")); + vm_page_wire(fs.m); } else vm_page_activate(fs.m); if (m_hold != NULL) { diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index f8172bda702a..65c3e2c4217e 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -2591,7 +2591,7 @@ vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, * it into the physical map. */ if ((rv = vm_fault(map, faddr, VM_PROT_NONE, - VM_FAULT_CHANGE_WIRING)) != KERN_SUCCESS) + VM_FAULT_WIRE)) != KERN_SUCCESS) break; } while ((faddr += PAGE_SIZE) < saved_end); vm_map_lock(map); diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h index 3bf7a6719ad8..2c0a4ad50859 100644 --- a/sys/vm/vm_map.h +++ b/sys/vm/vm_map.h @@ -326,9 +326,9 @@ long vmspace_resident_count(struct vmspace *vmspace); /* * vm_fault option flags */ -#define VM_FAULT_NORMAL 0 /* Nothing special */ -#define VM_FAULT_CHANGE_WIRING 1 /* Change the wiring as appropriate */ -#define VM_FAULT_DIRTY 2 /* Dirty the page; use w/VM_PROT_COPY */ +#define VM_FAULT_NORMAL 0 /* Nothing special */ +#define VM_FAULT_WIRE 1 /* Wire the mapped page */ +#define VM_FAULT_DIRTY 2 /* Dirty the page; use w/VM_PROT_COPY */ /* * Initially, mappings are slightly sequential. The maximum window size must From e2e45da0e80379aa1c8c9e9838b85cfc1bd0e6a5 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Thu, 30 Jul 2015 18:28:37 +0000 Subject: [PATCH 092/314] ib mad: fix an incorrect use of list_for_each_entry In tf_dequeue(), if we reach the end of the list without finding a non-cancelled element, "tmp" will be a pointer into the list head, so the tmp->canceled check is bogus. Use a flag instead. Submitted by: Tao Liu Reviewed by: hselasky MFC after: 1 week Sponsored by: EMC / Isilon Storage Division Differential Revision: https://reviews.freebsd.org/D3244 --- sys/ofed/drivers/infiniband/core/mad.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/ofed/drivers/infiniband/core/mad.c b/sys/ofed/drivers/infiniband/core/mad.c index 11b3ba372186..3eedca1d6b6a 100644 --- a/sys/ofed/drivers/infiniband/core/mad.c +++ b/sys/ofed/drivers/infiniband/core/mad.c @@ -292,6 +292,7 @@ static struct tf_entry *tf_dequeue(struct to_fifo *tf, u32 *time_left_ms) unsigned long flags; unsigned long time_left; struct tf_entry *tmp, *tmp1; + bool found = false; spin_lock_irqsave(&tf->lists_lock, flags); if (list_empty(&tf->fifo_head)) { @@ -300,11 +301,13 @@ static struct tf_entry *tf_dequeue(struct to_fifo *tf, u32 *time_left_ms) } list_for_each_entry(tmp, &tf->fifo_head, fifo_list) { - if (!tmp->canceled) + if (!tmp->canceled) { + found = true; break; + } } - if (tmp->canceled) { + if (!found) { spin_unlock_irqrestore(&tf->lists_lock, flags); return NULL; } From bc81f73771b69dc00239036df0e2bbf9e3143797 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Thu, 30 Jul 2015 18:59:01 +0000 Subject: [PATCH 093/314] Get function prototypes for msg, shm, sem functions from header files. Differential Revision: D2669 --- sys/sys/msg.h | 5 +++-- sys/sys/sem.h | 5 +++-- sys/sys/shm.h | 5 +++-- usr.bin/ipcrm/ipcrm.c | 3 +++ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/sys/sys/msg.h b/sys/sys/msg.h index f4193c8257df..8f56c9482257 100644 --- a/sys/sys/msg.h +++ b/sys/sys/msg.h @@ -163,8 +163,9 @@ struct msqid_kernel { struct ucred *cred; /* creator's credentials */ }; -#else /* !_KERNEL */ +#endif /* _KERNEL */ +#if !defined(_KERNEL) || defined(_WANT_MSG_PROTOTYPES) __BEGIN_DECLS int msgctl(int, int, struct msqid_ds *); int msgget(key_t, int); @@ -176,6 +177,6 @@ int msgsys(int, ...); #endif __END_DECLS -#endif /* _KERNEL */ +#endif /* !_KERNEL || _WANT_MSG_PROTOTYPES */ #endif /* !_SYS_MSG_H_ */ diff --git a/sys/sys/sem.h b/sys/sys/sem.h index 0ea259bd9ab8..abfb7cdcd4d8 100644 --- a/sys/sys/sem.h +++ b/sys/sys/sem.h @@ -137,8 +137,9 @@ struct semid_kernel { */ void semexit(struct proc *p); -#else /* ! _KERNEL */ +#endif /* _KERNEL */ +#if !defined(_KERNEL) || defined(_WANT_SEM_PROTOTYPES) __BEGIN_DECLS #if __BSD_VISIBLE int semsys(int, ...); @@ -148,6 +149,6 @@ int semget(key_t, int, int); int semop(int, struct sembuf *, size_t); __END_DECLS -#endif /* !_KERNEL */ +#endif /* !_KERNEL || _WANT_SEM_PROTOTYPES */ #endif /* !_SYS_SEM_H_ */ diff --git a/sys/sys/shm.h b/sys/sys/shm.h index 799bbf5fd8eb..f685df3fbe76 100644 --- a/sys/sys/shm.h +++ b/sys/sys/shm.h @@ -144,8 +144,9 @@ struct vmspace; void shmexit(struct vmspace *); void shmfork(struct proc *, struct proc *); -#else /* !_KERNEL */ +#endif /* _KERNEL */ +#if !defined(_KERNEL) || defined(_WANT_SHM_PROTOTYPES) #include #ifndef _SIZE_T_DECLARED @@ -163,6 +164,6 @@ int shmctl(int, int, struct shmid_ds *); int shmdt(const void *); __END_DECLS -#endif /* !_KERNEL */ +#endif /* _KERNEL || _WANT_SHM_PROTOTYPES */ #endif /* !_SYS_SHM_H_ */ diff --git a/usr.bin/ipcrm/ipcrm.c b/usr.bin/ipcrm/ipcrm.c index c255ef81e5d0..de97696bce9c 100644 --- a/usr.bin/ipcrm/ipcrm.c +++ b/usr.bin/ipcrm/ipcrm.c @@ -34,6 +34,9 @@ __FBSDID("$FreeBSD$"); #include +#define _WANT_MSG_PROTOTYPES +#define _WANT_SEM_PROTOTYPES +#define _WANT_SHM_PROTOTYPES #define _KERNEL #include #include From 40ebf1626f358f7a3fe6a54ac5396b77d341ee2a Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 30 Jul 2015 19:04:14 +0000 Subject: [PATCH 094/314] Add GPIO backlight driver compatible with Linux FDT bindings. Brightness is controlled through sysctl dev.gpiobacklight.X.brightness: - any value greater than 0: backlight is on - any value less than or equal to 0: backlight is off FDT bindings docs in Linux tree: Documentation/devicetree/bindings/video/backlight/gpio-backlight.txt --- sys/conf/files | 1 + sys/dev/gpio/gpiobacklight.c | 211 +++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 sys/dev/gpio/gpiobacklight.c diff --git a/sys/conf/files b/sys/conf/files index 99cef6dab2c2..d1060bc01750 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1436,6 +1436,7 @@ dev/fxp/inphy.c optional fxp dev/gem/if_gem.c optional gem dev/gem/if_gem_pci.c optional gem pci dev/gem/if_gem_sbus.c optional gem sbus +dev/gpio/gpiobacklight.c optional gpiobacklight fdt dev/gpio/gpiobus.c optional gpio \ dependency "gpiobus_if.h" dev/gpio/gpioc.c optional gpio \ diff --git a/sys/dev/gpio/gpiobacklight.c b/sys/dev/gpio/gpiobacklight.c new file mode 100644 index 000000000000..3ff74f1e8969 --- /dev/null +++ b/sys/dev/gpio/gpiobacklight.c @@ -0,0 +1,211 @@ +/*- + * Copyright (c) 2015 Oleksandr Tymoshenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_platform.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "gpiobus_if.h" + +/* + * Only one pin for led + */ +#define GPIOBL_PIN 0 + +#define GPIOBL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) +#define GPIOBL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) +#define GPIOBL_LOCK_INIT(_sc) \ + mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \ + "gpiobacklight", MTX_DEF) +#define GPIOBL_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); + +struct gpiobacklight_softc +{ + device_t sc_dev; + device_t sc_busdev; + struct mtx sc_mtx; + + struct sysctl_oid *sc_oid; + int sc_brightness; +}; + +static int gpiobacklight_sysctl(SYSCTL_HANDLER_ARGS); +static void gpiobacklight_update_brightness(struct gpiobacklight_softc *); +static int gpiobacklight_probe(device_t); +static int gpiobacklight_attach(device_t); +static int gpiobacklight_detach(device_t); + +static void +gpiobacklight_update_brightness(struct gpiobacklight_softc *sc) +{ + int error; + + GPIOBL_LOCK(sc); + error = GPIOBUS_ACQUIRE_BUS(sc->sc_busdev, sc->sc_dev, + GPIOBUS_DONTWAIT); + if (error != 0) { + GPIOBL_UNLOCK(sc); + return; + } + error = GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, + GPIOBL_PIN, GPIO_PIN_OUTPUT); + if (error == 0) + GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev, GPIOBL_PIN, + sc->sc_brightness ? GPIO_PIN_HIGH : GPIO_PIN_LOW); + GPIOBUS_RELEASE_BUS(sc->sc_busdev, sc->sc_dev); + GPIOBL_UNLOCK(sc); +} + +static int +gpiobacklight_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct gpiobacklight_softc *sc; + int error; + int brightness; + + sc = (struct gpiobacklight_softc*)arg1; + brightness = sc->sc_brightness; + error = sysctl_handle_int(oidp, &brightness, 0, req); + + if (error != 0 || req->newptr == NULL) + return (error); + + if (brightness <= 0) + sc->sc_brightness = 0; + else + sc->sc_brightness = 1; + + gpiobacklight_update_brightness(sc); + + return (error); +} + +static void +gpiobacklight_identify(driver_t *driver, device_t bus) +{ + phandle_t node, root; + + root = OF_finddevice("/"); + if (root == 0) + return; + for (node = OF_child(root); node != 0; node = OF_peer(node)) { + if (!fdt_is_compatible_strict(node, "gpio-backlight")) + continue; + ofw_gpiobus_add_fdt_child(bus, driver->name, node); + } +} + +static int +gpiobacklight_probe(device_t dev) +{ + + if (!ofw_bus_is_compatible(dev, "gpio-backlight")) + return (ENXIO); + + device_set_desc(dev, "GPIO backlight"); + + return (0); +} + +static int +gpiobacklight_attach(device_t dev) +{ + struct gpiobacklight_softc *sc; + struct sysctl_ctx_list *ctx; + struct sysctl_oid *tree; + phandle_t node; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + sc->sc_busdev = device_get_parent(dev); + + if ((node = ofw_bus_get_node(dev)) == -1) + return (ENXIO); + + GPIOBL_LOCK_INIT(sc); + if (OF_hasprop(node, "default-on")) + sc->sc_brightness = 1; + else + sc->sc_brightness = 0; + + /* Init backlight interface */ + ctx = device_get_sysctl_ctx(sc->sc_dev); + tree = device_get_sysctl_tree(sc->sc_dev); + sc->sc_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "brightness", CTLTYPE_INT | CTLFLAG_RW, sc, 0, + gpiobacklight_sysctl, "I", "backlight brightness"); + + gpiobacklight_update_brightness(sc); + + return (0); +} + +static int +gpiobacklight_detach(device_t dev) +{ + struct gpiobacklight_softc *sc; + + sc = device_get_softc(dev); + GPIOBL_LOCK_DESTROY(sc); + return (0); +} + +static devclass_t gpiobacklight_devclass; + +static device_method_t gpiobacklight_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, gpiobacklight_identify), + DEVMETHOD(device_probe, gpiobacklight_probe), + DEVMETHOD(device_attach, gpiobacklight_attach), + DEVMETHOD(device_detach, gpiobacklight_detach), + + DEVMETHOD_END +}; + +static driver_t gpiobacklight_driver = { + "gpiobacklight", + gpiobacklight_methods, + sizeof(struct gpiobacklight_softc), +}; + +DRIVER_MODULE(gpiobacklight, gpiobus, gpiobacklight_driver, gpiobacklight_devclass, 0, 0); From 703a08b23cf95ecf907af45944cc9ef4f9d79154 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Thu, 30 Jul 2015 19:08:23 +0000 Subject: [PATCH 095/314] The kernel option and module are actually called pmspcv. MFC after: 3 days --- share/man/man4/Makefile | 1 + share/man/man4/pms.4 | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index fc7370494c2c..8bb6a96def7c 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -666,6 +666,7 @@ MLINKS+=pccbb.4 cbb.4 MLINKS+=pcm.4 snd.4 \ pcm.4 sound.4 MLINKS+=pcn.4 if_pcn.4 +MLINKS+=pms.4 pmspcv.4 MLINKS+=ral.4 if_ral.4 MLINKS+=re.4 if_re.4 MLINKS+=rl.4 if_rl.4 diff --git a/share/man/man4/pms.4 b/share/man/man4/pms.4 index e4986c90c98c..05dd7bc09634 100644 --- a/share/man/man4/pms.4 +++ b/share/man/man4/pms.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 29, 2015 +.Dd July 30, 2015 .Dt PMS 4 .Os .Sh NAME @@ -35,14 +35,14 @@ To compile the driver into the kernel, place the following line in the kernel configuration file: .Bd -ragged -offset indent -.Cd "device pms" +.Cd "device pmspcv" .Ed .Pp Alternatively, to load the driver as a module at boot time, place the following line in .Xr loader.conf 5 : .Bd -literal -offset indent -pms_load="YES" +pmspcv_load="YES" .Ed .Sh DESCRIPTION The From 03041aaac83aa35525ca9c54ff6ff014fdcf707e Mon Sep 17 00:00:00 2001 From: Hiren Panchasara Date: Thu, 30 Jul 2015 19:24:49 +0000 Subject: [PATCH 096/314] Update snd_una description to make it more readable. Differential Revision: https://reviews.freebsd.org/D3179 Reviewed by: gnn Sponsored by: Limelight Networks --- sys/netinet/tcp_var.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index e8b6670cebb6..d16f27b0f379 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -113,7 +113,7 @@ struct tcpcb { struct vnet *t_vnet; /* back pointer to parent vnet */ - tcp_seq snd_una; /* send unacknowledged */ + tcp_seq snd_una; /* sent but unacknowledged */ tcp_seq snd_max; /* highest sequence number sent; * used to recognize retransmits */ From f5827b16eb7897c47889e598af1de533169439ff Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Thu, 30 Jul 2015 19:34:24 +0000 Subject: [PATCH 097/314] Fix a rendering issue in the zfs(8) manual. MFC after: 3 days Sponsored by: The FreeBSD Foundation --- cddl/contrib/opensolaris/cmd/zfs/zfs.8 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 index f2852cfc84a3..b7d9ac097a50 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 @@ -27,11 +27,11 @@ .\" Copyright (c) 2013, Steven Hartland .\" Copyright (c) 2014 Nexenta Systems, Inc. All Rights Reserved. .\" Copyright (c) 2014, Xin LI -.\" Copyright (c) 2014, The FreeBSD Foundation, All Rights Reserved. +.\" Copyright (c) 2014-2015, The FreeBSD Foundation, All Rights Reserved. .\" .\" $FreeBSD$ .\" -.Dd December 12, 2014 +.Dd July 30, 2015 .Dt ZFS 8 .Os .Sh NAME @@ -938,7 +938,7 @@ not be used by any other dataset. Disabling checksums is .Em NOT a recommended practice. -.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | zle | Cm lz4 +.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | Cm zle | Cm lz4 Controls the compression algorithm used for this dataset. The .Cm lzjb compression algorithm is optimized for performance while providing decent data From 4ed2d460bd9976f6ff0250d3003ec840da54dd92 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Thu, 30 Jul 2015 19:44:46 +0000 Subject: [PATCH 098/314] Use correct number of arguments to semctl() for IPC_RMID. PR: 118292 Submitted by: araujo Differential Revision: D2669 --- usr.bin/ipcrm/ipcrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/ipcrm/ipcrm.c b/usr.bin/ipcrm/ipcrm.c index de97696bce9c..98c45554384c 100644 --- a/usr.bin/ipcrm/ipcrm.c +++ b/usr.bin/ipcrm/ipcrm.c @@ -169,7 +169,7 @@ semrm(key_t key, int id) if ((kxsema[num].u.sem_perm.mode & SEM_ALLOC) != 0) { id = IXSEQ_TO_IPCID(num, kxsema[num].u.sem_perm); - if (semctl(id, IPC_RMID, NULL) < 0) { + if (semctl(id, 0, IPC_RMID, NULL) < 0) { if (rmverbose > 1) warn("semid(%d): ", id); errflg++; From 4ae1e3c75294c5442c4e94430ec4ff8b7f3a930c Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Thu, 30 Jul 2015 19:52:43 +0000 Subject: [PATCH 099/314] Revert r285125 until rmlocks get fixed. Right now there is a chance that sysctl unregister will cause reader to block on the sx lock associated with sysctl rmlock, in which case kernels with debug enabled will panic. --- sys/kern/kern_linker.c | 8 +- sys/kern/kern_sysctl.c | 204 +++++++++++++++++++++-------------------- sys/kern/vfs_init.c | 4 +- sys/sys/sysctl.h | 4 +- 4 files changed, 111 insertions(+), 109 deletions(-) diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index bb92e18db790..a4fde06198f4 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -292,10 +292,10 @@ linker_file_register_sysctls(linker_file_t lf) return; sx_xunlock(&kld_sx); - sysctl_wlock(); + sysctl_xlock(); for (oidp = start; oidp < stop; oidp++) sysctl_register_oid(*oidp); - sysctl_wunlock(); + sysctl_xunlock(); sx_xlock(&kld_sx); } @@ -313,10 +313,10 @@ linker_file_unregister_sysctls(linker_file_t lf) return; sx_xunlock(&kld_sx); - sysctl_wlock(); + sysctl_xlock(); for (oidp = start; oidp < stop; oidp++) sysctl_unregister_oid(*oidp); - sysctl_wunlock(); + sysctl_xunlock(); sx_xlock(&kld_sx); } diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 52075e47045d..b32198f18493 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -78,7 +77,7 @@ static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer"); * The sysctllock protects the MIB tree. It also protects sysctl * contexts used with dynamic sysctls. The sysctl_register_oid() and * sysctl_unregister_oid() routines require the sysctllock to already - * be held, so the sysctl_wlock() and sysctl_wunlock() routines are + * be held, so the sysctl_xlock() and sysctl_xunlock() routines are * provided for the few places in the kernel which need to use that * API rather than using the dynamic API. Use of the dynamic API is * strongly encouraged for most code. @@ -87,21 +86,20 @@ static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer"); * sysctl requests. This is implemented by serializing any userland * sysctl requests larger than a single page via an exclusive lock. */ -static struct rmlock sysctllock; +static struct sx sysctllock; static struct sx sysctlmemlock; -#define SYSCTL_WLOCK() rm_wlock(&sysctllock) -#define SYSCTL_WUNLOCK() rm_wunlock(&sysctllock) -#define SYSCTL_RLOCK(tracker) rm_rlock(&sysctllock, (tracker)) -#define SYSCTL_RUNLOCK(tracker) rm_runlock(&sysctllock, (tracker)) -#define SYSCTL_WLOCKED() rm_wowned(&sysctllock) -#define SYSCTL_ASSERT_LOCKED() rm_assert(&sysctllock, RA_LOCKED) -#define SYSCTL_ASSERT_WLOCKED() rm_assert(&sysctllock, RA_WLOCKED) -#define SYSCTL_ASSERT_RLOCKED() rm_assert(&sysctllock, RA_RLOCKED) -#define SYSCTL_INIT() rm_init_flags(&sysctllock, "sysctl lock", \ - RM_SLEEPABLE) +#define SYSCTL_XLOCK() sx_xlock(&sysctllock) +#define SYSCTL_XUNLOCK() sx_xunlock(&sysctllock) +#define SYSCTL_SLOCK() sx_slock(&sysctllock) +#define SYSCTL_SUNLOCK() sx_sunlock(&sysctllock) +#define SYSCTL_XLOCKED() sx_xlocked(&sysctllock) +#define SYSCTL_ASSERT_LOCKED() sx_assert(&sysctllock, SA_LOCKED) +#define SYSCTL_ASSERT_XLOCKED() sx_assert(&sysctllock, SA_XLOCKED) +#define SYSCTL_ASSERT_SLOCKED() sx_assert(&sysctllock, SA_SLOCKED) +#define SYSCTL_INIT() sx_init(&sysctllock, "sysctl lock") #define SYSCTL_SLEEP(ch, wmesg, timo) \ - rm_sleep(ch, &sysctllock, 0, wmesg, timo) + sx_sleep(ch, &sysctllock, 0, wmesg, timo) static int sysctl_root(SYSCTL_HANDLER_ARGS); @@ -113,6 +111,29 @@ static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, static int sysctl_old_kernel(struct sysctl_req *, const void *, size_t); static int sysctl_new_kernel(struct sysctl_req *, void *, size_t); +static void +sysctl_lock(bool xlock) +{ + + if (xlock) + SYSCTL_XLOCK(); + else + SYSCTL_SLOCK(); +} + +static bool +sysctl_unlock(void) +{ + bool xlocked; + + xlocked = SYSCTL_XLOCKED(); + if (xlocked) + SYSCTL_XUNLOCK(); + else + SYSCTL_SUNLOCK(); + return (xlocked); +} + static struct sysctl_oid * sysctl_find_oidname(const char *name, struct sysctl_oid_list *list) { @@ -133,32 +154,29 @@ sysctl_find_oidname(const char *name, struct sysctl_oid_list *list) * Order by number in each list. */ void -sysctl_wlock(void) +sysctl_xlock(void) { - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); } void -sysctl_wunlock(void) +sysctl_xunlock(void) { - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); } static int sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, intptr_t arg2, - struct sysctl_req *req, struct rm_priotracker *tracker) + struct sysctl_req *req) { int error; + bool xlocked; if (oid->oid_kind & CTLFLAG_DYN) atomic_add_int(&oid->oid_running, 1); - - if (tracker != NULL) - SYSCTL_RUNLOCK(tracker); - else - SYSCTL_WUNLOCK(); + xlocked = sysctl_unlock(); if (!(oid->oid_kind & CTLFLAG_MPSAFE)) mtx_lock(&Giant); @@ -166,11 +184,7 @@ sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, intptr_t arg2, if (!(oid->oid_kind & CTLFLAG_MPSAFE)) mtx_unlock(&Giant); - if (tracker != NULL) - SYSCTL_RLOCK(tracker); - else - SYSCTL_WLOCK(); - + sysctl_lock(xlocked); if (oid->oid_kind & CTLFLAG_DYN) { if (atomic_fetchadd_int(&oid->oid_running, -1) == 1 && (oid->oid_kind & CTLFLAG_DYING) != 0) @@ -269,7 +283,7 @@ sysctl_load_tunable_by_oid_locked(struct sysctl_oid *oidp) return; } error = sysctl_root_handler_locked(oidp, oidp->oid_arg1, - oidp->oid_arg2, &req, NULL); + oidp->oid_arg2, &req); if (error != 0) printf("Setting sysctl %s failed: %d\n", path + rem, error); if (penv != NULL) @@ -289,7 +303,7 @@ sysctl_register_oid(struct sysctl_oid *oidp) * First check if another oid with the same name already * exists in the parent's list. */ - SYSCTL_ASSERT_WLOCKED(); + SYSCTL_ASSERT_XLOCKED(); p = sysctl_find_oidname(oidp->oid_name, parent); if (p != NULL) { if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) { @@ -383,7 +397,7 @@ sysctl_unregister_oid(struct sysctl_oid *oidp) struct sysctl_oid *p; int error; - SYSCTL_ASSERT_WLOCKED(); + SYSCTL_ASSERT_XLOCKED(); error = ENOENT; if (oidp->oid_number == OID_AUTO) { error = EINVAL; @@ -439,7 +453,7 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist) * XXX This algorithm is a hack. But I don't know any * XXX better solution for now... */ - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); TAILQ_FOREACH(e, clist, link) { error = sysctl_remove_oid_locked(e->entry, 0, 0); if (error) @@ -459,7 +473,7 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist) e1 = TAILQ_PREV(e1, sysctl_ctx_list, link); } if (error) { - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return(EBUSY); } /* Now really delete the entries */ @@ -473,7 +487,7 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist) free(e, M_SYSCTLOID); e = e1; } - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (error); } @@ -483,7 +497,7 @@ sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) { struct sysctl_ctx_entry *e; - SYSCTL_ASSERT_WLOCKED(); + SYSCTL_ASSERT_XLOCKED(); if (clist == NULL || oidp == NULL) return(NULL); e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK); @@ -498,7 +512,7 @@ sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) { struct sysctl_ctx_entry *e; - SYSCTL_ASSERT_WLOCKED(); + SYSCTL_ASSERT_XLOCKED(); if (clist == NULL || oidp == NULL) return(NULL); TAILQ_FOREACH(e, clist, link) { @@ -520,15 +534,15 @@ sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) if (clist == NULL || oidp == NULL) return (EINVAL); - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); e = sysctl_ctx_entry_find(clist, oidp); if (e != NULL) { TAILQ_REMOVE(clist, e, link); - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); free(e, M_SYSCTLOID); return (0); } else { - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (ENOENT); } } @@ -544,9 +558,9 @@ sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse) { int error; - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); error = sysctl_remove_oid_locked(oidp, del, recurse); - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (error); } @@ -558,14 +572,14 @@ sysctl_remove_name(struct sysctl_oid *parent, const char *name, int error; error = ENOENT; - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); SLIST_FOREACH_SAFE(p, SYSCTL_CHILDREN(parent), oid_link, tmp) { if (strcmp(p->oid_name, name) == 0) { error = sysctl_remove_oid_locked(p, del, recurse); break; } } - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (error); } @@ -577,7 +591,7 @@ sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse) struct sysctl_oid *p, *tmp; int error; - SYSCTL_ASSERT_WLOCKED(); + SYSCTL_ASSERT_XLOCKED(); if (oidp == NULL) return(EINVAL); if ((oidp->oid_kind & CTLFLAG_DYN) == 0) { @@ -652,7 +666,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, if (parent == NULL) return(NULL); /* Check if the node already exists, otherwise create it */ - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); oidp = sysctl_find_oidname(name, parent); if (oidp != NULL) { if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { @@ -660,10 +674,10 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, /* Update the context */ if (clist != NULL) sysctl_ctx_entry_add(clist, oidp); - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (oidp); } else { - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); printf("can't re-use a leaf (%s)!\n", name); return (NULL); } @@ -686,7 +700,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, sysctl_ctx_entry_add(clist, oidp); /* Register this oid */ sysctl_register_oid(oidp); - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (oidp); } @@ -700,10 +714,10 @@ sysctl_rename_oid(struct sysctl_oid *oidp, const char *name) char *oldname; newname = strdup(name, M_SYSCTLOID); - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); oldname = __DECONST(char *, oidp->oid_name); oidp->oid_name = newname; - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); free(oldname, M_SYSCTLOID); } @@ -715,21 +729,21 @@ sysctl_move_oid(struct sysctl_oid *oid, struct sysctl_oid_list *parent) { struct sysctl_oid *oidp; - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); if (oid->oid_parent == parent) { - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (0); } oidp = sysctl_find_oidname(oid->oid_name, parent); if (oidp != NULL) { - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (EEXIST); } sysctl_unregister_oid(oid); oid->oid_parent = parent; oid->oid_number = OID_AUTO; sysctl_register_oid(oid); - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); return (0); } @@ -745,10 +759,10 @@ sysctl_register_all(void *arg) sx_init(&sysctlmemlock, "sysctl mem"); SYSCTL_INIT(); - SYSCTL_WLOCK(); + SYSCTL_XLOCK(); SET_FOREACH(oidp, sysctl_set) sysctl_register_oid(*oidp); - SYSCTL_WUNLOCK(); + SYSCTL_XUNLOCK(); } SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_register_all, 0); @@ -818,15 +832,14 @@ sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i) static int sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS) { - struct rm_priotracker tracker; int error; error = priv_check(req->td, PRIV_SYSCTL_DEBUG); if (error) return (error); - SYSCTL_RLOCK(&tracker); + SYSCTL_SLOCK(); sysctl_sysctl_debug_dump_node(&sysctl__children, 0); - SYSCTL_RUNLOCK(&tracker); + SYSCTL_SUNLOCK(); return (ENOENT); } @@ -842,10 +855,9 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) int error = 0; struct sysctl_oid *oid; struct sysctl_oid_list *lsp = &sysctl__children, *lsp2; - struct rm_priotracker tracker; char buf[10]; - SYSCTL_RLOCK(&tracker); + SYSCTL_SLOCK(); while (namelen) { if (!lsp) { snprintf(buf,sizeof(buf),"%d",*name); @@ -888,7 +900,7 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) } error = SYSCTL_OUT(req, "", 1); out: - SYSCTL_RUNLOCK(&tracker); + SYSCTL_SUNLOCK(); return (error); } @@ -967,12 +979,11 @@ sysctl_sysctl_next(SYSCTL_HANDLER_ARGS) int i, j, error; struct sysctl_oid *oid; struct sysctl_oid_list *lsp = &sysctl__children; - struct rm_priotracker tracker; int newoid[CTL_MAXNAME]; - SYSCTL_RLOCK(&tracker); + SYSCTL_SLOCK(); i = sysctl_sysctl_next_ls(lsp, name, namelen, newoid, &j, 1, &oid); - SYSCTL_RUNLOCK(&tracker); + SYSCTL_SUNLOCK(); if (i) return (ENOENT); error = SYSCTL_OUT(req, newoid, j * sizeof (int)); @@ -1031,7 +1042,6 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS) char *p; int error, oid[CTL_MAXNAME], len = 0; struct sysctl_oid *op = 0; - struct rm_priotracker tracker; if (!req->newlen) return (ENOENT); @@ -1048,9 +1058,9 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS) p [req->newlen] = '\0'; - SYSCTL_RLOCK(&tracker); + SYSCTL_SLOCK(); error = name2oid(p, oid, &len, &op); - SYSCTL_RUNLOCK(&tracker); + SYSCTL_SUNLOCK(); free(p, M_SYSCTL); @@ -1073,10 +1083,9 @@ static int sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS) { struct sysctl_oid *oid; - struct rm_priotracker tracker; int error; - SYSCTL_RLOCK(&tracker); + SYSCTL_SLOCK(); error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); if (error) goto out; @@ -1090,7 +1099,7 @@ sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS) goto out; error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1); out: - SYSCTL_RUNLOCK(&tracker); + SYSCTL_SUNLOCK(); return (error); } @@ -1102,10 +1111,9 @@ static int sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS) { struct sysctl_oid *oid; - struct rm_priotracker tracker; int error; - SYSCTL_RLOCK(&tracker); + SYSCTL_SLOCK(); error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); if (error) goto out; @@ -1116,7 +1124,7 @@ sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS) } error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1); out: - SYSCTL_RUNLOCK(&tracker); + SYSCTL_SUNLOCK(); return (error); } @@ -1421,7 +1429,9 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old, req.newfunc = sysctl_new_kernel; req.lock = REQ_UNWIRED; + SYSCTL_SLOCK(); error = sysctl_root(0, name, namelen, &req); + SYSCTL_SUNLOCK(); if (req.lock == REQ_WIRED && req.validlen > 0) vsunlock(req.oldptr, req.validlen); @@ -1598,14 +1608,13 @@ static int sysctl_root(SYSCTL_HANDLER_ARGS) { struct sysctl_oid *oid; - struct rm_priotracker tracker; int error, indx, lvl; - SYSCTL_RLOCK(&tracker); + SYSCTL_ASSERT_SLOCKED(); error = sysctl_find_oid(arg1, arg2, &oid, &indx, req); if (error) - goto out; + return (error); if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { /* @@ -1613,17 +1622,13 @@ sysctl_root(SYSCTL_HANDLER_ARGS) * no handler. Inform the user that it's a node. * The indx may or may not be the same as namelen. */ - if (oid->oid_handler == NULL) { - error = EISDIR; - goto out; - } + if (oid->oid_handler == NULL) + return (EISDIR); } /* Is this sysctl writable? */ - if (req->newptr && !(oid->oid_kind & CTLFLAG_WR)) { - error = EPERM; - goto out; - } + if (req->newptr && !(oid->oid_kind & CTLFLAG_WR)) + return (EPERM); KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL")); @@ -1633,11 +1638,10 @@ sysctl_root(SYSCTL_HANDLER_ARGS) * writing unless specifically granted for the node. */ if (IN_CAPABILITY_MODE(req->td)) { - if ((req->oldptr && !(oid->oid_kind & CTLFLAG_CAPRD)) || - (req->newptr && !(oid->oid_kind & CTLFLAG_CAPWR))) { - error = EPERM; - goto out; - } + if (req->oldptr && !(oid->oid_kind & CTLFLAG_CAPRD)) + return (EPERM); + if (req->newptr && !(oid->oid_kind & CTLFLAG_CAPWR)) + return (EPERM); } #endif @@ -1646,7 +1650,7 @@ sysctl_root(SYSCTL_HANDLER_ARGS) lvl = (oid->oid_kind & CTLMASK_SECURE) >> CTLSHIFT_SECURE; error = securelevel_gt(req->td->td_ucred, lvl); if (error) - goto out; + return (error); } /* Is this sysctl writable by only privileged users? */ @@ -1664,13 +1668,11 @@ sysctl_root(SYSCTL_HANDLER_ARGS) priv = PRIV_SYSCTL_WRITE; error = priv_check(req->td, priv); if (error) - goto out; + return (error); } - if (!oid->oid_handler) { - error = EINVAL; - goto out; - } + if (!oid->oid_handler) + return (EINVAL); if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { arg1 = (int *)arg1 + indx; @@ -1683,18 +1685,16 @@ sysctl_root(SYSCTL_HANDLER_ARGS) error = mac_system_check_sysctl(req->td->td_ucred, oid, arg1, arg2, req); if (error != 0) - goto out; + return (error); #endif #ifdef VIMAGE if ((oid->oid_kind & CTLFLAG_VNET) && arg1 != NULL) arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1); #endif - error = sysctl_root_handler_locked(oid, arg1, arg2, req, &tracker); + error = sysctl_root_handler_locked(oid, arg1, arg2, req); KFAIL_POINT_ERROR(_debug_fail_point, sysctl_running, error); -out: - SYSCTL_RUNLOCK(&tracker); return (error); } @@ -1794,7 +1794,9 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, for (;;) { req.oldidx = 0; req.newidx = 0; + SYSCTL_SLOCK(); error = sysctl_root(0, name, namelen, &req); + SYSCTL_SUNLOCK(); if (error != EAGAIN) break; kern_yield(PRI_USER); diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index 9ac193a9ebd5..f935954fcef2 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -291,7 +291,7 @@ vfs_register(struct vfsconf *vfc) * preserved by re-registering the oid after modifying its * number. */ - sysctl_wlock(); + sysctl_xlock(); SLIST_FOREACH(oidp, SYSCTL_CHILDREN(&sysctl___vfs), oid_link) { if (strcmp(oidp->oid_name, vfc->vfc_name) == 0) { sysctl_unregister_oid(oidp); @@ -300,7 +300,7 @@ vfs_register(struct vfsconf *vfc) break; } } - sysctl_wunlock(); + sysctl_xunlock(); return (0); } diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 4c66431e55f4..988dbae94087 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -807,8 +807,8 @@ int userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, size_t *retval, int flags); int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid, int *nindx, struct sysctl_req *req); -void sysctl_wlock(void); -void sysctl_wunlock(void); +void sysctl_xlock(void); +void sysctl_xunlock(void); int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len); struct sbuf; From 59959de526d5f0a9490e5e2c8a7dece961d8db7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ermal=20Lu=C3=A7i?= Date: Thu, 30 Jul 2015 20:56:27 +0000 Subject: [PATCH 100/314] Correct IPSec SA statistic keeping The IPsec SA statistic keeping is used even for decision making on expiry/rekeying SAs. When there are multiple transformations being done the statistic keeping might be wrong. This mostly impacts multiple encapsulations on IPsec since the usual scenario it is not noticed due to the code path not taken. Differential Revision: https://reviews.freebsd.org/D3239 Reviewed by: ae, gnn Approved by: gnn(mentor) --- sys/netipsec/ipsec_output.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c index ae360700b629..a6611a7e7fcb 100644 --- a/sys/netipsec/ipsec_output.c +++ b/sys/netipsec/ipsec_output.c @@ -158,6 +158,8 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) tdbi->spi = sav->spi; m_tag_prepend(m, mtag); + key_sa_recordxfer(sav, m); /* record data transfer */ + /* * If there's another (bundled) SA to apply, do so. * Note that this puts a burden on the kernel stack size. @@ -202,7 +204,6 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) goto bad; } } - key_sa_recordxfer(sav, m); /* record data transfer */ /* * We're done with IPsec processing, transmit the packet using the From 817c7ed900427f8ae3e152fd1ad770878465ff11 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Fri, 31 Jul 2015 00:23:21 +0000 Subject: [PATCH 101/314] Clean up this header file... use CTASSERTs now that we have them... Replace a draft w/ RFC that's over 10 years old. Note that _AALG and _EALG do not need to match what the IKE daemons think they should be.. This is part of the KABI... I decided to renumber AESCTR, but since we've never had working AESCTR mode, I'm not really breaking anything.. and it shortens a loop by quite a bit.. remove SKIPJACK IPsec support... SKIPJACK never made it out of draft (in 1999), only has 80bit key, NIST recommended it stop being used after 2010, and setkey nor any of the IKE daemons I checked supported it... jmgurney/ipsecgcm: a357a33, c75808b, e008669, b27b6d6 Reviewed by: gnn (earlier version) --- sys/net/pfkeyv2.h | 38 ++++++++++++++++++++------------------ sys/netipsec/xform_esp.c | 2 -- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index 98ffd4aecc7b..0fe3c96c348d 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -218,7 +218,6 @@ struct sadb_x_sa2 { }; /* XXX Policy Extension */ -/* sizeof(struct sadb_x_policy) == 16 */ struct sadb_x_policy { u_int16_t sadb_x_policy_len; u_int16_t sadb_x_policy_exttype; @@ -228,6 +227,8 @@ struct sadb_x_policy { u_int32_t sadb_x_policy_id; u_int32_t sadb_x_policy_reserved2; }; +CTASSERT(sizeof(struct sadb_x_policy) == 16); + /* * When policy_type == IPSEC, it is followed by some of * the ipsec policy request. @@ -256,31 +257,31 @@ struct sadb_x_ipsecrequest { }; /* NAT-Traversal type, see RFC 3948 (and drafts). */ -/* sizeof(struct sadb_x_nat_t_type) == 8 */ struct sadb_x_nat_t_type { u_int16_t sadb_x_nat_t_type_len; u_int16_t sadb_x_nat_t_type_exttype; u_int8_t sadb_x_nat_t_type_type; u_int8_t sadb_x_nat_t_type_reserved[3]; }; +CTASSERT(sizeof(struct sadb_x_nat_t_type) == 8); /* NAT-Traversal source or destination port. */ -/* sizeof(struct sadb_x_nat_t_port) == 8 */ struct sadb_x_nat_t_port { u_int16_t sadb_x_nat_t_port_len; u_int16_t sadb_x_nat_t_port_exttype; u_int16_t sadb_x_nat_t_port_port; u_int16_t sadb_x_nat_t_port_reserved; }; +CTASSERT(sizeof(struct sadb_x_nat_t_port) == 8); /* ESP fragmentation size. */ -/* sizeof(struct sadb_x_nat_t_frag) == 8 */ struct sadb_x_nat_t_frag { u_int16_t sadb_x_nat_t_frag_len; u_int16_t sadb_x_nat_t_frag_exttype; u_int16_t sadb_x_nat_t_frag_fraglen; u_int16_t sadb_x_nat_t_frag_reserved; }; +CTASSERT(sizeof(struct sadb_x_nat_t_frag) == 8); #define SADB_EXT_RESERVED 0 @@ -332,46 +333,47 @@ struct sadb_x_nat_t_frag { #define SADB_SAFLAGS_PFS 1 -/* RFC2367 numbers - meets RFC2407 */ +/* + * Though some of these numbers (both _AALG and _EALG) appear to be + * IKEv2 numbers and others original IKE numbers, they have no meaning. + * These are constants that the various IKE daemons use to tell the kernel + * what cipher to use. + * + * Do not use these constants directly to decide which Transformation ID + * to send. You are responsible for mapping them yourself. + */ #define SADB_AALG_NONE 0 #define SADB_AALG_MD5HMAC 2 #define SADB_AALG_SHA1HMAC 3 #define SADB_AALG_MAX 252 -/* private allocations - based on RFC2407/IANA assignment */ #define SADB_X_AALG_SHA2_256 5 #define SADB_X_AALG_SHA2_384 6 #define SADB_X_AALG_SHA2_512 7 #define SADB_X_AALG_RIPEMD160HMAC 8 -#define SADB_X_AALG_AES_XCBC_MAC 9 /* draft-ietf-ipsec-ciph-aes-xcbc-mac-04 */ +#define SADB_X_AALG_AES_XCBC_MAC 9 /* RFC3566 */ #define SADB_X_AALG_AES128GMAC 11 /* RFC4543 + Errata1821 */ #define SADB_X_AALG_AES192GMAC 12 #define SADB_X_AALG_AES256GMAC 13 -/* private allocations should use 249-255 (RFC2407) */ #define SADB_X_AALG_MD5 249 /* Keyed MD5 */ #define SADB_X_AALG_SHA 250 /* Keyed SHA */ #define SADB_X_AALG_NULL 251 /* null authentication */ #define SADB_X_AALG_TCP_MD5 252 /* Keyed TCP-MD5 (RFC2385) */ -/* RFC2367 numbers - meets RFC2407 */ #define SADB_EALG_NONE 0 #define SADB_EALG_DESCBC 2 #define SADB_EALG_3DESCBC 3 -#define SADB_EALG_NULL 11 -#define SADB_EALG_MAX 250 -/* private allocations - based on RFC2407/IANA assignment */ #define SADB_X_EALG_CAST128CBC 6 #define SADB_X_EALG_BLOWFISHCBC 7 +#define SADB_EALG_NULL 11 #define SADB_X_EALG_RIJNDAELCBC 12 #define SADB_X_EALG_AES 12 +#define SADB_X_EALG_AESCTR 13 #define SADB_X_EALG_AESGCM8 18 /* RFC4106 */ #define SADB_X_EALG_AESGCM12 19 #define SADB_X_EALG_AESGCM16 20 -/* private allocations - based on RFC4312/IANA assignment */ -#define SADB_X_EALG_CAMELLIACBC 22 -#define SADB_X_EALG_AESGMAC 23 /* RFC4543 + Errata1821 */ -/* private allocations should use 249-255 (RFC2407) */ -#define SADB_X_EALG_SKIPJACK 249 /*250*/ /* for IPSEC */ -#define SADB_X_EALG_AESCTR 250 /*249*/ /* draft-ietf-ipsec-ciph-aes-ctr-03 */ +#define SADB_X_EALG_CAMELLIACBC 22 +#define SADB_X_EALG_AESGMAC 23 /* RFC4543 + Errata1821 */ +#define SADB_EALG_MAX 23 /* !!! keep updated !!! */ /* private allocations - based on RFC2407/IANA assignment */ #define SADB_X_CALG_NONE 0 diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index dbb1a274c885..67551caef43e 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -115,8 +115,6 @@ esp_algorithm_lookup(int alg) return &enc_xform_blf; case SADB_X_EALG_CAST128CBC: return &enc_xform_cast5; - case SADB_X_EALG_SKIPJACK: - return &enc_xform_skipjack; case SADB_EALG_NULL: return &enc_xform_null; case SADB_X_EALG_CAMELLIACBC: From 42e5fcbf2befe204d7e64b7f93ae0bee86c6ec18 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Fri, 31 Jul 2015 00:31:52 +0000 Subject: [PATCH 102/314] these are comparing authenticators and need to be constant time... This could be a side channel attack... Now that we have a function for this, use it... jmgurney/ipsecgcm: 24d704cc and 7f37a14 --- sys/netipsec/xform_ah.c | 2 +- sys/netipsec/xform_esp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c index ae0feb9f627a..350a735a89b3 100644 --- a/sys/netipsec/xform_ah.c +++ b/sys/netipsec/xform_ah.c @@ -777,7 +777,7 @@ ah_input_cb(struct cryptop *crp) /* Verify authenticator. */ ptr = (caddr_t) (tc + 1); - if (bcmp(ptr + skip + rplen, calc, authsize)) { + if (timingsafe_bcmp(ptr + skip + rplen, calc, authsize)) { DPRINTF(("%s: authentication hash mismatch for packet " "in SA %s/%08lx\n", __func__, ipsec_address(&saidx->dst, buf, sizeof(buf)), diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index 67551caef43e..d8182dfdf588 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -534,7 +534,7 @@ esp_input_cb(struct cryptop *crp) ptr = (caddr_t) (tc + 1); /* Verify authenticator */ - if (bcmp(ptr, aalg, alen) != 0) { + if (timingsafe_bcmp(ptr, aalg, alen) != 0) { DPRINTF(("%s: authentication hash mismatch for " "packet in SA %s/%08lx\n", __func__, ipsec_address(&saidx->dst, buf, sizeof(buf)), From 479184e919c5d559cce49bb9be32fe7191dd1652 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Fri, 31 Jul 2015 01:12:31 +0000 Subject: [PATCH 103/314] Buffer overflow in wall(1). This affected syslogd, wall and talkd. Detected by FORTIFY_SOURCE GSoC (with clang). Submitted by: Oliver Pinter Differential Revision: https://reviews.freebsd.org/D3254 Reviewed by: delphij, jmg MFC after: 3 days --- usr.bin/wall/ttymsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.bin/wall/ttymsg.c b/usr.bin/wall/ttymsg.c index 37b09e9e95d6..1317a4b0cb60 100644 --- a/usr.bin/wall/ttymsg.c +++ b/usr.bin/wall/ttymsg.c @@ -62,7 +62,7 @@ ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) struct iovec localiov[7]; ssize_t left, wret; int cnt, fd; - static char device[MAXNAMLEN] = _PATH_DEV; + char device[MAXNAMLEN] = _PATH_DEV; static char errbuf[1024]; char *p; int forked; @@ -71,8 +71,8 @@ ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0]))) return ("too many iov's (change code in wall/ttymsg.c)"); + strlcat(device, line, sizeof(device)); p = device + sizeof(_PATH_DEV) - 1; - strlcpy(p, line, sizeof(device)); if (strncmp(p, "pts/", 4) == 0) p += 4; if (strchr(p, '/') != NULL) { From 215397449a172b26e33432966bfa759c92ede77b Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Fri, 31 Jul 2015 03:28:02 +0000 Subject: [PATCH 104/314] The implementation note isn't true anymore.. Not that anyone reads it, but those that do, remind them that this isn't usable in userland... I can't wait till this doc is wrong.. --- share/man/man9/CTASSERT.9 | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/share/man/man9/CTASSERT.9 b/share/man/man9/CTASSERT.9 index 6211c2e5095a..7b719e1e7ab0 100644 --- a/share/man/man9/CTASSERT.9 +++ b/share/man/man9/CTASSERT.9 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 5, 2008 +.Dd July 30, 2015 .Dt CTASSERT 9 .Os .Sh NAME @@ -48,14 +48,10 @@ The macro is useful for asserting the size or alignment of important data structures and variables during compilation, which would otherwise cause the code to fail at run time. -.Sh IMPLEMENTATION NOTES +.Pp The .Fn CTASSERT -macro should not be used in a header file. -It is implemented using a dummy typedef, with a name (based on line number) -that may conflict with a -.Fn CTASSERT -in a source file including that header. +macro is not usable in userland. .Sh EXAMPLES Assert that the size of the .Vt uuid From 89177288751a557b9348eb728ad4293c7e944956 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 31 Jul 2015 04:12:51 +0000 Subject: [PATCH 105/314] vn_io_fault() handling of the LOR for i/o into the file-backed buffers has observable overhead when the buffer pages are not resident or not mapped. The overhead comes at least from two factors, one is the additional work needed to detect the situation, prepare and execute the rollbacks. Another is the consequence of the i/o splitting into the batches of the held pages, causing filesystems see series of the smaller i/o requests instead of the single large request. Note that expected case of the resident i/o buffer does not expose these issues. Provide a prefaulting for the userspace i/o buffers, disabled by default. I am careful of not enabling prefaulting by default for now, since it would be detrimental for the applications which speculatively pass extra-large buffers of anonymous memory to not deal with buffer sizing (if such apps exist). Found and tested by: bde, emaste Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/kern/vfs_vnops.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index c8c49810b503..ecc93e13346e 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -116,6 +116,9 @@ static const int io_hold_cnt = 16; static int vn_io_fault_enable = 1; SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_enable, CTLFLAG_RW, &vn_io_fault_enable, 0, "Enable vn_io_fault lock avoidance"); +static int vn_io_fault_prefault = 0; +SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_prefault, CTLFLAG_RW, + &vn_io_fault_prefault, 0, "Enable vn_io_fault prefaulting"); static u_long vn_io_faults_cnt; SYSCTL_ULONG(_debug, OID_AUTO, vn_io_faults, CTLFLAG_RD, &vn_io_faults_cnt, 0, "Count of vn_io_fault lock avoidance triggers"); @@ -1020,6 +1023,59 @@ vn_io_fault_doio(struct vn_io_fault_args *args, struct uio *uio, uio->uio_rw); } +static int +vn_io_fault_touch(char *base, const struct uio *uio) +{ + int r; + + r = fubyte(base); + if (r == -1 || (uio->uio_rw == UIO_READ && subyte(base, r) == -1)) + return (EFAULT); + return (0); +} + +static int +vn_io_fault_prefault_user(const struct uio *uio) +{ + char *base; + const struct iovec *iov; + size_t len; + ssize_t resid; + int error, i; + + KASSERT(uio->uio_segflg == UIO_USERSPACE, + ("vn_io_fault_prefault userspace")); + + error = i = 0; + iov = uio->uio_iov; + resid = uio->uio_resid; + base = iov->iov_base; + len = iov->iov_len; + while (resid > 0) { + error = vn_io_fault_touch(base, uio); + if (error != 0) + break; + if (len < PAGE_SIZE) { + if (len != 0) { + error = vn_io_fault_touch(base + len - 1, uio); + if (error != 0) + break; + resid -= len; + } + if (++i >= uio->uio_iovcnt) + break; + iov = uio->uio_iov + i; + base = iov->iov_base; + len = iov->iov_len; + } else { + len -= PAGE_SIZE; + base += PAGE_SIZE; + resid -= PAGE_SIZE; + } + } + return (error); +} + /* * Common code for vn_io_fault(), agnostic to the kind of i/o request. * Uses vn_io_fault_doio() to make the call to an actual i/o function. @@ -1041,6 +1097,12 @@ vn_io_fault1(struct vnode *vp, struct uio *uio, struct vn_io_fault_args *args, ssize_t adv; int error, cnt, save, saveheld, prev_td_ma_cnt; + if (vn_io_fault_prefault) { + error = vn_io_fault_prefault_user(uio); + if (error != 0) + return (error); /* Or ignore ? */ + } + prot = uio->uio_rw == UIO_READ ? VM_PROT_WRITE : VM_PROT_READ; /* From 3d3169c8589fec2e13b8893c4850946fad0b003c Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Fri, 31 Jul 2015 04:50:47 +0000 Subject: [PATCH 106/314] cxgbe(4): initialize debug_flags from the kernel environment. MFC after: 3 days --- sys/dev/cxgbe/t4_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 8c96715c0bd6..442643eeebbf 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -585,9 +585,7 @@ t4_attach(device_t dev) sc = device_get_softc(dev); sc->dev = dev; -#ifdef INVARIANTS - sc->debug_flags = DF_DUMP_MBOX; -#endif + TUNABLE_INT_FETCH("hw.cxgbe.debug_flags", &sc->debug_flags); pci_enable_busmaster(dev); if (pci_find_cap(dev, PCIY_EXPRESS, &i) == 0) { From af024d3b2372323ca37ebf5a3c9f35d8d460e5f6 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Fri, 31 Jul 2015 07:48:08 +0000 Subject: [PATCH 107/314] temporarily fix build.. This isn't the final fix, and testing is still on going, but it has passed world for mips and powerpc... I know this has an extra semicolon, but this is the patch that is tested... Looks like better fix is to use _Static_assert... --- sys/net/pfkeyv2.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index 0fe3c96c348d..dcd67675cc99 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -39,6 +39,10 @@ #ifndef _NET_PFKEYV2_H_ #define _NET_PFKEYV2_H_ +#ifndef _KERNEL +#define CTASSERT(x) struct __thisisjustnothing; +#endif + /* This file defines structures and symbols for the PF_KEY Version 2 key management interface. It was written at the U.S. Naval Research From 42642ecd97135e9194f3d3176ca4e896f6da4c7f Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 31 Jul 2015 08:45:35 +0000 Subject: [PATCH 108/314] Document the existence of cloudabi_load and cloudabi64_load. --- sys/boot/forth/loader.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index caafcc65ba90..e2338abe4c05 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -268,6 +268,8 @@ screensave_name="green_saver" # Set to the name of the screensaver module ### Emulation modules ###################################### ############################################################## +cloudabi_load="NO" # Platform independent CloudABI support +cloudabi64_load="NO" # 64-bit CloudABI executables support ibcs2_load="NO" # IBCS2 (SCO) emulation ibcs2_coff_load="NO" linux_load="NO" # Linux emulation From cf14ccb0f7a1a8aa9729c97454f003f886fbaa90 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Fri, 31 Jul 2015 09:02:28 +0000 Subject: [PATCH 109/314] Remove unneded #include "opt_inet.h". --- sys/netinet/ip_ecn.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/netinet/ip_ecn.h b/sys/netinet/ip_ecn.h index 0886cc8277fe..c5c1c4ebf57f 100644 --- a/sys/netinet/ip_ecn.h +++ b/sys/netinet/ip_ecn.h @@ -38,10 +38,6 @@ #ifndef _NETINET_IP_ECN_H_ #define _NETINET_IP_ECN_H_ -#if defined(_KERNEL) && !defined(_LKM) -#include "opt_inet.h" -#endif - #define ECN_ALLOWED 1 /* ECN allowed */ #define ECN_FORBIDDEN 0 /* ECN forbidden */ #define ECN_NOCARE (-1) /* no consideration to ECN */ From 926381e1083dbaa5386adace06e22d2db9c47c85 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Fri, 31 Jul 2015 09:04:22 +0000 Subject: [PATCH 110/314] Ansify if_stf.c --- sys/net/if_stf.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index 6d7eeb8e33de..cbcee141ea62 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -272,10 +272,7 @@ stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) } static int -stfmodevent(mod, type, data) - module_t mod; - int type; - void *data; +stfmodevent(module_t mod, int type, void *data) { switch (type) { @@ -302,11 +299,7 @@ static moduledata_t stf_mod = { DECLARE_MODULE(if_stf, stf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); static int -stf_encapcheck(m, off, proto, arg) - const struct mbuf *m; - int off; - int proto; - void *arg; +stf_encapcheck(const struct mbuf *m, int off, int proto, void *arg) { struct ip ip; struct stf_softc *sc; @@ -401,7 +394,7 @@ stf_getsrcifa6(struct ifnet *ifp, struct in6_addr *addr, struct in6_addr *mask) static int stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, - struct route *ro) + struct route *ro) { struct stf_softc *sc; const struct sockaddr_in6 *dst6; @@ -507,8 +500,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, } static int -isrfc1918addr(in) - struct in_addr *in; +isrfc1918addr(struct in_addr *in) { /* * returns 1 if private address range: @@ -524,10 +516,7 @@ isrfc1918addr(in) } static int -stf_checkaddr4(sc, in, inifp) - struct stf_softc *sc; - struct in_addr *in; - struct ifnet *inifp; /* incoming interface */ +stf_checkaddr4(struct stf_softc *sc, struct in_addr *in, struct ifnet *inifp) { struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia4; @@ -594,10 +583,7 @@ stf_checkaddr4(sc, in, inifp) } static int -stf_checkaddr6(sc, in6, inifp) - struct stf_softc *sc; - struct in6_addr *in6; - struct ifnet *inifp; /* incoming interface */ +stf_checkaddr6(struct stf_softc *sc, struct in6_addr *in6, struct ifnet *inifp) { /* * check 6to4 addresses @@ -720,10 +706,7 @@ in_stf_input(struct mbuf **mp, int *offp, int proto) } static int -stf_ioctl(ifp, cmd, data) - struct ifnet *ifp; - u_long cmd; - caddr_t data; +stf_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct ifaddr *ifa; struct ifreq *ifr; From 56d6361d9291eed6eb4511f63da57527247a1b8e Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 31 Jul 2015 09:12:31 +0000 Subject: [PATCH 111/314] Limit the number of times we loop inside the DWC OTG poll handler to avoid starving other fast interrupts. Fix a comment while at it. MFC after: 1 week Suggested by: Svatopluk Kraus --- sys/dev/usb/controller/dwc_otg.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index 51f083bc235d..bd3e51b91a20 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -2551,12 +2551,18 @@ static void dwc_otg_interrupt_poll_locked(struct dwc_otg_softc *sc) { struct usb_xfer *xfer; + uint32_t count = 0; uint32_t temp; uint8_t got_rx_status; uint8_t x; repeat: - /* get all channel interrupts */ + if (++count == 16) { + /* give other interrupts a chance */ + DPRINTF("Yield\n"); + return; + } + /* get all host channel interrupts */ for (x = 0; x != sc->sc_host_ch_max; x++) { temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x)); if (temp != 0) { From a2b3dfad08f6b785cbadb3b3ba35e4c0e84ba29e Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Fri, 31 Jul 2015 10:00:45 +0000 Subject: [PATCH 112/314] Apply erratum for mrs ICC_IAR1_EL1 speculative execution on ThunderX ERRATUM: 22978, 23154 PASS (rev.): 1.0/1.1 Reviewed by: imp Obtained from: Semihalf Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3184 --- sys/arm64/arm64/gic_v3.c | 18 +++++++++++++++++- sys/arm64/conf/GENERIC | 3 +++ sys/arm64/include/cpu.h | 26 ++++++++++++++++++++++++++ sys/conf/options.arm64 | 9 +++++---- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index 5dc2c0bea2ae..022a6c207f0f 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include "pic_if.h" @@ -230,7 +231,22 @@ gic_v3_dispatch(device_t dev, struct trapframe *frame) uint64_t active_irq; while (1) { - active_irq = gic_icc_read(IAR1); + if (CPU_MATCH_ERRATA_CAVIUM_THUNDER_1_1) { + /* + * Hardware: Cavium ThunderX + * Chip revision: Pass 1.0 (early version) + * Pass 1.1 (production) + * ERRATUM: 22978, 23154 + */ + __asm __volatile( + "nop;nop;nop;nop;nop;nop;nop;nop; \n" + "mrs %0, ICC_IAR1_EL1 \n" + "nop;nop;nop;nop; \n" + "dsb sy \n" + : "=&r" (active_irq)); + } else { + active_irq = gic_icc_read(IAR1); + } if (__predict_false(active_irq == ICC_IAR1_EL1_SPUR)) break; diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index c4ef49d180b3..e3b0c77245d9 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -109,6 +109,9 @@ device psci # Support for ARM PSCI # Note that 'bpf' is required for DHCP. device bpf # Berkeley packet filter +# Chip-specific errata +options THUNDERX_PASS_1_1_ERRATA + options FDT device acpi diff --git a/sys/arm64/include/cpu.h b/sys/arm64/include/cpu.h index 15cdd80d4e26..ec351ad03b68 100644 --- a/sys/arm64/include/cpu.h +++ b/sys/arm64/include/cpu.h @@ -78,6 +78,9 @@ #define CPU_PART_CORTEX_A53 0xD03 #define CPU_PART_CORTEX_A57 0xD07 +#define CPU_REV_THUNDER_1_0 0x00 +#define CPU_REV_THUNDER_1_1 0x01 + #define CPU_IMPL(midr) (((midr) >> 24) & 0xff) #define CPU_PART(midr) (((midr) >> 4) & 0xfff) #define CPU_VAR(midr) (((midr) >> 20) & 0xf) @@ -105,6 +108,29 @@ #define CPU_MATCH_RAW(mask, devid) \ (((mask) & PCPU_GET(midr)) == ((mask) & (devid))) +/* + * Chip-specific errata. This defines are intended to be + * booleans used within if statements. When an appropriate + * kernel option is disabled, these defines must be defined + * as 0 to allow the compiler to remove a dead code thus + * produce better optimized kernel image. + */ +/* + * Vendor: Cavium + * Chip: ThunderX + * Revision(s): Pass 1.0, Pass 1.1 + */ +#ifdef THUNDERX_PASS_1_1_ERRATA +#define CPU_MATCH_ERRATA_CAVIUM_THUNDER_1_1 \ + (CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK | CPU_REV_MASK, \ + CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, CPU_REV_THUNDER_1_0) || \ + CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK | CPU_REV_MASK, \ + CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, CPU_REV_THUNDER_1_1)) +#else +#define CPU_MATCH_ERRATA_CAVIUM_THUNDER_1_1 0 +#endif + + extern char btext[]; extern char etext[]; diff --git a/sys/conf/options.arm64 b/sys/conf/options.arm64 index 1dfcbec11ffe..4965940d222d 100644 --- a/sys/conf/options.arm64 +++ b/sys/conf/options.arm64 @@ -1,6 +1,7 @@ # $FreeBSD$ -ARM64 opt_global.h -SOCDEV_PA opt_global.h -SOCDEV_VA opt_global.h -VFP opt_global.h +ARM64 opt_global.h +SOCDEV_PA opt_global.h +SOCDEV_VA opt_global.h +THUNDERX_PASS_1_1_ERRATA opt_global.h +VFP opt_global.h From 367a13f905874f6ad0a5f78cb88a4923cfe86e5e Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 31 Jul 2015 10:21:58 +0000 Subject: [PATCH 113/314] Limit rights on process descriptors. On CloudABI, the rights bits returned by cap_rights_get() match up with the operations that you can actually perform on the file descriptor. Limiting the rights is good, because it makes it easier to get uniform behaviour across different operating systems. If process descriptors on FreeBSD would suddenly gain support for any new file operation, this wouldn't become exposed to CloudABI processes without first extending the rights. Extend fork1() to gain a 'struct filecaps' argument that allows you to construct process descriptors with custom rights. Use this in cloudabi_sys_proc_fork() to limit the rights to just fstat() and pdwait(). Obtained from: https://github.com/NuxiNL/freebsd --- sys/compat/cloudabi/cloudabi_proc.c | 6 +++++- sys/compat/linux/linux_fork.c | 8 ++++---- sys/kern/init_main.c | 2 +- sys/kern/kern_fork.c | 13 +++++++------ sys/kern/kern_kthread.c | 2 +- sys/sys/proc.h | 4 +++- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_proc.c b/sys/compat/cloudabi/cloudabi_proc.c index 1f4418f0b589..b071aa390ad3 100644 --- a/sys/compat/cloudabi/cloudabi_proc.c +++ b/sys/compat/cloudabi/cloudabi_proc.c @@ -27,6 +27,8 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include #include #include @@ -67,10 +69,12 @@ int cloudabi_sys_proc_fork(struct thread *td, struct cloudabi_sys_proc_fork_args *uap) { + struct filecaps fcaps = {}; struct proc *p2; int error, fd; - error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, &fd, 0); + cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_PDWAIT); + error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, &fd, 0, &fcaps); if (error != 0) return (error); /* Return the file descriptor to the parent process. */ diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c index 6b3749009bcf..a8bf72091393 100644 --- a/sys/compat/linux/linux_fork.c +++ b/sys/compat/linux/linux_fork.c @@ -73,8 +73,8 @@ linux_fork(struct thread *td, struct linux_fork_args *args) printf(ARGS(fork, "")); #endif - if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2, NULL, 0)) - != 0) + if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2, NULL, 0, + NULL)) != 0) return (error); td2 = FIRST_THREAD_IN_PROC(p2); @@ -108,7 +108,7 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args) /* Exclude RFPPWAIT */ if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2, - NULL, 0)) != 0) + NULL, 0, NULL)) != 0) return (error); @@ -179,7 +179,7 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args) if (args->parent_tidptr == NULL) return (EINVAL); - error = fork1(td, ff, 0, &p2, NULL, 0); + error = fork1(td, ff, 0, &p2, NULL, 0, NULL); if (error) return (error); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index a362d00fbfdf..efb7317c0e09 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -831,7 +831,7 @@ create_init(const void *udata __unused) int error; error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc, - NULL, 0); + NULL, 0, NULL); if (error) panic("cannot fork init: %d\n", error); KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1")); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index a031435455aa..ccd879249630 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -104,7 +104,7 @@ sys_fork(struct thread *td, struct fork_args *uap) int error; struct proc *p2; - error = fork1(td, RFFDG | RFPROC, 0, &p2, NULL, 0); + error = fork1(td, RFFDG | RFPROC, 0, &p2, NULL, 0, NULL); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -127,7 +127,7 @@ sys_pdfork(td, uap) * itself from the parent using the return value. */ error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, - &fd, uap->flags); + &fd, uap->flags, NULL); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -144,7 +144,7 @@ sys_vfork(struct thread *td, struct vfork_args *uap) struct proc *p2; flags = RFFDG | RFPROC | RFPPWAIT | RFMEM; - error = fork1(td, flags, 0, &p2, NULL, 0); + error = fork1(td, flags, 0, &p2, NULL, 0, NULL); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -163,7 +163,7 @@ sys_rfork(struct thread *td, struct rfork_args *uap) return (EINVAL); AUDIT_ARG_FFLAGS(uap->flags); - error = fork1(td, uap->flags, 0, &p2, NULL, 0); + error = fork1(td, uap->flags, 0, &p2, NULL, 0, NULL); if (error == 0) { td->td_retval[0] = p2 ? p2->p_pid : 0; td->td_retval[1] = 0; @@ -768,7 +768,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, int fork1(struct thread *td, int flags, int pages, struct proc **procp, - int *procdescp, int pdflags) + int *procdescp, int pdflags, struct filecaps *fcaps) { struct proc *p1; struct proc *newproc; @@ -824,7 +824,8 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, * later. */ if (flags & RFPROCDESC) { - error = falloc(td, &fp_procdesc, procdescp, 0); + error = falloc_caps(td, &fp_procdesc, procdescp, 0, + fcaps); if (error != 0) return (error); } diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 68903ba079e5..2072dc726b08 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -89,7 +89,7 @@ kproc_create(void (*func)(void *), void *arg, panic("kproc_create called too soon"); error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, - pages, &p2, NULL, 0); + pages, &p2, NULL, 0, NULL); if (error) return error; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 40893ed34477..9689b17df0ea 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -161,6 +161,7 @@ struct pargs { * for write access. */ struct cpuset; +struct filecaps; struct kaioinfo; struct kaudit_record; struct kdtrace_proc; @@ -916,7 +917,8 @@ int enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp, int enterthispgrp(struct proc *p, struct pgrp *pgrp); void faultin(struct proc *p); void fixjobc(struct proc *p, struct pgrp *pgrp, int entering); -int fork1(struct thread *, int, int, struct proc **, int *, int); +int fork1(struct thread *, int, int, struct proc **, int *, int, + struct filecaps *); void fork_exit(void (*)(void *, struct trapframe *), void *, struct trapframe *); void fork_return(struct thread *, struct trapframe *); From 6236e71bfe7a77e1f4b1908c727cc52e4c2888cc Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 31 Jul 2015 10:46:45 +0000 Subject: [PATCH 114/314] Fix accidental line wrapping introduced in r286122. --- sys/kern/kern_fork.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index ccd879249630..85dbd944325c 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -824,8 +824,7 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, * later. */ if (flags & RFPROCDESC) { - error = falloc_caps(td, &fp_procdesc, procdescp, 0, - fcaps); + error = falloc_caps(td, &fp_procdesc, procdescp, 0, fcaps); if (error != 0) return (error); } From 71d72ea14f174439bcc35550e67bca8b3c58bdaf Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 31 Jul 2015 13:32:25 +0000 Subject: [PATCH 115/314] Add VIRT_IN_DMAP to check if a virtual address is from the DMAP range. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/include/vmparam.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/arm64/include/vmparam.h b/sys/arm64/include/vmparam.h index 8ad602994e48..d1ed7f3509c8 100644 --- a/sys/arm64/include/vmparam.h +++ b/sys/arm64/include/vmparam.h @@ -165,6 +165,9 @@ /* True if pa is in the dmap range */ #define PHYS_IN_DMAP(pa) ((pa) <= DMAP_MAX_PHYSADDR) +/* True if va is in the dmap range */ +#define VIRT_IN_DMAP(va) ((va) >= DMAP_MIN_ADDRESS && \ + (va) <= DMAP_MAX_ADDRESS) #define PHYS_TO_DMAP(pa) \ ({ \ @@ -176,7 +179,7 @@ #define DMAP_TO_PHYS(va) \ ({ \ - KASSERT(((va) <= DMAP_MAX_ADDRESS || (va) >= DMAP_MIN_ADDRESS), \ + KASSERT(VIRT_IN_DMAP(va), \ ("%s: VA out of range, VA: 0x%lx", __func__, \ (vm_offset_t)(va))); \ (va) & ~DMAP_MIN_ADDRESS; \ From 9b8c3c4f0bc86a2c9fc4f09189c7397473f6e614 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 31 Jul 2015 13:34:43 +0000 Subject: [PATCH 116/314] Add more atomic_swap_* functions. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/include/atomic.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sys/arm64/include/atomic.h b/sys/arm64/include/atomic.h index 4c9d7188e735..12ce4a1dcb86 100644 --- a/sys/arm64/include/atomic.h +++ b/sys/arm64/include/atomic.h @@ -153,6 +153,22 @@ atomic_set_32(volatile uint32_t *p, uint32_t val) ); } +static __inline uint32_t +atomic_swap_32(volatile uint32_t *p, uint32_t val) +{ + uint32_t tmp; + int res; + + __asm __volatile( + "1: ldxr %w0, [%2] \n" + " stxr %w1, %w3, [%2] \n" + " cbnz %w1, 1b \n" + : "=&r"(tmp), "=&r"(res), "+r" (p), "+r" (val) : : "cc", "memory" + ); + + return (tmp); +} + static __inline void atomic_subtract_32(volatile uint32_t *p, uint32_t val) { @@ -174,6 +190,7 @@ atomic_subtract_32(volatile uint32_t *p, uint32_t val) #define atomic_fetchadd_int atomic_fetchadd_32 #define atomic_readandclear_int atomic_readandclear_32 #define atomic_set_int atomic_set_32 +#define atomic_swap_int atomic_swap_32 #define atomic_subtract_int atomic_subtract_32 static __inline void @@ -515,6 +532,7 @@ atomic_swap_64(volatile uint64_t *p, uint64_t val) #define atomic_fetchadd_long atomic_fetchadd_64 #define atomic_readandclear_long atomic_readandclear_64 #define atomic_set_long atomic_set_64 +#define atomic_swap_long atomic_swap_64 #define atomic_subtract_long atomic_subtract_64 #define atomic_add_ptr atomic_add_64 @@ -523,6 +541,7 @@ atomic_swap_64(volatile uint64_t *p, uint64_t val) #define atomic_fetchadd_ptr atomic_fetchadd_64 #define atomic_readandclear_ptr atomic_readandclear_64 #define atomic_set_ptr atomic_set_64 +#define atomic_swap_ptr atomic_swap_64 #define atomic_subtract_ptr atomic_subtract_64 static __inline void From 872df66596ac6c737664d2756c36da9712d9db1a Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 31 Jul 2015 13:39:51 +0000 Subject: [PATCH 117/314] Add memrw. This has had minimal testing, and will likely panic the kernel when trying to read data from outside the DMAP region. I expect this panic to be from within uiomove_fromphys, which needs to grow support to support such addresses. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/arm64/mem.c | 71 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/sys/arm64/arm64/mem.c b/sys/arm64/arm64/mem.c index 373d0bf18c6a..481ef8842e92 100644 --- a/sys/arm64/arm64/mem.c +++ b/sys/arm64/arm64/mem.c @@ -33,15 +33,84 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include + +#include +#include +#include +#include struct mem_range_softc mem_range_softc; int memrw(struct cdev *dev, struct uio *uio, int flags) { + struct iovec *iov; + struct vm_page m; + vm_page_t marr; + vm_offset_t off, v; + u_int cnt; + int error; - panic("ARM64TODO: memrw"); + error = 0; + + while (uio->uio_resid > 0 && error == 0) { + iov = uio->uio_iov; + if (iov->iov_len == 0) { + uio->uio_iov++; + uio->uio_iovcnt--; + if (uio->uio_iovcnt < 0) + panic("memrw"); + continue; + } + + v = uio->uio_offset; + off = v & PAGE_MASK; + cnt = ulmin(iov->iov_len, PAGE_SIZE - (u_int)off); + if (cnt == 0) + continue; + + switch(dev2unit(dev)) { + case CDEV_MINOR_KMEM: + /* If the address is in the DMAP just copy it */ + if (VIRT_IN_DMAP(v)) { + error = uiomove((void *)v, cnt, uio); + break; + } + + if (!kernacc((void *)v, cnt, uio->uio_rw == UIO_READ ? + VM_PROT_READ : VM_PROT_WRITE)) { + error = EFAULT; + break; + } + + /* Get the physical address to read */ + v = pmap_extract(kernel_pmap, v); + if (v == 0) { + error = EFAULT; + break; + } + + /* FALLTHROUGH */ + case CDEV_MINOR_MEM: + /* If within the DMAP use this to copy from */ + if (PHYS_IN_DMAP(v)) { + v = PHYS_TO_DMAP(v); + error = uiomove((void *)v, cnt, uio); + break; + } + + /* Have uiomove_fromphys handle the data */ + m.phys_addr = trunc_page(v); + marr = &m; + uiomove_fromphys(&marr, off, cnt, uio); + break; + } + } + + return (error); } From 36baf858c9cc3d76b357399401a94fb7adcb7017 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 31 Jul 2015 14:17:26 +0000 Subject: [PATCH 118/314] Add support for uma_small_alloc and uma_small_free, and make use of these. This is copied from the amd64 version with minor changes. These should be merged into a single file as from a quick look there are other copies of the same file in other parts of the tree. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/arm64/uma_machdep.c | 81 +++++++++++++++++++++++++++++++++++ sys/arm64/arm64/vm_machdep.c | 15 ------- sys/arm64/include/vmparam.h | 2 + sys/conf/files.arm64 | 1 + 4 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 sys/arm64/arm64/uma_machdep.c diff --git a/sys/arm64/arm64/uma_machdep.c b/sys/arm64/arm64/uma_machdep.c new file mode 100644 index 000000000000..b17a2533875e --- /dev/null +++ b/sys/arm64/arm64/uma_machdep.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2003 Alan L. Cox + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void * +uma_small_alloc(uma_zone_t zone, vm_size_t bytes, u_int8_t *flags, int wait) +{ + vm_page_t m; + vm_paddr_t pa; + void *va; + int pflags; + + *flags = UMA_SLAB_PRIV; + pflags = malloc2vm_flags(wait) | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED; + for (;;) { + m = vm_page_alloc(NULL, 0, pflags); + if (m == NULL) { + if (wait & M_NOWAIT) + return (NULL); + else + VM_WAIT; + } else + break; + } + pa = m->phys_addr; + va = (void *)PHYS_TO_DMAP(pa); + if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0) + bzero(va, PAGE_SIZE); + return (va); +} + +void +uma_small_free(void *mem, vm_size_t size, u_int8_t flags) +{ + vm_page_t m; + vm_paddr_t pa; + + pa = DMAP_TO_PHYS((vm_offset_t)mem); + m = PHYS_TO_VM_PAGE(pa); + m->wire_count--; + vm_page_free(m); + atomic_subtract_int(&vm_cnt.v_wire_count, 1); +} diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c index f32901aa10a9..908b21fe22a8 100644 --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -258,18 +258,3 @@ swi_vm(void *v) /* Nothing to do here - busdma bounce buffers are not implemented. */ } - -void * -uma_small_alloc(uma_zone_t zone, vm_size_t bytes, u_int8_t *flags, int wait) -{ - - panic("ARM64TODO: uma_small_alloc"); -} - -void -uma_small_free(void *mem, vm_size_t size, u_int8_t flags) -{ - - panic("ARM64TODO: uma_small_free"); -} - diff --git a/sys/arm64/include/vmparam.h b/sys/arm64/include/vmparam.h index d1ed7f3509c8..3c14af8d101a 100644 --- a/sys/arm64/include/vmparam.h +++ b/sys/arm64/include/vmparam.h @@ -224,6 +224,8 @@ #define VM_INITIAL_PAGEIN 16 #endif +#define UMA_MD_SMALL_ALLOC + extern u_int tsb_kernel_ldd_phys; extern vm_offset_t vm_max_kernel_address; extern vm_offset_t init_pt_va; diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 92a422d4a1bf..a26d95acb67a 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -46,6 +46,7 @@ arm64/arm64/swtch.S standard arm64/arm64/sys_machdep.c standard arm64/arm64/trap.c standard arm64/arm64/uio_machdep.c standard +arm64/arm64/uma_machdep.c standard arm64/arm64/unwind.c optional ddb | kdtrace_hooks arm64/arm64/vfp.c standard arm64/arm64/vm_machdep.c standard From 45e1c1a38ddd03e64a8913aac6080d55a30b4adc Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Fri, 31 Jul 2015 15:23:48 +0000 Subject: [PATCH 119/314] Pull pmspcv (pms(4)) from GENERIC. It has PCI ID conflicts with ahd(4), mvs(4), and likely other drivers. MFC after: immediately With hat: re Sponsored by: The FreeBSD Foundation --- sys/amd64/conf/GENERIC | 3 ++- sys/i386/conf/GENERIC | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 5c7f7c035f43..1320ba7c4108 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -170,7 +170,8 @@ device ida # Compaq Smart RAID device mfi # LSI MegaRAID SAS device mlx # Mylex DAC960 family device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s -device pmspcv # PMC-Sierra SAS/SATA Controller driver +#XXX PCI ID conflicts with ahd(4) and mvs(4) +#device pmspcv # PMC-Sierra SAS/SATA Controller driver #XXX pointer/int warnings #device pst # Promise Supertrak SX6000 device twe # 3ware ATA RAID diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index dc11f73c4302..deed451a2335 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -175,7 +175,8 @@ device ida # Compaq Smart RAID device mfi # LSI MegaRAID SAS device mlx # Mylex DAC960 family device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s -device pmspcv # PMC-Sierra SAS/SATA Controller driver +#XXX PCI ID conflicts with ahd(4) and mvs(4) +#device pmspcv # PMC-Sierra SAS/SATA Controller driver device pst # Promise Supertrak SX6000 device twe # 3ware ATA RAID From 176739d3f59651f36a5b6b79b9d9dd3ccea68a59 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 31 Jul 2015 15:32:32 +0000 Subject: [PATCH 120/314] Load the stack in stack_save and stack_save_td. This uses the generalised unwind_frame function to read each stack frame until either the pc or stack are no longer withing the kernel's address space. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/arm64/stack_machdep.c | 32 ++++++++++++++++++++++++++++++-- sys/conf/files.arm64 | 4 ++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/sys/arm64/arm64/stack_machdep.c b/sys/arm64/arm64/stack_machdep.c index 7449eaa2199e..72a9ab9e92b6 100644 --- a/sys/arm64/arm64/stack_machdep.c +++ b/sys/arm64/arm64/stack_machdep.c @@ -40,21 +40,49 @@ __FBSDID("$FreeBSD$"); #include #include +static void +stack_capture(struct stack *st, struct unwind_state *frame) +{ + + stack_zero(st); + while (1) { + unwind_frame(frame); + if (!INKERNEL((vm_offset_t)frame->fp) || + !INKERNEL((vm_offset_t)frame->pc)) + break; + if (stack_put(st, frame->pc) == -1) + break; + } +} + void stack_save_td(struct stack *st, struct thread *td) { + struct unwind_state frame; if (TD_IS_SWAPPED(td)) panic("stack_save_td: swapped"); if (TD_IS_RUNNING(td)) panic("stack_save_td: running"); - stack_zero(st); /* ARM64TODO */ + frame.sp = td->td_pcb->pcb_sp; + frame.fp = td->td_pcb->pcb_x[29]; + frame.pc = td->td_pcb->pcb_x[30]; + + stack_capture(st, &frame); } void stack_save(struct stack *st) { + struct unwind_state frame; + uint64_t sp; - stack_zero(st); /* ARM64TODO */ + __asm __volatile("mov %0, sp" : "=&r" (sp)); + + frame.sp = sp; + frame.fp = (uint64_t)__builtin_frame_address(0); + frame.pc = (uint64_t)stack_save; + + stack_capture(st, &frame); } diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index a26d95acb67a..6a8c9661a6a4 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -40,14 +40,14 @@ arm64/arm64/mp_machdep.c optional smp arm64/arm64/nexus.c standard arm64/arm64/pic_if.m standard arm64/arm64/pmap.c standard -arm64/arm64/stack_machdep.c standard +arm64/arm64/stack_machdep.c optional ddb | stack arm64/arm64/support.S standard arm64/arm64/swtch.S standard arm64/arm64/sys_machdep.c standard arm64/arm64/trap.c standard arm64/arm64/uio_machdep.c standard arm64/arm64/uma_machdep.c standard -arm64/arm64/unwind.c optional ddb | kdtrace_hooks +arm64/arm64/unwind.c optional ddb | kdtrace_hooks | stack arm64/arm64/vfp.c standard arm64/arm64/vm_machdep.c standard crypto/blowfish/bf_enc.c optional crypto | ipsec From 9e2529043b4a862d652220863f6f1f2420c8d338 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 31 Jul 2015 15:54:34 +0000 Subject: [PATCH 121/314] Try to put the CPU into a low power state if we failed to otherwise halt the system. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/arm64/machdep.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index f2a8a25dcbd8..f3679c718891 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -376,7 +376,11 @@ void cpu_halt(void) { - panic("ARM64TODO: cpu_halt"); + /* We should have shutdown by now, if not enter a low power sleep */ + intr_disable(); + while (1) { + __asm __volatile("wfi"); + } } /* From ad6fe9fac71684bd505d354cbbb15788c14fb85a Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Fri, 31 Jul 2015 16:45:42 +0000 Subject: [PATCH 122/314] Use standard 'THE AUTHOR' license text Approved by: jmg --- usr.bin/brandelf/brandelf.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/brandelf/brandelf.1 b/usr.bin/brandelf/brandelf.1 index 6b8477773c6a..309f467ccc82 100644 --- a/usr.bin/brandelf/brandelf.1 +++ b/usr.bin/brandelf/brandelf.1 @@ -9,7 +9,7 @@ .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" -.\" THIS SOFTWARE IS PROVIDED BY John-Mark Gurney AND CONTRIBUTORS ``AS IS'' +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE From 2deb37542b9d14d4fe4722f2a433d593d7f41c3f Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Fri, 31 Jul 2015 17:41:53 +0000 Subject: [PATCH 123/314] Summary: Remove unsupported 3des-deriv encryption algorithm from documentation. --- sbin/setkey/setkey.8 | 1 - 1 file changed, 1 deletion(-) diff --git a/sbin/setkey/setkey.8 b/sbin/setkey/setkey.8 index b9c616066599..62fb2e1d2ba4 100644 --- a/sbin/setkey/setkey.8 +++ b/sbin/setkey/setkey.8 @@ -624,7 +624,6 @@ null 0 to 2048 rfc2410 blowfish-cbc 40 to 448 rfc2451 cast128-cbc 40 to 128 rfc2451 des-deriv 64 ipsec-ciph-des-derived-01 -3des-deriv 192 no document rijndael-cbc 128/192/256 rfc3602 aes-ctr 160/224/288 draft-ietf-ipsec-ciph-aes-ctr-03 aes-gcm-16 160/224/288 rfc4106 From 4f42daa4a326f6973dbe716e74dea6417d0ac496 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 31 Jul 2015 20:02:12 +0000 Subject: [PATCH 124/314] Do not allocate the buffers at opening of the descriptor, because once the buffer is allocated we are committed to a particular buffer method (BPF_BUFMODE_BUFFER in this case). If we are using zero-copy buffers, the userland program must register its buffers before set the interface. If we are using kernel memory buffers, we can allocate the buffer at the time that the interface is being set. This fix allows the usage of BIOCSETBUFMODE after r235746. Update the comments to reflect the recent changes. MFC after: 2 weeks Sponsored by: Rubicon Communications (Netgate) --- sys/net/bpf.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 9fc5e9f7433c..fcd74454ffba 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -862,7 +862,7 @@ static int bpfopen(struct cdev *dev, int flags, int fmt, struct thread *td) { struct bpf_d *d; - int error, size; + int error; d = malloc(sizeof(*d), M_BPF, M_WAITOK | M_ZERO); error = devfs_set_cdevpriv(d, bpf_dtor); @@ -892,10 +892,6 @@ bpfopen(struct cdev *dev, int flags, int fmt, struct thread *td) callout_init_mtx(&d->bd_callout, &d->bd_lock, 0); knlist_init_mtx(&d->bd_sel.si_note, &d->bd_lock); - /* Allocate default buffers */ - size = d->bd_bufsize; - bpf_buffer_ioctl_sblen(d, &size); - return (0); } @@ -1472,10 +1468,33 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, * Set interface. */ case BIOCSETIF: - BPF_LOCK(); - error = bpf_setif(d, (struct ifreq *)addr); - BPF_UNLOCK(); - break; + { + int alloc_buf, size; + + /* + * Behavior here depends on the buffering model. If + * we're using kernel memory buffers, then we can + * allocate them here. If we're using zero-copy, + * then the user process must have registered buffers + * by the time we get here. + */ + alloc_buf = 0; + BPFD_LOCK(d); + if (d->bd_bufmode == BPF_BUFMODE_BUFFER && + d->bd_sbuf == NULL) + alloc_buf = 1; + BPFD_UNLOCK(d); + if (alloc_buf) { + size = d->bd_bufsize; + error = bpf_buffer_ioctl_sblen(d, &size); + if (error != 0) + break; + } + BPF_LOCK(); + error = bpf_setif(d, (struct ifreq *)addr); + BPF_UNLOCK(); + break; + } /* * Set read timeout. @@ -1912,10 +1931,8 @@ bpf_setif(struct bpf_d *d, struct ifreq *ifr) BPFIF_RUNLOCK(bp); /* - * Behavior here depends on the buffering model. If we're using - * kernel memory buffers, then we can allocate them here. If we're - * using zero-copy, then the user process must have registered - * buffers by the time we get here. If not, return an error. + * At this point, we expect the buffer is already allocated. If not, + * return an error. */ switch (d->bd_bufmode) { case BPF_BUFMODE_BUFFER: From faa693cdbeee14ec8331020aca3569d8aa6f70ca Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 31 Jul 2015 20:25:54 +0000 Subject: [PATCH 125/314] Remove the sleep from the buffer allocation routine. The buffer must be allocated (or even changed) before the interface is set and thus, there is no need to verify if the buffer is in use. MFC after: 2 weeks Sponsored by: Rubicon Communications (Netgate) --- sys/net/bpf_buffer.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sys/net/bpf_buffer.c b/sys/net/bpf_buffer.c index 74e1ae488ab9..64bb982aab22 100644 --- a/sys/net/bpf_buffer.c +++ b/sys/net/bpf_buffer.c @@ -79,8 +79,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define PRINET 26 /* interruptible */ - /* * Implement historical kernel memory buffering model for BPF: two malloc(9) * kernel buffers are hung off of the descriptor. The size is fixed prior to @@ -191,9 +189,6 @@ bpf_buffer_ioctl_sblen(struct bpf_d *d, u_int *i) return (EINVAL); } - while (d->bd_hbuf_in_use) - mtx_sleep(&d->bd_hbuf_in_use, &d->bd_lock, - PRINET, "bd_hbuf", 0); /* Free old buffers if set */ if (d->bd_fbuf != NULL) free(d->bd_fbuf, M_BPF); From f87e372ef2bb0a3b4ef41ba33b1322b311794075 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 31 Jul 2015 21:43:27 +0000 Subject: [PATCH 126/314] Remove two unnecessary sleeps from the hot path in bpf(4). The first one never triggers because bpf_canfreebuf() can only be true for zero-copy buffers and zero-copy buffers are not read with read(2). The second also never triggers, because we check the free buffer before calling ROTATE_BUFFERS(). If the hold buffer is in use the free buffer will be NULL and there is nothing else to do besides drop the packet. If the free buffer isn't NULL the hold buffer _is_ free and it is safe to rotate the buffers. Update the comment in ROTATE_BUFFERS macro to match the logic described here. While here fix a few typos in comments. MFC after: 2 weeks Sponsored by: Rubicon Communications (Netgate) --- sys/net/bpf.c | 10 ++-------- sys/net/bpf.h | 6 +++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index fcd74454ffba..413ee41081ff 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -620,7 +620,7 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp) bpf_detachd_locked(d); /* * Point d at bp, and add d to the interface's list. - * Since there are many applicaiotns using BPF for + * Since there are many applications using BPF for * sending raw packets only (dhcpd, cdpd are good examples) * we can delay adding d to the list of active listeners until * some filter is configured. @@ -718,7 +718,7 @@ bpf_check_upgrade(u_long cmd, struct bpf_d *d, struct bpf_insn *fcode, int flen) /* * Add d to the list of active bp filters. - * Reuqires bpf_attachd() to be called before + * Requires bpf_attachd() to be called before. */ static void bpf_upgraded(struct bpf_d *d) @@ -2370,9 +2370,6 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen, * spot to do it. */ if (d->bd_fbuf == NULL && bpf_canfreebuf(d)) { - while (d->bd_hbuf_in_use) - mtx_sleep(&d->bd_hbuf_in_use, &d->bd_lock, - PRINET, "bd_hbuf", 0); d->bd_fbuf = d->bd_hbuf; d->bd_hbuf = NULL; d->bd_hlen = 0; @@ -2415,9 +2412,6 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen, ++d->bd_dcount; return; } - while (d->bd_hbuf_in_use) - mtx_sleep(&d->bd_hbuf_in_use, &d->bd_lock, - PRINET, "bd_hbuf", 0); ROTATE_BUFFERS(d); do_wakeup = 1; curlen = 0; diff --git a/sys/net/bpf.h b/sys/net/bpf.h index df326e69b8b6..a74b521e5fef 100644 --- a/sys/net/bpf.h +++ b/sys/net/bpf.h @@ -1436,9 +1436,9 @@ SYSCTL_DECL(_net_bpf); /* * Rotate the packet buffers in descriptor d. Move the store buffer into the - * hold slot, and the free buffer ino the store slot. Zero the length of the - * new store buffer. Descriptor lock should be held. Hold buffer must - * not be marked "in use". + * hold slot, and the free buffer into the store slot. Zero the length of the + * new store buffer. Descriptor lock should be held. One must be careful to + * not rotate the buffers twice, i.e. if fbuf != NULL. */ #define ROTATE_BUFFERS(d) do { \ (d)->bd_hbuf = (d)->bd_sbuf; \ From afd010c196fa7803a607e53c8b2336f73f3d0894 Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Fri, 31 Jul 2015 23:40:18 +0000 Subject: [PATCH 127/314] Add support for keys that include 4 byte SALT values, including GCM and ICM/CTR modes for AES. Reviewed by: jmg MFC after: 1 week Sponsored by: Rubicon Communications (Netgate) --- sbin/setkey/parse.y | 23 +++++++++++++++++++++++ sbin/setkey/token.l | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/sbin/setkey/parse.y b/sbin/setkey/parse.y index c551c356e737..60e779d47c2d 100644 --- a/sbin/setkey/parse.y +++ b/sbin/setkey/parse.y @@ -100,6 +100,7 @@ extern void yyerror(const char *); %token F_EXT EXTENSION NOCYCLICSEQ %token ALG_AUTH ALG_AUTH_NOKEY %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD +%token ALG_ENC_SALT %token ALG_COMP %token F_LIFETIME_HARD F_LIFETIME_SOFT %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY @@ -111,6 +112,7 @@ extern void yyerror(const char *); %type prefix protocol_spec upper_spec %type ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY +%type ALG_ENC_SALT %type ALG_AUTH ALG_AUTH_NOKEY %type ALG_COMP %type PR_ESP PR_AH PR_IPCOMP PR_TCP @@ -402,6 +404,27 @@ enc_alg return -1; } } + | ALG_ENC_SALT key_string + { + if ($1 < 0) { + yyerror("unsupported algorithm"); + return -1; + } + p_alg_enc = $1; + + p_key_enc_len = $2.len; + + p_key_enc = $2.buf; + /* + * Salted keys include a 4 byte value that is + * not part of the key. + */ + if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, + p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len - 4)) < 0) { + yyerror(ipsec_strerror()); + return -1; + } + } ; auth_alg diff --git a/sbin/setkey/token.l b/sbin/setkey/token.l index 1b667190fe39..7f30859e3861 100644 --- a/sbin/setkey/token.l +++ b/sbin/setkey/token.l @@ -166,9 +166,9 @@ tcp { yylval.num = 0; return(PR_TCP); } des-deriv { yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC_DESDERIV); } des-32iv { yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC_DES32IV); } rijndael-cbc { yylval.num = SADB_X_EALG_RIJNDAELCBC; BEGIN INITIAL; return(ALG_ENC); } -aes-ctr { yylval.num = SADB_X_EALG_AESCTR; BEGIN INITIAL; return(ALG_ENC); } +aes-ctr { yylval.num = SADB_X_EALG_AESCTR; BEGIN INITIAL; return(ALG_ENC_SALT); } camellia-cbc { yylval.num = SADB_X_EALG_CAMELLIACBC; BEGIN INITIAL; return(ALG_ENC); } -aes-gcm-16 { yylval.num = SADB_X_EALG_AESGCM16; BEGIN INITIAL; return(ALG_ENC); } +aes-gcm-16 { yylval.num = SADB_X_EALG_AESGCM16; BEGIN INITIAL; return(ALG_ENC_SALT); } /* compression algorithms */ {hyphen}C { return(F_COMP); } From fc9ce3812df40730cbf17cfcd4ce64bf9387fadb Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Sat, 1 Aug 2015 01:29:55 +0000 Subject: [PATCH 128/314] Buffer overflow in wall(1). Revert r286102 and apply a cleaner fix. Tested for overflows by FORTIFY_SOURCE GSoC (with clang). Suggested by: bde Reviewed by: Oliver Pinter Tested by: Oliver Pinter MFC after: 3 days --- usr.bin/wall/ttymsg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/usr.bin/wall/ttymsg.c b/usr.bin/wall/ttymsg.c index 1317a4b0cb60..afa3d266ad3a 100644 --- a/usr.bin/wall/ttymsg.c +++ b/usr.bin/wall/ttymsg.c @@ -62,7 +62,7 @@ ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) struct iovec localiov[7]; ssize_t left, wret; int cnt, fd; - char device[MAXNAMLEN] = _PATH_DEV; + char device[MAXNAMLEN]; static char errbuf[1024]; char *p; int forked; @@ -71,8 +71,9 @@ ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0]))) return ("too many iov's (change code in wall/ttymsg.c)"); - strlcat(device, line, sizeof(device)); + strlcpy(device, _PATH_DEV, sizeof(device)); p = device + sizeof(_PATH_DEV) - 1; + strlcpy(p, line, sizeof(device) - sizeof(_PATH_DEV)); if (strncmp(p, "pts/", 4) == 0) p += 4; if (strchr(p, '/') != NULL) { From 7ee1b208c3c90fd336878d38b7237d7c92710f24 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 1 Aug 2015 07:21:14 +0000 Subject: [PATCH 129/314] Add kern_shm_open(). This allows you to specify the capabilities that the new file descriptor should have. This allows us to create shared memory objects that only have the rights we're interested in. The idea behind restricting the rights is that it makes it a lot easier for CloudABI to get consistent behaviour across different operating systems. We only need to make sure that a shared memory implementation consistently implements the operations that are whitelisted. Approved by: kib Obtained from: https://github.com/NuxiNL/freebsd --- sys/kern/uipc_shm.c | 43 +++++++++++++++++++++++++------------------ sys/sys/syscallsubr.h | 2 ++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c index fb8433027b81..21cbe49e5cb6 100644 --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -683,9 +684,9 @@ shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred) return (ENOENT); } -/* System calls. */ int -sys_shm_open(struct thread *td, struct shm_open_args *uap) +kern_shm_open(struct thread *td, const char *userpath, int flags, mode_t mode, + struct filecaps *fcaps) { struct filedesc *fdp; struct shmfd *shmfd; @@ -699,28 +700,27 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap) /* * shm_open(2) is only allowed for anonymous objects. */ - if (IN_CAPABILITY_MODE(td) && (uap->path != SHM_ANON)) + if (IN_CAPABILITY_MODE(td) && (userpath != SHM_ANON)) return (ECAPMODE); #endif - if ((uap->flags & O_ACCMODE) != O_RDONLY && - (uap->flags & O_ACCMODE) != O_RDWR) + if ((flags & O_ACCMODE) != O_RDONLY && (flags & O_ACCMODE) != O_RDWR) return (EINVAL); - if ((uap->flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0) + if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0) return (EINVAL); fdp = td->td_proc->p_fd; - cmode = (uap->mode & ~fdp->fd_cmask) & ACCESSPERMS; + cmode = (mode & ~fdp->fd_cmask) & ACCESSPERMS; - error = falloc(td, &fp, &fd, O_CLOEXEC); + error = falloc_caps(td, &fp, &fd, O_CLOEXEC, fcaps); if (error) return (error); /* A SHM_ANON path pointer creates an anonymous object. */ - if (uap->path == SHM_ANON) { + if (userpath == SHM_ANON) { /* A read-only anonymous object is pointless. */ - if ((uap->flags & O_ACCMODE) == O_RDONLY) { + if ((flags & O_ACCMODE) == O_RDONLY) { fdclose(td, fp, fd); fdrop(fp, td); return (EINVAL); @@ -728,7 +728,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap) shmfd = shm_alloc(td->td_ucred, cmode); } else { path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); - error = copyinstr(uap->path, path, MAXPATHLEN, NULL); + error = copyinstr(userpath, path, MAXPATHLEN, NULL); #ifdef KTRACE if (error == 0 && KTRPOINT(curthread, KTR_NAMEI)) ktrnamei(path); @@ -748,7 +748,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap) shmfd = shm_lookup(path, fnv); if (shmfd == NULL) { /* Object does not yet exist, create it if requested. */ - if (uap->flags & O_CREAT) { + if (flags & O_CREAT) { #ifdef MAC error = mac_posixshm_check_create(td->td_ucred, path); @@ -769,17 +769,16 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap) * reference if requested and permitted. */ free(path, M_SHMFD); - if ((uap->flags & (O_CREAT | O_EXCL)) == - (O_CREAT | O_EXCL)) + if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) error = EEXIST; else { #ifdef MAC error = mac_posixshm_check_open(td->td_ucred, - shmfd, FFLAGS(uap->flags & O_ACCMODE)); + shmfd, FFLAGS(flags & O_ACCMODE)); if (error == 0) #endif error = shm_access(shmfd, td->td_ucred, - FFLAGS(uap->flags & O_ACCMODE)); + FFLAGS(flags & O_ACCMODE)); } /* @@ -788,7 +787,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap) * opened with read/write. */ if (error == 0 && - (uap->flags & (O_ACCMODE | O_TRUNC)) == + (flags & (O_ACCMODE | O_TRUNC)) == (O_RDWR | O_TRUNC)) { #ifdef MAC error = mac_posixshm_check_truncate( @@ -809,7 +808,7 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap) } } - finit(fp, FFLAGS(uap->flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops); + finit(fp, FFLAGS(flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops); td->td_retval[0] = fd; fdrop(fp, td); @@ -817,6 +816,14 @@ sys_shm_open(struct thread *td, struct shm_open_args *uap) return (0); } +/* System calls. */ +int +sys_shm_open(struct thread *td, struct shm_open_args *uap) +{ + + return (kern_shm_open(td, uap->path, uap->flags, uap->mode, NULL)); +} + int sys_shm_unlink(struct thread *td, struct shm_unlink_args *uap) { diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index f6f851b60a52..579ac83752d1 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -204,6 +204,8 @@ int kern_setsockopt(struct thread *td, int s, int level, int name, void *optval, enum uio_seg valseg, socklen_t valsize); int kern_settimeofday(struct thread *td, struct timeval *tv, struct timezone *tzp); +int kern_shm_open(struct thread *td, const char *userpath, int flags, + mode_t mode, struct filecaps *fcaps); int kern_shmat(struct thread *td, int shmid, const void *shmaddr, int shmflg); int kern_shmctl(struct thread *td, int shmid, int cmd, void *buf, From f52c3dd41595ae691afa68a2689918b690e11c56 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 1 Aug 2015 07:51:48 +0000 Subject: [PATCH 130/314] Allow CloudABI processes to create shared memory objects. Summary: Use the newly created `kern_shm_open()` function to create objects with just the rights that are actually needed. Reviewers: jhb, kib Subscribers: imp Differential Revision: https://reviews.freebsd.org/D3260 --- sys/compat/cloudabi/cloudabi_fd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index 5a58cb312d98..d2004a9e27d1 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -97,11 +98,16 @@ int cloudabi_sys_fd_create1(struct thread *td, struct cloudabi_sys_fd_create1_args *uap) { + struct filecaps fcaps = {}; struct socket_args socket_args = { .domain = AF_UNIX, }; switch (uap->type) { + case CLOUDABI_FILETYPE_SHARED_MEMORY: + cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_FTRUNCATE, + CAP_MMAP_RWX); + return (kern_shm_open(td, SHM_ANON, O_RDWR, 0, &fcaps)); case CLOUDABI_FILETYPE_SOCKET_DGRAM: socket_args.type = SOCK_DGRAM; return (sys_socket(td, &socket_args)); From e622418c5bee0970d278fa667bae4dbf1e91cda0 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 08:35:20 +0000 Subject: [PATCH 131/314] Use strtoumax instead of strtoul --- usr.sbin/chkgrp/chkgrp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/usr.sbin/chkgrp/chkgrp.c b/usr.sbin/chkgrp/chkgrp.c index d7c15067102e..03758d138de9 100644 --- a/usr.sbin/chkgrp/chkgrp.c +++ b/usr.sbin/chkgrp/chkgrp.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -169,9 +170,9 @@ main(int argc, char *argv[]) /* check the range of the group id */ errno = 0; - gid = strtoul(f[2], NULL, 10); + gid = strtoumax(f[2], NULL, 10); if (errno != 0) { - warnx("%s: line %d: strtoul failed", gfn, n); + warnx("%s: line %d: strtoumax failed", gfn, n); } else if (gid > GID_MAX) { warnx("%s: line %d: group id is too large (%ju > %ju)", gfn, n, (uintmax_t)gid, (uintmax_t)GID_MAX); From f4e060d0f7b7e02e55d666e3d30021724c62de63 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 08:39:55 +0000 Subject: [PATCH 132/314] Handle +:*:: the same way we handle +::: when checking group file The first is what the documentation recommands for NIS client --- usr.sbin/chkgrp/chkgrp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr.sbin/chkgrp/chkgrp.c b/usr.sbin/chkgrp/chkgrp.c index 03758d138de9..0811e30f4e9d 100644 --- a/usr.sbin/chkgrp/chkgrp.c +++ b/usr.sbin/chkgrp/chkgrp.c @@ -106,7 +106,8 @@ main(int argc, char *argv[]) /* * Hack: special case for + line */ - if (strncmp(line, "+:::", len) == 0) + if (strncmp(line, "+:::", len) == 0 || + strncmp(line, "+:*::", len) == 0) continue; /* From 50698e67188c06a08727764a4c8e19e4192ecccf Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 09:55:47 +0000 Subject: [PATCH 133/314] Cast uid/git to uintmax_t when using printf-like functions so the size of uid/gid size remains a implementation detail --- usr.sbin/pw/pw_conf.c | 9 +++++---- usr.sbin/pw/pw_group.c | 7 ++++--- usr.sbin/pw/pw_user.c | 34 ++++++++++++++++++---------------- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index 33bb6b3105e7..d351a8fa0c7f 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -31,6 +31,7 @@ static const char rcsid[] = #include #include +#include #include #include #include @@ -446,19 +447,19 @@ write_userconfig(char const * file) config.default_class : ""); break; case _UC_MINUID: - sbuf_printf(buf, "%u", config.min_uid); + sbuf_printf(buf, "%ju", (uintmax_t)config.min_uid); quote = 0; break; case _UC_MAXUID: - sbuf_printf(buf, "%u", config.max_uid); + sbuf_printf(buf, "%ju", (uintmax_t)config.max_uid); quote = 0; break; case _UC_MINGID: - sbuf_printf(buf, "%u", config.min_gid); + sbuf_printf(buf, "%ju", (uintmax_t)config.min_gid); quote = 0; break; case _UC_MAXGID: - sbuf_printf(buf, "%u", config.max_gid); + sbuf_printf(buf, "%ju", (uintmax_t)config.max_gid); quote = 0; break; case _UC_EXPIRE: diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c index b0db3cffbc45..3d5e70af8949 100644 --- a/usr.sbin/pw/pw_group.c +++ b/usr.sbin/pw/pw_group.c @@ -31,6 +31,7 @@ static const char rcsid[] = #include #include +#include #include #include #include @@ -97,7 +98,7 @@ pw_groupnext(struct userconf *cnf, bool quiet) if (quiet) return (next); - printf("%u\n", next); + printf("%ju\n", (uintmax_t)next); return (EXIT_SUCCESS); } @@ -283,7 +284,7 @@ pw_group(int mode, char *name, long id, struct cargs * args) if ((grp = GETGRNAM(name)) == NULL) errx(EX_SOFTWARE, "group disappeared during update"); - pw_log(cnf, mode, W_GROUP, "%s(%u)", grp->gr_name, grp->gr_gid); + pw_log(cnf, mode, W_GROUP, "%s(%ju)", grp->gr_name, (uintmax_t)grp->gr_gid); return EXIT_SUCCESS; } @@ -345,7 +346,7 @@ gr_gidpolicy(struct userconf * cnf, long id) gid = (gid_t) id; if ((grp = GETGRGID(gid)) != NULL && conf.checkduplicate) - errx(EX_DATAERR, "gid `%u' has already been allocated", grp->gr_gid); + errx(EX_DATAERR, "gid `%ju' has already been allocated", (uintmax_t)grp->gr_gid); } else { struct bitmap bm; diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index cd9c23c3676c..eca8235f6e23 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -33,6 +33,7 @@ static const char rcsid[] = #include #include #include +#include #include #include #include @@ -81,8 +82,8 @@ create_and_populate_homedir(struct passwd *pwd) copymkdir(conf.rootfd, pwd->pw_dir, skelfd, cnf->homemode, pwd->pw_uid, pwd->pw_gid, 0); - pw_log(cnf, M_ADD, W_USER, "%s(%u) home %s made", pwd->pw_name, - pwd->pw_uid, pwd->pw_dir); + pw_log(cnf, M_ADD, W_USER, "%s(%ju) home %s made", pwd->pw_name, + (uintmax_t)pwd->pw_uid, pwd->pw_dir); } static int @@ -155,7 +156,7 @@ pw_usernext(struct userconf *cnf, bool quiet) if (quiet) return (next); - printf("%u:", next); + printf("%ju:", (uintmax_t)next); pw_groupnext(cnf, quiet); return (EXIT_SUCCESS); @@ -749,9 +750,9 @@ pw_user(int mode, char *name, long id, struct cargs * args) errx(EX_NOUSER, "user '%s' disappeared during update", name); grp = GETGRGID(pwd->pw_gid); - pw_log(cnf, mode, W_USER, "%s(%u):%s(%u):%s:%s:%s", - pwd->pw_name, pwd->pw_uid, - grp ? grp->gr_name : "unknown", (grp ? grp->gr_gid : (uid_t)-1), + pw_log(cnf, mode, W_USER, "%s(%ju):%s(%ju):%s:%s:%s", + pwd->pw_name, (uintmax_t)pwd->pw_uid, + grp ? grp->gr_name : "unknown", (uintmax_t)(grp ? grp->gr_gid : (uid_t)-1), pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); /* @@ -794,8 +795,8 @@ pw_user(int mode, char *name, long id, struct cargs * args) fputs(line, pfp); } pclose(pfp); - pw_log(cnf, mode, W_USER, "%s(%u) new user mail sent", - pwd->pw_name, pwd->pw_uid); + pw_log(cnf, mode, W_USER, "%s(%ju) new user mail sent", + pwd->pw_name, (uintmax_t)pwd->pw_uid); } fclose(fp); } @@ -817,7 +818,8 @@ pw_uidpolicy(struct userconf * cnf, long id) uid = (uid_t) id; if ((pwd = GETPWUID(uid)) != NULL && conf.checkduplicate) - errx(EX_DATAERR, "uid `%u' has already been allocated", pwd->pw_uid); + errx(EX_DATAERR, "uid `%ju' has already been allocated", + (uintmax_t)pwd->pw_uid); } else { struct bitmap bm; @@ -1177,8 +1179,8 @@ pw_userdel(char *name, long id) } ENDGRENT(); - pw_log(conf.userconf, M_DELETE, W_USER, "%s(%u) account removed", name, - uid); + pw_log(conf.userconf, M_DELETE, W_USER, "%s(%ju) account removed", name, + (uintmax_t)uid); /* Remove mail file */ if (PWALTDIR() != PWF_ALT) @@ -1193,8 +1195,8 @@ pw_userdel(char *name, long id) getpwuid(uid) == NULL && fstatat(conf.rootfd, home + 1, &st, 0) != -1) { rm_r(conf.rootfd, home, uid); - pw_log(conf.userconf, M_DELETE, W_USER, "%s(%u) home '%s' %s" - "removed", name, uid, home, + pw_log(conf.userconf, M_DELETE, W_USER, "%s(%ju) home '%s' %s" + "removed", name, (uintmax_t)uid, home, fstatat(conf.rootfd, home + 1, &st, 0) == -1 ? "" : "not " "completely "); } @@ -1248,14 +1250,14 @@ print_user(struct passwd * pwd) strftime(acexpire, sizeof acexpire, "%c", tptr); if (pwd->pw_change > (time_t)0 && (tptr = localtime(&pwd->pw_change)) != NULL) strftime(pwexpire, sizeof pwexpire, "%c", tptr); - printf("Login Name: %-15s #%-12u Group: %-15s #%u\n" + printf("Login Name: %-15s #%-12ju Group: %-15s #%ju\n" " Full Name: %s\n" " Home: %-26.26s Class: %s\n" " Shell: %-26.26s Office: %s\n" "Work Phone: %-26.26s Home Phone: %s\n" "Acc Expire: %-26.26s Pwd Expire: %s\n", - pwd->pw_name, pwd->pw_uid, - grp ? grp->gr_name : "(invalid)", pwd->pw_gid, + pwd->pw_name, (uintmax_t)pwd->pw_uid, + grp ? grp->gr_name : "(invalid)", (uintmax_t)pwd->pw_gid, uname, pwd->pw_dir, pwd->pw_class, pwd->pw_shell, office, wphone, hphone, acexpire, pwexpire); From e5e7ef48eba9679734e11c6e89f88e5b26fa7123 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 10:10:13 +0000 Subject: [PATCH 134/314] Validate the max_uid/max_gid boundaries and entry type in pw.conf --- usr.sbin/pw/pw_conf.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index d351a8fa0c7f..c6a86b73dc84 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -230,6 +230,7 @@ read_userconfig(char const * file) char *buf, *p; size_t linecap; ssize_t linelen; + const char *errstr; buf = NULL; linecap = 0; @@ -323,20 +324,35 @@ read_userconfig(char const * file) ? NULL : newstr(q); break; case _UC_MINUID: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.min_uid = (uid_t) atol(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.min_uid = strtounum(q, 0, UID_MAX, &errstr); + if (errstr) + warnx("Invalid min_uid: '%s', ignoring", q); + } break; case _UC_MAXUID: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.max_uid = (uid_t) atol(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.max_uid = strtounum(q, 0, UID_MAX, &errstr); + if (errstr) + warnx("Invalid max_uid: '%s', ignoring", q); + } break; case _UC_MINGID: if ((q = unquote(q)) != NULL && isdigit(*q)) - config.min_gid = (gid_t) atol(q); + errstr = NULL; + config.min_gid = strtounum(q, 0, GID_MAX, &errstr); + if (errstr) + warnx("Invalid min_gid: '%s', ignoring", q); break; case _UC_MAXGID: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.max_gid = (gid_t) atol(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.max_gid = strtounum(q, 0, GID_MAX, &errstr); + if (errstr) + warnx("Invalid max_gid: '%s', ignoring", q); + } break; case _UC_EXPIRE: if ((q = unquote(q)) != NULL && isdigit(*q)) From 80d9f89289b06cf5518abd5490f10d440edd8b0c Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 10:25:55 +0000 Subject: [PATCH 135/314] Validate expiration days and password days from commmand line and pw.conf --- usr.sbin/pw/pw.c | 10 ++++++++++ usr.sbin/pw/pw_conf.c | 16 ++++++++++++---- usr.sbin/pw/pw_user.c | 8 ++++---- usr.sbin/pw/pwupd.h | 2 ++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index 88c83dbfa125..bca67159a91a 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -262,6 +262,11 @@ main(int argc, char *argv[]) case 'c': conf.gecos = pw_checkname(optarg, 1); break; + case 'e': + conf.expire_days = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(EX_USAGE, "Invalid expired days: %s", optarg); + break; case 'g': if (which == 0) { /* for user* */ addarg(&arglist, 'g', optarg); @@ -321,6 +326,11 @@ main(int argc, char *argv[]) case 'o': conf.checkduplicate = false; break; + case 'p': + conf.password_days = strtonum(optarg, 0, INT_MAX, &errstr); + if (errstr) + errx(EX_USAGE, "Invalid password days: %s", optarg); + break; case 'q': conf.quiet = true; break; diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index c6a86b73dc84..c1b5b336e00d 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -355,12 +355,20 @@ read_userconfig(char const * file) } break; case _UC_EXPIRE: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.expire_days = atoi(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.expire_days = strtonum(q, 0, INT_MAX, &errstr); + if (errstr) + warnx("Invalid expire days: '%s', ignoring", q); + } break; case _UC_PASSWORD: - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.password_days = atoi(q); + if ((q = unquote(q)) != NULL) { + errstr = NULL; + config.password_days = strtonum(q, 0, INT_MAX, &errstr); + if (errstr) + warnx("Invalid password days: '%s', ignoring", q); + } break; case _UC_FIELDS: case _UC_NONE: diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index eca8235f6e23..6e07f1f8ea4d 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -418,14 +418,14 @@ pw_user(int mode, char *name, long id, struct cargs * args) errx(EX_OSFILE, "root home `%s' is not a directory", cnf->home); } - if ((arg = getarg(args, 'e')) != NULL) - cnf->expire_days = atoi(arg->val); + if (conf.expire_days > 0) + cnf->expire_days = conf.expire_days; if ((arg = getarg(args, 'y')) != NULL) cnf->nispasswd = arg->val; - if ((arg = getarg(args, 'p')) != NULL && arg->val) - cnf->password_days = atoi(arg->val); + if (conf.password_days > 0) + cnf->password_days = conf.password_days; if ((arg = getarg(args, 'g')) != NULL) { if (!*(p = arg->val)) /* Handle empty group list specially */ diff --git a/usr.sbin/pw/pwupd.h b/usr.sbin/pw/pwupd.h index 054c5a55293b..9685bea603c4 100644 --- a/usr.sbin/pw/pwupd.h +++ b/usr.sbin/pw/pwupd.h @@ -86,6 +86,8 @@ struct pwconf { char *newname; char *config; char *gecos; + int expire_days; + int password_days; int fd; int rootfd; int which; From f2164ae0fac10feadff6a3c9d1fbe4f7d336fbfc Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 10:40:17 +0000 Subject: [PATCH 136/314] Revert r286148 --- usr.sbin/chkgrp/chkgrp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/chkgrp/chkgrp.c b/usr.sbin/chkgrp/chkgrp.c index 0811e30f4e9d..81cb83bfdf10 100644 --- a/usr.sbin/chkgrp/chkgrp.c +++ b/usr.sbin/chkgrp/chkgrp.c @@ -171,9 +171,9 @@ main(int argc, char *argv[]) /* check the range of the group id */ errno = 0; - gid = strtoumax(f[2], NULL, 10); + gid = strtoul(f[2], NULL, 10); if (errno != 0) { - warnx("%s: line %d: strtoumax failed", gfn, n); + warnx("%s: line %d: strtoul failed", gfn, n); } else if (gid > GID_MAX) { warnx("%s: line %d: group id is too large (%ju > %ju)", gfn, n, (uintmax_t)gid, (uintmax_t)GID_MAX); From 510113b84da4aa4fce1aca32edea1ca79b4dea10 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 11:31:59 +0000 Subject: [PATCH 137/314] Fix formatting of new code Fix sorting or errstr Remove useless initialisation or errstr Reported by: bde --- usr.sbin/pw/pw_conf.c | 46 ++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index c1b5b336e00d..10ded5cfe107 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -228,9 +228,9 @@ read_userconfig(char const * file) { FILE *fp; char *buf, *p; + const char *errstr; size_t linecap; ssize_t linelen; - const char *errstr; buf = NULL; linecap = 0; @@ -325,49 +325,55 @@ read_userconfig(char const * file) break; case _UC_MINUID: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.min_uid = strtounum(q, 0, UID_MAX, &errstr); + config.min_uid = strtounum(q, 0, + UID_MAX, &errstr); if (errstr) - warnx("Invalid min_uid: '%s', ignoring", q); + warnx("Invalid min_uid: '%s';" + " ignoring", q); } break; case _UC_MAXUID: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.max_uid = strtounum(q, 0, UID_MAX, &errstr); + config.max_uid = strtounum(q, 0, + UID_MAX, &errstr); if (errstr) - warnx("Invalid max_uid: '%s', ignoring", q); + warnx("Invalid max_uid: '%s';" + " ignoring", q); } break; case _UC_MINGID: - if ((q = unquote(q)) != NULL && isdigit(*q)) - errstr = NULL; - config.min_gid = strtounum(q, 0, GID_MAX, &errstr); + if ((q = unquote(q)) != NULL) { + config.min_gid = strtounum(q, 0, + GID_MAX, &errstr); if (errstr) - warnx("Invalid min_gid: '%s', ignoring", q); + warnx("Invalid min_gid: '%s';" + " ignoring", q); break; case _UC_MAXGID: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.max_gid = strtounum(q, 0, GID_MAX, &errstr); + config.max_gid = strtounum(q, 0, + GID_MAX, &errstr); if (errstr) - warnx("Invalid max_gid: '%s', ignoring", q); + warnx("Invalid max_gid: '%s';" + " ignoring", q); } break; case _UC_EXPIRE: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.expire_days = strtonum(q, 0, INT_MAX, &errstr); + config.expire_days = strtonum(q, 0, + INT_MAX, &errstr); if (errstr) - warnx("Invalid expire days: '%s', ignoring", q); + warnx("Invalid expire days:" + " '%s'; ignoring", q); } break; case _UC_PASSWORD: if ((q = unquote(q)) != NULL) { - errstr = NULL; - config.password_days = strtonum(q, 0, INT_MAX, &errstr); + config.password_days = strtonum(q, 0, + INT_MAX, &errstr); if (errstr) - warnx("Invalid password days: '%s', ignoring", q); + warnx("Invalid password days:" + " '%s'; ignoring", q); } break; case _UC_FIELDS: From 7391bf5ada4821a4b37258a78e4c9bc218bd80f8 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 11:52:48 +0000 Subject: [PATCH 138/314] Fix build --- usr.sbin/pw/pw_conf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index 10ded5cfe107..b723c31a39dd 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -348,6 +348,7 @@ read_userconfig(char const * file) if (errstr) warnx("Invalid min_gid: '%s';" " ignoring", q); + } break; case _UC_MAXGID: if ((q = unquote(q)) != NULL) { From 7493058fb6d966132992e03c64a5b5f6fcbb38eb Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 12:18:48 +0000 Subject: [PATCH 139/314] Partial revert of r286152 More work needed on the cli validation --- usr.sbin/pw/pw.c | 10 ---------- usr.sbin/pw/pw_conf.c | 2 ++ usr.sbin/pw/pw_user.c | 8 ++++---- usr.sbin/pw/pwupd.h | 2 -- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index bca67159a91a..88c83dbfa125 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -262,11 +262,6 @@ main(int argc, char *argv[]) case 'c': conf.gecos = pw_checkname(optarg, 1); break; - case 'e': - conf.expire_days = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr) - errx(EX_USAGE, "Invalid expired days: %s", optarg); - break; case 'g': if (which == 0) { /* for user* */ addarg(&arglist, 'g', optarg); @@ -326,11 +321,6 @@ main(int argc, char *argv[]) case 'o': conf.checkduplicate = false; break; - case 'p': - conf.password_days = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr) - errx(EX_USAGE, "Invalid password days: %s", optarg); - break; case 'q': conf.quiet = true; break; diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index b723c31a39dd..8ba8c07fd455 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -367,6 +367,8 @@ read_userconfig(char const * file) warnx("Invalid expire days:" " '%s'; ignoring", q); } + if ((q = unquote(q)) != NULL && isdigit(*q)) + config.expire_days = atoi(q); break; case _UC_PASSWORD: if ((q = unquote(q)) != NULL) { diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 6e07f1f8ea4d..eca8235f6e23 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -418,14 +418,14 @@ pw_user(int mode, char *name, long id, struct cargs * args) errx(EX_OSFILE, "root home `%s' is not a directory", cnf->home); } - if (conf.expire_days > 0) - cnf->expire_days = conf.expire_days; + if ((arg = getarg(args, 'e')) != NULL) + cnf->expire_days = atoi(arg->val); if ((arg = getarg(args, 'y')) != NULL) cnf->nispasswd = arg->val; - if (conf.password_days > 0) - cnf->password_days = conf.password_days; + if ((arg = getarg(args, 'p')) != NULL && arg->val) + cnf->password_days = atoi(arg->val); if ((arg = getarg(args, 'g')) != NULL) { if (!*(p = arg->val)) /* Handle empty group list specially */ diff --git a/usr.sbin/pw/pwupd.h b/usr.sbin/pw/pwupd.h index 9685bea603c4..054c5a55293b 100644 --- a/usr.sbin/pw/pwupd.h +++ b/usr.sbin/pw/pwupd.h @@ -86,8 +86,6 @@ struct pwconf { char *newname; char *config; char *gecos; - int expire_days; - int password_days; int fd; int rootfd; int which; From 458fdd97ab7158d5c31794de3d5b68c92d1a9678 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 1 Aug 2015 12:20:55 +0000 Subject: [PATCH 140/314] Remove things that crept in after badly checked revert --- usr.sbin/pw/pw_conf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index 8ba8c07fd455..b723c31a39dd 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -367,8 +367,6 @@ read_userconfig(char const * file) warnx("Invalid expire days:" " '%s'; ignoring", q); } - if ((q = unquote(q)) != NULL && isdigit(*q)) - config.expire_days = atoi(q); break; case _UC_PASSWORD: if ((q = unquote(q)) != NULL) { From 98685dc8af6354777ae09c5763fe4cbc9f3d99a1 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Sat, 1 Aug 2015 16:27:52 +0000 Subject: [PATCH 141/314] Clear P_TRACED before reparenting a detached process back to its original parent. Otherwise the debugee will be set as an orphan of the debugger. Add tests for tracing forks via PT_FOLLOW_FORK. Reviewed by: kib MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D2809 --- sys/kern/sys_process.c | 11 +- tests/sys/kern/ptrace_test.c | 581 +++++++++++++++++++++++++++++++---- 2 files changed, 536 insertions(+), 56 deletions(-) diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index cb88034b06fa..66109604ad57 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -947,7 +947,15 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) } break; case PT_DETACH: - /* reset process parent */ + /* + * Reset the process parent. + * + * NB: This clears P_TRACED before reparenting + * a detached process back to its original + * parent. Otherwise the debugee will be set + * as an orphan of the debugger. + */ + p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK); if (p->p_oppid != p->p_pptr->p_pid) { PROC_LOCK(p->p_pptr); sigqueue_take(p->p_ksi); @@ -963,7 +971,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) } else CTR1(KTR_PTRACE, "PT_DETACH: pid %d", p->p_pid); p->p_oppid = 0; - p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK); p->p_stops = 0; /* should we send SIGCHLD? */ diff --git a/tests/sys/kern/ptrace_test.c b/tests/sys/kern/ptrace_test.c index a64262a7b1da..c10c097b37b6 100644 --- a/tests/sys/kern/ptrace_test.c +++ b/tests/sys/kern/ptrace_test.c @@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$"); #exp " not met"); \ } while (0) -static void __dead2 +static __dead2 void child_fail_require(const char *file, int line, const char *str) { char buf[128]; @@ -60,6 +60,58 @@ child_fail_require(const char *file, int line, const char *str) _exit(32); } +static void +trace_me(void) +{ + + /* Attach the parent process as a tracer of this process. */ + CHILD_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + /* Trigger a stop. */ + raise(SIGSTOP); +} + +static void +attach_child(pid_t pid) +{ + pid_t wpid; + int status; + + ATF_REQUIRE(ptrace(PT_ATTACH, pid, NULL, 0) == 0); + + wpid = waitpid(pid, &status, 0); + ATF_REQUIRE(wpid == pid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); +} + +static void +wait_for_zombie(pid_t pid) +{ + + /* + * Wait for a process to exit. This is kind of gross, but + * there is not a better way. + */ + for (;;) { + struct kinfo_proc kp; + size_t len; + int mib[4]; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = pid; + len = sizeof(kp); + if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) { + /* The KERN_PROC_PID sysctl fails for zombies. */ + ATF_REQUIRE(errno == ESRCH); + break; + } + usleep(5000); + } +} + /* * Verify that a parent debugger process "sees" the exit of a debugged * process exactly once when attached via PT_TRACE_ME. @@ -73,10 +125,7 @@ ATF_TC_BODY(ptrace__parent_wait_after_trace_me, tc) ATF_REQUIRE((child = fork()) != -1); if (child == 0) { /* Child process. */ - CHILD_REQUIRE(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); - - /* Trigger a stop. */ - raise(SIGSTOP); + trace_me(); exit(1); } @@ -131,13 +180,7 @@ ATF_TC_BODY(ptrace__parent_wait_after_attach, tc) /* Parent process. */ /* Attach to the child process. */ - ATF_REQUIRE(ptrace(PT_ATTACH, child, NULL, 0) == 0); - - /* The first wait() should report the SIGSTOP from PT_ATTACH. */ - wpid = waitpid(child, &status, 0); - ATF_REQUIRE(wpid == child); - ATF_REQUIRE(WIFSTOPPED(status)); - ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + attach_child(child); /* Continue the child ignoring the SIGSTOP. */ ATF_REQUIRE(ptrace(PT_CONTINUE, child, (caddr_t)1, 0) != -1); @@ -223,27 +266,7 @@ ATF_TC_BODY(ptrace__parent_sees_exit_after_child_debugger, tc) ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0); close(cpipe[0]); - /* - * Wait for the child to exit. This is kind of gross, but - * there is not a better way. - */ - for (;;) { - struct kinfo_proc kp; - size_t len; - int mib[4]; - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = child; - len = sizeof(kp); - if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) { - /* The KERN_PROC_PID sysctl fails for zombies. */ - ATF_REQUIRE(errno == ESRCH); - break; - } - usleep(5000); - } + wait_for_zombie(child); /* * This wait should return a pid of 0 to indicate no status to @@ -357,27 +380,7 @@ ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc) ATF_REQUIRE(read(cpipe[0], &c, sizeof(c)) == 0); close(cpipe[0]); - /* - * Wait for the child to exit. This is kind of gross, but - * there is not a better way. - */ - for (;;) { - struct kinfo_proc kp; - size_t len; - int mib[4]; - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = child; - len = sizeof(kp); - if (sysctl(mib, nitems(mib), &kp, &len, NULL, 0) == -1) { - /* The KERN_PROC_PID sysctl fails for zombies. */ - ATF_REQUIRE(errno == ESRCH); - break; - } - usleep(5000); - } + wait_for_zombie(child); /* * This wait should return a pid of 0 to indicate no status to @@ -401,6 +404,468 @@ ATF_TC_BODY(ptrace__parent_sees_exit_after_unrelated_debugger, tc) ATF_REQUIRE(WEXITSTATUS(status) == 1); } +/* + * The parent process should always act the same regardless of how the + * debugger is attached to it. + */ +static __dead2 void +follow_fork_parent(void) +{ + pid_t fpid, wpid; + int status; + + CHILD_REQUIRE((fpid = fork()) != -1); + + if (fpid == 0) + /* Child */ + exit(2); + + wpid = waitpid(fpid, &status, 0); + CHILD_REQUIRE(wpid == fpid); + CHILD_REQUIRE(WIFEXITED(status)); + CHILD_REQUIRE(WEXITSTATUS(status) == 2); + + exit(1); +} + +/* + * Helper routine for follow fork tests. This waits for two stops + * that report both "sides" of a fork. It returns the pid of the new + * child process. + */ +static pid_t +handle_fork_events(pid_t parent) +{ + struct ptrace_lwpinfo pl; + bool fork_reported[2]; + pid_t child, wpid; + int i, status; + + fork_reported[0] = false; + fork_reported[1] = false; + child = -1; + + /* + * Each process should report a fork event. The parent should + * report a PL_FLAG_FORKED event, and the child should report + * a PL_FLAG_CHILD event. + */ + for (i = 0; i < 2; i++) { + wpid = wait(&status); + ATF_REQUIRE(wpid > 0); + ATF_REQUIRE(WIFSTOPPED(status)); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, + sizeof(pl)) != -1); + ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != + 0); + ATF_REQUIRE((pl.pl_flags & (PL_FLAG_FORKED | PL_FLAG_CHILD)) != + (PL_FLAG_FORKED | PL_FLAG_CHILD)); + if (pl.pl_flags & PL_FLAG_CHILD) { + ATF_REQUIRE(wpid != parent); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + ATF_REQUIRE(!fork_reported[1]); + if (child == -1) + child = wpid; + else + ATF_REQUIRE(child == wpid); + fork_reported[1] = true; + } else { + ATF_REQUIRE(wpid == parent); + ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); + ATF_REQUIRE(!fork_reported[0]); + if (child == -1) + child = pl.pl_child_pid; + else + ATF_REQUIRE(child == pl.pl_child_pid); + fork_reported[0] = true; + } + } + + return (child); +} + +/* + * Verify that a new child process is stopped after a followed fork and + * that the traced parent sees the exit of the child after the debugger + * when both processes remain attached to the debugger. + */ +ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached); +ATF_TC_BODY(ptrace__follow_fork_both_attached, tc) +{ + pid_t children[0], fpid, wpid; + int status; + + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + trace_me(); + follow_fork_parent(); + } + + /* Parent process. */ + children[0] = fpid; + + /* The first wait() should report the stop from SIGSTOP. */ + wpid = waitpid(children[0], &status, 0); + ATF_REQUIRE(wpid == children[0]); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); + + /* Continue the child ignoring the SIGSTOP. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + + children[1] = handle_fork_events(children[0]); + ATF_REQUIRE(children[1] > 0); + + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); + + /* + * The child can't exit until the grandchild reports status, so the + * grandchild should report its exit first to the debugger. + */ + wpid = wait(&status); + ATF_REQUIRE(wpid == children[1]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 2); + + wpid = wait(&status); + ATF_REQUIRE(wpid == children[0]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + +/* + * Verify that a new child process is stopped after a followed fork + * and that the traced parent sees the exit of the child when the new + * child process is detached after it reports its fork. + */ +ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached); +ATF_TC_BODY(ptrace__follow_fork_child_detached, tc) +{ + pid_t children[0], fpid, wpid; + int status; + + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + trace_me(); + follow_fork_parent(); + } + + /* Parent process. */ + children[0] = fpid; + + /* The first wait() should report the stop from SIGSTOP. */ + wpid = waitpid(children[0], &status, 0); + ATF_REQUIRE(wpid == children[0]); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); + + /* Continue the child ignoring the SIGSTOP. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + + children[1] = handle_fork_events(children[0]); + ATF_REQUIRE(children[1] > 0); + + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); + + /* + * Should not see any status from the grandchild now, only the + * child. + */ + wpid = wait(&status); + ATF_REQUIRE(wpid == children[0]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + +/* + * Verify that a new child process is stopped after a followed fork + * and that the traced parent sees the exit of the child when the + * traced parent is detached after the fork. + */ +ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached); +ATF_TC_BODY(ptrace__follow_fork_parent_detached, tc) +{ + pid_t children[0], fpid, wpid; + int status; + + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + trace_me(); + follow_fork_parent(); + } + + /* Parent process. */ + children[0] = fpid; + + /* The first wait() should report the stop from SIGSTOP. */ + wpid = waitpid(children[0], &status, 0); + ATF_REQUIRE(wpid == children[0]); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); + + ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); + + /* Continue the child ignoring the SIGSTOP. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + + children[1] = handle_fork_events(children[0]); + ATF_REQUIRE(children[1] > 0); + + ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); + ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); + + /* + * The child can't exit until the grandchild reports status, so the + * grandchild should report its exit first to the debugger. + * + * Even though the child process is detached, it is still a + * child of the debugger, so it will still report it's exit + * after the grandchild. + */ + wpid = wait(&status); + ATF_REQUIRE(wpid == children[1]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 2); + + wpid = wait(&status); + ATF_REQUIRE(wpid == children[0]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + +static void +attach_fork_parent(int cpipe[2]) +{ + pid_t fpid; + + close(cpipe[0]); + + /* Double-fork to disassociate from the debugger. */ + CHILD_REQUIRE((fpid = fork()) != -1); + if (fpid != 0) + exit(3); + + /* Send the pid of the disassociated child to the debugger. */ + fpid = getpid(); + CHILD_REQUIRE(write(cpipe[1], &fpid, sizeof(fpid)) == sizeof(fpid)); + + /* Wait for the debugger to attach. */ + CHILD_REQUIRE(read(cpipe[1], &fpid, sizeof(fpid)) == 0); +} + +/* + * Verify that a new child process is stopped after a followed fork and + * that the traced parent sees the exit of the child after the debugger + * when both processes remain attached to the debugger. In this test + * the parent that forks is not a direct child of the debugger. + */ +ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_both_attached_unrelated_debugger); +ATF_TC_BODY(ptrace__follow_fork_both_attached_unrelated_debugger, tc) +{ + pid_t children[0], fpid, wpid; + int cpipe[2], status; + + ATF_REQUIRE(pipe(cpipe) == 0); + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + attach_fork_parent(cpipe); + follow_fork_parent(); + } + + /* Parent process. */ + close(cpipe[1]); + + /* Wait for the direct child to exit. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 3); + + /* Read the pid of the fork parent. */ + ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == + sizeof(children[0])); + + /* Attach to the fork parent. */ + attach_child(children[0]); + + ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); + + /* Continue the fork parent ignoring the SIGSTOP. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + + /* Signal the fork parent to continue. */ + close(cpipe[0]); + + children[1] = handle_fork_events(children[0]); + ATF_REQUIRE(children[1] > 0); + + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); + + /* + * The fork parent can't exit until the child reports status, + * so the child should report its exit first to the debugger. + */ + wpid = wait(&status); + ATF_REQUIRE(wpid == children[1]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 2); + + wpid = wait(&status); + ATF_REQUIRE(wpid == children[0]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + +/* + * Verify that a new child process is stopped after a followed fork + * and that the traced parent sees the exit of the child when the new + * child process is detached after it reports its fork. In this test + * the parent that forks is not a direct child of the debugger. + */ +ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_child_detached_unrelated_debugger); +ATF_TC_BODY(ptrace__follow_fork_child_detached_unrelated_debugger, tc) +{ + pid_t children[0], fpid, wpid; + int cpipe[2], status; + + ATF_REQUIRE(pipe(cpipe) == 0); + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + attach_fork_parent(cpipe); + follow_fork_parent(); + } + + /* Parent process. */ + close(cpipe[1]); + + /* Wait for the direct child to exit. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 3); + + /* Read the pid of the fork parent. */ + ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == + sizeof(children[0])); + + /* Attach to the fork parent. */ + attach_child(children[0]); + + ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); + + /* Continue the fork parent ignoring the SIGSTOP. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + + /* Signal the fork parent to continue. */ + close(cpipe[0]); + + children[1] = handle_fork_events(children[0]); + ATF_REQUIRE(children[1] > 0); + + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + ATF_REQUIRE(ptrace(PT_DETACH, children[1], (caddr_t)1, 0) != -1); + + /* + * Should not see any status from the child now, only the fork + * parent. + */ + wpid = wait(&status); + ATF_REQUIRE(wpid == children[0]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 1); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + +/* + * Verify that a new child process is stopped after a followed fork + * and that the traced parent sees the exit of the child when the + * traced parent is detached after the fork. In this test the parent + * that forks is not a direct child of the debugger. + */ +ATF_TC_WITHOUT_HEAD(ptrace__follow_fork_parent_detached_unrelated_debugger); +ATF_TC_BODY(ptrace__follow_fork_parent_detached_unrelated_debugger, tc) +{ + pid_t children[0], fpid, wpid; + int cpipe[2], status; + + ATF_REQUIRE(pipe(cpipe) == 0); + ATF_REQUIRE((fpid = fork()) != -1); + if (fpid == 0) { + attach_fork_parent(cpipe); + follow_fork_parent(); + } + + /* Parent process. */ + close(cpipe[1]); + + /* Wait for the direct child to exit. */ + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 3); + + /* Read the pid of the fork parent. */ + ATF_REQUIRE(read(cpipe[0], &children[0], sizeof(children[0])) == + sizeof(children[0])); + + /* Attach to the fork parent. */ + attach_child(children[0]); + + ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, children[0], NULL, 1) != -1); + + /* Continue the fork parent ignoring the SIGSTOP. */ + ATF_REQUIRE(ptrace(PT_CONTINUE, children[0], (caddr_t)1, 0) != -1); + + /* Signal the fork parent to continue. */ + close(cpipe[0]); + + children[1] = handle_fork_events(children[0]); + ATF_REQUIRE(children[1] > 0); + + ATF_REQUIRE(ptrace(PT_DETACH, children[0], (caddr_t)1, 0) != -1); + ATF_REQUIRE(ptrace(PT_CONTINUE, children[1], (caddr_t)1, 0) != -1); + + /* + * Should not see any status from the fork parent now, only + * the child. + */ + wpid = wait(&status); + ATF_REQUIRE(wpid == children[1]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE(WEXITSTATUS(status) == 2); + + wpid = wait(&status); + ATF_REQUIRE(wpid == -1); + ATF_REQUIRE(errno == ECHILD); +} + ATF_TP_ADD_TCS(tp) { @@ -408,6 +873,14 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); + ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); + ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); + ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); + ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); + ATF_TP_ADD_TC(tp, + ptrace__follow_fork_child_detached_unrelated_debugger); + ATF_TP_ADD_TC(tp, + ptrace__follow_fork_parent_detached_unrelated_debugger); return (atf_no_error()); } From c47f6acf73561f57a808c87273d044871ceb7953 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Sat, 1 Aug 2015 17:27:47 +0000 Subject: [PATCH 142/314] use : instead of true... Change file file to file1 file2, partly for igor, and partly because it's odd to pass the same file to a command twice.. --- usr.bin/getopt/getopt.1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/usr.bin/getopt/getopt.1 b/usr.bin/getopt/getopt.1 index d8271372a922..781b6e0b4406 100644 --- a/usr.bin/getopt/getopt.1 +++ b/usr.bin/getopt/getopt.1 @@ -1,6 +1,6 @@ .\" $FreeBSD$ .\" -.Dd January 26, 2011 +.Dd August 1, 2015 .Dt GETOPT 1 .Os .Sh NAME @@ -62,7 +62,7 @@ set \-\- $args # You cannot use the set command with a backquoted getopt directly, # since the exit code from getopt would be shadowed by those of set, # which is zero by definition. -while true; do +while :; do case "$1" in \-a|\-b) echo "flag $1 set"; sflags="${1#-}$sflags" @@ -83,10 +83,10 @@ echo "oarg is '$oarg'" .Pp This code will accept any of the following as equivalent: .Bd -literal -offset indent -cmd \-aoarg file file -cmd \-a \-o arg file file -cmd \-oarg -a file file -cmd \-a \-oarg \-\- file file +cmd \-aoarg file1 file2 +cmd \-a \-o arg file1 file2 +cmd \-oarg -a file1 file2 +cmd \-a \-oarg \-\- file1 file2 .Ed .Sh SEE ALSO .Xr getopts 1 , From 994cfa1f630ec1d035395a41fe91449782e85c7d Mon Sep 17 00:00:00 2001 From: Jason Unovitch Date: Sat, 1 Aug 2015 17:29:52 +0000 Subject: [PATCH 143/314] - Add myself to the committers-ports.dot and add my mentor relationship. - Add myself to the calendar.freebsd. Approved by: delphij (mentor) Differential Revision: https://reviews.FreeBSD.org/D3265 --- share/misc/committers-ports.dot | 5 +++++ usr.bin/calendar/calendars/calendar.freebsd | 1 + 2 files changed, 6 insertions(+) diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot index b007609f3789..aac0ade02b8e 100644 --- a/share/misc/committers-ports.dot +++ b/share/misc/committers-ports.dot @@ -128,6 +128,7 @@ johans [label="Johan Selst\njohans@FreeBSD.org\n2006/04/01"] josef [label="Josef El-Rayes\njosef@FreeBSD.org\n2004/12/20"] jpaetzel [label="Josh Paetzel\njpaetzel@FreeBSD.org\n2008/09/05"] jsa [label="Joseph S. Atkinson\njsa@FreeBSD.org\n2010/07/15"] +junovitch [label="Jason Unovitch\njunovitch@FreeBSD.org\n2015/07/27"] jylefort [label="Jean-Yves Lefort\njylefort@FreeBSD.org\n2005/04/12"] kami [label="Dominic Fandrey\nkami@FreeBSD.org\n2014/09/09"] kevlo [label="Kevin Lo\nkevlo@FreeBSD.org\n2003/02/21"] @@ -315,6 +316,7 @@ db -> tj decke -> sperber +delphij -> junovitch delphij -> nemoliu delphij -> rafan @@ -347,6 +349,8 @@ erwin -> lbr erwin -> lth erwin -> simon +feld -> junovitch + fjoe -> danfe fjoe -> flo fjoe -> krion @@ -508,6 +512,7 @@ pawel -> nemysis pgj -> ashish pgj -> jacula +pgollucci -> junovitch pgollucci -> sunpoet pgollucci -> swills diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index 41e8ea6cff9e..b0d56a2b0185 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -122,6 +122,7 @@ 04/03 Hellmuth Michaelis born in Kiel, Schleswig-Holstein, Germany, 1958 04/03 Tong Liu born in Beijing, People's Republic of China, 1981 04/03 Gabor Pali born in Kunhegyes, Hungary, 1982 +04/04 Jason Unovitch born in Scranton, Pennsylvania, United States, 1986 04/05 Stacey Son born in Burley, Idaho, United States, 1967 04/06 Peter Jeremy born in Sydney, New South Wales, Australia, 1961 04/07 Edward Tomasz Napierala born in Wolsztyn, Poland, 1981 From 0697ab6ec0492cd07becb238e4142ac1559f44b5 Mon Sep 17 00:00:00 2001 From: Jason Unovitch Date: Sat, 1 Aug 2015 17:48:35 +0000 Subject: [PATCH 144/314] - Add myself to the calendar.freebsd. (fix typo in r286160) Approved by: delphij (mentor) Differential Revision: https://reviews.FreeBSD.org/D3265 --- usr.bin/calendar/calendars/calendar.freebsd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index b0d56a2b0185..4d473c9c34cd 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -122,7 +122,7 @@ 04/03 Hellmuth Michaelis born in Kiel, Schleswig-Holstein, Germany, 1958 04/03 Tong Liu born in Beijing, People's Republic of China, 1981 04/03 Gabor Pali born in Kunhegyes, Hungary, 1982 -04/04 Jason Unovitch born in Scranton, Pennsylvania, United States, 1986 +04/04 Jason Unovitch born in Scranton, Pennsylvania, United States, 1986 04/05 Stacey Son born in Burley, Idaho, United States, 1967 04/06 Peter Jeremy born in Sydney, New South Wales, Australia, 1961 04/07 Edward Tomasz Napierala born in Wolsztyn, Poland, 1981 From 577c341353fbeda7ed72667b0ea61183dbe436cc Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Sat, 1 Aug 2015 20:40:37 +0000 Subject: [PATCH 145/314] Free mbufs when busdma loading fails. Reviewed by: erj, sbruno MFC after: 1 month --- sys/dev/e1000/if_em.c | 3 --- sys/dev/e1000/if_igb.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 528ad149ae89..830325b2ef95 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -2029,9 +2029,6 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp) /* Try it again, but only once */ remap = 0; goto retry; - } else if (error == ENOMEM) { - adapter->no_tx_dma_setup++; - return (error); } else if (error != 0) { adapter->no_tx_dma_setup++; m_freem(*m_headp); diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index 384a46bc223d..9eacc78a1cf4 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -1908,9 +1908,6 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) goto retry; } else return (error); - case ENOMEM: - txr->no_tx_dma_setup++; - return (error); default: txr->no_tx_dma_setup++; m_freem(*m_headp); From 738b6d41092362554de4bda29c489ec8dfdd650b Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 1 Aug 2015 22:00:25 +0000 Subject: [PATCH 146/314] rc.subr: Allow rc.conf.d with multi-directory local_startup. I also changed ${...%*/rc.d} to ${...%/rc.d} since the shortest match always has an empty string for the asterisk. PR: 201641 Submitted by: Jamie Landeg-Jones (original version) MFC after: 1 week --- etc/rc.subr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/etc/rc.subr b/etc/rc.subr index 7b1e38737c10..914d17f87a83 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -1333,7 +1333,8 @@ load_rc_config() # If a service name was specified, attempt to load # service-specific configuration if [ -n "$_name" ] ; then - for _d in /etc ${local_startup%*/rc.d}; do + for _d in /etc ${local_startup}; do + _d=${_d%/rc.d} if [ -f ${_d}/rc.conf.d/"$_name" ]; then debug "Sourcing ${_d}/rc.conf.d/$_name" . ${_d}/rc.conf.d/"$_name" From c3321180ec37fa49d1cc59139691a20b28ad5bf8 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 1 Aug 2015 23:10:36 +0000 Subject: [PATCH 147/314] Set output pin initial value based on pin's pinmux pullup/pulldown setup Some of FDT blobs for AM335x-based devices use pinmux pullup/pulldown flag to setup initial GPIO ouputp value, e.g. 4DCAPE-43 sets LCD DATAEN signal this way. It works for Linux because Linux driver does not enforce pin direction until after it's requested by consumer. So input with pullup flag set acts as output with GPIO_HIGH value Reviewed by: loos --- sys/arm/ti/ti_gpio.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index 8e28adc07944..a5f4176f6c1c 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -573,7 +573,7 @@ ti_gpio_bank_init(device_t dev) { int pin; struct ti_gpio_softc *sc; - uint32_t flags, reg_oe, rev; + uint32_t flags, reg_oe, reg_set, rev; clk_ident_t clk; sc = device_get_softc(dev); @@ -607,12 +607,18 @@ ti_gpio_bank_init(device_t dev) /* Init OE register based on pads configuration. */ reg_oe = 0xffffffff; + reg_set = 0; for (pin = 0; pin < PINS_PER_BANK; pin++) { TI_GPIO_GET_FLAGS(dev, pin, &flags); - if (flags & GPIO_PIN_OUTPUT) + if (flags & GPIO_PIN_OUTPUT) { reg_oe &= ~(1UL << pin); + if (flags & GPIO_PIN_PULLUP) + reg_set |= (1UL << pin); + } } ti_gpio_write_4(sc, TI_GPIO_OE, reg_oe); + if (reg_set) + ti_gpio_write_4(sc, TI_GPIO_SETDATAOUT, reg_set); return (0); } From ce1c953ee0309526f0bcbbe4bb41df5aed86200b Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 2 Aug 2015 00:03:08 +0000 Subject: [PATCH 148/314] Don't modify curthread->td_locks unless INVARIANTS is enabled. This field is only used in a KASSERT that verifies that no locks are held when returning to user mode. Moreover, the td_locks accounting is only correct when LOCK_DEBUG > 0, which is implied by INVARIANTS. Reviewed by: jhb MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D3205 --- sys/kern/kern_lock.c | 6 +----- sys/kern/kern_mutex.c | 8 ++++---- sys/kern/kern_rmlock.c | 13 ++++--------- sys/kern/kern_rwlock.c | 13 +++++++------ sys/kern/kern_sx.c | 12 ++++++------ sys/sys/proc.h | 8 +++++++- 6 files changed, 29 insertions(+), 31 deletions(-) diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 36a8470d2971..aa671804afd6 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -69,12 +69,8 @@ CTASSERT(LK_UNLOCKED == (LK_UNLOCKED & #ifndef INVARIANTS #define _lockmgr_assert(lk, what, file, line) -#define TD_LOCKS_INC(td) -#define TD_LOCKS_DEC(td) -#else -#define TD_LOCKS_INC(td) ((td)->td_locks++) -#define TD_LOCKS_DEC(td) ((td)->td_locks--) #endif + #define TD_SLOCKS_INC(td) ((td)->td_lk_slocks++) #define TD_SLOCKS_DEC(td) ((td)->td_lk_slocks--) diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index 97e198584ddb..bec8f6b0669b 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -224,7 +224,7 @@ __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file, int line) line); WITNESS_LOCK(&m->lock_object, (opts & ~MTX_RECURSE) | LOP_EXCLUSIVE, file, line); - curthread->td_locks++; + TD_LOCKS_INC(curthread); } void @@ -248,7 +248,7 @@ __mtx_unlock_flags(volatile uintptr_t *c, int opts, const char *file, int line) mtx_assert(m, MA_OWNED); __mtx_unlock(m, curthread, opts, file, line); - curthread->td_locks--; + TD_LOCKS_DEC(curthread); } void @@ -347,7 +347,7 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line) if (rval) { WITNESS_LOCK(&m->lock_object, opts | LOP_EXCLUSIVE | LOP_TRYLOCK, file, line); - curthread->td_locks++; + TD_LOCKS_INC(curthread); if (m->mtx_recurse == 0) LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(adaptive__acquire, m, contested, waittime, file, line); @@ -958,7 +958,7 @@ _mtx_destroy(volatile uintptr_t *c) if (LOCK_CLASS(&m->lock_object) == &lock_class_mtx_spin) spinlock_exit(); else - curthread->td_locks--; + TD_LOCKS_DEC(curthread); lock_profile_release_lock(&m->lock_object); /* Tell witness this isn't locked to make it happy. */ diff --git a/sys/kern/kern_rmlock.c b/sys/kern/kern_rmlock.c index 945608da2834..2667e6e3482c 100644 --- a/sys/kern/kern_rmlock.c +++ b/sys/kern/kern_rmlock.c @@ -608,11 +608,8 @@ _rm_wlock_debug(struct rmlock *rm, const char *file, int line) _rm_wlock(rm); LOCK_LOG_LOCK("RMWLOCK", &rm->lock_object, 0, 0, file, line); - WITNESS_LOCK(&rm->lock_object, LOP_EXCLUSIVE, file, line); - - curthread->td_locks++; - + TD_LOCKS_INC(curthread); } void @@ -628,7 +625,7 @@ _rm_wunlock_debug(struct rmlock *rm, const char *file, int line) WITNESS_UNLOCK(&rm->lock_object, LOP_EXCLUSIVE, file, line); LOCK_LOG_LOCK("RMWUNLOCK", &rm->lock_object, 0, 0, file, line); _rm_wunlock(rm); - curthread->td_locks--; + TD_LOCKS_DEC(curthread); } int @@ -670,9 +667,7 @@ _rm_rlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, LOCK_LOG_LOCK("RMRLOCK", &rm->lock_object, 0, 0, file, line); WITNESS_LOCK(&rm->lock_object, 0, file, line); - - curthread->td_locks++; - + TD_LOCKS_INC(curthread); return (1); } else if (trylock) LOCK_LOG_TRY("RMRLOCK", &rm->lock_object, 0, 0, file, line); @@ -694,7 +689,7 @@ _rm_runlock_debug(struct rmlock *rm, struct rm_priotracker *tracker, WITNESS_UNLOCK(&rm->lock_object, 0, file, line); LOCK_LOG_LOCK("RMRUNLOCK", &rm->lock_object, 0, 0, file, line); _rm_runlock(rm, tracker); - curthread->td_locks--; + TD_LOCKS_DEC(curthread); } #else diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index 370d0d6fca4b..6541724f5aef 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -268,7 +268,7 @@ _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line) __rw_wlock(rw, curthread, file, line); LOCK_LOG_LOCK("WLOCK", &rw->lock_object, 0, rw->rw_recurse, file, line); WITNESS_LOCK(&rw->lock_object, LOP_EXCLUSIVE, file, line); - curthread->td_locks++; + TD_LOCKS_INC(curthread); } int @@ -303,7 +303,7 @@ __rw_try_wlock(volatile uintptr_t *c, const char *file, int line) if (!rw_recursed(rw)) LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, 0, 0, file, line, LOCKSTAT_WRITER); - curthread->td_locks++; + TD_LOCKS_INC(curthread); } return (rval); } @@ -325,8 +325,9 @@ _rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line) LOCK_LOG_LOCK("WUNLOCK", &rw->lock_object, 0, rw->rw_recurse, file, line); __rw_wunlock(rw, curthread, file, line); - curthread->td_locks--; + TD_LOCKS_DEC(curthread); } + /* * Determines whether a new reader can acquire a lock. Succeeds if the * reader already owns a read lock and the lock is locked for read to @@ -565,7 +566,7 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line) waittime, file, line, LOCKSTAT_READER); LOCK_LOG_LOCK("RLOCK", &rw->lock_object, 0, 0, file, line); WITNESS_LOCK(&rw->lock_object, 0, file, line); - curthread->td_locks++; + TD_LOCKS_INC(curthread); curthread->td_rw_rlocks++; } @@ -596,7 +597,7 @@ __rw_try_rlock(volatile uintptr_t *c, const char *file, int line) WITNESS_LOCK(&rw->lock_object, LOP_TRYLOCK, file, line); LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw, 0, 0, file, line, LOCKSTAT_READER); - curthread->td_locks++; + TD_LOCKS_INC(curthread); curthread->td_rw_rlocks++; return (1); } @@ -714,7 +715,7 @@ _rw_runlock_cookie(volatile uintptr_t *c, const char *file, int line) break; } LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw, LOCKSTAT_READER); - curthread->td_locks--; + TD_LOCKS_DEC(curthread); curthread->td_rw_rlocks--; } diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index 1ba1ab2aff53..96e117b429b5 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -261,7 +261,7 @@ _sx_slock(struct sx *sx, int opts, const char *file, int line) if (!error) { LOCK_LOG_LOCK("SLOCK", &sx->lock_object, 0, 0, file, line); WITNESS_LOCK(&sx->lock_object, 0, file, line); - curthread->td_locks++; + TD_LOCKS_INC(curthread); } return (error); @@ -290,7 +290,7 @@ sx_try_slock_(struct sx *sx, const char *file, int line) WITNESS_LOCK(&sx->lock_object, LOP_TRYLOCK, file, line); LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx, 0, 0, file, line, LOCKSTAT_READER); - curthread->td_locks++; + TD_LOCKS_INC(curthread); return (1); } } @@ -318,7 +318,7 @@ _sx_xlock(struct sx *sx, int opts, const char *file, int line) LOCK_LOG_LOCK("XLOCK", &sx->lock_object, 0, sx->sx_recurse, file, line); WITNESS_LOCK(&sx->lock_object, LOP_EXCLUSIVE, file, line); - curthread->td_locks++; + TD_LOCKS_INC(curthread); } return (error); @@ -353,7 +353,7 @@ sx_try_xlock_(struct sx *sx, const char *file, int line) if (!sx_recursed(sx)) LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx, 0, 0, file, line, LOCKSTAT_WRITER); - curthread->td_locks++; + TD_LOCKS_INC(curthread); } return (rval); @@ -371,7 +371,7 @@ _sx_sunlock(struct sx *sx, const char *file, int line) WITNESS_UNLOCK(&sx->lock_object, 0, file, line); LOCK_LOG_LOCK("SUNLOCK", &sx->lock_object, 0, 0, file, line); __sx_sunlock(sx, file, line); - curthread->td_locks--; + TD_LOCKS_DEC(curthread); } void @@ -387,7 +387,7 @@ _sx_xunlock(struct sx *sx, const char *file, int line) LOCK_LOG_LOCK("XUNLOCK", &sx->lock_object, 0, sx->sx_recurse, file, line); __sx_xunlock(sx, curthread, file, line); - curthread->td_locks--; + TD_LOCKS_DEC(curthread); } /* diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 9689b17df0ea..62c4b05c0061 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -238,7 +238,7 @@ struct thread { int td_oncpu; /* (t) Which cpu we are on. */ volatile u_char td_owepreempt; /* (k*) Preempt on last critical_exit */ u_char td_tsqueue; /* (t) Turnstile queue blocked on. */ - short td_locks; /* (k) Count of non-spin locks. */ + short td_locks; /* (k) Debug: count of non-spin locks */ short td_rw_rlocks; /* (k) Count of rwlock read locks. */ short td_lk_slocks; /* (k) Count of lockmgr shared locks. */ short td_stopsched; /* (k) Scheduler stopped. */ @@ -351,8 +351,14 @@ do { \ KASSERT((__m == &blocked_lock || __m == (lock)), \ ("Thread %p lock %p does not match %p", td, __m, (lock))); \ } while (0) + +#define TD_LOCKS_INC(td) ((td)->td_locks++) +#define TD_LOCKS_DEC(td) ((td)->td_locks--) #else #define THREAD_LOCKPTR_ASSERT(td, lock) + +#define TD_LOCKS_INC(td) +#define TD_LOCKS_DEC(td) #endif /* From 48fcd357c42f0e06d8fe211bd40c966c3c5a23a2 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 2 Aug 2015 00:11:56 +0000 Subject: [PATCH 149/314] Avoid dereferencing curthread->td_proc->p_cred in DTrace probe context. When a process is exiting, there is a narrow window where p_cred may be NULL while its threads are still executing. Specifically, the last thread to exit a process sets the process state to PRS_ZOMBIE with the proc spinlock held and then calls thread_exit(). thread_exit() drops the spin lock, permitting the process to be reaped and thus causing its cred struct to be released. However, the exiting thread may still cause DTrace probes to fire by calling sched_throw(), resulting in a double fault if such a probe enabling attempts to access the GID or UID DIF variables. The thread's cred reference is not susceptible to this race since it is not released until after the thread has exited. MFC after: 1 week --- sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c index 4da94445e3ca..a3a0bba9d26f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -3510,7 +3510,6 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, */ if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU)) return ((uint64_t)p0.p_cred->cr_uid); -#endif /* * It is always safe to dereference one's own t_procp pointer: @@ -3522,6 +3521,9 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, * credential, since this is never NULL after process birth. */ return ((uint64_t)curthread->t_procp->p_cred->cr_uid); +#else + return ((uint64_t)curthread->td_ucred->cr_uid); +#endif case DIF_VAR_GID: if (!dtrace_priv_proc(state)) @@ -3533,7 +3535,6 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, */ if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU)) return ((uint64_t)p0.p_cred->cr_gid); -#endif /* * It is always safe to dereference one's own t_procp pointer: @@ -3545,6 +3546,9 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, * credential, since this is never NULL after process birth. */ return ((uint64_t)curthread->t_procp->p_cred->cr_gid); +#else + return ((uint64_t)curthread->td_ucred->cr_gid); +#endif case DIF_VAR_ERRNO: { #ifdef illumos From 70e47040b02784d896c999700ef8601fb6cc8e8f Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Sun, 2 Aug 2015 00:15:52 +0000 Subject: [PATCH 150/314] convert to C11's _Static_assert, and pull in sys/cdefs.h for compatibility w/ older non-C11 compilers... passed make tinerdbox.. Suggested by: imp --- sys/net/pfkeyv2.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index dcd67675cc99..ecefcaceb9b2 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -39,9 +39,7 @@ #ifndef _NET_PFKEYV2_H_ #define _NET_PFKEYV2_H_ -#ifndef _KERNEL -#define CTASSERT(x) struct __thisisjustnothing; -#endif +#include /* This file defines structures and symbols for the PF_KEY Version 2 @@ -231,7 +229,7 @@ struct sadb_x_policy { u_int32_t sadb_x_policy_id; u_int32_t sadb_x_policy_reserved2; }; -CTASSERT(sizeof(struct sadb_x_policy) == 16); +_Static_assert(sizeof(struct sadb_x_policy) == 16, "struct size mismatch"); /* * When policy_type == IPSEC, it is followed by some of @@ -267,7 +265,7 @@ struct sadb_x_nat_t_type { u_int8_t sadb_x_nat_t_type_type; u_int8_t sadb_x_nat_t_type_reserved[3]; }; -CTASSERT(sizeof(struct sadb_x_nat_t_type) == 8); +_Static_assert(sizeof(struct sadb_x_nat_t_type) == 8, "struct size mismatch"); /* NAT-Traversal source or destination port. */ struct sadb_x_nat_t_port { @@ -276,7 +274,7 @@ struct sadb_x_nat_t_port { u_int16_t sadb_x_nat_t_port_port; u_int16_t sadb_x_nat_t_port_reserved; }; -CTASSERT(sizeof(struct sadb_x_nat_t_port) == 8); +_Static_assert(sizeof(struct sadb_x_nat_t_port) == 8, "struct size mismatch"); /* ESP fragmentation size. */ struct sadb_x_nat_t_frag { @@ -285,7 +283,7 @@ struct sadb_x_nat_t_frag { u_int16_t sadb_x_nat_t_frag_fraglen; u_int16_t sadb_x_nat_t_frag_reserved; }; -CTASSERT(sizeof(struct sadb_x_nat_t_frag) == 8); +_Static_assert(sizeof(struct sadb_x_nat_t_frag) == 8, "struct size mismatch"); #define SADB_EXT_RESERVED 0 From 61ab25cd3d89c5169a3a56ce13a30bb92ffef8d9 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 2 Aug 2015 00:18:48 +0000 Subject: [PATCH 151/314] Perform bounds checking when constructing a format string. This was detected by the FORTIFY_SOURCE build. PR: 201657 Reported by: pfg MFC after: 2 weeks --- .../lib/libdtrace/common/dt_printf.c | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c index ae26d55ba8be..d408aed45199 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c @@ -1348,6 +1348,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, dtrace_aggdesc_t *agg; caddr_t lim = (caddr_t)buf + len, limit; char format[64] = "%"; + size_t ret; int i, aggrec, curagg = -1; uint64_t normal; @@ -1379,7 +1380,9 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, int prec = pfd->pfd_prec; int rval; + const char *start; char *f = format + 1; /* skip initial '%' */ + size_t fmtsz = sizeof(format) - 1; const dtrace_recdesc_t *rec; dt_pfprint_f *func; caddr_t addr; @@ -1536,6 +1539,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, break; } + start = f; if (pfd->pfd_flags & DT_PFCONV_ALT) *f++ = '#'; if (pfd->pfd_flags & DT_PFCONV_ZPAD) @@ -1548,6 +1552,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, *f++ = '\''; if (pfd->pfd_flags & DT_PFCONV_SPACE) *f++ = ' '; + fmtsz -= f - start; /* * If we're printing a stack and DT_PFCONV_LEFT is set, we @@ -1558,13 +1563,20 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, if (func == pfprint_stack && (pfd->pfd_flags & DT_PFCONV_LEFT)) width = 0; - if (width != 0) - f += snprintf(f, sizeof (format), "%d", ABS(width)); + if (width != 0) { + ret = snprintf(f, fmtsz, "%d", ABS(width)); + f += ret; + fmtsz = MAX(0, fmtsz - ret); + } - if (prec > 0) - f += snprintf(f, sizeof (format), ".%d", prec); + if (prec > 0) { + ret = snprintf(f, fmtsz, ".%d", prec); + f += ret; + fmtsz = MAX(0, fmtsz - ret); + } - (void) strcpy(f, pfd->pfd_fmt); + if (strlcpy(f, pfd->pfd_fmt, fmtsz) >= fmtsz) + return (dt_set_errno(dtp, EDT_COMPILER)); pfd->pfd_rec = rec; if (func(dtp, fp, format, pfd, addr, size, normal) < 0) From 94d919b9990e187119b90f5db9a79f73a05e2cf9 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Sun, 2 Aug 2015 00:22:14 +0000 Subject: [PATCH 152/314] mark this function as deprecated, and put the warning first, since I doubt most people will read to the end... Note the use of sys/cdefs.h for pre-C11 compilers... I didn't included a note about being compatibile w/ userland since a C11 feature should be obviously usable in userland... Suggested by: imp --- share/man/man9/CTASSERT.9 | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/share/man/man9/CTASSERT.9 b/share/man/man9/CTASSERT.9 index 7b719e1e7ab0..39f25d6dbe82 100644 --- a/share/man/man9/CTASSERT.9 +++ b/share/man/man9/CTASSERT.9 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 30, 2015 +.Dd August 1, 2015 .Dt CTASSERT 9 .Os .Sh NAME @@ -39,6 +39,15 @@ .Sh DESCRIPTION The .Fn CTASSERT +macro is deprecated and the C11 standard +.Fn _Static_assert +should be used instead. +The header +.Fa sys/cdefs.h +should be included to provide compatibility for pre-C11 compilers. +.Pp +The +.Fn CTASSERT macro evaluates .Fa expression at compile time and causes a compiler error if it is false. @@ -48,10 +57,6 @@ The macro is useful for asserting the size or alignment of important data structures and variables during compilation, which would otherwise cause the code to fail at run time. -.Pp -The -.Fn CTASSERT -macro is not usable in userland. .Sh EXAMPLES Assert that the size of the .Vt uuid From 6b9db41be6e209df59227c2f41b16687c5a17894 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 2 Aug 2015 00:23:18 +0000 Subject: [PATCH 153/314] - Remove hardcoded paths for the perl executable. - Rather than assuming that a process is listening on 127.0.0.1:22, use nc(1) to find an available port and bind to it for the duration of the test. MFC after: 1 week Sponsored by: EMC / Isilon Storage Division --- .../dtrace/test/tst/common/ip/get.ipv4remote.pl | 2 +- .../dtrace/test/tst/common/ip/get.ipv6remote.pl | 2 +- .../test/tst/common/ip/tst.ipv4localtcp.ksh | 17 +++++++++++++++-- .../test/tst/common/ip/tst.ipv4remotetcp.ksh | 2 +- .../test/tst/common/ip/tst.localtcpstate.ksh | 2 +- .../test/tst/common/ip/tst.remotetcpstate.ksh | 2 +- 6 files changed, 20 insertions(+), 7 deletions(-) diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl index ccc247dec514..5f58eb8e0ca8 100755 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # CDDL HEADER START # diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl index 35bea8e58fa1..fbfcdfdab35f 100755 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # # CDDL HEADER START # diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh index 2e3ffec52ba6..1d2a99237068 100755 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh @@ -58,12 +58,25 @@ fi dtrace=$1 local=127.0.0.1 -tcpport=22 DIR=/var/tmp/dtest.$$ +tcpport=1024 +bound=5000 +while [ $tcpport -lt $bound ]; do + nc -z $local $tcpport >/dev/null || break + tcpport=$(($tcpport + 1)) +done +if [ $tcpport -eq $bound ]; then + echo "couldn't find an available TCP port" + exit 1 +fi + mkdir $DIR cd $DIR +# nc will exit when the connection is closed. +nc -l $local $tcpport & + cat > test.pl <<-EOPERL use IO::Socket; my \$s = IO::Socket::INET->new( @@ -76,7 +89,7 @@ cat > test.pl <<-EOPERL sleep(2); EOPERL -$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin < test.pl <<-EOPERL sleep(2); EOPERL -$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin < test.pl <<-EOPERL sleep(2); EOPERL -$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin < test.pl <<-EOPERL sleep(2); EOPERL -$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin < Date: Sun, 2 Aug 2015 00:24:21 +0000 Subject: [PATCH 154/314] Don't hardcode the module or function component of lockstat probes. MFC after: 1 week --- .../cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d | 2 +- .../dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d | 2 +- .../dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d | 2 +- .../dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d | 2 +- .../cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d | 2 +- .../cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d index cf4dd5e0e550..823a98d4dd3e 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d @@ -34,7 +34,7 @@ * */ -lockstat:kernel:mtx_lock:adaptive-acquire +lockstat:::adaptive-acquire { mutex_owned(); exit(1); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d index 6cc4be03fa30..37637c052b20 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d @@ -34,7 +34,7 @@ * */ -lockstat:kernel:mtx_lock:adaptive-acquire +lockstat:::adaptive-acquire { mutex_owned((kmutex_t *)arg0, 99); exit(1); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d index 61d967a5b470..2d299d4b7312 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d @@ -36,7 +36,7 @@ */ -lockstat:kernel:mtx_lock:adaptive-acquire +lockstat:::adaptive-acquire { mutex_type_adaptive(); exit(1); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d index f2c3178e31c6..42ae0168644a 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d @@ -35,7 +35,7 @@ */ -lockstat:kernel:mtx_lock:adaptive-acquire +lockstat:::adaptive-acquire { mutex_type_adaptive((kmutex_t *)arg0, 99); exit(1); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d index dbb10c3fd598..0784eda4d775 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d @@ -48,7 +48,7 @@ BEGIN i = 0; } -lockstat::mtx_lock:adaptive-acquire +lockstat:::adaptive-acquire { ptr = mutex_owner((struct mtx *)arg0); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d index ac43e790b7b3..f953d2407374 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d @@ -44,7 +44,7 @@ BEGIN ret = -99; } -mtx_lock:adaptive-acquire +lockstat:::adaptive-acquire { ret = mutex_type_adaptive((struct mtx *)arg0); i++; From 0996b154643cea48857a4e002b8641caebb82a09 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 00:33:34 +0000 Subject: [PATCH 155/314] Remove netbsd tests on pw(8) First they are redundant with the tests we currently have on pw(8) Second they to modify the host database instead of being self contained withing the test directory --- usr.sbin/pw/tests/Makefile | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/usr.sbin/pw/tests/Makefile b/usr.sbin/pw/tests/Makefile index c43285fa7fff..a1605aadaf57 100644 --- a/usr.sbin/pw/tests/Makefile +++ b/usr.sbin/pw/tests/Makefile @@ -1,8 +1,5 @@ # $FreeBSD$ -TESTSRC= ${.CURDIR}/../../../contrib/netbsd-tests/usr.sbin/useradd -.PATH: ${TESTSRC} - TESTSDIR= ${TESTSBASE}/usr.sbin/pw ATF_TESTS_SH= pw_etcdir \ @@ -24,12 +21,4 @@ FILES= group helper_functions.shin master.passwd pw.conf \ pw-modified.conf FILESDIR= ${TESTSDIR} -ATF_TESTS_SH+= pw_test -# - user{add,del} does not exist on FreeBSD; use pw user{add,del} instead -# - The command passes on FreeBSD -ATF_TESTS_SH_SED_pw_test= -e 's/useradd /pw useradd /' -ATF_TESTS_SH_SED_pw_test+= -e 's/userdel /pw userdel /' -ATF_TESTS_SH_SED_pw_test+= -e '/atf_expect_fail "PR bin\/39546"/d' -ATF_TESTS_SH_SRC_pw_test= t_useradd.sh - .include From d912066c36534e9820d304b986e64e520af08547 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 2 Aug 2015 00:37:33 +0000 Subject: [PATCH 156/314] Add a src.conf option to build and install the DTrace test suite. Reviewed by: gnn, ngie Differential Revision: https://reviews.freebsd.org/D3195 --- cddl/usr.sbin/dtrace/Makefile | 6 ++++++ share/mk/src.opts.mk | 5 +++++ tools/build/options/WITH_DTRACE_TESTS | 5 +++++ 3 files changed, 16 insertions(+) create mode 100644 tools/build/options/WITH_DTRACE_TESTS diff --git a/cddl/usr.sbin/dtrace/Makefile b/cddl/usr.sbin/dtrace/Makefile index 8c5e3abe5a07..551f6cf80031 100644 --- a/cddl/usr.sbin/dtrace/Makefile +++ b/cddl/usr.sbin/dtrace/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include + .PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/dtrace PROG= dtrace @@ -22,4 +24,8 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \ LIBADD= dtrace +.if ${MK_DTRACE_TESTS} != "no" +SUBDIR+= tests +.endif + .include diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 48c51fa575da..ba8f48f8eabf 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -178,6 +178,7 @@ __DEFAULT_YES_OPTIONS = \ __DEFAULT_NO_OPTIONS = \ BSD_GREP \ CLANG_EXTRAS \ + DTRACE_TESTS \ EISA \ HESIOD \ LLDB \ @@ -318,6 +319,10 @@ MK_KERBEROS:= no MK_AUTHPF:= no .endif +.if ${MK_TESTS} == "no" +MK_DTRACE_TESTS:= no +.endif + .if ${MK_TEXTPROC} == "no" MK_GROFF:= no .endif diff --git a/tools/build/options/WITH_DTRACE_TESTS b/tools/build/options/WITH_DTRACE_TESTS new file mode 100644 index 000000000000..dc85e2b5defd --- /dev/null +++ b/tools/build/options/WITH_DTRACE_TESTS @@ -0,0 +1,5 @@ +.\" $FreeBSD$ +Set to build and install the DTrace test suite in +.Pa /usr/tests/cddl/usr.sbin/dtrace . +This test suite is considered experimental on architectures other than +amd64/amd64 and running it may cause system instability. From 16f3fdf55f13c2ebb4453a2c10804f75a95244c1 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sun, 2 Aug 2015 00:56:16 +0000 Subject: [PATCH 157/314] Regenerate after r286174. --- share/man/man5/src.conf.5 | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index e236ce27955b..b1ac39482ca1 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,7 +1,7 @@ .\" DO NOT EDIT-- this file is automatically generated. .\" from FreeBSD: head/tools/build/options/makeman 284708 2015-06-22 20:21:57Z sjg .\" $FreeBSD$ -.Dd July 29, 2015 +.Dd August 1, 2015 .Dt SRC.CONF 5 .Os .Sh NAME @@ -137,8 +137,8 @@ associated utilities, and examples. .Pp This option only affects amd64/amd64. .It Va WITHOUT_BINUTILS -.\" from FreeBSD: head/tools/build/options/WITHOUT_BINUTILS 266158 2014-05-15 16:51:45Z brooks -Set to not build or install binutils (as, c++-filt, gconv, +.\" from FreeBSD: head/tools/build/options/WITHOUT_BINUTILS 286036 2015-07-29 20:02:20Z emaste +Set to not build or install binutils (as, c++-filt, ld, nm, objcopy, objdump, readelf, size and strip) as part of the normal system build. The resulting system cannot build programs from source. @@ -274,14 +274,14 @@ Set to avoid building the ARCMigrate, Rewriter and StaticAnalyzer components of the Clang C/C++ compiler. .Pp It is a default setting on -arm/arm, arm/armeb, arm/armv6, arm/armv6hf, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32 and sparc64/sparc64. +mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32 and sparc64/sparc64. .It Va WITH_CLANG_FULL .\" from FreeBSD: head/tools/build/options/WITH_CLANG_FULL 246259 2013-02-02 22:28:29Z dim Set to build the ARCMigrate, Rewriter and StaticAnalyzer components of the Clang C/C++ compiler. .Pp It is a default setting on -amd64/amd64, arm64/aarch64, i386/i386, pc98/i386, powerpc/powerpc and powerpc/powerpc64. +amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, arm64/aarch64, i386/i386, pc98/i386, powerpc/powerpc and powerpc/powerpc64. .It Va WITHOUT_CLANG_IS_CC .\" from FreeBSD: head/tools/build/options/WITHOUT_CLANG_IS_CC 242629 2012-11-05 21:53:23Z brooks Set to install the GCC compiler as @@ -414,6 +414,12 @@ Set to not build dma Mail Transport Agent .\" from FreeBSD: head/tools/build/options/WITHOUT_DOCCOMPRESS 266752 2014-05-27 15:52:27Z gjb Set to not to install compressed system documentation. Only the uncompressed version will be installed. +.It Va WITH_DTRACE_TESTS +.\" from FreeBSD: head/tools/build/options/WITH_DTRACE_TESTS 286174 2015-08-02 00:37:33Z markj +Set to build and install the DTrace test suite in +.Pa /usr/tests/cddl/usr.sbin/dtrace . +This test suite is considered experimental on architectures other than +amd64/amd64 and running it may cause system instability. .It Va WITHOUT_DYNAMICROOT .\" from FreeBSD: head/tools/build/options/WITHOUT_DYNAMICROOT 156932 2006-03-21 07:50:50Z ru Set this if you do not want to link @@ -1268,6 +1274,8 @@ When set, it also enforces the following options: .Pp .Bl -item -compact .It +.Va WITHOUT_DTRACE_TESTS +.It .Va WITHOUT_TESTS_SUPPORT .El .It Va WITHOUT_TESTS_SUPPORT From 015b858345562ce87bf369a14d0fb639ca28f1ba Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 2 Aug 2015 01:09:30 +0000 Subject: [PATCH 158/314] Rename busdma_sync() to busdma_sync_range() and rename the base and size parameters to ofs and len (resp). Add a new busdma_sync() that makes the entire MD coherent. --- tools/bus_space/C/lang.c | 11 +++++++++-- tools/bus_space/C/libbus.h | 3 ++- tools/bus_space/Python/lang.c | 25 +++++++++++++++++++++---- tools/bus_space/busdma.c | 6 +++--- tools/bus_space/busdma.h | 2 +- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/tools/bus_space/C/lang.c b/tools/bus_space/C/lang.c index f9b404b1b26c..3ef454466f9d 100644 --- a/tools/bus_space/C/lang.c +++ b/tools/bus_space/C/lang.c @@ -227,8 +227,15 @@ busdma_seg_get_size(busdma_seg_t seg) } int -busdma_sync(busdma_md_t md, int op, bus_addr_t base, bus_size_t size) +busdma_sync(busdma_md_t md, int op) { - return (bd_sync(md, op, base, size)); + return (bd_sync(md, op, 0UL, ~0UL)); +} + +int +busdma_sync_range(busdma_md_t md, int op, bus_size_t ofs, bus_size_t len) +{ + + return (bd_sync(md, op, ofs, len)); } diff --git a/tools/bus_space/C/libbus.h b/tools/bus_space/C/libbus.h index 0fae9879d2ce..1f0c3f176516 100644 --- a/tools/bus_space/C/libbus.h +++ b/tools/bus_space/C/libbus.h @@ -78,6 +78,7 @@ bus_size_t busdma_seg_get_size(busdma_seg_t seg); #define BUSDMA_SYNC_PREWRITE 4 #define BUSDMA_SYNC_POSTWRITE 8 -int busdma_sync(busdma_md_t md, int op, bus_addr_t, bus_size_t); +int busdma_sync(busdma_md_t md, int op); +int busdma_sync_range(busdma_md_t md, int op, bus_size_t, bus_size_t); #endif /* _LIBBUS_SPACE_H_ */ diff --git a/tools/bus_space/Python/lang.c b/tools/bus_space/Python/lang.c index 48a112ba0c30..0fde8fc1bb62 100644 --- a/tools/bus_space/Python/lang.c +++ b/tools/bus_space/Python/lang.c @@ -384,12 +384,27 @@ busdma_seg_get_size(PyObject *self, PyObject *args) static PyObject * busdma_sync(PyObject *self, PyObject *args) { - u_long base, size; int error, mdid, op; - if (!PyArg_ParseTuple(args, "iikk", &mdid, &op, &base, &size)) + if (!PyArg_ParseTuple(args, "ii", &mdid, &op)) return (NULL); - error = bd_sync(mdid, op, base, size); + error = bd_sync(mdid, op, 0UL, ~0UL); + if (error) { + PyErr_SetString(PyExc_IOError, strerror(error)); + return (NULL); + } + Py_RETURN_NONE; +} + +static PyObject * +busdma_sync_range(PyObject *self, PyObject *args) +{ + u_long ofs, len; + int error, mdid, op; + + if (!PyArg_ParseTuple(args, "iikk", &mdid, &op, &ofs, &len)) + return (NULL); + error = bd_sync(mdid, op, ofs, len); if (error) { PyErr_SetString(PyExc_IOError, strerror(error)); return (NULL); @@ -448,7 +463,9 @@ static PyMethodDef busdma_methods[] = { "Return the size of the segment." }, { "sync", busdma_sync, METH_VARARGS, - "Keep memory/caches coherent WRT to DMA." }, + "Make the entire memory descriptor coherent WRT to DMA." }, + { "sync_range", busdma_sync_range, METH_VARARGS, + "Make part of the memory descriptor coherent WRT to DMA." }, { NULL, NULL, 0, NULL } }; diff --git a/tools/bus_space/busdma.c b/tools/bus_space/busdma.c index 3f948b72f983..04a9da8b2ef4 100644 --- a/tools/bus_space/busdma.c +++ b/tools/bus_space/busdma.c @@ -536,7 +536,7 @@ bd_seg_get_size(int sid, u_long *size_p) } int -bd_sync(int mdid, u_int op, u_long base, u_long size) +bd_sync(int mdid, u_int op, u_long ofs, u_long len) { struct proto_ioc_busdma ioc; struct obj *md; @@ -549,8 +549,8 @@ bd_sync(int mdid, u_int op, u_long base, u_long size) ioc.request = PROTO_IOC_BUSDMA_SYNC; ioc.key = md->key; ioc.u.sync.op = op; - ioc.u.sync.base = base; - ioc.u.sync.size = size; + ioc.u.sync.base = ofs; + ioc.u.sync.size = len; if (ioctl(md->fd, PROTO_IOC_BUSDMA, &ioc) == -1) return (errno); diff --git a/tools/bus_space/busdma.h b/tools/bus_space/busdma.h index cf9d4f27542f..ec4890dd201f 100644 --- a/tools/bus_space/busdma.h +++ b/tools/bus_space/busdma.h @@ -51,6 +51,6 @@ int bd_md_next_seg(int mdid, int sid); int bd_seg_get_addr(int sid, u_long *); int bd_seg_get_size(int sid, u_long *); -int bd_sync(int mdid, u_int op, u_long base, u_long size); +int bd_sync(int mdid, u_int op, u_long ofs, u_long len); #endif /* _TOOLS_BUS_DMA_H_ */ From e7b2187928b073943426ccb7152248a7945e7fa5 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Sun, 2 Aug 2015 02:00:20 +0000 Subject: [PATCH 159/314] Fix a couple of markup typos. MFC after: 2 weeks --- lib/libc/stdio/open_memstream.3 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/libc/stdio/open_memstream.3 b/lib/libc/stdio/open_memstream.3 index e01952bc4941..1a0cb0753aba 100644 --- a/lib/libc/stdio/open_memstream.3 +++ b/lib/libc/stdio/open_memstream.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 28, 2014 +.Dd August 1, 2015 .Dt OPEN_MEMSTREAM 3 .Os .Sh NAME @@ -86,13 +86,13 @@ will contain the start of the memory buffer and the variable referenced by will contain the smaller of the current position and the current buffer length. .Pp After a successful call to -.Xr fflush 3, +.Xr fflush 3 , the pointer referenced by .Fa bufp and the variable referenced by .Fa sizep are only valid until the next write operation or a call to -.Xr fclose 3. +.Xr fclose 3 . .Pp Once a stream is closed, the allocated buffer referenced by From 90c11a7328e0015f19aa9ff78b7b6754813bd41d Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 02:23:30 +0000 Subject: [PATCH 160/314] Add removed tests to ObsoleteFiles.inc Submitted by: ngie --- ObsoleteFiles.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 236da23f1cc2..96bfbb651cb2 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,8 @@ # xargs -n1 | sort | uniq -d; # done +# 20150802: Remove netbsd's test on pw(8) +OLD_FILES+=usr/tests/usr.sbin/pw/pw_test # 20150719: Remove libarchive.pc OLD_FILES+=usr/libdata/pkgconfig/libarchive.pc # 20150705: Rename DTrace provider man pages. From a6f7dea1fef4878aa1f37c1aadf20454709da630 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Sun, 2 Aug 2015 11:58:24 +0000 Subject: [PATCH 161/314] Remove redundant check. --- sys/netinet6/in6_src.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index d77324ff6538..b2edce7a1ac6 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -640,14 +640,9 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, if (ron->ro_rt == NULL) { in6_rtalloc(ron, fibnum); /* multi path case? */ if (ron->ro_rt == NULL) { - /* XXX-BZ WT.? */ - if (ron->ro_rt) { - RTFREE(ron->ro_rt); - ron->ro_rt = NULL; - } error = EHOSTUNREACH; goto done; - } + } } rt = ron->ro_rt; From 51a01baf23fe5199a9cf335b6d0b2bacc12779c1 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Sun, 2 Aug 2015 12:40:56 +0000 Subject: [PATCH 162/314] Properly handle IPV6_NEXTHOP socket option in selectroute(). o remove disabled code; o if nexthop address is link-local, use embedded scope zone id to determine outgoing interface; o properly fill ro_dst before doing route lookup; o remove LLE lookup, instead check rt_flags for RTF_GATEWAY bit. Sponsored by: Yandex LLC --- sys/netinet6/in6_src.c | 89 ++++++++++++------------------------------ 1 file changed, 25 insertions(+), 64 deletions(-) diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index b2edce7a1ac6..020c5cfe9370 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -616,77 +616,38 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, */ if (opts && opts->ip6po_nexthop) { struct route_in6 *ron; - struct llentry *la; - + sin6_next = satosin6(opts->ip6po_nexthop); - - /* at this moment, we only support AF_INET6 next hops */ - if (sin6_next->sin6_family != AF_INET6) { - error = EAFNOSUPPORT; /* or should we proceed? */ - goto done; + if (IN6_IS_ADDR_LINKLOCAL(&sin6_next->sin6_addr)) { + /* + * Next hop is LLA, thus it should be neighbor. + * Determine outgoing interface by zone index. + */ + zoneid = ntohs(in6_getscope(&sin6_next->sin6_addr)); + if (zoneid > 0) { + ifp = in6_getlinkifnet(zoneid); + goto done; + } } - - /* - * If the next hop is an IPv6 address, then the node identified - * by that address must be a neighbor of the sending host. - */ ron = &opts->ip6po_nextroute; - /* - * XXX what do we do here? - * PLZ to be fixing - */ - - + /* Use a cached route if it exists and is valid. */ + if (ron->ro_rt != NULL && ( + (ron->ro_rt->rt_flags & RTF_UP) == 0 || + ron->ro_dst.sin6_family != AF_INET6 || + !IN6_ARE_ADDR_EQUAL(&ron->ro_dst.sin6_addr, + &sin6_next->sin6_addr))) + RO_RTFREE(ron); if (ron->ro_rt == NULL) { + ron->ro_dst = *sin6_next; in6_rtalloc(ron, fibnum); /* multi path case? */ - if (ron->ro_rt == NULL) { - error = EHOSTUNREACH; - goto done; - } } - - rt = ron->ro_rt; - ifp = rt->rt_ifp; - IF_AFDATA_RLOCK(ifp); - la = lla_lookup(LLTABLE6(ifp), 0, (struct sockaddr *)sin6_next); - IF_AFDATA_RUNLOCK(ifp); - if (la != NULL) - LLE_RUNLOCK(la); - else { + /* + * The node identified by that address must be a + * neighbor of the sending host. + */ + if (ron->ro_rt == NULL || + (ron->ro_rt->rt_flags & RTF_GATEWAY) != 0) error = EHOSTUNREACH; - goto done; - } -#if 0 - if ((ron->ro_rt && - (ron->ro_rt->rt_flags & (RTF_UP | RTF_LLINFO)) != - (RTF_UP | RTF_LLINFO)) || - !IN6_ARE_ADDR_EQUAL(&satosin6(&ron->ro_dst)->sin6_addr, - &sin6_next->sin6_addr)) { - if (ron->ro_rt) { - RTFREE(ron->ro_rt); - ron->ro_rt = NULL; - } - *satosin6(&ron->ro_dst) = *sin6_next; - } - if (ron->ro_rt == NULL) { - in6_rtalloc(ron, fibnum); /* multi path case? */ - if (ron->ro_rt == NULL || - !(ron->ro_rt->rt_flags & RTF_LLINFO)) { - if (ron->ro_rt) { - RTFREE(ron->ro_rt); - ron->ro_rt = NULL; - } - error = EHOSTUNREACH; - goto done; - } - } -#endif - - /* - * When cloning is required, try to allocate a route to the - * destination so that the caller can store path MTU - * information. - */ goto done; } From d2d022b9fdebd6bfe2983bb688818ed8bfc422a6 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 12:47:50 +0000 Subject: [PATCH 163/314] Rewrite parsing subcommands arguments of pw(8) Now each subcommands checks its arguments in a dedicated functions. This helps improving input validation, code readability/maintainability While here: - Add a -y option to pw userdel/usermod so it can maintain NIS servers if nispasswd is not defined in pw.conf(5) - Allow pw -r to remove directory with userdel -r - Fix bug when renaming a user which was not renaming the user name it groups it is a member of. - Only parse pw.conf(5) when needed. --- usr.sbin/pw/Makefile | 3 +- usr.sbin/pw/pw.c | 296 +--- usr.sbin/pw/pw.h | 28 +- usr.sbin/pw/pw_conf.c | 61 +- usr.sbin/pw/pw_group.c | 769 +++++++---- usr.sbin/pw/pw_nis.c | 1 + usr.sbin/pw/pw_user.c | 2183 +++++++++++++++++------------- usr.sbin/pw/pw_utils.c | 97 ++ usr.sbin/pw/pwupd.h | 17 +- usr.sbin/pw/strtounum.c | 2 +- usr.sbin/pw/tests/pw_groupdel.sh | 2 +- usr.sbin/pw/tests/pw_useradd.sh | 15 +- usr.sbin/pw/tests/pw_userdel.sh | 2 +- usr.sbin/pw/tests/pw_usermod.sh | 49 +- 14 files changed, 2023 insertions(+), 1502 deletions(-) create mode 100644 usr.sbin/pw/pw_utils.c diff --git a/usr.sbin/pw/Makefile b/usr.sbin/pw/Makefile index 87bb5f68e3d6..f26c9de540e9 100644 --- a/usr.sbin/pw/Makefile +++ b/usr.sbin/pw/Makefile @@ -3,7 +3,8 @@ PROG= pw MAN= pw.conf.5 pw.8 SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \ - grupd.c pwupd.c psdate.c bitmap.c cpdir.c rm_r.c strtounum.c + grupd.c pwupd.c psdate.c bitmap.c cpdir.c rm_r.c strtounum.c \ + pw_utils.c WARNS?= 3 diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index 88c83dbfa125..b13db70a57d1 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -37,9 +37,6 @@ static const char rcsid[] = #include #include "pw.h" -#if !defined(_PATH_YP) -#define _PATH_YP "/var/yp/" -#endif const char *Modes[] = { "add", "del", "mod", "show", "next", NULL}; @@ -85,55 +82,39 @@ struct pwf VPWF = vgetgrnam, }; +static int (*cmdfunc[W_NUM][M_NUM])(int argc, char **argv, char *_name) = { + { /* user */ + pw_user_add, + pw_user_del, + pw_user_mod, + pw_user_show, + pw_user_next, + pw_user_lock, + pw_user_unlock, + }, + { /* group */ + pw_group_add, + pw_group_del, + pw_group_mod, + pw_group_show, + pw_group_next, + } +}; + struct pwconf conf; -static struct cargs arglist; - -static int getindex(const char *words[], const char *word); -static void cmdhelp(int mode, int which); - +static int getindex(const char *words[], const char *word); +static void cmdhelp(int mode, int which); int main(int argc, char *argv[]) { - int ch; - int mode = -1; - int which = -1; - long id = -1; - char *config = NULL; + int mode = -1, which = -1, tmp; struct stat st; - const char *errstr; - char arg, *name; + char arg, *arg1; bool relocated, nis; - static const char *opts[W_NUM][M_NUM] = - { - { /* user */ - "R:V:C:qn:u:c:d:e:p:g:G:mM:k:s:oL:i:w:h:H:Db:NPy:Y", - "R:V:C:qn:u:rY", - "R:V:C:qn:u:c:d:e:p:g:G:mM:l:k:s:w:L:h:H:FNPY", - "R:V:C:qn:u:FPa7", - "R:V:C:q", - "R:V:C:q", - "R:V:C:q" - }, - { /* grp */ - "R:V:C:qn:g:h:H:M:opNPY", - "R:V:C:qn:g:Y", - "R:V:C:qn:d:g:l:h:H:FM:m:NPY", - "R:V:C:qn:g:FPa", - "R:V:C:q" - } - }; - - static int (*funcs[W_NUM]) (int _mode, char *_name, long _id, - struct cargs * _args) = - { /* Request handlers */ - pw_user, - pw_group - }; - - name = NULL; + arg1 = NULL; relocated = nis = false; memset(&conf, 0, sizeof(conf)); strlcpy(conf.rootdir, "/", sizeof(conf.rootdir)); @@ -141,17 +122,13 @@ main(int argc, char *argv[]) conf.fd = -1; conf.checkduplicate = true; - LIST_INIT(&arglist); - - (void)setlocale(LC_ALL, ""); + setlocale(LC_ALL, ""); /* * Break off the first couple of words to determine what exactly * we're being asked to do */ while (argc > 1) { - int tmp; - if (*argv[1] == '-') { /* * Special case, allow pw -V [args] for scripts etc. @@ -197,15 +174,9 @@ main(int argc, char *argv[]) mode = tmp % M_NUM; } else if (strcmp(argv[1], "help") == 0 && argv[2] == NULL) cmdhelp(mode, which); - else if (which != -1 && mode != -1) { - if (strspn(argv[1], "0123456789") == strlen(argv[1])) { - id = strtounum(argv[1], 0, UID_MAX, &errstr); - if (errstr != NULL) - errx(EX_USAGE, "Bad id '%s': %s", - argv[1], errstr); - } else - name = argv[1]; - } else + else if (which != -1 && mode != -1) + arg1 = argv[1]; + else errx(EX_USAGE, "unknown keyword `%s'", argv[1]); ++argv; --argc; @@ -220,193 +191,22 @@ main(int argc, char *argv[]) conf.rootfd = open(conf.rootdir, O_DIRECTORY|O_CLOEXEC); if (conf.rootfd == -1) errx(EXIT_FAILURE, "Unable to open '%s'", conf.rootdir); - conf.which = which; - /* - * We know which mode we're in and what we're about to do, so now - * let's dispatch the remaining command line args in a genric way. - */ - optarg = NULL; - while ((ch = getopt(argc, argv, opts[which][mode])) != -1) { - switch (ch) { - case '?': - errx(EX_USAGE, "unknown switch"); - break; - case '7': - conf.v7 = true; - break; - case 'C': - conf.config = optarg; - config = conf.config; - break; - case 'F': - conf.force = true; - break; - case 'N': - conf.dryrun = true; - break; - case 'l': - if (strlen(optarg) >= MAXLOGNAME) - errx(EX_USAGE, "new name too long: %s", optarg); - conf.newname = optarg; - break; - case 'P': - conf.pretty = true; - break; - case 'Y': - nis = true; - break; - case 'a': - conf.all = true; - break; - case 'c': - conf.gecos = pw_checkname(optarg, 1); - break; - case 'g': - if (which == 0) { /* for user* */ - addarg(&arglist, 'g', optarg); - break; - } - if (strspn(optarg, "0123456789") != strlen(optarg)) - errx(EX_USAGE, "-g expects a number"); - id = strtounum(optarg, 0, GID_MAX, &errstr); - if (errstr != NULL) - errx(EX_USAGE, "Bad id '%s': %s", optarg, - errstr); - break; - case 'u': - if (strspn(optarg, "0123456789,") != strlen(optarg)) - errx(EX_USAGE, "-u expects a number"); - if (strchr(optarg, ',') != NULL) { - addarg(&arglist, 'u', optarg); - break; - } - id = strtounum(optarg, 0, UID_MAX, &errstr); - if (errstr != NULL) - errx(EX_USAGE, "Bad id '%s': %s", optarg, - errstr); - break; - case 'n': - name = optarg; - break; - case 'H': - if (conf.fd != -1) - errx(EX_USAGE, "'-h' and '-H' are mutually " - "exclusive options"); - conf.precrypted = true; - if (strspn(optarg, "0123456789") != strlen(optarg)) - errx(EX_USAGE, "'-H' expects a file descriptor"); - - conf.fd = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) - errx(EX_USAGE, "Bad file descriptor '%s': %s", - optarg, errstr); - break; - case 'h': - if (conf.fd != -1) - errx(EX_USAGE, "'-h' and '-H' are mutually " - "exclusive options"); - - if (strcmp(optarg, "-") == 0) - conf.fd = '-'; - else if (strspn(optarg, "0123456789") == strlen(optarg)) { - conf.fd = strtonum(optarg, 0, INT_MAX, &errstr); - if (errstr != NULL) - errx(EX_USAGE, "'-h' expects a " - "file descriptor or '-'"); - } else - errx(EX_USAGE, "'-h' expects a file " - "descriptor or '-'"); - break; - case 'o': - conf.checkduplicate = false; - break; - case 'q': - conf.quiet = true; - break; - case 'r': - conf.deletehome = true; - break; - default: - addarg(&arglist, ch, optarg); - break; - } - optarg = NULL; - } - - if (name != NULL && strlen(name) >= MAXLOGNAME) - errx(EX_USAGE, "name too long: %s", name); - - /* - * Must be root to attempt an update - */ - if (geteuid() != 0 && mode != M_PRINT && mode != M_NEXT && !conf.dryrun) - errx(EX_NOPERM, "you must be root to run this program"); - - /* - * We should immediately look for the -q 'quiet' switch so that we - * don't bother with extraneous errors - */ - if (conf.quiet) - freopen(_PATH_DEVNULL, "w", stderr); - - /* - * Set our base working path if not overridden - */ - - if (config == NULL) { /* Only override config location if -C not specified */ - asprintf(&config, "%s/pw.conf", conf.etcpath); - if (config == NULL) - errx(EX_OSERR, "out of memory"); - } - - /* - * Now, let's do the common initialisation - */ - conf.userconf = read_userconfig(config); - - ch = funcs[which] (mode, name, id, &arglist); - - /* - * If everything went ok, and we've been asked to update - * the NIS maps, then do it now - */ - if (ch == EXIT_SUCCESS && nis) { - pid_t pid; - - fflush(NULL); - if (chdir(_PATH_YP) == -1) - warn("chdir(" _PATH_YP ")"); - else if ((pid = fork()) == -1) - warn("fork()"); - else if (pid == 0) { - /* Is make anywhere else? */ - execlp("/usr/bin/make", "make", (char *)NULL); - _exit(1); - } else { - int i; - waitpid(pid, &i, 0); - if ((i = WEXITSTATUS(i)) != 0) - errx(ch, "make exited with status %d", i); - else - pw_log(conf.userconf, mode, which, "NIS maps updated"); - } - } - return ch; + return (cmdfunc[which][mode](argc, argv, arg1)); } static int getindex(const char *words[], const char *word) { - int i = 0; + int i = 0; while (words[i]) { if (strcmp(words[i], word) == 0) - return i; + return (i); i++; } - return -1; + return (-1); } @@ -456,7 +256,7 @@ cmdhelp(int mode, int which) " Setting defaults:\n" "\t-V etcdir alternate /etc location\n" "\t-R rootir alternate root directory\n" - "\t-D set user defaults\n" + "\t-D set user defaults\n" "\t-b dir default home root dir\n" "\t-e period default expiry period\n" "\t-p period default password change period\n" @@ -476,6 +276,7 @@ cmdhelp(int mode, int which) "\t-n name login name\n" "\t-u uid user id\n" "\t-Y update NIS maps\n" + "\t-y path set NIS passwd file path\n" "\t-r remove home & contents\n", "usage: pw usermod [uid|name] [switches]\n" "\t-V etcdir alternate /etc location\n" @@ -500,6 +301,7 @@ cmdhelp(int mode, int which) "\t-h fd read password on fd\n" "\t-H fd read encrypted password on fd\n" "\t-Y update NIS maps\n" + "\t-y path set NIS passwd file path\n" "\t-N no update\n", "usage: pw usershow [uid|name] [switches]\n" "\t-V etcdir alternate /etc location\n" @@ -576,31 +378,3 @@ cmdhelp(int mode, int which) } exit(EXIT_FAILURE); } - -struct carg * -getarg(struct cargs * _args, int ch) -{ - struct carg *c; - - if (_args == NULL) - return (NULL); - - c = LIST_FIRST(_args); - - while (c != NULL && c->ch != ch) - c = LIST_NEXT(c, list); - return c; -} - -struct carg * -addarg(struct cargs * _args, int ch, char *argstr) -{ - struct carg *ca = malloc(sizeof(struct carg)); - - if (ca == NULL) - errx(EX_OSERR, "out of memory"); - ca->ch = ch; - ca->val = argstr; - LIST_INSERT_HEAD(_args, ca, list); - return ca; -} diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h index a22572e57cab..b6e2ccf5dca9 100644 --- a/usr.sbin/pw/pw.h +++ b/usr.sbin/pw/pw.h @@ -78,21 +78,41 @@ LIST_HEAD(cargs, carg); #define _UC_MAXLINE 1024 #define _UC_MAXSHELLS 32 +struct userconf *get_userconfig(const char *cfg); struct userconf *read_userconfig(char const * file); -int write_userconfig(char const * file); +int write_userconfig(struct userconf *cnf, char const * file); struct carg *addarg(struct cargs * _args, int ch, char *argstr); struct carg *getarg(struct cargs * _args, int ch); -int pw_user(int mode, char *name, long id, struct cargs * _args); -int pw_usernext(struct userconf *cnf, bool quiet); -int pw_group(int mode, char *name, long id, struct cargs * _args); +int pw_group_add(int argc, char **argv, char *name); +int pw_group_del(int argc, char **argv, char *name); +int pw_group_mod(int argc, char **argv, char *name); +int pw_group_next(int argc, char **argv, char *name); +int pw_group_show(int argc, char **argv, char *name); +int pw_user_add(int argc, char **argv, char *name); +int pw_user_add(int argc, char **argv, char *name); +int pw_user_add(int argc, char **argv, char *name); +int pw_user_add(int argc, char **argv, char *name); +int pw_user_del(int argc, char **argv, char *name); +int pw_user_lock(int argc, char **argv, char *name); +int pw_user_mod(int argc, char **argv, char *name); +int pw_user_next(int argc, char **argv, char *name); +int pw_user_show(int argc, char **argv, char *name); +int pw_user_unlock(int argc, char **argv, char *name); int pw_groupnext(struct userconf *cnf, bool quiet); char *pw_checkname(char *name, int gecos); +uintmax_t pw_checkid(char *nptr, uintmax_t maxval); +int pw_checkfd(char *nptr); int addnispwent(const char *path, struct passwd *pwd); int delnispwent(const char *path, const char *login); int chgnispwent(const char *path, const char *login, struct passwd *pwd); +int groupadd(struct userconf *, char *name, gid_t id, char *members, int fd, + bool dryrun, bool pretty, bool precrypted); + +int nis_update(void); + int boolean_val(char const * str, int dflt); char const *boolean_str(int val); char *newstr(char const * p); diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index b723c31a39dd..41ab79b2f177 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -235,9 +235,6 @@ read_userconfig(char const * file) buf = NULL; linecap = 0; - config.groups = sl_init(); - if (config.groups == NULL) - err(1, "sl_init()"); if (file == NULL) file = _PATH_PW_CONF; @@ -316,8 +313,11 @@ read_userconfig(char const * file) ? NULL : newstr(q); break; case _UC_EXTRAGROUPS: - for (i = 0; q != NULL; q = strtok(NULL, toks)) + for (i = 0; q != NULL; q = strtok(NULL, toks)) { + if (config.groups == NULL) + config.groups = sl_init(); sl_add(config.groups, newstr(q)); + } break; case _UC_DEFAULTCLASS: config.default_class = (q == NULL || !boolean_val(q, 1)) @@ -391,7 +391,7 @@ read_userconfig(char const * file) int -write_userconfig(char const * file) +write_userconfig(struct userconf *cnf, const char *file) { int fd; int i, j; @@ -416,40 +416,39 @@ write_userconfig(char const * file) sbuf_clear(buf); switch (i) { case _UC_DEFAULTPWD: - sbuf_cat(buf, boolean_str(config.default_password)); + sbuf_cat(buf, boolean_str(cnf->default_password)); break; case _UC_REUSEUID: - sbuf_cat(buf, boolean_str(config.reuse_uids)); + sbuf_cat(buf, boolean_str(cnf->reuse_uids)); break; case _UC_REUSEGID: - sbuf_cat(buf, boolean_str(config.reuse_gids)); + sbuf_cat(buf, boolean_str(cnf->reuse_gids)); break; case _UC_NISPASSWD: - sbuf_cat(buf, config.nispasswd ? config.nispasswd : - ""); + sbuf_cat(buf, cnf->nispasswd ? cnf->nispasswd : ""); quote = 0; break; case _UC_DOTDIR: - sbuf_cat(buf, config.dotdir ? config.dotdir : + sbuf_cat(buf, cnf->dotdir ? cnf->dotdir : boolean_str(0)); break; case _UC_NEWMAIL: - sbuf_cat(buf, config.newmail ? config.newmail : + sbuf_cat(buf, cnf->newmail ? cnf->newmail : boolean_str(0)); break; case _UC_LOGFILE: - sbuf_cat(buf, config.logfile ? config.logfile : + sbuf_cat(buf, cnf->logfile ? cnf->logfile : boolean_str(0)); break; case _UC_HOMEROOT: - sbuf_cat(buf, config.home); + sbuf_cat(buf, cnf->home); break; case _UC_HOMEMODE: - sbuf_printf(buf, "%04o", config.homemode); + sbuf_printf(buf, "%04o", cnf->homemode); quote = 0; break; case _UC_SHELLPATH: - sbuf_cat(buf, config.shelldir); + sbuf_cat(buf, cnf->shelldir); break; case _UC_SHELLS: for (j = 0; j < _UC_MAXSHELLS && @@ -459,46 +458,46 @@ write_userconfig(char const * file) quote = 0; break; case _UC_DEFAULTSHELL: - sbuf_cat(buf, config.shell_default ? - config.shell_default : bourne_shell); + sbuf_cat(buf, cnf->shell_default ? + cnf->shell_default : bourne_shell); break; case _UC_DEFAULTGROUP: - sbuf_cat(buf, config.default_group ? - config.default_group : ""); + sbuf_cat(buf, cnf->default_group ? + cnf->default_group : ""); break; case _UC_EXTRAGROUPS: - for (j = 0; config.groups != NULL && - j < (int)config.groups->sl_cur; j++) + for (j = 0; cnf->groups != NULL && + j < (int)cnf->groups->sl_cur; j++) sbuf_printf(buf, "%s\"%s\"", j ? - "," : "", config.groups->sl_str[j]); + "," : "", cnf->groups->sl_str[j]); quote = 0; break; case _UC_DEFAULTCLASS: - sbuf_cat(buf, config.default_class ? - config.default_class : ""); + sbuf_cat(buf, cnf->default_class ? + cnf->default_class : ""); break; case _UC_MINUID: - sbuf_printf(buf, "%ju", (uintmax_t)config.min_uid); + sbuf_printf(buf, "%ju", (uintmax_t)cnf->min_uid); quote = 0; break; case _UC_MAXUID: - sbuf_printf(buf, "%ju", (uintmax_t)config.max_uid); + sbuf_printf(buf, "%ju", (uintmax_t)cnf->max_uid); quote = 0; break; case _UC_MINGID: - sbuf_printf(buf, "%ju", (uintmax_t)config.min_gid); + sbuf_printf(buf, "%ju", (uintmax_t)cnf->min_gid); quote = 0; break; case _UC_MAXGID: - sbuf_printf(buf, "%ju", (uintmax_t)config.max_gid); + sbuf_printf(buf, "%ju", (uintmax_t)cnf->max_gid); quote = 0; break; case _UC_EXPIRE: - sbuf_printf(buf, "%d", config.expire_days); + sbuf_printf(buf, "%ld", cnf->expire_days); quote = 0; break; case _UC_PASSWORD: - sbuf_printf(buf, "%d", config.password_days); + sbuf_printf(buf, "%ld", cnf->password_days); quote = 0; break; case _UC_NONE: diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c index 3d5e70af8949..5ba5e39fa06d 100644 --- a/usr.sbin/pw/pw_group.c +++ b/usr.sbin/pw/pw_group.c @@ -31,47 +31,50 @@ static const char rcsid[] = #include #include -#include -#include -#include -#include #include +#include #include +#include +#include +#include +#include #include "pw.h" #include "bitmap.h" - static struct passwd *lookup_pwent(const char *user); static void delete_members(struct group *grp, char *list); -static int print_group(struct group * grp); -static gid_t gr_gidpolicy(struct userconf * cnf, long id); +static int print_group(struct group * grp, bool pretty); +static gid_t gr_gidpolicy(struct userconf * cnf, intmax_t id); static void -set_passwd(struct group *grp, bool update) +grp_set_passwd(struct group *grp, bool update, int fd, bool precrypted) { int b; int istty; struct termios t, n; char *p, line[256]; - if (conf.fd == '-') { + if (fd == -1) + return; + + if (fd == '-') { grp->gr_passwd = "*"; /* No access */ return; } - if ((istty = isatty(conf.fd))) { + if ((istty = isatty(fd))) { n = t; /* Disable echo */ n.c_lflag &= ~(ECHO); - tcsetattr(conf.fd, TCSANOW, &n); + tcsetattr(fd, TCSANOW, &n); printf("%sassword for group %s:", update ? "New p" : "P", grp->gr_name); fflush(stdout); } - b = read(conf.fd, line, sizeof(line) - 1); + b = read(fd, line, sizeof(line) - 1); if (istty) { /* Restore state */ - tcsetattr(conf.fd, TCSANOW, &t); + tcsetattr(fd, TCSANOW, &t); fputc('\n', stdout); fflush(stdout); } @@ -83,7 +86,7 @@ set_passwd(struct group *grp, bool update) if (!*line) errx(EX_DATAERR, "empty password read on file descriptor %d", conf.fd); - if (conf.precrypted) { + if (precrypted) { if (strchr(line, ':') != 0) errx(EX_DATAERR, "wrong encrypted passwrd"); grp->gr_passwd = line; @@ -103,193 +106,24 @@ pw_groupnext(struct userconf *cnf, bool quiet) return (EXIT_SUCCESS); } -static int -pw_groupshow(const char *name, long id, struct group *fakegroup) +static struct group * +getgroup(char *name, intmax_t id, bool fatal) { - struct group *grp = NULL; - - if (id < 0 && name == NULL && !conf.all) - errx(EX_DATAERR, "groupname or id or '-a' required"); - - if (conf.all) { - SETGRENT(); - while ((grp = GETGRENT()) != NULL) - print_group(grp); - ENDGRENT(); - - return (EXIT_SUCCESS); - } - - grp = (name != NULL) ? GETGRNAM(name) : GETGRGID(id); - if (grp == NULL) { - if (conf.force) { - grp = fakegroup; - } else { - if (name == NULL) - errx(EX_DATAERR, "unknown gid `%ld'", id); - errx(EX_DATAERR, "unknown group `%s'", name); - } - } - - return (print_group(grp)); -} - -static int -pw_groupdel(const char *name, long id) -{ - struct group *grp = NULL; - int rc; - - grp = (name != NULL) ? GETGRNAM(name) : GETGRGID(id); - if (grp == NULL) { - if (name == NULL) - errx(EX_DATAERR, "unknown gid `%ld'", id); - errx(EX_DATAERR, "unknown group `%s'", name); - } - - rc = delgrent(grp); - if (rc == -1) - err(EX_IOERR, "group '%s' not available (NIS?)", name); - else if (rc != 0) - err(EX_IOERR, "group update"); - pw_log(conf.userconf, M_DELETE, W_GROUP, "%s(%ld) removed", name, id); - - return (EXIT_SUCCESS); -} - -int -pw_group(int mode, char *name, long id, struct cargs * args) -{ - int rc; - struct carg *arg; - struct group *grp = NULL; - struct userconf *cnf = conf.userconf; - - static struct group fakegroup = - { - "nogroup", - "*", - -1, - NULL - }; - - if (mode == M_NEXT) - return (pw_groupnext(cnf, conf.quiet)); - - if (mode == M_PRINT) - return (pw_groupshow(name, id, &fakegroup)); - - if (mode == M_DELETE) - return (pw_groupdel(name, id)); - - if (mode == M_LOCK || mode == M_UNLOCK) - errx(EX_USAGE, "'lock' command is not available for groups"); + struct group *grp; if (id < 0 && name == NULL) - errx(EX_DATAERR, "group name or id required"); - + errx(EX_DATAERR, "groupname or id required"); grp = (name != NULL) ? GETGRNAM(name) : GETGRGID(id); - - if (mode == M_UPDATE) { - if (name == NULL && grp == NULL) /* Try harder */ - grp = GETGRGID(id); - - if (grp == NULL) { - if (name == NULL) - errx(EX_DATAERR, "unknown group `%s'", name); - else - errx(EX_DATAERR, "unknown group `%ld'", id); - } - if (name == NULL) /* Needed later */ - name = grp->gr_name; - - if (id > 0) - grp->gr_gid = (gid_t) id; - - if (conf.newname != NULL) - grp->gr_name = pw_checkname(conf.newname, 0); - } else { - if (name == NULL) /* Required */ - errx(EX_DATAERR, "group name required"); - else if (grp != NULL) /* Exists */ - errx(EX_DATAERR, "group name `%s' already exists", name); - - grp = &fakegroup; - grp->gr_name = pw_checkname(name, 0); - grp->gr_passwd = "*"; - grp->gr_gid = gr_gidpolicy(cnf, id); - grp->gr_mem = NULL; + if (grp == NULL) { + if (!fatal) + return (NULL); + if (name == NULL) + errx(EX_DATAERR, "unknown gid `%ju'", id); + errx(EX_DATAERR, "unknown group `%s'", name); } - - /* - * This allows us to set a group password Group passwords is an - * antique idea, rarely used and insecure (no secure database) Should - * be discouraged, but it is apparently still supported by some - * software. - */ - - if (conf.which == W_GROUP && conf.fd != -1) - set_passwd(grp, mode == M_UPDATE); - - if (((arg = getarg(args, 'M')) != NULL || - (arg = getarg(args, 'd')) != NULL || - (arg = getarg(args, 'm')) != NULL) && arg->val) { - char *p; - struct passwd *pwd; - - /* Make sure this is not stay NULL with -M "" */ - if (arg->ch == 'd') - delete_members(grp, arg->val); - else if (arg->ch == 'M') - grp->gr_mem = NULL; - - for (p = strtok(arg->val, ", \t"); arg->ch != 'd' && p != NULL; - p = strtok(NULL, ", \t")) { - int j; - - /* - * Check for duplicates - */ - pwd = lookup_pwent(p); - for (j = 0; grp->gr_mem != NULL && grp->gr_mem[j] != NULL; j++) { - if (strcmp(grp->gr_mem[j], pwd->pw_name) == 0) - break; - } - if (grp->gr_mem != NULL && grp->gr_mem[j] != NULL) - continue; - grp = gr_add(grp, pwd->pw_name); - } - } - - if (conf.dryrun) - return print_group(grp); - - if (mode == M_ADD && (rc = addgrent(grp)) != 0) { - if (rc == -1) - errx(EX_IOERR, "group '%s' already exists", - grp->gr_name); - else - err(EX_IOERR, "group update"); - } else if (mode == M_UPDATE && (rc = chggrent(name, grp)) != 0) { - if (rc == -1) - errx(EX_IOERR, "group '%s' not available (NIS?)", - grp->gr_name); - else - err(EX_IOERR, "group update"); - } - - if (conf.newname != NULL) - name = conf.newname; - /* grp may have been invalidated */ - if ((grp = GETGRNAM(name)) == NULL) - errx(EX_SOFTWARE, "group disappeared during update"); - - pw_log(cnf, mode, W_GROUP, "%s(%ju)", grp->gr_name, (uintmax_t)grp->gr_gid); - - return EXIT_SUCCESS; + return (grp); } - /* * Lookup a passwd entry using a name or UID. */ @@ -332,11 +166,11 @@ delete_members(struct group *grp, char *list) } } - -static gid_t -gr_gidpolicy(struct userconf * cnf, long id) +static gid_t +gr_gidpolicy(struct userconf * cnf, intmax_t id) { struct group *grp; + struct bitmap bm; gid_t gid = (gid_t) - 1; /* @@ -347,66 +181,59 @@ gr_gidpolicy(struct userconf * cnf, long id) if ((grp = GETGRGID(gid)) != NULL && conf.checkduplicate) errx(EX_DATAERR, "gid `%ju' has already been allocated", (uintmax_t)grp->gr_gid); - } else { - struct bitmap bm; - - /* - * We need to allocate the next available gid under one of - * two policies a) Grab the first unused gid b) Grab the - * highest possible unused gid - */ - if (cnf->min_gid >= cnf->max_gid) { /* Sanity claus^H^H^H^Hheck */ - cnf->min_gid = 1000; - cnf->max_gid = 32000; - } - bm = bm_alloc(cnf->max_gid - cnf->min_gid + 1); - - /* - * Now, let's fill the bitmap from the password file - */ - SETGRENT(); - while ((grp = GETGRENT()) != NULL) - if ((gid_t)grp->gr_gid >= (gid_t)cnf->min_gid && - (gid_t)grp->gr_gid <= (gid_t)cnf->max_gid) - bm_setbit(&bm, grp->gr_gid - cnf->min_gid); - ENDGRENT(); - - /* - * Then apply the policy, with fallback to reuse if necessary - */ - if (cnf->reuse_gids) - gid = (gid_t) (bm_firstunset(&bm) + cnf->min_gid); - else { - gid = (gid_t) (bm_lastset(&bm) + 1); - if (!bm_isset(&bm, gid)) - gid += cnf->min_gid; - else - gid = (gid_t) (bm_firstunset(&bm) + cnf->min_gid); - } - - /* - * Another sanity check - */ - if (gid < cnf->min_gid || gid > cnf->max_gid) - errx(EX_SOFTWARE, "unable to allocate a new gid - range fully used"); - bm_dealloc(&bm); + return (gid); } - return gid; + + /* + * We need to allocate the next available gid under one of + * two policies a) Grab the first unused gid b) Grab the + * highest possible unused gid + */ + if (cnf->min_gid >= cnf->max_gid) { /* Sanity claus^H^H^H^Hheck */ + cnf->min_gid = 1000; + cnf->max_gid = 32000; + } + bm = bm_alloc(cnf->max_gid - cnf->min_gid + 1); + + /* + * Now, let's fill the bitmap from the password file + */ + SETGRENT(); + while ((grp = GETGRENT()) != NULL) + if ((gid_t)grp->gr_gid >= (gid_t)cnf->min_gid && + (gid_t)grp->gr_gid <= (gid_t)cnf->max_gid) + bm_setbit(&bm, grp->gr_gid - cnf->min_gid); + ENDGRENT(); + + /* + * Then apply the policy, with fallback to reuse if necessary + */ + if (cnf->reuse_gids) + gid = (gid_t) (bm_firstunset(&bm) + cnf->min_gid); + else { + gid = (gid_t) (bm_lastset(&bm) + 1); + if (!bm_isset(&bm, gid)) + gid += cnf->min_gid; + else + gid = (gid_t) (bm_firstunset(&bm) + cnf->min_gid); + } + + /* + * Another sanity check + */ + if (gid < cnf->min_gid || gid > cnf->max_gid) + errx(EX_SOFTWARE, "unable to allocate a new gid - range fully used"); + bm_dealloc(&bm); + return (gid); } - static int -print_group(struct group * grp) +print_group(struct group * grp, bool pretty) { - if (!conf.pretty) { - char *buf = NULL; - - buf = gr_make(grp); - printf("%s\n", buf); - free(buf); - } else { - int i; + char *buf = NULL; + int i; + if (pretty) { printf("Group Name: %-15s #%lu\n" " Members: ", grp->gr_name, (long) grp->gr_gid); @@ -415,6 +242,444 @@ print_group(struct group * grp) printf("%s%s", i ? "," : "", grp->gr_mem[i]); } fputs("\n\n", stdout); + return (EXIT_SUCCESS); } - return EXIT_SUCCESS; + + buf = gr_make(grp); + printf("%s\n", buf); + free(buf); + return (EXIT_SUCCESS); +} + +int +pw_group_next(int argc, char **argv, char *arg1 __unused) +{ + struct userconf *cnf; + const char *cfg = NULL; + int ch; + bool quiet; + + while ((ch = getopt(argc, argv, "Cq")) != -1) { + switch (ch) { + case 'C': + cfg = optarg; + break; + case 'q': + quiet = true; + break; + } + } + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + cnf = get_userconfig(cfg); + return (pw_groupnext(cnf, quiet)); +} + +int +pw_group_show(int argc, char **argv, char *arg1) +{ + struct group *grp = NULL; + char *name; + intmax_t id = -1; + int ch; + bool all, force, quiet, pretty; + + all = force = quiet = pretty = false; + + struct group fakegroup = { + "nogroup", + "*", + -1, + NULL + }; + + if (arg1 != NULL) { + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, GID_MAX); + else + name = arg1; + } + + while ((ch = getopt(argc, argv, "C:qn:g:FPa")) != -1) { + switch (ch) { + case 'C': + /* ignore compatibility */ + break; + case 'q': + quiet = true; + break; + case 'n': + name = optarg; + break; + case 'g': + id = pw_checkid(optarg, GID_MAX); + break; + case 'F': + force = true; + break; + case 'P': + pretty = true; + break; + case 'a': + all = true; + break; + } + } + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + + if (all) { + SETGRENT(); + while ((grp = GETGRENT()) != NULL) + print_group(grp, pretty); + ENDGRENT(); + return (EXIT_SUCCESS); + } + + grp = getgroup(name, id, !force); + if (grp == NULL) + grp = &fakegroup; + + return (print_group(grp, pretty)); +} + +int +pw_group_del(int argc, char **argv, char *arg1) +{ + struct userconf *cnf = NULL; + struct group *grp = NULL; + char *name; + const char *cfg = NULL; + intmax_t id = -1; + int ch, rc; + bool quiet = false; + bool nis = false; + + if (arg1 != NULL) { + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, GID_MAX); + else + name = arg1; + } + + while ((ch = getopt(argc, argv, "C:qn:g:Y")) != -1) { + switch (ch) { + case 'C': + cfg = optarg; + break; + case 'q': + quiet = true; + break; + case 'n': + name = optarg; + break; + case 'g': + id = pw_checkid(optarg, GID_MAX); + break; + case 'Y': + nis = true; + break; + } + } + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + grp = getgroup(name, id, true); + cnf = get_userconfig(cfg); + rc = delgrent(grp); + if (rc == -1) + err(EX_IOERR, "group '%s' not available (NIS?)", name); + else if (rc != 0) + err(EX_IOERR, "group update"); + pw_log(cnf, M_DELETE, W_GROUP, "%s(%ju) removed", name, + (uintmax_t)id); + + if (nis && nis_update() == 0) + pw_log(cnf, M_DELETE, W_GROUP, "NIS maps updated"); + + return (EXIT_SUCCESS); +} + +static bool +grp_has_member(struct group *grp, const char *name) +{ + int j; + + for (j = 0; grp->gr_mem != NULL && grp->gr_mem[j] != NULL; j++) + if (strcmp(grp->gr_mem[j], name) == 0) + return (true); + return (false); +} + +static void +grp_add_members(struct group **grp, char *members) +{ + struct passwd *pwd; + char *p; + char tok[] = ", \t"; + + if (members == NULL) + return; + for (p = strtok(members, tok); p != NULL; p = strtok(NULL, tok)) { + pwd = lookup_pwent(p); + if (grp_has_member(*grp, pwd->pw_name)) + continue; + *grp = gr_add(*grp, pwd->pw_name); + } +} + +int +groupadd(struct userconf *cnf, char *name, gid_t id, char *members, int fd, + bool dryrun, bool pretty, bool precrypted) +{ + struct group *grp; + int rc; + + struct group fakegroup = { + "nogroup", + "*", + -1, + NULL + }; + + grp = &fakegroup; + grp->gr_name = pw_checkname(name, 0); + grp->gr_passwd = "*"; + grp->gr_gid = gr_gidpolicy(cnf, id); + grp->gr_mem = NULL; + + /* + * This allows us to set a group password Group passwords is an + * antique idea, rarely used and insecure (no secure database) Should + * be discouraged, but it is apparently still supported by some + * software. + */ + grp_set_passwd(grp, false, fd, precrypted); + grp_add_members(&grp, members); + if (dryrun) + return (print_group(grp, pretty)); + + if ((rc = addgrent(grp)) != 0) { + if (rc == -1) + errx(EX_IOERR, "group '%s' already exists", + grp->gr_name); + else + err(EX_IOERR, "group update"); + } + + pw_log(cnf, M_ADD, W_GROUP, "%s(%ju)", grp->gr_name, + (uintmax_t)grp->gr_gid); + + return (EXIT_SUCCESS); +} + +int +pw_group_add(int argc, char **argv, char *arg1) +{ + struct userconf *cnf = NULL; + char *name = NULL; + char *members = NULL; + const char *cfg = NULL; + intmax_t id = -1; + int ch, rc, fd = -1; + bool quiet, precrypted, dryrun, pretty, nis; + + quiet = precrypted = dryrun = pretty = nis = false; + + if (arg1 != NULL) { + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, GID_MAX); + else + name = arg1; + } + + while ((ch = getopt(argc, argv, "C:qn:g:h:H:M:oNPY")) != -1) { + switch (ch) { + case 'C': + cfg = optarg; + break; + case 'q': + quiet = true; + break; + case 'n': + name = optarg; + break; + case 'g': + id = pw_checkid(optarg, GID_MAX); + break; + case 'H': + if (fd != -1) + errx(EX_USAGE, "'-h' and '-H' are mutually " + "exclusive options"); + fd = pw_checkfd(optarg); + precrypted = true; + if (fd == '-') + errx(EX_USAGE, "-H expects a file descriptor"); + break; + case 'h': + if (fd != -1) + errx(EX_USAGE, "'-h' and '-H' are mutually " + "exclusive options"); + fd = pw_checkfd(optarg); + break; + case 'M': + members = optarg; + break; + case 'o': + conf.checkduplicate = false; + break; + case 'N': + dryrun = true; + break; + case 'P': + pretty = true; + break; + case 'Y': + nis = true; + break; + } + } + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + if (name == NULL) + errx(EX_DATAERR, "group name required"); + cnf = get_userconfig(cfg); + rc = groupadd(cnf, name, gr_gidpolicy(cnf, id), members, fd, dryrun, + pretty, precrypted); + if (nis && rc == EXIT_SUCCESS && nis_update() == 0) + pw_log(cnf, M_ADD, W_GROUP, "NIS maps updated"); + + return (rc); +} + +int +pw_group_mod(int argc, char **argv, char *arg1) +{ + struct userconf *cnf; + struct group *grp = NULL; + const char *cfg = NULL; + char *oldmembers = NULL; + char *members = NULL; + char *newmembers = NULL; + char *newname = NULL; + char *name = NULL; + intmax_t id = -1; + int ch, rc, fd = -1; + bool quiet, pretty, dryrun, nis, precrypted; + + quiet = pretty = dryrun = nis = precrypted = false; + + if (arg1 != NULL) { + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, GID_MAX); + else + name = arg1; + } + + while ((ch = getopt(argc, argv, "C:qn:d:g:l:h:H:M:m:NPY")) != -1) { + switch (ch) { + case 'C': + cfg = optarg; + break; + case 'q': + quiet = true; + break; + case 'n': + name = optarg; + break; + case 'g': + id = pw_checkid(optarg, GID_MAX); + break; + case 'd': + oldmembers = optarg; + break; + case 'l': + newname = optarg; + break; + case 'H': + if (fd != -1) + errx(EX_USAGE, "'-h' and '-H' are mutually " + "exclusive options"); + fd = pw_checkfd(optarg); + precrypted = true; + if (fd == '-') + errx(EX_USAGE, "-H expects a file descriptor"); + break; + case 'h': + if (fd != -1) + errx(EX_USAGE, "'-h' and '-H' are mutually " + "exclusive options"); + fd = pw_checkfd(optarg); + break; + case 'M': + members = optarg; + break; + case 'm': + newmembers = optarg; + break; + case 'N': + dryrun = true; + break; + case 'P': + pretty = true; + break; + case 'Y': + nis = true; + break; + } + } + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + cnf = get_userconfig(cfg); + grp = getgroup(name, id, true); + if (name == NULL) + name = grp->gr_name; + if (id > 0) + grp->gr_gid = id; + + if (newname != NULL) + grp->gr_name = pw_checkname(newname, 0); + + grp_set_passwd(grp, true, fd, precrypted); + /* + * Keep the same logic as old code for now: + * if -M is passed, -d and -m are ignored + * then id -d, -m is ignored + * last is -m + */ + + if (members) { + grp->gr_mem = NULL; + grp_add_members(&grp, members); + } else if (oldmembers) { + delete_members(grp, oldmembers); + } else if (newmembers) { + grp_add_members(&grp, newmembers); + } + + if ((rc = chggrent(name, grp)) != 0) { + if (rc == -1) + errx(EX_IOERR, "group '%s' not available (NIS?)", + grp->gr_name); + else + err(EX_IOERR, "group update"); + } + + if (newname) + name = newname; + + /* grp may have been invalidated */ + if ((grp = GETGRNAM(name)) == NULL) + errx(EX_SOFTWARE, "group disappeared during update"); + + pw_log(cnf, M_UPDATE, W_GROUP, "%s(%ju)", grp->gr_name, + (uintmax_t)grp->gr_gid); + + if (nis && nis_update() == 0) + pw_log(cnf, M_UPDATE, W_GROUP, "NIS maps updated"); + + return (EXIT_SUCCESS); } diff --git a/usr.sbin/pw/pw_nis.c b/usr.sbin/pw/pw_nis.c index c786cc7ba4dc..669783546505 100644 --- a/usr.sbin/pw/pw_nis.c +++ b/usr.sbin/pw/pw_nis.c @@ -43,6 +43,7 @@ pw_nisupdate(const char * path, struct passwd * pwd, char const * user) struct passwd *pw = NULL; struct passwd *old_pw = NULL; + printf("===> %s\n", path); if (pwd != NULL) pw = pw_dup(pwd); diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index eca8235f6e23..8ff4159108d8 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -52,42 +52,53 @@ static const char rcsid[] = static char locked_str[] = "*LOCKED*"; -static int pw_userdel(char *name, long id); -static int print_user(struct passwd * pwd); -static uid_t pw_uidpolicy(struct userconf * cnf, long id); -static uid_t pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer); -static time_t pw_pwdpolicy(struct userconf * cnf, struct cargs * args); -static time_t pw_exppolicy(struct userconf * cnf, struct cargs * args); -static char *pw_homepolicy(struct userconf * cnf, struct cargs * args, char const * user); -static char *pw_shellpolicy(struct userconf * cnf, struct cargs * args, char *newshell); -static char *pw_password(struct userconf * cnf, char const * user); -static char *shell_path(char const * path, char *shells[], char *sh); -static void rmat(uid_t uid); -static void rmopie(char const * name); +static struct passwd fakeuser = { + "nouser", + "*", + -1, + -1, + 0, + "", + "User &", + "/nonexistent", + "/bin/sh", + 0, + 0 +}; + +static int print_user(struct passwd *pwd, bool pretty, bool v7); +static uid_t pw_uidpolicy(struct userconf *cnf, intmax_t id); +static uid_t pw_gidpolicy(struct userconf *cnf, char *grname, char *nam, + gid_t prefer, bool dryrun); +static char *pw_homepolicy(struct userconf * cnf, char *homedir, + const char *user); +static char *pw_shellpolicy(struct userconf * cnf); +static char *pw_password(struct userconf * cnf, char const * user, + bool dryrun); +static char *shell_path(char const * path, char *shells[], char *sh); +static void rmat(uid_t uid); +static void rmopie(char const * name); static void -create_and_populate_homedir(struct passwd *pwd) +create_and_populate_homedir(struct userconf *cnf, struct passwd *pwd, + const char *skeldir, mode_t homemode, bool update) { - struct userconf *cnf = conf.userconf; - const char *skeldir; int skelfd = -1; - skeldir = cnf->dotdir; - if (skeldir != NULL && *skeldir != '\0') { if (*skeldir == '/') skeldir++; skelfd = openat(conf.rootfd, skeldir, O_DIRECTORY|O_CLOEXEC); } - copymkdir(conf.rootfd, pwd->pw_dir, skelfd, cnf->homemode, pwd->pw_uid, + copymkdir(conf.rootfd, pwd->pw_dir, skelfd, homemode, pwd->pw_uid, pwd->pw_gid, 0); - pw_log(cnf, M_ADD, W_USER, "%s(%ju) home %s made", pwd->pw_name, - (uintmax_t)pwd->pw_uid, pwd->pw_dir); + pw_log(cnf, update ? M_UPDATE : M_ADD, W_USER, "%s(%ju) home %s made", + pwd->pw_name, (uintmax_t)pwd->pw_uid, pwd->pw_dir); } static int -set_passwd(struct passwd *pwd, bool update) +pw_set_passwd(struct passwd *pwd, int fd, bool precrypted, bool update) { int b, istty; struct termios t, n; @@ -95,7 +106,7 @@ set_passwd(struct passwd *pwd, bool update) char line[_PASSWORD_LEN+1]; char *p; - if (conf.fd == '-') { + if (fd == '-') { if (!pwd->pw_passwd || *pwd->pw_passwd != '*') { pwd->pw_passwd = "*"; /* No access */ return (1); @@ -103,40 +114,40 @@ set_passwd(struct passwd *pwd, bool update) return (0); } - if ((istty = isatty(conf.fd))) { - if (tcgetattr(conf.fd, &t) == -1) + if ((istty = isatty(fd))) { + if (tcgetattr(fd, &t) == -1) istty = 0; else { n = t; n.c_lflag &= ~(ECHO); - tcsetattr(conf.fd, TCSANOW, &n); + tcsetattr(fd, TCSANOW, &n); printf("%s%spassword for user %s:", update ? "new " : "", - conf.precrypted ? "encrypted " : "", + precrypted ? "encrypted " : "", pwd->pw_name); fflush(stdout); } } - b = read(conf.fd, line, sizeof(line) - 1); + b = read(fd, line, sizeof(line) - 1); if (istty) { /* Restore state */ - tcsetattr(conf.fd, TCSANOW, &t); + tcsetattr(fd, TCSANOW, &t); fputc('\n', stdout); fflush(stdout); } if (b < 0) err(EX_IOERR, "-%c file descriptor", - conf.precrypted ? 'H' : 'h'); + precrypted ? 'H' : 'h'); line[b] = '\0'; if ((p = strpbrk(line, "\r\n")) != NULL) *p = '\0'; if (!*line) errx(EX_DATAERR, "empty password read on file descriptor %d", - conf.fd); - if (conf.precrypted) { + fd); + if (precrypted) { if (strchr(line, ':') != NULL) errx(EX_DATAERR, "bad encrypted password"); - pwd->pw_passwd = line; + pwd->pw_passwd = strdup(line); } else { lc = login_getpwclass(pwd); if (lc == NULL || @@ -148,54 +159,15 @@ set_passwd(struct passwd *pwd, bool update) return (1); } -int -pw_usernext(struct userconf *cnf, bool quiet) -{ - uid_t next = pw_uidpolicy(cnf, -1); - - if (quiet) - return (next); - - printf("%ju:", (uintmax_t)next); - pw_groupnext(cnf, quiet); - - return (EXIT_SUCCESS); -} - -static int -pw_usershow(char *name, long id, struct passwd *fakeuser) -{ - struct passwd *pwd = NULL; - - if (id < 0 && name == NULL && !conf.all) - errx(EX_DATAERR, "username or id or '-a' required"); - - if (conf.all) { - SETPWENT(); - while ((pwd = GETPWENT()) != NULL) - print_user(pwd); - ENDPWENT(); - return (EXIT_SUCCESS); - } - - pwd = (name != NULL) ? GETPWNAM(pw_checkname(name, 0)) : GETPWUID(id); - if (pwd == NULL) { - if (conf.force) { - pwd = fakeuser; - } else { - if (name == NULL) - errx(EX_NOUSER, "no such uid `%ld'", id); - errx(EX_NOUSER, "no such user `%s'", name); - } - } - - return (print_user(pwd)); -} - static void -perform_chgpwent(const char *name, struct passwd *pwd) +perform_chgpwent(const char *name, struct passwd *pwd, char *nispasswd) { int rc; + struct passwd *nispwd; + + /* duplicate for nis so that chgpwent is not modifying before NIS */ + if (nispasswd && *nispasswd == '/') + nispwd = pw_dup(pwd); rc = chgpwent(name, pwd); if (rc == -1) @@ -203,8 +175,8 @@ perform_chgpwent(const char *name, struct passwd *pwd) else if (rc != 0) err(EX_IOERR, "passwd file update"); - if (conf.userconf->nispasswd && *conf.userconf->nispasswd == '/') { - rc = chgnispwent(conf.userconf->nispasswd, name, pwd); + if (nispasswd && *nispasswd == '/') { + rc = chgnispwent(nispasswd, name, nispwd); if (rc == -1) warn("User '%s' not found in NIS passwd", pwd->pw_name); else if (rc != 0) @@ -223,19 +195,29 @@ perform_chgpwent(const char *name, struct passwd *pwd) * that is a known limitation. */ static int -pw_userlock(char *name, long id, int mode) +pw_userlock(char *arg1, int mode) { struct passwd *pwd = NULL; char *passtmp = NULL; + char *name; bool locked = false; + uid_t id; - if (id < 0 && name == NULL) + if (geteuid() != 0) + errx(EX_NOPERM, "you must be root"); + + if (arg1 == NULL) errx(EX_DATAERR, "username or id required"); + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, UID_MAX); + else + name = arg1; + pwd = (name != NULL) ? GETPWNAM(pw_checkname(name, 0)) : GETPWUID(id); if (pwd == NULL) { if (name == NULL) - errx(EX_NOUSER, "no such uid `%ld'", id); + errx(EX_NOUSER, "no such uid `%ju'", (uintmax_t) id); errx(EX_NOUSER, "no such user `%s'", name); } @@ -258,557 +240,17 @@ pw_userlock(char *name, long id, int mode) pwd->pw_passwd += sizeof(locked_str)-1; } - perform_chgpwent(name, pwd); + perform_chgpwent(name, pwd, NULL); free(passtmp); return (EXIT_SUCCESS); } -/*- - * -C config configuration file - * -q quiet operation - * -n name login name - * -u uid user id - * -c comment user name/comment - * -d directory home directory - * -e date account expiry date - * -p date password expiry date - * -g grp primary group - * -G grp1,grp2 additional groups - * -m [ -k dir ] create and set up home - * -s shell name of login shell - * -o duplicate uid ok - * -L class user class - * -l name new login name - * -h fd password filehandle - * -H fd encrypted password filehandle - * -F force print or add - * Setting defaults: - * -D set user defaults - * -b dir default home root dir - * -e period default expiry period - * -p period default password change period - * -g group default group - * -G grp1,grp2.. default additional groups - * -L class default login class - * -k dir default home skeleton - * -s shell default shell - * -w method default password method - */ - -int -pw_user(int mode, char *name, long id, struct cargs * args) -{ - int rc, edited = 0; - char *p = NULL; - struct carg *arg; - struct passwd *pwd = NULL; - struct group *grp; - struct stat st; - struct userconf *cnf; - char line[_PASSWORD_LEN+1]; - char path[MAXPATHLEN]; - FILE *fp; - char *dmode_c; - void *set = NULL; - int valid_type = _PWF_FILES; - - static struct passwd fakeuser = - { - "nouser", - "*", - -1, - -1, - 0, - "", - "User &", - "/nonexistent", - "/bin/sh", - 0 -#if defined(__FreeBSD__) - ,0 -#endif - }; - - cnf = conf.userconf; - - if (mode == M_NEXT) - return (pw_usernext(cnf, conf.quiet)); - - if (mode == M_PRINT) - return (pw_usershow(name, id, &fakeuser)); - - if (mode == M_DELETE) - return (pw_userdel(name, id)); - - if (mode == M_LOCK || mode == M_UNLOCK) - return (pw_userlock(name, id, mode)); - - /* - * We can do all of the common legwork here - */ - - if ((arg = getarg(args, 'b')) != NULL) { - cnf->home = arg->val; - } - - if ((arg = getarg(args, 'M')) != NULL) { - dmode_c = arg->val; - if ((set = setmode(dmode_c)) == NULL) - errx(EX_DATAERR, "invalid directory creation mode '%s'", - dmode_c); - cnf->homemode = getmode(set, _DEF_DIRMODE); - free(set); - } - - /* - * If we'll need to use it or we're updating it, - * then create the base home directory if necessary - */ - if (arg != NULL || getarg(args, 'm') != NULL) { - int l = strlen(cnf->home); - - if (l > 1 && cnf->home[l-1] == '/') /* Shave off any trailing path delimiter */ - cnf->home[--l] = '\0'; - - if (l < 2 || *cnf->home != '/') /* Check for absolute path name */ - errx(EX_DATAERR, "invalid base directory for home '%s'", cnf->home); - - if (stat(cnf->home, &st) == -1) { - char dbuf[MAXPATHLEN]; - - /* - * This is a kludge especially for Joerg :) - * If the home directory would be created in the root partition, then - * we really create it under /usr which is likely to have more space. - * But we create a symlink from cnf->home -> "/usr" -> cnf->home - */ - if (strchr(cnf->home+1, '/') == NULL) { - snprintf(dbuf, MAXPATHLEN, "/usr%s", cnf->home); - if (mkdir(dbuf, _DEF_DIRMODE) != -1 || errno == EEXIST) { - chown(dbuf, 0, 0); - /* - * Skip first "/" and create symlink: - * /home -> usr/home - */ - symlink(dbuf+1, cnf->home); - } - /* If this falls, fall back to old method */ - } - strlcpy(dbuf, cnf->home, sizeof(dbuf)); - p = dbuf; - if (stat(dbuf, &st) == -1) { - while ((p = strchr(p + 1, '/')) != NULL) { - *p = '\0'; - if (stat(dbuf, &st) == -1) { - if (mkdir(dbuf, _DEF_DIRMODE) == -1) - err(EX_OSFILE, "mkdir '%s'", dbuf); - chown(dbuf, 0, 0); - } else if (!S_ISDIR(st.st_mode)) - errx(EX_OSFILE, "'%s' (root home parent) is not a directory", dbuf); - *p = '/'; - } - } - if (stat(dbuf, &st) == -1) { - if (mkdir(dbuf, _DEF_DIRMODE) == -1) - err(EX_OSFILE, "mkdir '%s'", dbuf); - chown(dbuf, 0, 0); - } - } else if (!S_ISDIR(st.st_mode)) - errx(EX_OSFILE, "root home `%s' is not a directory", cnf->home); - } - - if ((arg = getarg(args, 'e')) != NULL) - cnf->expire_days = atoi(arg->val); - - if ((arg = getarg(args, 'y')) != NULL) - cnf->nispasswd = arg->val; - - if ((arg = getarg(args, 'p')) != NULL && arg->val) - cnf->password_days = atoi(arg->val); - - if ((arg = getarg(args, 'g')) != NULL) { - if (!*(p = arg->val)) /* Handle empty group list specially */ - cnf->default_group = ""; - else { - if ((grp = GETGRNAM(p)) == NULL) { - if (!isdigit((unsigned char)*p) || (grp = GETGRGID((gid_t) atoi(p))) == NULL) - errx(EX_NOUSER, "group `%s' does not exist", p); - } - cnf->default_group = newstr(grp->gr_name); - } - } - if ((arg = getarg(args, 'L')) != NULL) - cnf->default_class = pw_checkname(arg->val, 0); - - if ((arg = getarg(args, 'G')) != NULL && arg->val) { - for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) { - if ((grp = GETGRNAM(p)) == NULL) { - if (!isdigit((unsigned char)*p) || (grp = GETGRGID((gid_t) atoi(p))) == NULL) - errx(EX_NOUSER, "group `%s' does not exist", p); - } - sl_add(cnf->groups, newstr(grp->gr_name)); - } - } - - if ((arg = getarg(args, 'k')) != NULL) { - char *tmp = cnf->dotdir = arg->val; - if (*tmp == '/') - tmp++; - if ((fstatat(conf.rootfd, tmp, &st, 0) == -1) || - !S_ISDIR(st.st_mode)) - errx(EX_OSFILE, "skeleton `%s' is not a directory or " - "does not exist", cnf->dotdir); - } - - if ((arg = getarg(args, 's')) != NULL) - cnf->shell_default = arg->val; - - if ((arg = getarg(args, 'w')) != NULL) - cnf->default_password = boolean_val(arg->val, cnf->default_password); - if (mode == M_ADD && getarg(args, 'D')) { - if (name != NULL) - errx(EX_DATAERR, "can't combine `-D' with `-n name'"); - if ((arg = getarg(args, 'u')) != NULL && (p = strtok(arg->val, ", \t")) != NULL) { - if ((cnf->min_uid = (uid_t) atoi(p)) == 0) - cnf->min_uid = 1000; - if ((p = strtok(NULL, " ,\t")) == NULL || (cnf->max_uid = (uid_t) atoi(p)) < cnf->min_uid) - cnf->max_uid = 32000; - } - if ((arg = getarg(args, 'i')) != NULL && (p = strtok(arg->val, ", \t")) != NULL) { - if ((cnf->min_gid = (gid_t) atoi(p)) == 0) - cnf->min_gid = 1000; - if ((p = strtok(NULL, " ,\t")) == NULL || (cnf->max_gid = (gid_t) atoi(p)) < cnf->min_gid) - cnf->max_gid = 32000; - } - - if (write_userconfig(conf.config)) - return (EXIT_SUCCESS); - err(EX_IOERR, "config udpate"); - } - - if (name != NULL) - pwd = GETPWNAM(pw_checkname(name, 0)); - - if (id < 0 && name == NULL) - errx(EX_DATAERR, "user name or id required"); - - /* - * Update require that the user exists - */ - if (mode == M_UPDATE) { - - if (name == NULL && pwd == NULL) /* Try harder */ - pwd = GETPWUID(id); - - if (pwd == NULL) { - if (name == NULL) - errx(EX_NOUSER, "no such uid `%ld'", id); - errx(EX_NOUSER, "no such user `%s'", name); - } - - if (conf.userconf->nispasswd && *conf.userconf->nispasswd == '/') - valid_type = _PWF_NIS; - - if (PWF._altdir == PWF_REGULAR && - ((pwd->pw_fields & _PWF_SOURCE) != valid_type)) - errx(EX_NOUSER, "no such %s user `%s'", - valid_type == _PWF_FILES ? "local" : "NIS" , name); - - if (name == NULL) - name = pwd->pw_name; - - /* - * The rest is edit code - */ - if (conf.newname != NULL) { - if (strcmp(pwd->pw_name, "root") == 0) - errx(EX_DATAERR, "can't rename `root' account"); - pwd->pw_name = pw_checkname(conf.newname, 0); - edited = 1; - } - - if (id > 0 && isdigit((unsigned char)*arg->val)) { - pwd->pw_uid = (uid_t)id; - edited = 1; - if (pwd->pw_uid != 0 && strcmp(pwd->pw_name, "root") == 0) - errx(EX_DATAERR, "can't change uid of `root' account"); - if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0) - warnx("WARNING: account `%s' will have a uid of 0 (superuser access!)", pwd->pw_name); - } - - if ((arg = getarg(args, 'g')) != NULL && pwd->pw_uid != 0) { /* Already checked this */ - gid_t newgid = (gid_t) GETGRNAM(cnf->default_group)->gr_gid; - if (newgid != pwd->pw_gid) { - edited = 1; - pwd->pw_gid = newgid; - } - } - - if ((arg = getarg(args, 'p')) != NULL) { - if (*arg->val == '\0' || strcmp(arg->val, "0") == 0) { - if (pwd->pw_change != 0) { - pwd->pw_change = 0; - edited = 1; - } - } - else { - time_t now = time(NULL); - time_t expire = parse_date(now, arg->val); - - if (pwd->pw_change != expire) { - pwd->pw_change = expire; - edited = 1; - } - } - } - - if ((arg = getarg(args, 'e')) != NULL) { - if (*arg->val == '\0' || strcmp(arg->val, "0") == 0) { - if (pwd->pw_expire != 0) { - pwd->pw_expire = 0; - edited = 1; - } - } - else { - time_t now = time(NULL); - time_t expire = parse_date(now, arg->val); - - if (pwd->pw_expire != expire) { - pwd->pw_expire = expire; - edited = 1; - } - } - } - - if ((arg = getarg(args, 's')) != NULL) { - char *shell = shell_path(cnf->shelldir, cnf->shells, arg->val); - if (shell == NULL) - shell = ""; - if (strcmp(shell, pwd->pw_shell) != 0) { - pwd->pw_shell = shell; - edited = 1; - } - } - - if (getarg(args, 'L')) { - if (cnf->default_class == NULL) - cnf->default_class = ""; - if (strcmp(pwd->pw_class, cnf->default_class) != 0) { - pwd->pw_class = cnf->default_class; - edited = 1; - } - } - - if ((arg = getarg(args, 'd')) != NULL) { - if (strcmp(pwd->pw_dir, arg->val)) - edited = 1; - if (stat(pwd->pw_dir = arg->val, &st) == -1) { - if (getarg(args, 'm') == NULL && strcmp(pwd->pw_dir, "/nonexistent") != 0) - warnx("WARNING: home `%s' does not exist", pwd->pw_dir); - } else if (!S_ISDIR(st.st_mode)) - warnx("WARNING: home `%s' is not a directory", pwd->pw_dir); - } - - if ((arg = getarg(args, 'w')) != NULL && conf.fd == -1) { - login_cap_t *lc; - - lc = login_getpwclass(pwd); - if (lc == NULL || - login_setcryptfmt(lc, "sha512", NULL) == NULL) - warn("setting crypt(3) format"); - login_close(lc); - pwd->pw_passwd = pw_password(cnf, pwd->pw_name); - edited = 1; - } - - } else { - login_cap_t *lc; - - /* - * Add code - */ - - if (name == NULL) /* Required */ - errx(EX_DATAERR, "login name required"); - else if ((pwd = GETPWNAM(name)) != NULL) /* Exists */ - errx(EX_DATAERR, "login name `%s' already exists", name); - - /* - * Now, set up defaults for a new user - */ - pwd = &fakeuser; - pwd->pw_name = name; - pwd->pw_class = cnf->default_class ? cnf->default_class : ""; - pwd->pw_uid = pw_uidpolicy(cnf, id); - pwd->pw_gid = pw_gidpolicy(args, pwd->pw_name, (gid_t) pwd->pw_uid); - pwd->pw_change = pw_pwdpolicy(cnf, args); - pwd->pw_expire = pw_exppolicy(cnf, args); - pwd->pw_dir = pw_homepolicy(cnf, args, pwd->pw_name); - pwd->pw_shell = pw_shellpolicy(cnf, args, NULL); - lc = login_getpwclass(pwd); - if (lc == NULL || login_setcryptfmt(lc, "sha512", NULL) == NULL) - warn("setting crypt(3) format"); - login_close(lc); - pwd->pw_passwd = pw_password(cnf, pwd->pw_name); - edited = 1; - - if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0) - warnx("WARNING: new account `%s' has a uid of 0 (superuser access!)", pwd->pw_name); - } - - /* - * Shared add/edit code - */ - if (conf.gecos != NULL) { - if (strcmp(pwd->pw_gecos, conf.gecos) != 0) { - pwd->pw_gecos = conf.gecos; - edited = 1; - } - } - - if (conf.fd != -1) - edited = set_passwd(pwd, mode == M_UPDATE); - - /* - * Special case: -N only displays & exits - */ - if (conf.dryrun) - return print_user(pwd); - - if (mode == M_ADD) { - edited = 1; /* Always */ - rc = addpwent(pwd); - if (rc == -1) - errx(EX_IOERR, "user '%s' already exists", - pwd->pw_name); - else if (rc != 0) - err(EX_IOERR, "passwd file update"); - if (cnf->nispasswd && *cnf->nispasswd=='/') { - rc = addnispwent(cnf->nispasswd, pwd); - if (rc == -1) - warnx("User '%s' already exists in NIS passwd", pwd->pw_name); - else if (rc != 0) - warn("NIS passwd update"); - /* NOTE: we treat NIS-only update errors as non-fatal */ - } - } else if (mode == M_UPDATE && edited) /* Only updated this if required */ - perform_chgpwent(name, pwd); - - /* - * Ok, user is created or changed - now edit group file - */ - - if (mode == M_ADD || getarg(args, 'G') != NULL) { - int j; - size_t i; - /* First remove the user from all group */ - SETGRENT(); - while ((grp = GETGRENT()) != NULL) { - char group[MAXLOGNAME]; - if (grp->gr_mem == NULL) - continue; - for (i = 0; grp->gr_mem[i] != NULL; i++) { - if (strcmp(grp->gr_mem[i] , pwd->pw_name) != 0) - continue; - for (j = i; grp->gr_mem[j] != NULL ; j++) - grp->gr_mem[j] = grp->gr_mem[j+1]; - strlcpy(group, grp->gr_name, MAXLOGNAME); - chggrent(group, grp); - } - } - ENDGRENT(); - - /* now add to group where needed */ - for (i = 0; i < cnf->groups->sl_cur; i++) { - grp = GETGRNAM(cnf->groups->sl_str[i]); - grp = gr_add(grp, pwd->pw_name); - /* - * grp can only be NULL in 2 cases: - * - the new member is already a member - * - a problem with memory occurs - * in both cases we want to skip now. - */ - if (grp == NULL) - continue; - chggrent(grp->gr_name, grp); - free(grp); - } - } - - - /* go get a current version of pwd */ - pwd = GETPWNAM(name); - if (pwd == NULL) { - /* This will fail when we rename, so special case that */ - if (mode == M_UPDATE && conf.newname != NULL) { - name = conf.newname; /* update new name */ - pwd = GETPWNAM(name); /* refetch renamed rec */ - } - } - if (pwd == NULL) /* can't go on without this */ - errx(EX_NOUSER, "user '%s' disappeared during update", name); - - grp = GETGRGID(pwd->pw_gid); - pw_log(cnf, mode, W_USER, "%s(%ju):%s(%ju):%s:%s:%s", - pwd->pw_name, (uintmax_t)pwd->pw_uid, - grp ? grp->gr_name : "unknown", (uintmax_t)(grp ? grp->gr_gid : (uid_t)-1), - pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); - - /* - * If adding, let's touch and chown the user's mail file. This is not - * strictly necessary under BSD with a 0755 maildir but it also - * doesn't hurt anything to create the empty mailfile - */ - if (mode == M_ADD) { - if (PWALTDIR() != PWF_ALT) { - snprintf(path, sizeof(path), "%s/%s", _PATH_MAILDIR, - pwd->pw_name); - close(openat(conf.rootfd, path +1, O_RDWR | O_CREAT, - 0600)); /* Preserve contents & mtime */ - fchownat(conf.rootfd, path + 1, pwd->pw_uid, - pwd->pw_gid, AT_SYMLINK_NOFOLLOW); - } - } - - /* - * Let's create and populate the user's home directory. Note - * that this also `works' for editing users if -m is used, but - * existing files will *not* be overwritten. - */ - if (PWALTDIR() != PWF_ALT && getarg(args, 'm') != NULL && pwd->pw_dir && - *pwd->pw_dir == '/' && pwd->pw_dir[1]) - create_and_populate_homedir(pwd); - - /* - * Finally, send mail to the new user as well, if we are asked to - */ - if (mode == M_ADD && !PWALTDIR() && cnf->newmail && *cnf->newmail && (fp = fopen(cnf->newmail, "r")) != NULL) { - FILE *pfp = popen(_PATH_SENDMAIL " -t", "w"); - - if (pfp == NULL) - warn("sendmail"); - else { - fprintf(pfp, "From: root\n" "To: %s\n" "Subject: Welcome!\n\n", pwd->pw_name); - while (fgets(line, sizeof(line), fp) != NULL) { - /* Do substitutions? */ - fputs(line, pfp); - } - pclose(pfp); - pw_log(cnf, mode, W_USER, "%s(%ju) new user mail sent", - pwd->pw_name, (uintmax_t)pwd->pw_uid); - } - fclose(fp); - } - - return EXIT_SUCCESS; -} - - -static uid_t -pw_uidpolicy(struct userconf * cnf, long id) +static uid_t +pw_uidpolicy(struct userconf * cnf, intmax_t id) { struct passwd *pwd; + struct bitmap bm; uid_t uid = (uid_t) - 1; /* @@ -820,77 +262,65 @@ pw_uidpolicy(struct userconf * cnf, long id) if ((pwd = GETPWUID(uid)) != NULL && conf.checkduplicate) errx(EX_DATAERR, "uid `%ju' has already been allocated", (uintmax_t)pwd->pw_uid); - } else { - struct bitmap bm; - - /* - * We need to allocate the next available uid under one of - * two policies a) Grab the first unused uid b) Grab the - * highest possible unused uid - */ - if (cnf->min_uid >= cnf->max_uid) { /* Sanity - * claus^H^H^H^Hheck */ - cnf->min_uid = 1000; - cnf->max_uid = 32000; - } - bm = bm_alloc(cnf->max_uid - cnf->min_uid + 1); - - /* - * Now, let's fill the bitmap from the password file - */ - SETPWENT(); - while ((pwd = GETPWENT()) != NULL) - if (pwd->pw_uid >= (uid_t) cnf->min_uid && pwd->pw_uid <= (uid_t) cnf->max_uid) - bm_setbit(&bm, pwd->pw_uid - cnf->min_uid); - ENDPWENT(); - - /* - * Then apply the policy, with fallback to reuse if necessary - */ - if (cnf->reuse_uids || (uid = (uid_t) (bm_lastset(&bm) + cnf->min_uid + 1)) > cnf->max_uid) - uid = (uid_t) (bm_firstunset(&bm) + cnf->min_uid); - - /* - * Another sanity check - */ - if (uid < cnf->min_uid || uid > cnf->max_uid) - errx(EX_SOFTWARE, "unable to allocate a new uid - range fully used"); - bm_dealloc(&bm); + return (uid); } - return uid; + /* + * We need to allocate the next available uid under one of + * two policies a) Grab the first unused uid b) Grab the + * highest possible unused uid + */ + if (cnf->min_uid >= cnf->max_uid) { /* Sanity + * claus^H^H^H^Hheck */ + cnf->min_uid = 1000; + cnf->max_uid = 32000; + } + bm = bm_alloc(cnf->max_uid - cnf->min_uid + 1); + + /* + * Now, let's fill the bitmap from the password file + */ + SETPWENT(); + while ((pwd = GETPWENT()) != NULL) + if (pwd->pw_uid >= (uid_t) cnf->min_uid && pwd->pw_uid <= (uid_t) cnf->max_uid) + bm_setbit(&bm, pwd->pw_uid - cnf->min_uid); + ENDPWENT(); + + /* + * Then apply the policy, with fallback to reuse if necessary + */ + if (cnf->reuse_uids || (uid = (uid_t) (bm_lastset(&bm) + cnf->min_uid + 1)) > cnf->max_uid) + uid = (uid_t) (bm_firstunset(&bm) + cnf->min_uid); + + /* + * Another sanity check + */ + if (uid < cnf->min_uid || uid > cnf->max_uid) + errx(EX_SOFTWARE, "unable to allocate a new uid - range fully used"); + bm_dealloc(&bm); + return (uid); } - -static uid_t -pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer) +static uid_t +pw_gidpolicy(struct userconf *cnf, char *grname, char *nam, gid_t prefer, bool dryrun) { struct group *grp; gid_t gid = (uid_t) - 1; - struct carg *a_gid = getarg(args, 'g'); - struct userconf *cnf = conf.userconf; - - /* - * If no arg given, see if default can help out - */ - if (a_gid == NULL && cnf->default_group && *cnf->default_group) - a_gid = addarg(args, 'g', cnf->default_group); /* * Check the given gid, if any */ SETGRENT(); - if (a_gid != NULL) { - if ((grp = GETGRNAM(a_gid->val)) == NULL) { - gid = (gid_t) atol(a_gid->val); - if ((gid == 0 && !isdigit((unsigned char)*a_gid->val)) || (grp = GETGRGID(gid)) == NULL) - errx(EX_NOUSER, "group `%s' is not defined", a_gid->val); + if (grname) { + if ((grp = GETGRNAM(grname)) == NULL) { + gid = pw_checkid(grname, GID_MAX); + grp = GETGRGID(gid); } gid = grp->gr_gid; } else if ((grp = GETGRNAM(nam)) != NULL && (grp->gr_mem == NULL || grp->gr_mem[0] == NULL)) { gid = grp->gr_gid; /* Already created? Use it anyway... */ } else { - gid_t grid = -1; + intmax_t grid = -1; /* * We need to auto-create a group with the user's name. We @@ -903,59 +333,27 @@ pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer) */ if (GETGRGID(prefer) == NULL) grid = prefer; - if (conf.dryrun) { + if (dryrun) { gid = pw_groupnext(cnf, true); } else { - pw_group(M_ADD, nam, grid, NULL); + if (grid == -1) + grid = pw_groupnext(cnf, true); + groupadd(cnf, nam, grid, NULL, -1, false, false, false); if ((grp = GETGRNAM(nam)) != NULL) gid = grp->gr_gid; } } ENDGRENT(); - return gid; + return (gid); } - -static time_t -pw_pwdpolicy(struct userconf * cnf, struct cargs * args) +static char * +pw_homepolicy(struct userconf * cnf, char *homedir, const char *user) { - time_t result = 0; - time_t now = time(NULL); - struct carg *arg = getarg(args, 'p'); - - if (arg != NULL) { - if ((result = parse_date(now, arg->val)) == now) - errx(EX_DATAERR, "invalid date/time `%s'", arg->val); - } else if (cnf->password_days > 0) - result = now + ((long) cnf->password_days * 86400L); - return result; -} - - -static time_t -pw_exppolicy(struct userconf * cnf, struct cargs * args) -{ - time_t result = 0; - time_t now = time(NULL); - struct carg *arg = getarg(args, 'e'); - - if (arg != NULL) { - if ((result = parse_date(now, arg->val)) == now) - errx(EX_DATAERR, "invalid date/time `%s'", arg->val); - } else if (cnf->expire_days > 0) - result = now + ((long) cnf->expire_days * 86400L); - return result; -} - - -static char * -pw_homepolicy(struct userconf * cnf, struct cargs * args, char const * user) -{ - struct carg *arg = getarg(args, 'd'); static char home[128]; - if (arg) - return (arg->val); + if (homedir) + return (homedir); if (cnf->home == NULL || *cnf->home == '\0') errx(EX_CONFIG, "no base home directory set"); @@ -964,7 +362,7 @@ pw_homepolicy(struct userconf * cnf, struct cargs * args, char const * user) return (home); } -static char * +static char * shell_path(char const * path, char *shells[], char *sh) { if (sh != NULL && (*sh == '/' || *sh == '\0')) @@ -999,29 +397,23 @@ shell_path(char const * path, char *shells[], char *sh) } } - -static char * -pw_shellpolicy(struct userconf * cnf, struct cargs * args, char *newshell) +static char * +pw_shellpolicy(struct userconf * cnf) { - char *sh = newshell; - struct carg *arg = getarg(args, 's'); - if (newshell == NULL && arg != NULL) - sh = arg->val; - return shell_path(cnf->shelldir, cnf->shells, sh ? sh : cnf->shell_default); + return shell_path(cnf->shelldir, cnf->shells, cnf->shell_default); } #define SALTSIZE 32 static char const chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./"; -char * +char * pw_pwcrypt(char *password) { int i; char salt[SALTSIZE + 1]; char *cryptpw; - static char buf[256]; /* @@ -1037,9 +429,8 @@ pw_pwcrypt(char *password) return strcpy(buf, cryptpw); } - -static char * -pw_password(struct userconf * cnf, char const * user) +static char * +pw_password(struct userconf * cnf, char const * user, bool dryrun) { int i, l; char pwbuf[32]; @@ -1054,7 +445,7 @@ pw_password(struct userconf * cnf, char const * user) /* * We give this information back to the user */ - if (conf.fd == -1 && !conf.dryrun) { + if (conf.fd == -1 && !dryrun) { if (isatty(STDOUT_FILENO)) printf("Password for '%s' is: ", user); printf("%s\n", pwbuf); @@ -1077,213 +468,80 @@ pw_password(struct userconf * cnf, char const * user) } static int -pw_userdel(char *name, long id) +print_user(struct passwd * pwd, bool pretty, bool v7) { - struct passwd *pwd = NULL; - char file[MAXPATHLEN]; - char home[MAXPATHLEN]; - uid_t uid; - struct group *gr, *grp; - char grname[LOGNAMESIZE]; - int rc; - struct stat st; - int valid_type = _PWF_FILES; + int j; + char *p; + struct group *grp = GETGRGID(pwd->pw_gid); + char uname[60] = "User &", office[60] = "[None]", + wphone[60] = "[None]", hphone[60] = "[None]"; + char acexpire[32] = "[None]", pwexpire[32] = "[None]"; + struct tm * tptr; - if (id < 0 && name == NULL) - errx(EX_DATAERR, "username or id required"); - - pwd = (name != NULL) ? GETPWNAM(pw_checkname(name, 0)) : GETPWUID(id); - if (pwd == NULL) { - if (name == NULL) - errx(EX_NOUSER, "no such uid `%ld'", id); - errx(EX_NOUSER, "no such user `%s'", name); + if (!pretty) { + p = v7 ? pw_make_v7(pwd) : pw_make(pwd); + printf("%s\n", p); + free(p); + return (EXIT_SUCCESS); } - if (conf.userconf->nispasswd && *conf.userconf->nispasswd == '/') - valid_type = _PWF_NIS; - - if (PWF._altdir == PWF_REGULAR && - ((pwd->pw_fields & _PWF_SOURCE) != valid_type)) - errx(EX_NOUSER, "no such %s user `%s'", - valid_type == _PWF_FILES ? "local" : "NIS" , name); - - uid = pwd->pw_uid; - if (name == NULL) - name = pwd->pw_name; - - if (strcmp(pwd->pw_name, "root") == 0) - errx(EX_DATAERR, "cannot remove user 'root'"); - - /* Remove opie record from /etc/opiekeys */ - - if (PWALTDIR() != PWF_ALT) - rmopie(pwd->pw_name); - - if (!PWALTDIR()) { - /* Remove crontabs */ - snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name); - if (access(file, F_OK) == 0) { - snprintf(file, sizeof(file), "crontab -u %s -r", pwd->pw_name); - system(file); + if ((p = strtok(pwd->pw_gecos, ",")) != NULL) { + strlcpy(uname, p, sizeof(uname)); + if ((p = strtok(NULL, ",")) != NULL) { + strlcpy(office, p, sizeof(office)); + if ((p = strtok(NULL, ",")) != NULL) { + strlcpy(wphone, p, sizeof(wphone)); + if ((p = strtok(NULL, "")) != NULL) { + strlcpy(hphone, p, sizeof(hphone)); + } + } } } /* - * Save these for later, since contents of pwd may be - * invalidated by deletion + * Handle '&' in gecos field */ - snprintf(file, sizeof(file), "%s/%s", _PATH_MAILDIR, pwd->pw_name); - strlcpy(home, pwd->pw_dir, sizeof(home)); - gr = GETGRGID(pwd->pw_gid); - if (gr != NULL) - strlcpy(grname, gr->gr_name, LOGNAMESIZE); - else - grname[0] = '\0'; + if ((p = strchr(uname, '&')) != NULL) { + int l = strlen(pwd->pw_name); + int m = strlen(p); - rc = delpwent(pwd); - if (rc == -1) - err(EX_IOERR, "user '%s' does not exist", pwd->pw_name); - else if (rc != 0) - err(EX_IOERR, "passwd update"); - - if (conf.userconf->nispasswd && *conf.userconf->nispasswd=='/') { - rc = delnispwent(conf.userconf->nispasswd, name); - if (rc == -1) - warnx("WARNING: user '%s' does not exist in NIS passwd", - pwd->pw_name); - else if (rc != 0) - warn("WARNING: NIS passwd update"); - /* non-fatal */ + memmove(p + l, p + 1, m); + memmove(p, pwd->pw_name, l); + *p = (char) toupper((unsigned char)*p); } - - grp = GETGRNAM(name); - if (grp != NULL && - (grp->gr_mem == NULL || *grp->gr_mem == NULL) && - strcmp(name, grname) == 0) - delgrent(GETGRNAM(name)); - SETGRENT(); - while ((grp = GETGRENT()) != NULL) { - int i, j; - char group[MAXLOGNAME]; - if (grp->gr_mem == NULL) - continue; - - for (i = 0; grp->gr_mem[i] != NULL; i++) { - if (strcmp(grp->gr_mem[i], name) != 0) - continue; - - for (j = i; grp->gr_mem[j] != NULL; j++) - grp->gr_mem[j] = grp->gr_mem[j+1]; - strlcpy(group, grp->gr_name, MAXLOGNAME); - chggrent(group, grp); + if (pwd->pw_expire > (time_t)0 && (tptr = localtime(&pwd->pw_expire)) != NULL) + strftime(acexpire, sizeof acexpire, "%c", tptr); + if (pwd->pw_change > (time_t)0 && (tptr = localtime(&pwd->pw_change)) != NULL) + strftime(pwexpire, sizeof pwexpire, "%c", tptr); + printf("Login Name: %-15s #%-12ju Group: %-15s #%ju\n" + " Full Name: %s\n" + " Home: %-26.26s Class: %s\n" + " Shell: %-26.26s Office: %s\n" + "Work Phone: %-26.26s Home Phone: %s\n" + "Acc Expire: %-26.26s Pwd Expire: %s\n", + pwd->pw_name, (uintmax_t)pwd->pw_uid, + grp ? grp->gr_name : "(invalid)", (uintmax_t)pwd->pw_gid, + uname, pwd->pw_dir, pwd->pw_class, + pwd->pw_shell, office, wphone, hphone, + acexpire, pwexpire); + SETGRENT(); + j = 0; + while ((grp=GETGRENT()) != NULL) { + int i = 0; + if (grp->gr_mem != NULL) { + while (grp->gr_mem[i] != NULL) { + if (strcmp(grp->gr_mem[i], pwd->pw_name)==0) { + printf(j++ == 0 ? " Groups: %s" : ",%s", grp->gr_name); + break; + } + ++i; + } } } ENDGRENT(); - - pw_log(conf.userconf, M_DELETE, W_USER, "%s(%ju) account removed", name, - (uintmax_t)uid); - - /* Remove mail file */ - if (PWALTDIR() != PWF_ALT) - unlinkat(conf.rootfd, file + 1, 0); - - /* Remove at jobs */ - if (!PWALTDIR() && getpwuid(uid) == NULL) - rmat(uid); - - /* Remove home directory and contents */ - if (PWALTDIR() != PWF_ALT && conf.deletehome && *home == '/' && - getpwuid(uid) == NULL && - fstatat(conf.rootfd, home + 1, &st, 0) != -1) { - rm_r(conf.rootfd, home, uid); - pw_log(conf.userconf, M_DELETE, W_USER, "%s(%ju) home '%s' %s" - "removed", name, (uintmax_t)uid, home, - fstatat(conf.rootfd, home + 1, &st, 0) == -1 ? "" : "not " - "completely "); - } - + printf("%s", j ? "\n" : ""); return (EXIT_SUCCESS); } -static int -print_user(struct passwd * pwd) -{ - if (!conf.pretty) { - char *buf; - - buf = conf.v7 ? pw_make_v7(pwd) : pw_make(pwd); - printf("%s\n", buf); - free(buf); - } else { - int j; - char *p; - struct group *grp = GETGRGID(pwd->pw_gid); - char uname[60] = "User &", office[60] = "[None]", - wphone[60] = "[None]", hphone[60] = "[None]"; - char acexpire[32] = "[None]", pwexpire[32] = "[None]"; - struct tm * tptr; - - if ((p = strtok(pwd->pw_gecos, ",")) != NULL) { - strlcpy(uname, p, sizeof(uname)); - if ((p = strtok(NULL, ",")) != NULL) { - strlcpy(office, p, sizeof(office)); - if ((p = strtok(NULL, ",")) != NULL) { - strlcpy(wphone, p, sizeof(wphone)); - if ((p = strtok(NULL, "")) != NULL) { - strlcpy(hphone, p, - sizeof(hphone)); - } - } - } - } - /* - * Handle '&' in gecos field - */ - if ((p = strchr(uname, '&')) != NULL) { - int l = strlen(pwd->pw_name); - int m = strlen(p); - - memmove(p + l, p + 1, m); - memmove(p, pwd->pw_name, l); - *p = (char) toupper((unsigned char)*p); - } - if (pwd->pw_expire > (time_t)0 && (tptr = localtime(&pwd->pw_expire)) != NULL) - strftime(acexpire, sizeof acexpire, "%c", tptr); - if (pwd->pw_change > (time_t)0 && (tptr = localtime(&pwd->pw_change)) != NULL) - strftime(pwexpire, sizeof pwexpire, "%c", tptr); - printf("Login Name: %-15s #%-12ju Group: %-15s #%ju\n" - " Full Name: %s\n" - " Home: %-26.26s Class: %s\n" - " Shell: %-26.26s Office: %s\n" - "Work Phone: %-26.26s Home Phone: %s\n" - "Acc Expire: %-26.26s Pwd Expire: %s\n", - pwd->pw_name, (uintmax_t)pwd->pw_uid, - grp ? grp->gr_name : "(invalid)", (uintmax_t)pwd->pw_gid, - uname, pwd->pw_dir, pwd->pw_class, - pwd->pw_shell, office, wphone, hphone, - acexpire, pwexpire); - SETGRENT(); - j = 0; - while ((grp=GETGRENT()) != NULL) - { - int i = 0; - if (grp->gr_mem != NULL) { - while (grp->gr_mem[i] != NULL) - { - if (strcmp(grp->gr_mem[i], pwd->pw_name)==0) - { - printf(j++ == 0 ? " Groups: %s" : ",%s", grp->gr_name); - break; - } - ++i; - } - } - } - ENDGRENT(); - printf("%s", j ? "\n" : ""); - } - return EXIT_SUCCESS; -} - char * pw_checkname(char *name, int gecos) { @@ -1337,13 +595,12 @@ pw_checkname(char *name, int gecos) showch, (ch - name), showtype); } if (!gecos && (ch - name) > LOGNAMESIZE) - errx(EX_DATAERR, "name too long `%s' (max is %d)", name, + errx(EX_USAGE, "name too long `%s' (max is %d)", name, LOGNAMESIZE); return (name); } - static void rmat(uid_t uid) { @@ -1398,3 +655,1071 @@ rmopie(char const * name) */ fclose(fp); } + +int +pw_user_next(int argc, char **argv, char *name __unused) +{ + struct userconf *cnf = NULL; + const char *cfg = NULL; + int ch; + bool quiet = false; + uid_t next; + + while ((ch = getopt(argc, argv, "Cq")) != -1) { + switch (ch) { + case 'C': + cfg = optarg; + break; + case 'q': + quiet; + break; + } + } + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + + cnf = get_userconfig(cfg); + + next = pw_uidpolicy(cnf, -1); + + printf("%ju:", (uintmax_t)next); + pw_groupnext(cnf, quiet); + + return (EXIT_SUCCESS); +} + +int +pw_user_show(int argc, char **argv, char *arg1) +{ + struct passwd *pwd = NULL; + char *name = NULL; + uid_t id = -1; + int ch; + bool all = false; + bool pretty = false; + bool force = false; + bool v7 = false; + bool quiet = false; + + if (arg1 != NULL) { + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, UID_MAX); + else + name = arg1; + } + + while ((ch = getopt(argc, argv, "C:qn:u:FPa7")) != -1) { + switch (ch) { + case 'C': + /* ignore compatibility */ + break; + case 'q': + quiet = true; + break; + case 'n': + name = optarg; + break; + case 'u': + id = pw_checkid(optarg, UID_MAX); + break; + case 'F': + force = true; + break; + case 'P': + pretty = true; + break; + case 'a': + all = true; + break; + case 7: + v7 = true; + break; + } + } + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + + if (all) { + SETPWENT(); + while ((pwd = GETPWENT()) != NULL) + print_user(pwd, pretty, v7); + ENDPWENT(); + return (EXIT_SUCCESS); + } + + if (id < 0 && name == NULL) + errx(EX_DATAERR, "username or id required"); + + pwd = (name != NULL) ? GETPWNAM(pw_checkname(name, 0)) : GETPWUID(id); + if (pwd == NULL) { + if (force) { + pwd = &fakeuser; + } else { + if (name == NULL) + errx(EX_NOUSER, "no such uid `%ju'", + (uintmax_t) id); + errx(EX_NOUSER, "no such user `%s'", name); + } + } + + return (print_user(pwd, pretty, v7)); +} + +int +pw_user_del(int argc, char **argv, char *arg1) +{ + struct userconf *cnf = NULL; + struct passwd *pwd = NULL; + struct group *gr, *grp; + char *name = NULL; + char grname[MAXLOGNAME]; + char *nispasswd = NULL; + char file[MAXPATHLEN]; + char home[MAXPATHLEN]; + const char *cfg = NULL; + struct stat st; + uid_t id; + int ch, rc; + bool nis = false; + bool deletehome = false; + bool quiet = false; + + if (arg1 != NULL) { + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, UID_MAX); + else + name = arg1; + } + + while ((ch = getopt(argc, argv, "C:qn:u:rYy:")) != -1) { + switch (ch) { + case 'C': + cfg = optarg; + break; + case 'q': + quiet = true; + break; + case 'n': + name = optarg; + break; + case 'u': + id = pw_checkid(optarg, UID_MAX); + break; + case 'r': + deletehome = true; + break; + case 'y': + nispasswd = optarg; + break; + case 'Y': + nis = true; + break; + } + } + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + + if (id < 0 && name == NULL) + errx(EX_DATAERR, "username or id required"); + + cnf = get_userconfig(cfg); + + if (nispasswd == NULL) + nispasswd = cnf->nispasswd; + + pwd = (name != NULL) ? GETPWNAM(pw_checkname(name, 0)) : GETPWUID(id); + if (pwd == NULL) { + if (name == NULL) + errx(EX_NOUSER, "no such uid `%ju'", (uintmax_t) id); + errx(EX_NOUSER, "no such user `%s'", name); + } + + if (PWF._altdir == PWF_REGULAR && + ((pwd->pw_fields & _PWF_SOURCE) != _PWF_FILES)) { + if ((pwd->pw_fields & _PWF_SOURCE) == _PWF_NIS) { + if (!nis && nispasswd && *nispasswd != '/') + errx(EX_NOUSER, "Cannot remove NIS user `%s'", + name); + } else { + errx(EX_NOUSER, "Cannot remove non local user `%s'", + name); + } + } + + id = pwd->pw_uid; + if (name == NULL) + name = pwd->pw_name; + + if (strcmp(pwd->pw_name, "root") == 0) + errx(EX_DATAERR, "cannot remove user 'root'"); + + /* Remove opie record from /etc/opiekeys */ + if (PWALTDIR() != PWF_ALT) + rmopie(pwd->pw_name); + + if (!PWALTDIR()) { + /* Remove crontabs */ + snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name); + if (access(file, F_OK) == 0) { + snprintf(file, sizeof(file), "crontab -u %s -r", pwd->pw_name); + system(file); + } + } + + /* + * Save these for later, since contents of pwd may be + * invalidated by deletion + */ + snprintf(file, sizeof(file), "%s/%s", _PATH_MAILDIR, pwd->pw_name); + strlcpy(home, pwd->pw_dir, sizeof(home)); + gr = GETGRGID(pwd->pw_gid); + if (gr != NULL) + strlcpy(grname, gr->gr_name, LOGNAMESIZE); + else + grname[0] = '\0'; + + rc = delpwent(pwd); + if (rc == -1) + err(EX_IOERR, "user '%s' does not exist", pwd->pw_name); + else if (rc != 0) + err(EX_IOERR, "passwd update"); + + if (nis && nispasswd && *nispasswd=='/') { + rc = delnispwent(nispasswd, name); + if (rc == -1) + warnx("WARNING: user '%s' does not exist in NIS passwd", + pwd->pw_name); + else if (rc != 0) + warn("WARNING: NIS passwd update"); + } + + grp = GETGRNAM(name); + if (grp != NULL && + (grp->gr_mem == NULL || *grp->gr_mem == NULL) && + strcmp(name, grname) == 0) + delgrent(GETGRNAM(name)); + SETGRENT(); + while ((grp = GETGRENT()) != NULL) { + int i, j; + char group[MAXLOGNAME]; + if (grp->gr_mem == NULL) + continue; + + for (i = 0; grp->gr_mem[i] != NULL; i++) { + if (strcmp(grp->gr_mem[i], name) != 0) + continue; + + for (j = i; grp->gr_mem[j] != NULL; j++) + grp->gr_mem[j] = grp->gr_mem[j+1]; + strlcpy(group, grp->gr_name, MAXLOGNAME); + chggrent(group, grp); + } + } + ENDGRENT(); + + pw_log(cnf, M_DELETE, W_USER, "%s(%ju) account removed", name, + (uintmax_t)id); + + /* Remove mail file */ + if (PWALTDIR() != PWF_ALT) + unlinkat(conf.rootfd, file + 1, 0); + + /* Remove at jobs */ + if (!PWALTDIR() && getpwuid(id) == NULL) + rmat(id); + + /* Remove home directory and contents */ + if (PWALTDIR() != PWF_ALT && deletehome && *home == '/' && + GETPWUID(id) == NULL && + fstatat(conf.rootfd, home + 1, &st, 0) != -1) { + rm_r(conf.rootfd, home, id); + pw_log(cnf, M_DELETE, W_USER, "%s(%ju) home '%s' %s" + "removed", name, (uintmax_t)id, home, + fstatat(conf.rootfd, home + 1, &st, 0) == -1 ? "" : "not " + "completely "); + } + + return (EXIT_SUCCESS); +} + +int +pw_user_lock(int argc, char **argv, char *arg1) +{ + int ch; + + while ((ch = getopt(argc, argv, "Cq")) != -1) { + switch (ch) { + case 'C': + case 'q': + /* compatibility */ + break; + } + } + + return (pw_userlock(arg1, M_LOCK)); +} + +int +pw_user_unlock(int argc, char **argv, char *arg1) +{ + int ch; + + while ((ch = getopt(argc, argv, "Cq")) != -1) { + switch (ch) { + case 'C': + case 'q': + /* compatibility */ + break; + } + } + + return (pw_userlock(arg1, M_UNLOCK)); +} + +static struct group * +group_from_name_or_id(char *name) +{ + const char *errstr = NULL; + struct group *grp; + uintmax_t id; + + if ((grp = GETGRNAM(name)) == NULL) { + id = strtounum(name, 0, GID_MAX, &errstr); + if (errstr) + errx(EX_NOUSER, "group `%s' does not exist", name); + grp = GETGRGID(id); + if (grp == NULL) + errx(EX_NOUSER, "group `%s' does not exist", name); + } + + return (grp); +} + +static void +split_groups(StringList **groups, char *groupsstr) +{ + struct group *grp; + char *p; + char tok[] = ", \t"; + + for (p = strtok(groupsstr, tok); p != NULL; p = strtok(NULL, tok)) { + grp = group_from_name_or_id(p); + if (*groups == NULL) + *groups = sl_init(); + sl_add(*groups, newstr(grp->gr_name)); + } +} + +static void +validate_grname(struct userconf *cnf, char *group) +{ + struct group *grp; + + if (group == NULL || *group == '\0') { + cnf->default_group = ""; + return; + } + grp = group_from_name_or_id(group); + cnf->default_group = newstr(grp->gr_name); +} + +static mode_t +validate_mode(char *mode) +{ + mode_t m; + void *set; + + if ((set = setmode(mode)) == NULL) + errx(EX_DATAERR, "invalid directory creation mode '%s'", mode); + + m = getmode(set, _DEF_DIRMODE); + free(set); + return (m); +} + +static void +mix_config(struct userconf *cmdcnf, struct userconf *cfg) +{ + + if (cmdcnf->default_password == 0) + cmdcnf->default_password = cfg->default_password; + if (cmdcnf->reuse_uids == 0) + cmdcnf->reuse_uids = cfg->reuse_uids; + if (cmdcnf->reuse_gids == 0) + cmdcnf->reuse_gids = cfg->reuse_gids; + if (cmdcnf->nispasswd == NULL) + cmdcnf->nispasswd = cfg->nispasswd; + if (cmdcnf->dotdir == NULL) + cmdcnf->dotdir = cfg->dotdir; + if (cmdcnf->newmail == NULL) + cmdcnf->newmail = cfg->newmail; + if (cmdcnf->logfile == NULL) + cmdcnf->logfile = cfg->logfile; + if (cmdcnf->home == NULL) + cmdcnf->home = cfg->home; + if (cmdcnf->homemode == 0) + cmdcnf->homemode = cfg->homemode; + if (cmdcnf->shelldir == NULL) + cmdcnf->shelldir = cfg->shelldir; + if (cmdcnf->shells == NULL) + cmdcnf->shells = cfg->shells; + if (cmdcnf->shell_default == NULL) + cmdcnf->shell_default = cfg->shell_default; + if (cmdcnf->default_group == NULL) + cmdcnf->default_group = cfg->default_group; + if (cmdcnf->groups == NULL) + cmdcnf->groups = cfg->groups; + if (cmdcnf->default_class == NULL) + cmdcnf->default_class = cfg->default_class; + if (cmdcnf->min_uid == 0) + cmdcnf->min_uid = cfg->min_uid; + if (cmdcnf->max_uid == 0) + cmdcnf->max_uid = cfg->max_uid; + if (cmdcnf->min_gid == 0) + cmdcnf->min_gid = cfg->min_gid; + if (cmdcnf->max_gid == 0) + cmdcnf->max_gid = cfg->max_gid; + if (cmdcnf->expire_days == 0) + cmdcnf->expire_days = cfg->expire_days; + if (cmdcnf->password_days == 0) + cmdcnf->password_days = cfg->password_days; +} + +int +pw_user_add(int argc, char **argv, char *arg1) +{ + struct userconf *cnf, *cmdcnf; + struct passwd *pwd; + struct group *grp; + struct stat st; + char args[] = "C:qn:u:c:d:e:p:g:G:mM:k:s:oL:i:w:h:H:Db:NPy:Y"; + char line[_PASSWORD_LEN+1], path[MAXPATHLEN]; + char *gecos, *homedir, *skel, *walk, *userid, *groupid, *grname; + char *default_passwd, *name, *p; + const char *cfg; + login_cap_t *lc; + FILE *pfp, *fp; + intmax_t id = -1; + time_t now; + int rc, ch, fd = -1; + size_t i; + bool dryrun, nis, pretty, quiet, createhome, precrypted, genconf; + + dryrun = nis = pretty = quiet = createhome = precrypted = false; + genconf = false; + gecos = homedir = skel = userid = groupid = default_passwd = NULL; + grname = name = NULL; + + if ((cmdcnf = calloc(1, sizeof(struct userconf))) == NULL) + err(EXIT_FAILURE, "calloc()"); + + if (arg1 != NULL) { + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, UID_MAX); + else + name = arg1; + } + + while ((ch = getopt(argc, argv, args)) != -1) { + switch (ch) { + case 'C': + cfg = optarg; + break; + case 'q': + quiet = true; + break; + case 'n': + name = optarg; + break; + case 'u': + userid = optarg; + break; + case 'c': + gecos = pw_checkname(optarg, 1); + break; + case 'd': + homedir = optarg; + break; + case 'e': + now = time(NULL); + cmdcnf->expire_days = parse_date(now, optarg); + break; + case 'p': + now = time(NULL); + cmdcnf->password_days = parse_date(now, optarg); + break; + case 'g': + validate_grname(cmdcnf, optarg); + grname = optarg; + break; + case 'G': + split_groups(&cmdcnf->groups, optarg); + break; + case 'm': + createhome = true; + break; + case 'M': + cmdcnf->homemode = validate_mode(optarg); + break; + case 'k': + walk = skel = optarg; + if (*walk == '/') + walk++; + if (fstatat(conf.rootfd, walk, &st, 0) == -1) + errx(EX_OSFILE, "skeleton `%s' does not " + "exists", skel); + if (!S_ISDIR(st.st_mode)) + errx(EX_OSFILE, "skeleton `%s' is not a " + "directory", skel); + cmdcnf->dotdir = skel; + break; + case 's': + cmdcnf->shell_default = optarg; + break; + case 'o': + conf.checkduplicate = false; + break; + case 'L': + cmdcnf->default_class = pw_checkname(optarg, 0); + break; + case 'i': + groupid = optarg; + break; + case 'w': + default_passwd = optarg; + break; + case 'H': + if (fd != -1) + errx(EX_USAGE, "'-h' and '-H' are mutually " + "exclusive options"); + fd = pw_checkfd(optarg); + precrypted = true; + if (fd == '-') + errx(EX_USAGE, "-H expects a file descriptor"); + break; + case 'h': + if (fd != -1) + errx(EX_USAGE, "'-h' and '-H' are mutually " + "exclusive options"); + fd = pw_checkfd(optarg); + break; + case 'D': + genconf = true; + break; + case 'b': + cmdcnf->home = optarg; + break; + case 'N': + dryrun = true; + break; + case 'P': + pretty = true; + break; + case 'y': + cmdcnf->nispasswd = optarg; + break; + case 'Y': + nis = true; + break; + } + } + + if (geteuid() != 0 && ! dryrun) + errx(EX_NOPERM, "you must be root"); + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + + cnf = get_userconfig(cfg); + + mix_config(cmdcnf, cnf); + if (default_passwd) + cmdcnf->default_password = boolean_val(default_passwd, + cnf->default_password); + if (genconf) { + if (name != NULL) + errx(EX_DATAERR, "can't combine `-D' with `-n name'"); + if (userid != NULL) { + if ((p = strtok(userid, ", \t")) != NULL) + cmdcnf->min_uid = pw_checkid(p, UID_MAX); + if (cmdcnf->min_uid == 0) + cmdcnf->min_uid = 1000; + if ((p = strtok(NULL, " ,\t")) != NULL) + cmdcnf->max_uid = pw_checkid(p, UID_MAX); + if (cmdcnf->max_uid == 0) + cmdcnf->max_uid = 32000; + } + if (groupid != NULL) { + if ((p = strtok(groupid, ", \t")) != NULL) + cmdcnf->min_gid = pw_checkid(p, GID_MAX); + if (cmdcnf->min_gid == 0) + cmdcnf->min_gid = 1000; + if ((p = strtok(NULL, " ,\t")) != NULL) + cmdcnf->max_gid = pw_checkid(p, GID_MAX); + if (cmdcnf->max_gid == 0) + cmdcnf->max_gid = 32000; + } + if (write_userconfig(cmdcnf, cfg)) + return (EXIT_SUCCESS); + err(EX_IOERR, "config update"); + } + + if (userid) + id = pw_checkid(userid, UID_MAX); + if (id < 0 && name == NULL) + errx(EX_DATAERR, "user name or id required"); + + if (name == NULL) + errx(EX_DATAERR, "login name required"); + + pwd = &fakeuser; + pwd->pw_name = name; + pwd->pw_class = cmdcnf->default_class ? cmdcnf->default_class : ""; + pwd->pw_uid = pw_uidpolicy(cmdcnf, id); + pwd->pw_gid = pw_gidpolicy(cnf, grname, pwd->pw_name, + (gid_t) pwd->pw_uid, dryrun); + pwd->pw_change = cmdcnf->password_days; + pwd->pw_expire = cmdcnf->expire_days; + pwd->pw_dir = pw_homepolicy(cmdcnf, homedir, pwd->pw_name); + pwd->pw_shell = pw_shellpolicy(cmdcnf); + lc = login_getpwclass(pwd); + if (lc == NULL || login_setcryptfmt(lc, "sha512", NULL) == NULL) + warn("setting crypt(3) format"); + login_close(lc); + pwd->pw_passwd = pw_password(cmdcnf, pwd->pw_name, dryrun); + if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0) + warnx("WARNING: new account `%s' has a uid of 0 " + "(superuser access!)", pwd->pw_name); + if (gecos) + pwd->pw_gecos = gecos; + + if (fd != -1) + pw_set_passwd(pwd, fd, precrypted, false); + + if (dryrun) + return (print_user(pwd, pretty, false)); + + if ((rc = addpwent(pwd)) != 0) { + if (rc == -1) + errx(EX_IOERR, "user '%s' already exists", + pwd->pw_name); + else if (rc != 0) + err(EX_IOERR, "passwd file update"); + } + if (nis && cmdcnf->nispasswd && *cmdcnf->nispasswd == '/') { + printf("%s\n", cmdcnf->nispasswd); + rc = addnispwent(cmdcnf->nispasswd, pwd); + if (rc == -1) + warnx("User '%s' already exists in NIS passwd", pwd->pw_name); + else if (rc != 0) + warn("NIS passwd update"); + /* NOTE: we treat NIS-only update errors as non-fatal */ + } + + if (cmdcnf->groups != NULL) { + for (i = 0; i < cmdcnf->groups->sl_cur; i++) { + grp = GETGRNAM(cmdcnf->groups->sl_str[i]); + grp = gr_add(grp, pwd->pw_name); + /* + * grp can only be NULL in 2 cases: + * - the new member is already a member + * - a problem with memory occurs + * in both cases we want to skip now. + */ + if (grp == NULL) + continue; + chggrent(grp->gr_name, grp); + free(grp); + } + } + + pwd = GETPWNAM(name); + if (pwd == NULL) + errx(EX_NOUSER, "user '%s' disappeared during update", name); + + grp = GETGRGID(pwd->pw_gid); + pw_log(cnf, M_ADD, W_USER, "%s(%ju):%s(%ju):%s:%s:%s", + pwd->pw_name, (uintmax_t)pwd->pw_uid, + grp ? grp->gr_name : "unknown", (uintmax_t)(grp ? grp->gr_gid : (uid_t)-1), + pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); + + /* + * let's touch and chown the user's mail file. This is not + * strictly necessary under BSD with a 0755 maildir but it also + * doesn't hurt anything to create the empty mailfile + */ + if (PWALTDIR() != PWF_ALT) { + snprintf(path, sizeof(path), "%s/%s", _PATH_MAILDIR, + pwd->pw_name); + /* Preserve contents & mtime */ + close(openat(conf.rootfd, path +1, O_RDWR | O_CREAT, 0600)); + fchownat(conf.rootfd, path + 1, pwd->pw_uid, pwd->pw_gid, + AT_SYMLINK_NOFOLLOW); + } + + /* + * Let's create and populate the user's home directory. Note + * that this also `works' for editing users if -m is used, but + * existing files will *not* be overwritten. + */ + if (PWALTDIR() != PWF_ALT && createhome && pwd->pw_dir && + *pwd->pw_dir == '/' && pwd->pw_dir[1]) + create_and_populate_homedir(cmdcnf, pwd, cmdcnf->dotdir, + cmdcnf->homemode, false); + + if (!PWALTDIR() && cmdcnf->newmail && *cmdcnf->newmail && + (fp = fopen(cnf->newmail, "r")) != NULL) { + if ((pfp = popen(_PATH_SENDMAIL " -t", "w")) == NULL) + warn("sendmail"); + else { + fprintf(pfp, "From: root\n" "To: %s\n" + "Subject: Welcome!\n\n", pwd->pw_name); + while (fgets(line, sizeof(line), fp) != NULL) { + /* Do substitutions? */ + fputs(line, pfp); + } + pclose(pfp); + pw_log(cnf, M_ADD, W_USER, "%s(%ju) new user mail sent", + pwd->pw_name, (uintmax_t)pwd->pw_uid); + } + fclose(fp); + } + + if (nis && nis_update() == 0) + pw_log(cnf, M_ADD, W_USER, "NIS maps updated"); + + return (EXIT_SUCCESS); +} + +int +pw_user_mod(int argc, char **argv, char *arg1) +{ + struct userconf *cnf; + struct passwd *pwd; + struct group *grp; + StringList *groups = NULL; + char args[] = "C:qn:u:c:d:e:p:g:G:mM:l:k:s:w:L:h:H:NPYy:"; + const char *cfg; + char *gecos, *homedir, *grname, *name, *newname, *walk, *skel, *shell; + char *passwd, *class, *nispasswd; + login_cap_t *lc; + struct stat st; + intmax_t id = -1; + int ch, fd = -1; + size_t i, j; + bool quiet, createhome, pretty, dryrun, nis, edited, docreatehome; + mode_t homemode = 0; + time_t expire_days, password_days, now, precrypted; + + expire_days = password_days = -1; + gecos = homedir = grname = name = newname = skel = shell =NULL; + passwd = NULL; + class = nispasswd = NULL; + quiet = createhome = pretty = dryrun = nis = precrypted = false; + edited = docreatehome = false; + + if (arg1 != NULL) { + if (strspn(arg1, "0123456789") == strlen(arg1)) + id = pw_checkid(arg1, UID_MAX); + else + name = arg1; + } + + while ((ch = getopt(argc, argv, args)) != -1) { + switch (ch) { + case 'C': + cfg = optarg; + break; + case 'q': + quiet = true; + break; + case 'n': + name = optarg; + break; + case 'u': + id = pw_checkid(optarg, UID_MAX); + break; + case 'c': + gecos = pw_checkname(optarg, 1); + break; + case 'd': + homedir = optarg; + break; + case 'e': + now = time(NULL); + expire_days = parse_date(now, optarg); + break; + case 'p': + now = time(NULL); + password_days = parse_date(now, optarg); + break; + case 'g': + group_from_name_or_id(optarg); + grname = optarg; + break; + case 'G': + split_groups(&groups, optarg); + break; + case 'm': + createhome = true; + break; + case 'M': + homemode = validate_mode(optarg); + break; + case 'l': + newname = optarg; + break; + case 'k': + walk = skel = optarg; + if (*walk == '/') + walk++; + if (fstatat(conf.rootfd, walk, &st, 0) == -1) + errx(EX_OSFILE, "skeleton `%s' does not " + "exists", skel); + if (!S_ISDIR(st.st_mode)) + errx(EX_OSFILE, "skeleton `%s' is not a " + "directory", skel); + break; + case 's': + shell = optarg; + break; + case 'w': + passwd = optarg; + break; + case 'L': + class = pw_checkname(optarg, 0); + break; + case 'H': + if (fd != -1) + errx(EX_USAGE, "'-h' and '-H' are mutually " + "exclusive options"); + fd = pw_checkfd(optarg); + precrypted = true; + if (fd == '-') + errx(EX_USAGE, "-H expects a file descriptor"); + break; + case 'h': + if (fd != -1) + errx(EX_USAGE, "'-h' and '-H' are mutually " + "exclusive options"); + fd = pw_checkfd(optarg); + break; + case 'N': + dryrun = true; + break; + case 'P': + pretty = true; + break; + case 'y': + nispasswd = optarg; + break; + case 'Y': + nis = true; + break; + } + } + + if (geteuid() != 0 && ! dryrun) + errx(EX_NOPERM, "you must be root"); + + if (quiet) + freopen(_PATH_DEVNULL, "w", stderr); + + cnf = get_userconfig(cfg); + + if (id < 0 && name == NULL) + errx(EX_DATAERR, "username or id required"); + + pwd = (name != NULL) ? GETPWNAM(pw_checkname(name, 0)) : GETPWUID(id); + if (pwd == NULL) { + if (name == NULL) + errx(EX_NOUSER, "no such uid `%ju'", + (uintmax_t) id); + errx(EX_NOUSER, "no such user `%s'", name); + } + + if (name == NULL) + name = pwd->pw_name; + + if (nis && nispasswd == NULL) + nispasswd = cnf->nispasswd; + + if (PWF._altdir == PWF_REGULAR && + ((pwd->pw_fields & _PWF_SOURCE) != _PWF_FILES)) { + if ((pwd->pw_fields & _PWF_SOURCE) == _PWF_NIS) { + if (!nis && nispasswd && *nispasswd != '/') + errx(EX_NOUSER, "Cannot modify NIS user `%s'", + name); + } else { + errx(EX_NOUSER, "Cannot modify non local user `%s'", + name); + } + } + + if (newname) { + if (strcmp(pwd->pw_name, "root") == 0) + errx(EX_DATAERR, "can't rename `root' account"); + if (strcmp(pwd->pw_name, newname) != 0) { + pwd->pw_name = pw_checkname(newname, 0); + edited = true; + } + } + + if (id > 0 && pwd->pw_uid != id) { + pwd->pw_uid = id; + edited = true; + if (pwd->pw_uid != 0 && strcmp(pwd->pw_name, "root") == 0) + errx(EX_DATAERR, "can't change uid of `root' account"); + if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0) + warnx("WARNING: account `%s' will have a uid of 0 (superuser access!)", pwd->pw_name); + } + + if (grname && pwd->pw_uid != 0) { + grp = GETGRNAM(grname); + if (grp == NULL) + grp = GETGRGID(pw_checkid(grname, GID_MAX)); + if (grp->gr_gid != pwd->pw_gid) { + pwd->pw_gid = grp->gr_gid; + edited = true; + } + } + + if (password_days >= 0 && pwd->pw_change != password_days) { + pwd->pw_change = password_days; + edited = true; + } + + if (expire_days >= 0 && pwd->pw_expire != expire_days) { + pwd->pw_expire = expire_days; + edited = true; + } + + if (shell) { + shell = shell_path(cnf->shelldir, cnf->shells, shell); + if (shell == NULL) + shell = ""; + if (strcmp(shell, pwd->pw_shell) != 0) { + pwd->pw_shell = shell; + edited = true; + } + } + + if (class && strcmp(pwd->pw_class, class) != 0) { + pwd->pw_class = class; + edited = true; + } + + if (homedir && strcmp(pwd->pw_dir, homedir) != 0) { + pwd->pw_dir = homedir; + if (fstatat(conf.rootfd, pwd->pw_dir, &st, 0) == -1) { + if (!createhome) + warnx("WARNING: home `%s' does not exist", + pwd->pw_dir); + else + docreatehome = true; + } else if (!S_ISDIR(st.st_mode)) { + warnx("WARNING: home `%s' is not a directory", + pwd->pw_dir); + } + } + + if (passwd && conf.fd == -1) { + lc = login_getpwclass(pwd); + if (lc == NULL || login_setcryptfmt(lc, "sha512", NULL) == NULL) + warn("setting crypt(3) format"); + login_close(lc); + pwd->pw_passwd = pw_password(cnf, pwd->pw_name, dryrun); + edited = true; + } + + if (gecos && strcmp(pwd->pw_gecos, gecos) != 0) { + pwd->pw_gecos = gecos; + edited = true; + } + + if (fd != -1) + edited = pw_set_passwd(pwd, fd, precrypted, true); + + if (dryrun) + return (print_user(pwd, pretty, false)); + + if (edited) /* Only updated this if required */ + perform_chgpwent(name, pwd, nis ? nispasswd : NULL); + /* Now perform the needed changes concern groups */ + if (groups != NULL) { + /* Delete User from groups using old name */ + SETGRENT(); + while ((grp = GETGRENT()) != NULL) { + if (grp->gr_mem == NULL) + continue; + for (i = 0; grp->gr_mem[i] != NULL; i++) { + if (strcmp(grp->gr_mem[i] , name) != 0) + continue; + for (j = i; grp->gr_mem[j] != NULL ; j++) + grp->gr_mem[j] = grp->gr_mem[j+1]; + chggrent(grp->gr_name, grp); + break; + } + } + ENDGRENT(); + /* Add the user to the needed groups */ + for (i = 0; i < groups->sl_cur; i++) { + grp = GETGRNAM(groups->sl_str[i]); + grp = gr_add(grp, pwd->pw_name); + if (grp == NULL) + continue; + chggrent(grp->gr_name, grp); + free(grp); + } + } + /* In case of rename we need to walk over the different groups */ + if (newname) { + SETGRENT(); + while ((grp = GETGRENT()) != NULL) { + if (grp->gr_mem == NULL) + continue; + for (i = 0; grp->gr_mem[i] != NULL; i++) { + if (strcmp(grp->gr_mem[i], name) != 0) + continue; + grp->gr_mem[i] = newname; + chggrent(grp->gr_name, grp); + break; + } + } + } + + /* go get a current version of pwd */ + if (newname) + name = newname; + pwd = GETPWNAM(name); + if (pwd == NULL) + errx(EX_NOUSER, "user '%s' disappeared during update", name); + grp = GETGRGID(pwd->pw_gid); + pw_log(cnf, M_UPDATE, W_USER, "%s(%ju):%s(%ju):%s:%s:%s", + pwd->pw_name, (uintmax_t)pwd->pw_uid, + grp ? grp->gr_name : "unknown", + (uintmax_t)(grp ? grp->gr_gid : (uid_t)-1), + pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); + + /* + * Let's create and populate the user's home directory. Note + * that this also `works' for editing users if -m is used, but + * existing files will *not* be overwritten. + */ + if (PWALTDIR() != PWF_ALT && docreatehome && pwd->pw_dir && + *pwd->pw_dir == '/' && pwd->pw_dir[1]) { + if (!skel) + skel = cnf->dotdir; + if (homemode == 0) + homemode = cnf->homemode; + create_and_populate_homedir(cnf, pwd, skel, homemode, true); + } + + if (nis && nis_update() == 0) + pw_log(cnf, M_UPDATE, W_USER, "NIS maps updated"); + + return (EXIT_SUCCESS); +} diff --git a/usr.sbin/pw/pw_utils.c b/usr.sbin/pw/pw_utils.c new file mode 100644 index 000000000000..31b79c078e4a --- /dev/null +++ b/usr.sbin/pw/pw_utils.c @@ -0,0 +1,97 @@ +/*- + * Copyright (C) 2015 Baptiste Daroussin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include + +#include "pw.h" + +int +pw_checkfd(char *nptr) +{ + const char *errstr; + int fd = -1; + + if (strcmp(nptr, "-") == 0) + return '-'; + fd = strtonum(nptr, 0, INT_MAX, &errstr); + if (errstr != NULL) + errx(EX_USAGE, "Bad file descriptor '%s': %s", + nptr, errstr); + return (fd); +} + +uintmax_t +pw_checkid(char *nptr, uintmax_t maxval) +{ + const char *errstr = NULL; + uintmax_t id; + + id = strtounum(nptr, 0, maxval, &errstr); + if (errstr) + errx(EX_USAGE, "Bad id '%s': %s", nptr, errstr); + return (id); +} + +struct userconf * +get_userconfig(const char *config) +{ + char defaultcfg[MAXPATHLEN]; + + if (config != NULL) + return (read_userconfig(config)); + snprintf(defaultcfg, sizeof(defaultcfg), "%s/pw.conf", conf.etcpath); + return (read_userconfig(defaultcfg)); +} + +int +nis_update(void) { + pid_t pid; + int i; + + fflush(NULL); + if ((pid = fork()) == -1) { + warn("fork()"); + return (1); + } + if (pid == 0) { + execlp("/usr/bin/make", "make", "-C", "/var/yp/", (char*) NULL); + _exit(1); + } + waitpid(pid, &i, 0); + if ((i = WEXITSTATUS(i)) != 0) + errx(i, "make exited with status %d", i); + return (i); +} diff --git a/usr.sbin/pw/pwupd.h b/usr.sbin/pw/pwupd.h index 054c5a55293b..7fecffb7da4b 100644 --- a/usr.sbin/pw/pwupd.h +++ b/usr.sbin/pw/pwupd.h @@ -76,29 +76,16 @@ struct userconf { char *default_class; /* Default user class */ uid_t min_uid, max_uid; /* Allowed range of uids */ gid_t min_gid, max_gid; /* Allowed range of gids */ - int expire_days; /* Days to expiry */ - int password_days; /* Days to password expiry */ + time_t expire_days; /* Days to expiry */ + time_t password_days; /* Days to password expiry */ }; struct pwconf { char rootdir[MAXPATHLEN]; char etcpath[MAXPATHLEN]; - char *newname; - char *config; - char *gecos; int fd; int rootfd; - int which; - bool quiet; - bool force; - bool all; - bool dryrun; - bool pretty; - bool v7; bool checkduplicate; - bool deletehome; - bool precrypted; - struct userconf *userconf; }; extern struct pwf PWF; diff --git a/usr.sbin/pw/strtounum.c b/usr.sbin/pw/strtounum.c index 8d8347080ac2..be572764b60c 100644 --- a/usr.sbin/pw/strtounum.c +++ b/usr.sbin/pw/strtounum.c @@ -1,5 +1,5 @@ /*- - * Copyright (C) Baptiste Daroussin + * Copyright (C) 2015 Baptiste Daroussin * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/usr.sbin/pw/tests/pw_groupdel.sh b/usr.sbin/pw/tests/pw_groupdel.sh index 75b063a34b32..88cc0e08b8bf 100755 --- a/usr.sbin/pw/tests/pw_groupdel.sh +++ b/usr.sbin/pw/tests/pw_groupdel.sh @@ -13,7 +13,7 @@ group_do_not_delete_wheel_if_group_unknown_head() { group_do_not_delete_wheel_if_group_unknown_body() { populate_etc_skel atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel - atf_check -e inline:"pw: -g expects a number\n" -s exit:64 -x \ + atf_check -e inline:"pw: Bad id 'I_do_not_exist': invalid\n" -s exit:64 -x \ ${PW} groupdel -g I_do_not_exist atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel } diff --git a/usr.sbin/pw/tests/pw_useradd.sh b/usr.sbin/pw/tests/pw_useradd.sh index 7306387bd194..401769bcbdb1 100755 --- a/usr.sbin/pw/tests/pw_useradd.sh +++ b/usr.sbin/pw/tests/pw_useradd.sh @@ -250,9 +250,9 @@ user_add_R_body() { test -d ${HOME}/home/bar || atf_fail "Directory not created" atf_check -s exit:0 ${RPW} userdel bar test -d ${HOME}/home/bar || atf_fail "Directory removed" -# atf_check -s exit:0 ${RPW} useradd bar -# atf_check -s exit:0 ${RPW} userdel bar -r -# test -d ${HOME}/home/bar && atf_fail "Directory not removed" + atf_check -s exit:0 ${RPW} useradd bar + atf_check -s exit:0 ${RPW} userdel bar -r + [ ! -d ${HOME}/home/bar ] || atf_fail "Directory not removed" } atf_test_case user_add_skel @@ -296,6 +296,14 @@ user_add_uid_too_large_body() { ${PW} useradd -n test1 -u 9999999999999 } +atf_test_case user_add_bad_shell +user_add_bad_shell_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo -s sh + atf_check -s exit:78 -e ignore ${PW} useradd bar -s badshell +} + atf_init_test_cases() { atf_add_test_case user_add atf_add_test_case user_add_noupdate @@ -321,4 +329,5 @@ atf_init_test_cases() { atf_add_test_case user_add_skel atf_add_test_case user_add_uid0 atf_add_test_case user_add_uid_too_large + atf_add_test_case user_add_bad_shell } diff --git a/usr.sbin/pw/tests/pw_userdel.sh b/usr.sbin/pw/tests/pw_userdel.sh index 1305cb74f847..f608029bef45 100755 --- a/usr.sbin/pw/tests/pw_userdel.sh +++ b/usr.sbin/pw/tests/pw_userdel.sh @@ -27,7 +27,7 @@ user_do_not_try_to_delete_root_if_user_unknown_head() { } user_do_not_try_to_delete_root_if_user_unknown_body() { populate_etc_skel - atf_check -e inline:"pw: -u expects a number\n" -s exit:64 -x \ + atf_check -e inline:"pw: Bad id 'plop': invalid\n" -s exit:64 -x \ ${PW} userdel -u plop } diff --git a/usr.sbin/pw/tests/pw_usermod.sh b/usr.sbin/pw/tests/pw_usermod.sh index 006bb2c17328..7acc7a526122 100755 --- a/usr.sbin/pw/tests/pw_usermod.sh +++ b/usr.sbin/pw/tests/pw_usermod.sh @@ -100,6 +100,36 @@ user_mod_name_noupdate_body() { grep "^foo:.*" $HOME/master.passwd } +atf_test_case user_mod_rename_multigroups +user_mod_rename_multigroups_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} groupadd test1 + atf_check -s exit:0 ${PW} groupadd test2 + atf_check -s exit:0 ${PW} useradd foo -G test1,test2 + atf_check -o match:"foo" -s exit:0 ${PW} groupshow test1 + atf_check -o match:"foo" -s exit:0 ${PW} groupshow test2 + atf_check -s exit:0 ${PW} usermod foo -l bar + atf_check -o match:"bar" -s exit:0 ${PW} groupshow test1 + atf_check -o match:"bar" -s exit:0 ${PW} groupshow test2 +} + +atf_test_case user_mod_nogroups +user_mod_nogroups_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} groupadd test1 + atf_check -s exit:0 ${PW} groupadd test2 + atf_check -s exit:0 ${PW} groupadd test3 + atf_check -s exit:0 ${PW} groupadd test4 + atf_check -s exit:0 ${PW} useradd foo -G test1,test2 + atf_check -o match:"foo" -s exit:0 ${PW} groupshow test1 + atf_check -o match:"foo" -s exit:0 ${PW} groupshow test2 + atf_check -s exit:0 ${PW} usermod foo -G test3,test4 + atf_check -s exit:0 -o inline:"test3\ntest4\n" \ + awk -F\: '$4 == "foo" { print $1 }' ${HOME}/group +} + atf_test_case user_mod_rename user_mod_rename_body() { populate_etc_skel @@ -134,7 +164,7 @@ user_mod_h_body() { EOF atf_check -s exit:0 -o match:"^foo:\*:.*" \ grep "^foo" ${HOME}/master.passwd - atf_check -e inline:"pw: '-h' expects a file descriptor or '-'\n" \ + atf_check -e inline:"pw: Bad file descriptor 'a': invalid\n" \ -s exit:64 ${PW} usermod foo -h a <<- EOF $(echo a) EOF @@ -150,10 +180,21 @@ user_mod_H_body() { EOF atf_check -s exit:0 -o match:"^foo:a:.*" \ grep "^foo" ${HOME}/master.passwd - atf_check -s exit:64 -e inline:"pw: '-H' expects a file descriptor\n" \ + atf_check -s exit:64 -e inline:"pw: -H expects a file descriptor\n" \ ${PW} usermod foo -H - } +atf_test_case user_mod_renamehome +user_mod_renamehome_body() { + populate_root_etc_skel + + mkdir -p ${HOME}/home + atf_check -s exit:0 ${RPW} useradd foo -m + test -d ${HOME}/home/foo || atf_fail "Directory not created" + atf_check -s exit:0 ${RPW} usermod foo -l bar -d /home/bar -m + test -d ${HOME}/home/bar || atf_fail "Directory not created" +} + atf_init_test_cases() { atf_add_test_case user_mod atf_add_test_case user_mod_noupdate @@ -161,10 +202,12 @@ atf_init_test_cases() { atf_add_test_case user_mod_comments_noupdate atf_add_test_case user_mod_comments_invalid atf_add_test_case user_mod_comments_invalid_noupdate + atf_add_test_case user_mod_nogroups atf_add_test_case user_mod_rename atf_add_test_case user_mod_name_noupdate - atf_add_test_case user_mod_rename atf_add_test_case user_mod_rename_too_long + atf_add_test_case user_mod_rename_multigroups atf_add_test_case user_mod_h atf_add_test_case user_mod_H + atf_add_test_case user_mod_renamehome } From db533440b7a9cc380ed7c72ec2f4ad9a37f51e1b Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 12:48:36 +0000 Subject: [PATCH 164/314] Remove dead code --- usr.sbin/pw/pw.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h index b6e2ccf5dca9..e1a394995c19 100644 --- a/usr.sbin/pw/pw.h +++ b/usr.sbin/pw/pw.h @@ -64,15 +64,6 @@ enum _which W_NUM }; -struct carg -{ - int ch; - char *val; - LIST_ENTRY(carg) list; -}; - -LIST_HEAD(cargs, carg); - #define _DEF_DIRMODE (S_IRWXU | S_IRWXG | S_IRWXO) #define _PATH_PW_CONF "/etc/pw.conf" #define _UC_MAXLINE 1024 @@ -81,8 +72,6 @@ LIST_HEAD(cargs, carg); struct userconf *get_userconfig(const char *cfg); struct userconf *read_userconfig(char const * file); int write_userconfig(struct userconf *cnf, char const * file); -struct carg *addarg(struct cargs * _args, int ch, char *argstr); -struct carg *getarg(struct cargs * _args, int ch); int pw_group_add(int argc, char **argv, char *name); int pw_group_del(int argc, char **argv, char *name); From a64b90fbaa161ec68aec69bec110e0cdab7b4dd3 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 12:54:15 +0000 Subject: [PATCH 165/314] Fix regression: report again if a username already exists when creating it --- usr.sbin/pw/pw_user.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 8ff4159108d8..172e5efec144 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -1275,6 +1275,9 @@ pw_user_add(int argc, char **argv, char *arg1) if (name == NULL) errx(EX_DATAERR, "login name required"); + if (GETPWNAM(name) != NULL) + errx(EX_DATAERR, "login name `%s' already exists", name); + pwd = &fakeuser; pwd->pw_name = name; pwd->pw_class = cmdcnf->default_class ? cmdcnf->default_class : ""; From f4124312a11597ce61b918879185984e8bcb427a Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 12:56:25 +0000 Subject: [PATCH 166/314] Fix regression: report if a group already exists when creating it --- usr.sbin/pw/pw_group.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c index 5ba5e39fa06d..22e80b0cc2d3 100644 --- a/usr.sbin/pw/pw_group.c +++ b/usr.sbin/pw/pw_group.c @@ -546,6 +546,8 @@ pw_group_add(int argc, char **argv, char *arg1) freopen(_PATH_DEVNULL, "w", stderr); if (name == NULL) errx(EX_DATAERR, "group name required"); + if (GETGRNAM(name) != NULL) + errx(EX_DATAERR, "group name `%s' already exists", name); cnf = get_userconfig(cfg); rc = groupadd(cnf, name, gr_gidpolicy(cnf, id), members, fd, dryrun, pretty, precrypted); From b8a5086ef0d85787700f7e94c08ed148a1fa9f2c Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 13:02:53 +0000 Subject: [PATCH 167/314] Add regression tests about adding already existsing groups/users --- usr.sbin/pw/tests/pw_groupadd.sh | 11 +++++++++++ usr.sbin/pw/tests/pw_useradd.sh | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/usr.sbin/pw/tests/pw_groupadd.sh b/usr.sbin/pw/tests/pw_groupadd.sh index 9c8fdf12ebe8..5fa7bef0fdf1 100755 --- a/usr.sbin/pw/tests/pw_groupadd.sh +++ b/usr.sbin/pw/tests/pw_groupadd.sh @@ -10,6 +10,17 @@ group_add_gid_too_large_body() { ${PW} groupadd -n test1 -g 9999999999999 } +atf_test_case group_add_already_exists +group_add_already_exists_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} groupadd foo + atf_check -s exit:65 \ + -e inline:"pw: group name \`foo' already exists\n" \ + ${PW} groupadd foo +} + atf_init_test_cases() { atf_add_test_case group_add_gid_too_large + atf_add_test_case group_add_already_exists } diff --git a/usr.sbin/pw/tests/pw_useradd.sh b/usr.sbin/pw/tests/pw_useradd.sh index 401769bcbdb1..f42980d76cc2 100755 --- a/usr.sbin/pw/tests/pw_useradd.sh +++ b/usr.sbin/pw/tests/pw_useradd.sh @@ -304,6 +304,16 @@ user_add_bad_shell_body() { atf_check -s exit:78 -e ignore ${PW} useradd bar -s badshell } +atf_test_case user_add_already_exists +user_add_already_exists_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:65 \ + -e inline:"pw: login name \`foo' already exists\n" \ + ${PW} useradd foo +} + atf_init_test_cases() { atf_add_test_case user_add atf_add_test_case user_add_noupdate @@ -330,4 +340,5 @@ atf_init_test_cases() { atf_add_test_case user_add_uid0 atf_add_test_case user_add_uid_too_large atf_add_test_case user_add_bad_shell + atf_add_test_case user_add_already_exists } From bcbdb01e569876034a66c001132994482b048c31 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 13:22:46 +0000 Subject: [PATCH 168/314] Cleanup a bit includes --- usr.sbin/pw/cpdir.c | 7 +------ usr.sbin/pw/grupd.c | 4 +--- usr.sbin/pw/psdate.c | 5 ++--- usr.sbin/pw/pw.c | 7 ++++--- usr.sbin/pw/pw.h | 16 +++------------- usr.sbin/pw/pw_conf.c | 8 ++++---- usr.sbin/pw/pw_group.c | 4 ++-- usr.sbin/pw/pw_log.c | 2 ++ usr.sbin/pw/pw_nis.c | 1 + usr.sbin/pw/pw_user.c | 25 +++++++++++++++---------- usr.sbin/pw/pw_utils.c | 2 ++ usr.sbin/pw/pwupd.c | 14 ++++++-------- 12 files changed, 43 insertions(+), 52 deletions(-) diff --git a/usr.sbin/pw/cpdir.c b/usr.sbin/pw/cpdir.c index e84d0f34a6bc..334f789bb75e 100644 --- a/usr.sbin/pw/cpdir.c +++ b/usr.sbin/pw/cpdir.c @@ -29,17 +29,12 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include #include #include #include -#include #include -#include #include -#include -#include -#include -#include #include "pw.h" #include "pwupd.h" diff --git a/usr.sbin/pw/grupd.c b/usr.sbin/pw/grupd.c index d52a345b48fb..9cbe0cb0b345 100644 --- a/usr.sbin/pw/grupd.c +++ b/usr.sbin/pw/grupd.c @@ -29,13 +29,11 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include #include #include -#include #include #include -#include -#include #include "pwupd.h" diff --git a/usr.sbin/pw/psdate.c b/usr.sbin/pw/psdate.c index 8e3a951ef85b..bd2aa152b437 100644 --- a/usr.sbin/pw/psdate.c +++ b/usr.sbin/pw/psdate.c @@ -29,12 +29,11 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include +#include +#include #include #include -#include #include -#include #include "psdate.h" diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index b13db70a57d1..1f42101a9add 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -32,9 +32,10 @@ static const char rcsid[] = #include #include #include -#include -#include -#include +#include +#include +#include + #include "pw.h" const char *Modes[] = { diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h index e1a394995c19..b389f1248dd1 100644 --- a/usr.sbin/pw/pw.h +++ b/usr.sbin/pw/pw.h @@ -26,23 +26,13 @@ * $FreeBSD$ */ +#include + #define _WITH_GETLINE +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "psdate.h" #include "pwupd.h" enum _mode diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index 41ab79b2f177..087f48e3fdf7 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -31,11 +31,11 @@ static const char rcsid[] = #include #include -#include -#include -#include -#include + #include +#include +#include +#include #include "pw.h" diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c index 22e80b0cc2d3..3f19e77aa7c3 100644 --- a/usr.sbin/pw/pw_group.c +++ b/usr.sbin/pw/pw_group.c @@ -32,10 +32,10 @@ static const char rcsid[] = #include #include #include -#include #include #include -#include +#include +#include #include #include diff --git a/usr.sbin/pw/pw_log.c b/usr.sbin/pw/pw_log.c index b7744234c336..29038d903747 100644 --- a/usr.sbin/pw/pw_log.c +++ b/usr.sbin/pw/pw_log.c @@ -30,6 +30,8 @@ static const char rcsid[] = #endif /* not lint */ #include +#include +#include #include "pw.h" diff --git a/usr.sbin/pw/pw_nis.c b/usr.sbin/pw/pw_nis.c index 669783546505..6cc361b7a25c 100644 --- a/usr.sbin/pw/pw_nis.c +++ b/usr.sbin/pw/pw_nis.c @@ -30,6 +30,7 @@ static const char rcsid[] = #endif /* not lint */ #include + #include #include #include diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 172e5efec144..b54cccb07da8 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -30,23 +30,28 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include +#include +#include +#include + #include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include #include +#include +#include +#include +#include +#include +#include + #include "pw.h" #include "bitmap.h" +#include "psdate.h" #define LOGNAMESIZE (MAXLOGNAME-1) diff --git a/usr.sbin/pw/pw_utils.c b/usr.sbin/pw/pw_utils.c index 31b79c078e4a..1a4f8127de14 100644 --- a/usr.sbin/pw/pw_utils.c +++ b/usr.sbin/pw/pw_utils.c @@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include "pw.h" diff --git a/usr.sbin/pw/pwupd.c b/usr.sbin/pw/pwupd.c index f9e1959f44a7..ee23952e090f 100644 --- a/usr.sbin/pw/pwupd.c +++ b/usr.sbin/pw/pwupd.c @@ -29,18 +29,16 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include + +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include "pwupd.h" From 9261982d92ebcc190f0b7fb269afbb47bd884756 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 13:32:23 +0000 Subject: [PATCH 169/314] Split some extra long lines --- usr.sbin/pw/pw_user.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index b54cccb07da8..33968ee138be 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -623,7 +623,8 @@ rmat(uid_t uid) st.st_uid == uid) { char tmp[MAXPATHLEN]; - snprintf(tmp, sizeof(tmp), "/usr/bin/atrm %s", e->d_name); + snprintf(tmp, sizeof(tmp), "/usr/bin/atrm %s", + e->d_name); system(tmp); } } @@ -869,7 +870,8 @@ pw_user_del(int argc, char **argv, char *arg1) /* Remove crontabs */ snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name); if (access(file, F_OK) == 0) { - snprintf(file, sizeof(file), "crontab -u %s -r", pwd->pw_name); + snprintf(file, sizeof(file), "crontab -u %s -r", + pwd->pw_name); system(file); } } @@ -1321,7 +1323,8 @@ pw_user_add(int argc, char **argv, char *arg1) printf("%s\n", cmdcnf->nispasswd); rc = addnispwent(cmdcnf->nispasswd, pwd); if (rc == -1) - warnx("User '%s' already exists in NIS passwd", pwd->pw_name); + warnx("User '%s' already exists in NIS passwd", + pwd->pw_name); else if (rc != 0) warn("NIS passwd update"); /* NOTE: we treat NIS-only update errors as non-fatal */ @@ -1351,7 +1354,8 @@ pw_user_add(int argc, char **argv, char *arg1) grp = GETGRGID(pwd->pw_gid); pw_log(cnf, M_ADD, W_USER, "%s(%ju):%s(%ju):%s:%s:%s", pwd->pw_name, (uintmax_t)pwd->pw_uid, - grp ? grp->gr_name : "unknown", (uintmax_t)(grp ? grp->gr_gid : (uid_t)-1), + grp ? grp->gr_name : "unknown", + (uintmax_t)(grp ? grp->gr_gid : (uid_t)-1), pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); /* @@ -1582,7 +1586,8 @@ pw_user_mod(int argc, char **argv, char *arg1) if (pwd->pw_uid != 0 && strcmp(pwd->pw_name, "root") == 0) errx(EX_DATAERR, "can't change uid of `root' account"); if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0) - warnx("WARNING: account `%s' will have a uid of 0 (superuser access!)", pwd->pw_name); + warnx("WARNING: account `%s' will have a uid of 0 " + "(superuser access!)", pwd->pw_name); } if (grname && pwd->pw_uid != 0) { From 8159e0373f3875960feaa3a6a56085fb92e6b033 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 13:33:17 +0000 Subject: [PATCH 170/314] Split some extra long lines --- usr.sbin/pw/pw_group.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c index 3f19e77aa7c3..df2d76da4a1e 100644 --- a/usr.sbin/pw/pw_group.c +++ b/usr.sbin/pw/pw_group.c @@ -180,7 +180,8 @@ gr_gidpolicy(struct userconf * cnf, intmax_t id) gid = (gid_t) id; if ((grp = GETGRGID(gid)) != NULL && conf.checkduplicate) - errx(EX_DATAERR, "gid `%ju' has already been allocated", (uintmax_t)grp->gr_gid); + errx(EX_DATAERR, "gid `%ju' has already been allocated", + (uintmax_t)grp->gr_gid); return (gid); } @@ -222,7 +223,8 @@ gr_gidpolicy(struct userconf * cnf, intmax_t id) * Another sanity check */ if (gid < cnf->min_gid || gid > cnf->max_gid) - errx(EX_SOFTWARE, "unable to allocate a new gid - range fully used"); + errx(EX_SOFTWARE, "unable to allocate a new gid - range fully " + "used"); bm_dealloc(&bm); return (gid); } From fc5079452d00bfa4932b7744221fd74a56cc5884 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 13:50:11 +0000 Subject: [PATCH 171/314] Fix build on 32bits --- usr.sbin/pw/pw_conf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index 087f48e3fdf7..c79b60aa3f95 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -493,11 +493,11 @@ write_userconfig(struct userconf *cnf, const char *file) quote = 0; break; case _UC_EXPIRE: - sbuf_printf(buf, "%ld", cnf->expire_days); + sbuf_printf(buf, "%lld", (long long)cnf->expire_days); quote = 0; break; case _UC_PASSWORD: - sbuf_printf(buf, "%ld", cnf->password_days); + sbuf_printf(buf, "%lld", (long long)cnf->password_days); quote = 0; break; case _UC_NONE: From 43a81e6322099b6f2820d5ec3cf15416f74cb30b Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 2 Aug 2015 14:56:30 +0000 Subject: [PATCH 172/314] Add a manual page for the cloudabi and cloudabi64 kernel modules. CloudABI has two separate kernel modules: cloudabi and cloudabi64. The first module contains all the pointer size independent code, whereas cloudabi64 contains the actual 64-bits specific system calls and the ELF loader. Reviewed by: wblock Obtained from: https://github.com/NuxiNL/freebsd Differential Revision: https://reviews.freebsd.org/D3258 --- share/man/man4/Makefile | 2 + share/man/man4/cloudabi.4 | 103 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 share/man/man4/cloudabi.4 diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 8bb6a96def7c..5cb8c2308c63 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -96,6 +96,7 @@ MAN= aac.4 \ cdce.4 \ ch.4 \ ciss.4 \ + cloudabi.4 \ cm.4 \ cmx.4 \ ${_coretemp.4} \ @@ -583,6 +584,7 @@ MLINKS+=bwn.4 if_bwn.4 MLINKS+=${_bxe.4} ${_if_bxe.4} MLINKS+=cas.4 if_cas.4 MLINKS+=cdce.4 if_cdce.4 +MLINKS+=cloudabi.4 cloudabi64.4 MLINKS+=crypto.4 cryptodev.4 MLINKS+=cue.4 if_cue.4 MLINKS+=cxgb.4 if_cxgb.4 diff --git a/share/man/man4/cloudabi.4 b/share/man/man4/cloudabi.4 new file mode 100644 index 000000000000..050e8c0eb63d --- /dev/null +++ b/share/man/man4/cloudabi.4 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2015 Nuxi, https://nuxi.nl/ +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.Dd July 31, 2015 +.Dt CLOUDABI 4 +.Os +.Sh NAME +.Nm cloudabi , +.Nm cloudabi64 +.Nd CloudABI support +.Sh SYNOPSIS +Support for 64-bit CloudABI executables can be compiled into the kernel +by adding this line to the kernel configuration file: +.Bd -ragged -offset indent +.Cd "options COMPAT_CLOUDABI64" +.Ed +.Pp +CloudABI support can also be loaded at boot time from +.Xr loader.conf 5 : +.Bd -literal -offset indent +cloudabi_load="YES" +cloudabi64_load="YES" +.Ed +.Sh DESCRIPTION +CloudABI is a POSIX-like pure capability-based runtime environment, +similar to +.Xr capsicum 4 . +It can be used to develop applications that are cross-platform, +easier to test, +and hardened against security exploits. +.Pp +Support for CloudABI on +.Fx +consists of two separate kernel modules. +The +.Nm cloudabi +kernel module implements all of the system calls that do not depend on +data structures that differ between architectures. +.Pp +The +.Nm cloudabi64 +kernel module provides implementations of all of the machine-dependent +system calls. +It assumes that pointers stored in data structures provided as system +call arguments are 64 bits in size. +It also provides the image activator that loads and starts 64-bit ELF +executables. +.Pp +Though the +.Nm cloudabi +module can be loaded on any architecture supported by +.Fx , +the +.Nm cloudabi64 +module is only available for amd64. +.Pp +A full cross compilation toolchain for CloudABI is available in the +.Pa devel/cloudabi-toolchain +port. +.Pp +The +.Pa sysutils/cloudabi-utils +port provides the +.Xr cloudabi-run 1 +utility. +.Xr cloudabi-run 1 +can be used to safely execute CloudABI processes with access to a +restricted set of resources. +.Sh SEE ALSO +.Xr cloudabi-run 1 , +.Xr capsicum 4 , +.Xr linux 4 , +.Xr elf 5 +.Pp +cloudlibc on GitHub: +.Pa https://github.com/NuxiNL/cloudlibc . +.Sh HISTORY +CloudABI support first appeared in +.Fx 11.0 . +.Sh AUTHORS +Nuxi: +.Pa https://nuxi.nl/ . From e7e71dd7f3a496ec1e3bcaf85d46d8da3a216a44 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sun, 2 Aug 2015 16:07:30 +0000 Subject: [PATCH 173/314] Don't take the port numbers for packets containing ABORT chunks from a freed mbuf. Just use them from the stcb. MFC after: 3 days --- sys/netinet/sctp_indata.c | 24 +++++------------------- sys/netinet/sctp_indata.h | 6 +----- sys/netinet/sctp_input.c | 5 +---- 3 files changed, 7 insertions(+), 28 deletions(-) diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index a5eb3c6941df..7d92655cc745 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -2312,11 +2312,8 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc) int sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, - struct sockaddr *src, struct sockaddr *dst, - struct sctphdr *sh, struct sctp_inpcb *inp, - struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t * high_tsn, - uint8_t mflowtype, uint32_t mflowid, - uint32_t vrf_id, uint16_t port) + struct sctp_inpcb *inp, struct sctp_tcb *stcb, + struct sctp_nets *net, uint32_t * high_tsn) { struct sctp_data_chunk *ch, chunk_buf; struct sctp_association *asoc; @@ -2408,10 +2405,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, chk_length); op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_21; - sctp_abort_association(inp, stcb, m, iphlen, - src, dst, sh, op_err, - mflowtype, mflowid, - vrf_id, port); + sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); return (2); } if ((size_t)chk_length == sizeof(struct sctp_data_chunk)) { @@ -2423,10 +2417,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, op_err = sctp_generate_no_user_data_cause(ch->dp.tsn); stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_22; - sctp_abort_association(inp, stcb, m, iphlen, - src, dst, sh, op_err, - mflowtype, mflowid, - vrf_id, port); + sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); return (2); } #ifdef SCTP_AUDITING_ENABLED @@ -2493,12 +2484,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, snprintf(msg, sizeof(msg), "DATA chunk followed by chunk of type %2.2x", ch->ch.chunk_type); op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); - sctp_abort_association(inp, stcb, - m, iphlen, - src, dst, - sh, op_err, - mflowtype, mflowid, - vrf_id, port); + sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); return (2); } break; diff --git a/sys/netinet/sctp_indata.h b/sys/netinet/sctp_indata.h index 79a86e2a6ff0..94cd49c6f51b 100644 --- a/sys/netinet/sctp_indata.h +++ b/sys/netinet/sctp_indata.h @@ -112,12 +112,8 @@ void int sctp_process_data(struct mbuf **, int, int *, int, - struct sockaddr *src, struct sockaddr *dst, - struct sctphdr *, struct sctp_inpcb *, struct sctp_tcb *, - struct sctp_nets *, uint32_t *, - uint8_t, uint32_t, - uint32_t, uint16_t); + struct sctp_nets *, uint32_t *); void sctp_slide_mapping_arrays(struct sctp_tcb *stcb); diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 4e9fa88e72df..9071bf6708ee 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -5981,10 +5981,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt } /* plow through the data chunks while length > offset */ retval = sctp_process_data(mm, iphlen, &offset, length, - src, dst, sh, - inp, stcb, net, &high_tsn, - mflowtype, mflowid, - vrf_id, port); + inp, stcb, net, &high_tsn); if (retval == 2) { /* * The association aborted, NO UNLOCK needed since From 123049cf36f4d2bd7bf4027522d700869db51982 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 2 Aug 2015 16:26:41 +0000 Subject: [PATCH 174/314] Don't forget to check the vendor when probing. Also, there's no need to double check for if the card has probed before. In fact, there's no reason to single check either. Simplify the code as a result. $FreeBSD$ added to lxutil.c in a non-standard way to help keep the diffs with upstream to a minimum. Differential Revision: https://reviews.freebsd.org/D3263 --- sys/dev/pms/freebsd/driver/common/lxutil.c | 48 +++++++++----------- sys/dev/pms/freebsd/driver/ini/src/agtiapi.c | 42 +++++------------ 2 files changed, 33 insertions(+), 57 deletions(-) diff --git a/sys/dev/pms/freebsd/driver/common/lxutil.c b/sys/dev/pms/freebsd/driver/common/lxutil.c index 4cc16c150792..365ba5ae4116 100644 --- a/sys/dev/pms/freebsd/driver/common/lxutil.c +++ b/sys/dev/pms/freebsd/driver/common/lxutil.c @@ -19,6 +19,7 @@ *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE ******************************************************************************/ +/* $FreeBSD$ */ /****************************************************************************** This program is part of PMC-Sierra initiator/target device driver. The functions here are commonly used by different type of drivers that support @@ -756,37 +757,30 @@ STATIC int agtiapi_ProbeCard( device_t dev, int thisCard ) { int idx; - static U32 cardMap[4] = { 0, 0, 0, 0 }; + u_int16_t agtiapi_vendor; // PCI vendor ID u_int16_t agtiapi_dev; // PCI device ID AGTIAPI_PRINTK("agtiapi_ProbeCard: start\n"); - if ( ! atomic_cmpset_32( &cardMap[thisCard], 0, 5 ) ) { // card already ran - AGTIAPI_PRINTK( "We'll only ID this card once -- %d\n", thisCard ); - return 2; // error return value; card already ran this function - } - else { - agtiapi_dev = pci_get_device( dev ); // get PCI device ID - for( idx = 0; idx < COUNT(ag_card_type); idx++ ) - { - if( ag_card_type[idx].deviceId == agtiapi_dev ) - { // device ID match - memset( (void *)&agCardInfoList[ thisCard ], 0, - sizeof(ag_card_info_t) ); - thisCardInst->cardIdIndex = idx; - thisCardInst->pPCIDev = dev; - thisCardInst->cardNameIndex = ag_card_type[idx].cardNameIndex; - thisCardInst->cardID = - pci_read_config( dev, ag_card_type[idx].membar, 4 ); // memAddr - AGTIAPI_PRINTK("agtiapi_ProbeCard: We've got PMC SAS, probe successful %p / %p\n", - thisCardInst->pPCIDev, thisCardInst ); - device_printf( dev, - "agtiapi PCI Probe Vendor ID : 0x%x Device ID : 0x%x\n", - pci_get_vendor(dev), agtiapi_dev ); - device_set_desc( dev, ag_card_names[ag_card_type[idx].cardNameIndex] ); - return 0; - } + agtiapi_vendor = pci_get_vendor( dev ); // get PCI vendor ID + agtiapi_dev = pci_get_device( dev ); // get PCI device ID + for( idx = 0; idx < COUNT(ag_card_type); idx++ ) + { + if ( ag_card_type[idx].deviceId == agtiapi_dev && + ag_card_type[idx].vendorId == agtiapi_vendor) + { // device ID match + memset( (void *)&agCardInfoList[ thisCard ], 0, + sizeof(ag_card_info_t) ); + thisCardInst->cardIdIndex = idx; + thisCardInst->pPCIDev = dev; + thisCardInst->cardNameIndex = ag_card_type[idx].cardNameIndex; + thisCardInst->cardID = + pci_read_config( dev, ag_card_type[idx].membar, 4 ); // memAddr + AGTIAPI_PRINTK("agtiapi_ProbeCard: We've got PMC SAS, probe successful %p / %p\n", + thisCardInst->pPCIDev, thisCardInst ); + device_set_desc( dev, ag_card_names[ag_card_type[idx].cardNameIndex] ); + return 0; } } - return 7; + return 1; } diff --git a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c index 47922db9d863..0a500cb23bb6 100644 --- a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c +++ b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c @@ -214,7 +214,6 @@ STATIC void agtiapi_CheckIOTimeout(void *data); -static unsigned char cardMap[AGTIAPI_MAX_CARDS] = { 0, 0, 0, 0 }; static ag_card_info_t agCardInfoList[ AGTIAPI_MAX_CARDS ]; // card info list static void agtiapi_cam_action( struct cam_sim *, union ccb * ); static void agtiapi_cam_poll( struct cam_sim * ); @@ -695,37 +694,20 @@ agtiapi_probe() static int agtiapi_probe( device_t dev ) { int retVal; - - if ( pci_get_vendor(dev) == PCI_VENDOR_ID_PMC_SIERRA || - pci_get_vendor(dev) == PCI_VENDOR_ID_HIALEAH ) + int thisCard; + ag_card_info_t *thisCardInst; + + thisCard = device_get_unit( dev ); + if ( thisCard >= AGTIAPI_MAX_CARDS ) { - int thisCard = device_get_unit( dev ); -// AGTIAPI_PRINTK("agtiapi_probe: thisCard %d\n", thisCard); - if( thisCard >= AGTIAPI_MAX_CARDS) - { - device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" ); - return (ENXIO); // maybe change to different return value? - } - ag_card_info_t *thisCardInst = &agCardInfoList[ thisCard ]; - retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard ); - if ( retVal ) { - // error on probe - if( retVal == 2 ) return 0; // another thread ran probe on this card - device_printf( dev, - "agtiapi_probe: PCI DEVICE NOT SUPPORTED by this driver!!" - "Vendor ID : 0x%x Device ID : 0x%x\n", - pci_get_vendor(dev), pci_get_device( dev ) ); - return (ENXIO); // maybe change to different return value? - } - else { - // AGTIAPI_PRINTK( "agtiapi_ProbeCard: returned with pointer values " - // "%p / %p\n", - // thisCardInst->pPCIDev, thisCardInst ); - cardMap[thisCard] = 11; // record this card is present - return( BUS_PROBE_DEFAULT ); // successful probe - } + device_printf( dev, "Too many PMC-Sierra cards detected ERROR!\n" ); + return (ENXIO); // maybe change to different return value? } - return (ENXIO); + thisCardInst = &agCardInfoList[ thisCard ]; + retVal = agtiapi_ProbeCard( dev, thisCardInst, thisCard ); + if ( retVal ) + return (ENXIO); // maybe change to different return value? + return( BUS_PROBE_DEFAULT ); // successful probe } From 9e24273cca4d0909e6e6e58354aa25840a26123f Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 18:20:36 +0000 Subject: [PATCH 175/314] Convert the year used for regression test fro 2043 to 2037 This makes the regression tests pass on systems where time_t is 32bits --- usr.sbin/pw/tests/pw_useradd.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/usr.sbin/pw/tests/pw_useradd.sh b/usr.sbin/pw/tests/pw_useradd.sh index f42980d76cc2..2ac31c96ac2f 100755 --- a/usr.sbin/pw/tests/pw_useradd.sh +++ b/usr.sbin/pw/tests/pw_useradd.sh @@ -181,29 +181,29 @@ user_add_expiration_body() { populate_etc_skel atf_check -s exit:0 \ - ${PW} useradd foo -e 20-03-2043 - atf_check -o inline:"foo:*:1001:1001::0:2310422400:User &:/home/foo:/bin/sh\n" \ + ${PW} useradd foo -e 20-03-2037 + atf_check -o inline:"foo:*:1001:1001::0:2121120000:User &:/home/foo:/bin/sh\n" \ -s exit:0 grep "^foo" ${HOME}/master.passwd atf_check -s exit:0 ${PW} userdel foo atf_check -s exit:0 \ - ${PW} useradd foo -e 20-03-43 - atf_check -o inline:"foo:*:1001:1001::0:2310422400:User &:/home/foo:/bin/sh\n" \ + ${PW} useradd foo -e 20-03-37 + atf_check -o inline:"foo:*:1001:1001::0:2121120000:User &:/home/foo:/bin/sh\n" \ -s exit:0 grep "^foo" ${HOME}/master.passwd atf_check -s exit:0 ${PW} userdel foo atf_check -s exit:0 \ - ${PW} useradd foo -e 20-Mar-2043 - atf_check -o inline:"foo:*:1001:1001::0:2310422400:User &:/home/foo:/bin/sh\n" \ + ${PW} useradd foo -e 20-Mar-2037 + atf_check -o inline:"foo:*:1001:1001::0:2121120000:User &:/home/foo:/bin/sh\n" \ -s exit:0 grep "^foo" ${HOME}/master.passwd atf_check -s exit:0 ${PW} userdel foo atf_check -e inline:"pw: Invalid date\n" -s exit:1 \ - ${PW} useradd foo -e 20-Foo-2043 + ${PW} useradd foo -e 20-Foo-2037 atf_check -e inline:"pw: Invalid date\n" -s exit:1 \ - ${PW} useradd foo -e 20-13-2043 - atf_check -s exit:0 ${PW} useradd foo -e "12:00 20-03-2043" + ${PW} useradd foo -e 20-13-2037 + atf_check -s exit:0 ${PW} useradd foo -e "12:00 20-03-2037" atf_check -s exit:0 ${PW} userdel foo atf_check -e inline:"pw: Invalid date\n" -s exit:1 \ - ${PW} useradd foo -e "12 20-03-2043" - atf_check -s exit:0 ${PW} useradd foo -e "20-03-2043 12:00" + ${PW} useradd foo -e "12 20-03-2037" + atf_check -s exit:0 ${PW} useradd foo -e "20-03-2037 12:00" atf_check -s exit:0 ${PW} userdel foo } From 5cc12db1c76615e73b435ae6c27d60db045e49cf Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sun, 2 Aug 2015 19:49:24 +0000 Subject: [PATCH 176/314] Use intmax_t rather than long long --- usr.sbin/pw/pw_conf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index c79b60aa3f95..e9606b4e6a2f 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -493,11 +493,11 @@ write_userconfig(struct userconf *cnf, const char *file) quote = 0; break; case _UC_EXPIRE: - sbuf_printf(buf, "%lld", (long long)cnf->expire_days); + sbuf_printf(buf, "%jd", (intmax_t)cnf->expire_days); quote = 0; break; case _UC_PASSWORD: - sbuf_printf(buf, "%lld", (long long)cnf->password_days); + sbuf_printf(buf, "%jd", (intmax_t)cnf->password_days); quote = 0; break; case _UC_NONE: From 8743ddd850c816e67ab1b0ea23be6ed28c890cb2 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sun, 2 Aug 2015 21:24:03 +0000 Subject: [PATCH 177/314] Add an example program (in Python) for the AMD Am79c900 (ILACC) ethernet controller. The ethernet controller is emulated by VMware Fusion (for example) and is a good device to demonstrate how to use the bus space and busdma functions due to its simple programming. The program sets up the DMA structures, sends a DHCP discover packet, waits 2 seconds, and iterates over the receive ring for an offer. --- tools/bus_space/examples/am79c900_diag.py | 344 ++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 tools/bus_space/examples/am79c900_diag.py diff --git a/tools/bus_space/examples/am79c900_diag.py b/tools/bus_space/examples/am79c900_diag.py new file mode 100644 index 000000000000..bcea31b32460 --- /dev/null +++ b/tools/bus_space/examples/am79c900_diag.py @@ -0,0 +1,344 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014 Marcel Moolenaar +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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$ +# + +''' +Simple diagnostics program fo the AMD Am89c900 series ILACC. +This ethernet controller is emulated by VMware Fusion among +possibly other virtualization platforms. + +The datasheet can be found here: + http://support.amd.com/TechDocs/18219.pdf + +This example program sends a single DHCP discovery packet, +waits 2 seconds and then iterates over the receive ring for +a targeted packet. + +For this program to function, connect the network interface +to a network with a DHCP server. In VMware Fusion this can +best be done by configuring the interface as a NAT interface +using the "Share with my Mac" setting. +''' + +import ctypes +import logging +import os +import sys +import time + +sys.path.append('/usr/lib') + +import bus +import busdma + + +# ILACC initialization block definition +class initblock(ctypes.LittleEndianStructure): + _fields_ = [('mode', ctypes.c_uint32), + ('hwaddr', ctypes.c_uint8 * 6), + ('_pad1_', ctypes.c_uint16), + ('filter', ctypes.c_uint16 * 4), + ('rxdesc', ctypes.c_uint32), + ('txdesc', ctypes.c_uint32), + ('_pad2_', ctypes.c_uint32)] + + +# ILACC ring buffer descriptor +class bufdesc(ctypes.LittleEndianStructure): + _fields_ = [('buffer', ctypes.c_uint32), + ('flags', ctypes.c_uint32), + ('length', ctypes.c_uint32), + ('_pad_', ctypes.c_uint32)] + + +# The DHCP packet definition (incl. all headers) +class packet(ctypes.BigEndianStructure): + _pack_ = 1 + _fields_ = [('eth_dest', ctypes.c_uint8 * 6), + ('eth_src', ctypes.c_uint8 * 6), + ('eth_type', ctypes.c_uint16), + ('ip_vl', ctypes.c_uint8), + ('ip_de', ctypes.c_uint8), + ('ip_len', ctypes.c_uint16), + ('ip_id', ctypes.c_uint16), + ('ip_ff', ctypes.c_uint16), + ('ip_ttl', ctypes.c_uint8), + ('ip_proto', ctypes.c_uint8), + ('ip_cksum', ctypes.c_uint16), + ('ip_src', ctypes.c_uint32), + ('ip_dest', ctypes.c_uint32), + ('udp_src', ctypes.c_uint16), + ('udp_dest', ctypes.c_uint16), + ('udp_len', ctypes.c_uint16), + ('udp_cksum', ctypes.c_uint16), + ('bootp_op', ctypes.c_uint8), + ('bootp_htype', ctypes.c_uint8), + ('bootp_hlen', ctypes.c_uint8), + ('bootp_hops', ctypes.c_uint8), + ('bootp_xid', ctypes.c_uint32), + ('bootp_secs', ctypes.c_uint16), + ('bootp_flags', ctypes.c_uint16), + ('bootp_ciaddr', ctypes.c_uint32), + ('bootp_yiaddr', ctypes.c_uint32), + ('bootp_siaddr', ctypes.c_uint32), + ('bootp_giaddr', ctypes.c_uint32), + ('bootp_chaddr', ctypes.c_uint8 * 16), + ('bootp_sname', ctypes.c_uint8 * 64), + ('bootp_file', ctypes.c_uint8 * 128), + ('dhcp_magic', ctypes.c_uint32), + ('dhcp_options', ctypes.c_uint8 * 60)] + +MACFMT = '%02x:%02x:%02x:%02x:%02x:%02x' + +dev = 'pci0:2:1:0' + +logging.basicConfig(level=logging.DEBUG) + +pcicfg = bus.map(dev, 'pcicfg') +logging.debug('pcicfg=%s (%s)' % (pcicfg, dev)) + +vendor = bus.read_2(pcicfg, 0) +device = bus.read_2(pcicfg, 2) +if vendor != 0x1022 or device != 0x2000: + logging.error('Not an AMD PCnet-PCI (vendor=%x, device=%x)' % + (vendor, device)) + sys.exit(1) + +command = bus.read_2(pcicfg, 4) +if not (command & 1): + logging.info('enabling I/O port decoding') + command |= 1 + bus.write_2(pcicfg, 4, command) + +if not (command & 4): + logging.info('enabling bus mastering') + command |= 4 + bus.write_2(pcicfg, 4, command) + +bus.unmap(pcicfg) + +io = bus.map(dev, '10.io') +logging.debug('io=%s (%s)' % (io, dev)) + + +def delay(msec): + time.sleep(msec / 1000.0) + + +def ffs(x): + y = (1 + (x ^ (x-1))) >> 1 + return y.bit_length() + + +def ip_str(a): + return '%d.%d.%d.%d' % ((a >> 24) & 255, (a >> 16) & 255, (a >> 8) & 255, + a & 255) + + +def mac_is(l, r): + for i in xrange(6): + if l[i] != r[i]: + return False + return True + + +def mac_str(m): + return MACFMT % (m[0], m[1], m[2], m[3], m[4], m[5]) + + +def rdbcr(reg): + bus.write_2(io, 0x12, reg & 0xffff) + return bus.read_2(io, 0x16) + + +def wrbcr(reg, val): + bus.write_2(io, 0x12, reg & 0xffff) + bus.write_2(io, 0x16, val & 0xffff) + + +def rdcsr(reg): + bus.write_2(io, 0x12, reg & 0xffff) + return bus.read_2(io, 0x10) + + +def wrcsr(reg, val): + bus.write_2(io, 0x12, reg & 0xffff) + bus.write_2(io, 0x10, val & 0xffff) + + +def start(): + wrcsr(0, 0x42) + delay(100) + + +def stop(): + wrcsr(0, 4) + delay(100) + + +mac = () +bcast = () +for o in xrange(6): + mac += (bus.read_1(io, o),) + bcast += (0xff,) +logging.info('ethernet address = ' + MACFMT % mac) + +stop() +wrbcr(20, 2) # reset +wrcsr(3, 0) # byte swapping mode +wrbcr(2, rdbcr(2) | 2) # Autoneg + +memsize = 32*1024 +bufsize = 1536 +nrxbufs = 16 +ntxbufs = 4 +logging.debug("DMA memory: size = %#x (TX buffers: %u, RX buffers: %u)" % + (memsize, ntxbufs, nrxbufs)) + +mem_tag = busdma.tag_create(dev, 16, 0, 0xffffffff, memsize, 1, memsize, 0, 0) +dmamem = busdma.mem_alloc(mem_tag, 0) +busseg = busdma.md_first_seg(dmamem, busdma.MD_BUS_SPACE) +cpuseg = busdma.md_first_seg(dmamem, busdma.MD_VIRT_SPACE) +busaddr = busdma.seg_get_addr(busseg) +cpuaddr = busdma.seg_get_addr(cpuseg) +logging.debug("DMA memory: CPU address: %#x, device address: %#x" % + (cpuaddr, busaddr)) + +addr_initblock = cpuaddr +addr_rxdesc = addr_initblock + ctypes.sizeof(initblock) +addr_txdesc = addr_rxdesc + ctypes.sizeof(bufdesc) * nrxbufs +addr_rxbufs = addr_txdesc + ctypes.sizeof(bufdesc) * ntxbufs +addr_txbufs = addr_rxbufs + bufsize * nrxbufs + +ib = initblock.from_address(addr_initblock) +ib.mode = ((ffs(ntxbufs) - 1) << 28) | ((ffs(nrxbufs) - 1) << 20) +for i in xrange(len(mac)): + ib.hwaddr[i] = mac[i] +for i in xrange(4): + ib.filter[i] = 0xffff +ib.rxdesc = busaddr + (addr_rxdesc - cpuaddr) +ib.txdesc = busaddr + (addr_txdesc - cpuaddr) +ib._pad1_ = 0 +ib._pad2_ = 0 + +for i in xrange(nrxbufs): + bd = bufdesc.from_address(addr_rxdesc + ctypes.sizeof(bufdesc) * i) + bd.buffer = busaddr + (addr_rxbufs - cpuaddr) + bufsize * i + bd.flags = (1 << 31) | (15 << 12) | (-bufsize & 0xfff) + bd.length = 0 + bd._pad_ = 0 + +for i in xrange(ntxbufs): + bd = bufdesc.from_address(addr_txdesc + ctypes.sizeof(bufdesc) * i) + bd.buffer = busaddr + (addr_txbufs - cpuaddr) + bufsize * i + bd.flags = (15 << 12) + bd.length = 0 + bd._pad_ = 0 + +busdma.sync_range(dmamem, busdma.SYNC_PREWRITE, 0, addr_rxbufs - cpuaddr) + +# Program address of DMA memory +wrcsr(1, busaddr) +wrcsr(2, busaddr >> 16) +delay(100) + +# Initialize hardware +wrcsr(0, 1) +logging.debug('Waiting for initialization to complete') +csr = rdcsr(0) +while (csr & 0x100) == 0: + logging.debug('CSR=%#x' % (csr)) + csr = rdcsr(0) + +start() + +pkt = packet.from_address(addr_txbufs) +ctypes.memset(addr_txbufs, 0, ctypes.sizeof(pkt)) +options = [53, 1, 1] +for i in xrange(len(options)): + pkt.dhcp_options[i] = options[i] +pkt.dhcp_magic = 0x63825363 +for i in xrange(6): + pkt.bootp_chaddr[i] = mac[i] +pkt.bootp_hlen = 6 +pkt.bootp_htype = 1 +pkt.bootp_op = 1 +pkt.udp_len = ctypes.sizeof(pkt) - 34 +pkt.udp_dest = 67 +pkt.udp_src = 68 +pkt.ip_dest = 0xffffffff +pkt.ip_cksum = 0x79a6 +pkt.ip_proto = 17 +pkt.ip_ttl = 64 +pkt.ip_len = ctypes.sizeof(pkt) - 14 +pkt.ip_vl = 0x45 +pkt.eth_type = 0x0800 +for i in xrange(6): + pkt.eth_src[i] = mac[i] + pkt.eth_dest[i] = bcast[i] +pktlen = ctypes.sizeof(pkt) + +busdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_txbufs - cpuaddr, bufsize) + +bd = bufdesc.from_address(addr_txdesc) +bd.length = 0 +bd.flags = (1 << 31) | (1 << 25) | (1 << 24) | (0xf << 12) | (-pktlen & 0xfff) + +busdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_txdesc - cpuaddr, + ctypes.sizeof(bufdesc)) + +wrcsr(0, 0x48) + +logging.info('DHCP discovery packet sent') + +# Now wait 2 seconds for a DHCP offer to be received. +logging.debug('Waiting 2 seconds for an offer to be received') +time.sleep(2) + +stop() + +busdma.sync_range(dmamem, busdma.SYNC_PREWRITE, addr_rxdesc - cpuaddr, + ctypes.sizeof(bufdesc) * nrxbufs) + +for i in xrange(nrxbufs): + bd = bufdesc.from_address(addr_rxdesc + ctypes.sizeof(bufdesc) * i) + if (bd.flags & 0x80000000): + continue + pkt = packet.from_address(addr_rxbufs + i * bufsize) + if mac_is(pkt.eth_dest, bcast): + logging.debug('RX #%d: broadcast packet: length %u' % (i, bd.length)) + continue + if not mac_is(pkt.eth_dest, mac): + logging.debug('RX #%d: packet for %s?' % (i, mac_str(pkt.eth_dest))) + continue + logging.debug('RX %d: packet from %s!' % (i, mac_str(pkt.eth_src))) + logging.info('Our IP address = %s' % (ip_str(pkt.ip_dest))) + +busdma.mem_free(dmamem) +busdma.tag_destroy(mem_tag) +bus.unmap(io) From bba6880eab5669dead818593ed193bb9560913cc Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Sun, 2 Aug 2015 21:33:40 +0000 Subject: [PATCH 178/314] looks like all archs either have clang or cdefs included before.. drop this include as unnecessary.. Requested by: bde --- sys/net/pfkeyv2.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index ecefcaceb9b2..bab26fe9411e 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -39,8 +39,6 @@ #ifndef _NET_PFKEYV2_H_ #define _NET_PFKEYV2_H_ -#include - /* This file defines structures and symbols for the PF_KEY Version 2 key management interface. It was written at the U.S. Naval Research From 7b25d1d63be96ffbe08d2b95956fe0f86905da48 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 3 Aug 2015 01:22:49 +0000 Subject: [PATCH 179/314] Pass correct type of argument to ti_gpio_unmask_irq in ti_gpio_activate_resource --- sys/arm/ti/ti_gpio.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index a5f4176f6c1c..2818babe5ed7 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -849,14 +849,16 @@ static int ti_gpio_activate_resource(device_t dev, device_t child, int type, int rid, struct resource *res) { - int pin; + struct ti_gpio_mask_arg mask_arg; if (type != SYS_RES_IRQ) return (ENXIO); /* Unmask the interrupt. */ - pin = rman_get_start(res); - ti_gpio_unmask_irq((void *)(uintptr_t)pin); + mask_arg.pin = rman_get_start(res); + mask_arg.softc = device_get_softc(dev); + + ti_gpio_unmask_irq((void *)&mask_arg); return (0); } From ddaceed224879130356d8802562339609e45d276 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 3 Aug 2015 01:24:48 +0000 Subject: [PATCH 180/314] Make image_copyout_zeroes() an interface function. --- usr.bin/mkimg/image.c | 12 ++++++------ usr.bin/mkimg/image.h | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/usr.bin/mkimg/image.c b/usr.bin/mkimg/image.c index be1c2e9fcbb2..a3bec6350e82 100644 --- a/usr.bin/mkimg/image.c +++ b/usr.bin/mkimg/image.c @@ -517,14 +517,14 @@ image_copyout_memory(int fd, size_t size, void *ptr) return (0); } -static int -image_copyout_zeroes(int fd, size_t size) +int +image_copyout_zeroes(int fd, size_t count) { static uint8_t *zeroes = NULL; size_t sz; int error; - if (lseek(fd, (off_t)size, SEEK_CUR) != -1) + if (lseek(fd, (off_t)count, SEEK_CUR) != -1) return (0); /* @@ -537,12 +537,12 @@ image_copyout_zeroes(int fd, size_t size) return (ENOMEM); } - while (size > 0) { - sz = (size > secsz) ? secsz : size; + while (count > 0) { + sz = (count > secsz) ? secsz : count; error = image_copyout_memory(fd, sz, zeroes); if (error) return (error); - size -= sz; + count -= sz; } return (0); } diff --git a/usr.bin/mkimg/image.h b/usr.bin/mkimg/image.h index ce195d9b41ee..0405c5b37c27 100644 --- a/usr.bin/mkimg/image.h +++ b/usr.bin/mkimg/image.h @@ -35,6 +35,7 @@ int image_copyin(lba_t blk, int fd, uint64_t *sizep); int image_copyout(int fd); int image_copyout_done(int fd); int image_copyout_region(int fd, lba_t blk, lba_t size); +int image_copyout_zeroes(int fd, size_t count); int image_data(lba_t blk, lba_t size); lba_t image_get_size(void); int image_init(void); From bbec1b5a7bf0da8f4406a1517982fcc6a7ac1668 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 3 Aug 2015 05:59:30 +0000 Subject: [PATCH 181/314] Actually set quiet to something. /usr/home/adrian/work/freebsd/head-embedded-2/src/usr.sbin/pw/pw_user.c: In function 'pw_user_next': /usr/home/adrian/work/freebsd/head-embedded-2/src/usr.sbin/pw/pw_user.c:680: warning: statement with no effect --- usr.sbin/pw/pw_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 33968ee138be..f1207e03f4c9 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -677,7 +677,7 @@ pw_user_next(int argc, char **argv, char *name __unused) cfg = optarg; break; case 'q': - quiet; + quiet = true; break; } } From 5e52b667a7884fb58303192da59a55d939ef2c3a Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Mon, 3 Aug 2015 06:06:56 +0000 Subject: [PATCH 182/314] Fix bugs spotted by gcc Reported by: adrian --- usr.sbin/pw/pw_user.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index f1207e03f4c9..b51a6cbbabf9 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -700,7 +700,7 @@ pw_user_show(int argc, char **argv, char *arg1) { struct passwd *pwd = NULL; char *name = NULL; - uid_t id = -1; + intmax_t id = -1; int ch; bool all = false; bool pretty = false; @@ -786,7 +786,7 @@ pw_user_del(int argc, char **argv, char *arg1) char home[MAXPATHLEN]; const char *cfg = NULL; struct stat st; - uid_t id; + intmax_t id = -1; int ch, rc; bool nis = false; bool deletehome = false; @@ -1423,8 +1423,9 @@ pw_user_mod(int argc, char **argv, char *arg1) int ch, fd = -1; size_t i, j; bool quiet, createhome, pretty, dryrun, nis, edited, docreatehome; + bool precrypted; mode_t homemode = 0; - time_t expire_days, password_days, now, precrypted; + time_t expire_days, password_days, now; expire_days = password_days = -1; gecos = homedir = grname = name = newname = skel = shell =NULL; From 75c9f223942e627c310cb01884fd0c92ee386402 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 3 Aug 2015 07:29:57 +0000 Subject: [PATCH 183/314] Set p_osrel to __FreeBSD_version on process startup. Certain system calls have quirks applied to make them work as if called on an older version of FreeBSD. As CloudABI executables don't have the FreeBSD OS release number in the ELF header, this value is set to zero, making the system calls fall back to typically historic, non-standard behaviour. Reviewed by: kib --- sys/amd64/cloudabi64/cloudabi64_sysvec.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/amd64/cloudabi64/cloudabi64_sysvec.c b/sys/amd64/cloudabi64/cloudabi64_sysvec.c index 428d9f7602da..8e0be1e2e00d 100644 --- a/sys/amd64/cloudabi64/cloudabi64_sysvec.c +++ b/sys/amd64/cloudabi64/cloudabi64_sysvec.c @@ -73,10 +73,20 @@ cloudabi64_fixup(register_t **stack_base, struct image_params *imgp) { char canarybuf[64]; Elf64_Auxargs *args; + struct thread *td; void *argdata, *canary; size_t argdatalen; int error; + /* + * CloudABI executables do not store the FreeBSD OS release + * number in their header. Set the OS release number to the + * latest version of FreeBSD, so that system calls behave as if + * called natively. + */ + td = curthread; + td->td_proc->p_osrel = __FreeBSD_version; + /* Store canary for stack smashing protection. */ argdata = *stack_base; arc4rand(canarybuf, sizeof(canarybuf), 0); @@ -108,7 +118,7 @@ cloudabi64_fixup(register_t **stack_base, struct image_params *imgp) VAL(CLOUDABI_AT_PAGESZ, args->pagesz), PTR(CLOUDABI_AT_PHDR, args->phdr), VAL(CLOUDABI_AT_PHNUM, args->phnum), - VAL(CLOUDABI_AT_TID, curthread->td_tid), + VAL(CLOUDABI_AT_TID, td->td_tid), #undef VAL #undef PTR { .a_type = CLOUDABI_AT_NULL }, From ebbc56ecd6f462f1be9b2d877fca79c8b770a154 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Mon, 3 Aug 2015 09:34:09 +0000 Subject: [PATCH 184/314] Fix KSTACK_PAGES check in ZFS module The check introduced by r285946 failed to add the dependency on opt_kstack_pages.h which meant the default value for the platform instead of the customised options KSTACK_PAGES=X was being tested. Also wrap in #ifdef __FreeBSD__ for portability. MFC after: 3 days Sponsored by: Multiplay --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index 432c2fb2e5f5..7bf9de2a3659 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -132,6 +132,9 @@ * distinguish between the operation failing, and * deserialization failing. */ +#ifdef __FreeBSD__ +#include "opt_kstack_pages.h" +#endif #include #include @@ -6491,17 +6494,21 @@ static void zfs_shutdown(void *, int); static eventhandler_tag zfs_shutdown_event_tag; +#ifdef __FreeBSD__ #define ZFS_MIN_KSTACK_PAGES 4 +#endif int zfs__init(void) { +#ifdef __FreeBSD__ #if KSTACK_PAGES < ZFS_MIN_KSTACK_PAGES printf("ZFS NOTICE: KSTACK_PAGES is %d which could result in stack " "overflow panic!\nPlease consider adding " "'options KSTACK_PAGES=%d' to your kernel config\n", KSTACK_PAGES, ZFS_MIN_KSTACK_PAGES); +#endif #endif zfs_root_token = root_mount_hold("ZFS"); From f692e3255568a0cbfb00f7981b100cfd717179c6 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 3 Aug 2015 11:05:02 +0000 Subject: [PATCH 185/314] Pass the pcb to store the vfp state in to vfp_save_state. This fixes a bug in savectx where it will be used to store the current state however will pass in a pcb when vfp_save_state expected a thread pointer. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/arm64/machdep.c | 4 ++-- sys/arm64/arm64/swtch.S | 8 ++++++-- sys/arm64/arm64/vfp.c | 14 ++++++++++---- sys/arm64/arm64/vm_machdep.c | 2 +- sys/arm64/include/vfp.h | 2 +- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index f3679c718891..55994b65d43e 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -180,7 +180,7 @@ fill_fpregs(struct thread *td, struct fpreg *regs) * If we have just been running VFP instructions we will * need to save the state to memcpy it below. */ - vfp_save_state(td); + vfp_save_state(td, pcb); memcpy(regs->fp_q, pcb->pcb_vfp, sizeof(regs->fp_q)); regs->fp_cr = pcb->pcb_fpcr; @@ -314,7 +314,7 @@ get_fpcontext(struct thread *td, mcontext_t *mcp) * If we have just been running VFP instructions we will * need to save the state to memcpy it below. */ - vfp_save_state(td); + vfp_save_state(td, curpcb); memcpy(mcp->mc_fpregs.fp_q, curpcb->pcb_vfp, sizeof(mcp->mc_fpregs)); diff --git a/sys/arm64/arm64/swtch.S b/sys/arm64/arm64/swtch.S index a987134bc3b3..fbffaed437a6 100644 --- a/sys/arm64/arm64/swtch.S +++ b/sys/arm64/arm64/swtch.S @@ -131,6 +131,8 @@ ENTRY(cpu_switch) mov x19, x0 mov x20, x1 mov x21, x2 + /* Load the pcb address */ + mov x1, x4 bl vfp_save_state mov x2, x21 mov x1, x20 @@ -268,9 +270,11 @@ ENTRY(savectx) /* Store the VFP registers */ #ifdef VFP - mov x29, lr + mov x28, lr + mov x1, x0 /* move pcb to the correct register */ + mov x0, xzr /* td = NULL */ bl vfp_save_state - mov lr, x29 + mov lr, x28 #endif ret diff --git a/sys/arm64/arm64/vfp.c b/sys/arm64/arm64/vfp.c index a98724202607..8278f87bacd8 100644 --- a/sys/arm64/arm64/vfp.c +++ b/sys/arm64/arm64/vfp.c @@ -82,12 +82,18 @@ vfp_discard(struct thread *td) } void -vfp_save_state(struct thread *td) +vfp_save_state(struct thread *td, struct pcb *pcb) { __int128_t *vfp_state; uint64_t fpcr, fpsr; uint32_t cpacr; + KASSERT(pcb != NULL, ("NULL vfp pcb")); + KASSERT(td == NULL || td->td_pcb == pcb, ("Invalid vfp pcb")); + + if (td == NULL) + td = curthread; + critical_enter(); /* * Only store the registers if the VFP is enabled, @@ -98,7 +104,7 @@ vfp_save_state(struct thread *td) KASSERT(PCPU_GET(fpcurthread) == td, ("Storing an invalid VFP state")); - vfp_state = td->td_pcb->pcb_vfp; + vfp_state = pcb->pcb_vfp; __asm __volatile( "mrs %0, fpcr \n" "mrs %1, fpsr \n" @@ -120,8 +126,8 @@ vfp_save_state(struct thread *td) "stp q30, q31, [%2, #16 * 30]\n" : "=&r"(fpcr), "=&r"(fpsr) : "r"(vfp_state)); - td->td_pcb->pcb_fpcr = fpcr; - td->td_pcb->pcb_fpsr = fpsr; + pcb->pcb_fpcr = fpcr; + pcb->pcb_fpsr = fpsr; dsb(ish); vfp_disable(); diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c index 908b21fe22a8..edcdeca1f742 100644 --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -74,7 +74,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) td1->td_pcb->pcb_tpidr_el0 = READ_SPECIALREG(tpidr_el0); #ifdef VFP if ((td1->td_pcb->pcb_fpflags & PCB_FP_STARTED) != 0) - vfp_save_state(td1); + vfp_save_state(td1, td1->td_pcb); #endif } diff --git a/sys/arm64/include/vfp.h b/sys/arm64/include/vfp.h index ccb853c8f3ed..39adf4fb742b 100644 --- a/sys/arm64/include/vfp.h +++ b/sys/arm64/include/vfp.h @@ -38,7 +38,7 @@ void vfp_init(void); void vfp_discard(struct thread *); void vfp_restore_state(void); -void vfp_save_state(struct thread *); +void vfp_save_state(struct thread *, struct pcb *); #endif #endif From e553ca49948a983329fb4f357d3fa6abdd2a0c3d Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 3 Aug 2015 11:57:11 +0000 Subject: [PATCH 186/314] Rework the way iSCSI initiator handles system shutdown. This fixes hangs on shutdown with LUNs with mounted filesystems over a disconnected iSCSI session. MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3052 --- sys/dev/iscsi/iscsi.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index 5188ac827664..10430f6f1512 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -2322,11 +2322,23 @@ iscsi_shutdown(struct iscsi_softc *sc) { struct iscsi_session *is; - ISCSI_DEBUG("removing all sessions due to shutdown"); + /* + * Trying to reconnect during system shutdown would lead to hang. + */ + fail_on_disconnection = 1; + /* + * If we have any sessions waiting for reconnection, request + * maintenance thread to fail them immediately instead of waiting + * for reconnect timeout. + */ sx_slock(&sc->sc_lock); - TAILQ_FOREACH(is, &sc->sc_sessions, is_next) - iscsi_session_terminate(is); + TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { + ISCSI_SESSION_LOCK(is); + if (is->is_waiting_for_iscsid) + iscsi_session_reconnect(is); + ISCSI_SESSION_UNLOCK(is); + } sx_sunlock(&sc->sc_lock); } @@ -2352,12 +2364,7 @@ iscsi_load(void) } sc->sc_cdev->si_drv1 = sc; - /* - * Note that this needs to get run before dashutdown(). Otherwise, - * when rebooting with iSCSI session with outstanding requests, - * but disconnected, dashutdown() will hang on cam_periph_runccb(). - */ - sc->sc_shutdown_eh = EVENTHANDLER_REGISTER(shutdown_post_sync, + sc->sc_shutdown_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync, iscsi_shutdown, sc, SHUTDOWN_PRI_FIRST); return (0); @@ -2375,7 +2382,7 @@ iscsi_unload(void) } if (sc->sc_shutdown_eh != NULL) - EVENTHANDLER_DEREGISTER(shutdown_post_sync, sc->sc_shutdown_eh); + EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->sc_shutdown_eh); sx_slock(&sc->sc_lock); TAILQ_FOREACH_SAFE(is, &sc->sc_sessions, is_next, tmp) From ff9b006d61dcf000f044dbaee56954be204137f4 Mon Sep 17 00:00:00 2001 From: Julien Charbon Date: Mon, 3 Aug 2015 12:13:54 +0000 Subject: [PATCH 187/314] Decompose TCP INP_INFO lock to increase short-lived TCP connections scalability: - The existing TCP INP_INFO lock continues to protect the global inpcb list stability during full list traversal (e.g. tcp_pcblist()). - A new INP_LIST lock protects inpcb list actual modifications (inp allocation and free) and inpcb global counters. It allows to use TCP INP_INFO_RLOCK lock in critical paths (e.g. tcp_input()) and INP_INFO_WLOCK only in occasional operations that walk all connections. PR: 183659 Differential Revision: https://reviews.freebsd.org/D2599 Reviewed by: jhb, adrian Tested by: adrian, nitroboost-gmail.com Sponsored by: Verisign, Inc. --- sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c | 30 ++++---- sys/dev/cxgb/ulp/tom/cxgb_listen.c | 28 +++---- sys/dev/cxgbe/tom/t4_connect.c | 4 +- sys/dev/cxgbe/tom/t4_cpl_io.c | 20 ++--- sys/dev/cxgbe/tom/t4_listen.c | 28 +++---- sys/netinet/in_pcb.c | 43 +++++++++-- sys/netinet/in_pcb.h | 97 ++++++++++++++++++------ sys/netinet/tcp_input.c | 114 +++++++++++++++-------------- sys/netinet/tcp_subr.c | 50 ++++++------- sys/netinet/tcp_syncache.c | 20 ++++- sys/netinet/tcp_timer.c | 44 ++++------- sys/netinet/tcp_timewait.c | 37 ++++++---- sys/netinet/tcp_usrreq.c | 44 +++++------ sys/netinet/toecore.c | 6 +- sys/netinet6/in6_pcb.c | 4 +- 15 files changed, 328 insertions(+), 241 deletions(-) diff --git a/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c b/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c index bdd746fcb44f..985306c3c6e8 100644 --- a/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c +++ b/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c @@ -639,7 +639,7 @@ t3_send_fin(struct toedev *tod, struct tcpcb *tp) unsigned int tid = toep->tp_tid; #endif - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); CTR4(KTR_CXGB, "%s: tid %d, toep %p, flags %x", __func__, tid, toep, @@ -925,12 +925,12 @@ do_act_open_rpl(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) rc = act_open_rpl_status_to_errno(s); if (rc != EAGAIN) - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); toe_connect_failed(tod, inp, rc); toepcb_release(toep); /* unlocks inp */ if (rc != EAGAIN) - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); m_freem(m); return (0); @@ -1061,7 +1061,7 @@ send_reset(struct toepcb *toep) struct adapter *sc = tod->tod_softc; struct mbuf *m; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); CTR4(KTR_CXGB, "%s: tid %d, toep %p (%x)", __func__, tid, toep, @@ -1172,12 +1172,12 @@ do_rx_data(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) SOCKBUF_UNLOCK(so_rcv); INP_WUNLOCK(inp); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = tcp_drop(tp, ECONNRESET); if (tp) INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); m_freem(m); return (0); @@ -1222,7 +1222,7 @@ do_peer_close(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) struct tcpcb *tp; struct socket *so; - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = intotcpcb(inp); @@ -1250,7 +1250,7 @@ do_peer_close(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) case TCPS_FIN_WAIT_2: tcp_twstart(tp); INP_UNLOCK_ASSERT(inp); /* safe, we have a ref on the inp */ - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); INP_WLOCK(inp); toepcb_release(toep); /* no more CPLs expected */ @@ -1264,7 +1264,7 @@ do_peer_close(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) done: INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); m_freem(m); return (0); @@ -1285,7 +1285,7 @@ do_close_con_rpl(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) struct tcpcb *tp; struct socket *so; - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = intotcpcb(inp); @@ -1303,7 +1303,7 @@ do_close_con_rpl(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) tcp_twstart(tp); release: INP_UNLOCK_ASSERT(inp); /* safe, we have a ref on the inp */ - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); INP_WLOCK(inp); toepcb_release(toep); /* no more CPLs expected */ @@ -1328,7 +1328,7 @@ do_close_con_rpl(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) done: INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); m_freem(m); return (0); @@ -1489,7 +1489,7 @@ do_abort_req(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) return (do_abort_req_synqe(qs, r, m)); inp = toep->tp_inp; - INP_INFO_WLOCK(&V_tcbinfo); /* for tcp_close */ + INP_INFO_RLOCK(&V_tcbinfo); /* for tcp_close */ INP_WLOCK(inp); tp = intotcpcb(inp); @@ -1503,7 +1503,7 @@ do_abort_req(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) toep->tp_flags |= TP_ABORT_REQ_RCVD; toep->tp_flags |= TP_ABORT_SHUTDOWN; INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); m_freem(m); return (0); } @@ -1523,7 +1523,7 @@ do_abort_req(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) INP_WLOCK(inp); /* re-acquire */ toepcb_release(toep); /* no more CPLs expected */ } - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); send_abort_rpl(tod, tid, qset); m_freem(m); diff --git a/sys/dev/cxgb/ulp/tom/cxgb_listen.c b/sys/dev/cxgb/ulp/tom/cxgb_listen.c index e11bb2583373..933a83c2aaa7 100644 --- a/sys/dev/cxgb/ulp/tom/cxgb_listen.c +++ b/sys/dev/cxgb/ulp/tom/cxgb_listen.c @@ -541,11 +541,11 @@ do_pass_accept_req(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) REJECT_PASS_ACCEPT(); /* no l2te, or ifp mismatch */ } - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); /* Don't offload if the 4-tuple is already in use */ if (toe_4tuple_check(&inc, &th, ifp) != 0) { - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); REJECT_PASS_ACCEPT(); } @@ -558,7 +558,7 @@ do_pass_accept_req(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) * resources tied to this listen context. */ INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); REJECT_PASS_ACCEPT(); } so = inp->inp_socket; @@ -686,7 +686,7 @@ do_pass_establish(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) struct toepcb *toep; struct socket *so; struct listen_ctx *lctx = synqe->lctx; - struct inpcb *inp = lctx->inp; + struct inpcb *inp = lctx->inp, *new_inp; struct tcpopt to; struct tcphdr th; struct in_conninfo inc; @@ -700,7 +700,7 @@ do_pass_establish(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) KASSERT(qs->idx == synqe->qset, ("%s qset mismatch %d %d", __func__, qs->idx, synqe->qset)); - INP_INFO_WLOCK(&V_tcbinfo); /* for syncache_expand */ + INP_INFO_RLOCK(&V_tcbinfo); /* for syncache_expand */ INP_WLOCK(inp); if (__predict_false(inp->inp_flags & INP_DROPPED)) { @@ -714,7 +714,7 @@ do_pass_establish(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) ("%s: listen socket dropped but tid %u not aborted.", __func__, tid)); INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); m_freem(m); return (0); } @@ -730,7 +730,7 @@ do_pass_establish(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) reset: t3_send_reset_synqe(tod, synqe); INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); m_freem(m); return (0); } @@ -748,21 +748,23 @@ do_pass_establish(struct sge_qset *qs, struct rsp_desc *r, struct mbuf *m) goto reset; } - if (__predict_false(!(synqe->flags & TP_SYNQE_EXPANDED))) { - struct inpcb *new_inp = sotoinpcb(so); + /* New connection inpcb is already locked by syncache_expand(). */ + new_inp = sotoinpcb(so); + INP_WLOCK_ASSERT(new_inp); - INP_WLOCK(new_inp); + if (__predict_false(!(synqe->flags & TP_SYNQE_EXPANDED))) { tcp_timer_activate(intotcpcb(new_inp), TT_KEEP, 0); t3_offload_socket(tod, synqe, so); - INP_WUNLOCK(new_inp); } + INP_WUNLOCK(new_inp); + /* Remove the synq entry and release its reference on the lctx */ TAILQ_REMOVE(&lctx->synq, synqe, link); inp = release_lctx(td, lctx); if (inp) INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); release_synqe(synqe); m_freem(m); @@ -1128,7 +1130,7 @@ t3_offload_socket(struct toedev *tod, void *arg, struct socket *so) struct cpl_pass_establish *cpl = synqe->cpl; struct toepcb *toep = synqe->toep; - INP_INFO_LOCK_ASSERT(&V_tcbinfo); /* prevents bad race with accept() */ + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); /* prevents bad race with accept() */ INP_WLOCK_ASSERT(inp); offload_socket(so, toep); diff --git a/sys/dev/cxgbe/tom/t4_connect.c b/sys/dev/cxgbe/tom/t4_connect.c index 425c56358e7e..fae7979db9a8 100644 --- a/sys/dev/cxgbe/tom/t4_connect.c +++ b/sys/dev/cxgbe/tom/t4_connect.c @@ -189,12 +189,12 @@ act_open_failure_cleanup(struct adapter *sc, u_int atid, u_int status) toep->tid = -1; if (status != EAGAIN) - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); toe_connect_failed(tod, inp, status); final_cpl_received(toep); /* unlocks inp */ if (status != EAGAIN) - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); } static int diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index 147802d927bf..eb972d074612 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -1085,7 +1085,7 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) KASSERT(toep->tid == tid, ("%s: toep tid mismatch", __func__)); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = intotcpcb(inp); @@ -1127,7 +1127,7 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) case TCPS_FIN_WAIT_2: tcp_twstart(tp); INP_UNLOCK_ASSERT(inp); /* safe, we have a ref on the inp */ - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); INP_WLOCK(inp); final_cpl_received(toep); @@ -1139,7 +1139,7 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) } done: INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (0); } @@ -1166,7 +1166,7 @@ do_close_con_rpl(struct sge_iq *iq, const struct rss_header *rss, KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__)); KASSERT(toep->tid == tid, ("%s: toep tid mismatch", __func__)); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = intotcpcb(inp); @@ -1184,7 +1184,7 @@ do_close_con_rpl(struct sge_iq *iq, const struct rss_header *rss, tcp_twstart(tp); release: INP_UNLOCK_ASSERT(inp); /* safe, we have a ref on the inp */ - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); INP_WLOCK(inp); final_cpl_received(toep); /* no more CPLs expected */ @@ -1208,7 +1208,7 @@ do_close_con_rpl(struct sge_iq *iq, const struct rss_header *rss, } done: INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (0); } @@ -1367,7 +1367,7 @@ do_abort_req(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) } inp = toep->inp; - INP_INFO_WLOCK(&V_tcbinfo); /* for tcp_close */ + INP_INFO_RLOCK(&V_tcbinfo); /* for tcp_close */ INP_WLOCK(inp); tp = intotcpcb(inp); @@ -1401,7 +1401,7 @@ do_abort_req(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) final_cpl_received(toep); done: - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); send_abort_rpl(sc, ofld_txq, tid, CPL_ABORT_NO_RST); return (0); } @@ -1515,12 +1515,12 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) SOCKBUF_UNLOCK(sb); INP_WUNLOCK(inp); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); tp = tcp_drop(tp, ECONNRESET); if (tp) INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (0); } diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c index fc5f9350db79..127abe0c1217 100644 --- a/sys/dev/cxgbe/tom/t4_listen.c +++ b/sys/dev/cxgbe/tom/t4_listen.c @@ -930,7 +930,7 @@ t4_offload_socket(struct toedev *tod, void *arg, struct socket *so) struct cpl_pass_establish *cpl = mtod(synqe->syn, void *); struct toepcb *toep = *(struct toepcb **)(cpl + 1); - INP_INFO_LOCK_ASSERT(&V_tcbinfo); /* prevents bad race with accept() */ + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); /* prevents bad race with accept() */ INP_WLOCK_ASSERT(inp); KASSERT(synqe->flags & TPF_SYNQE, ("%s: %p not a synq_entry?", __func__, arg)); @@ -1259,15 +1259,15 @@ do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss, REJECT_PASS_ACCEPT(); rpl = wrtod(wr); - INP_INFO_WLOCK(&V_tcbinfo); /* for 4-tuple check */ + INP_INFO_RLOCK(&V_tcbinfo); /* for 4-tuple check */ /* Don't offload if the 4-tuple is already in use */ if (toe_4tuple_check(&inc, &th, ifp) != 0) { - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); free(wr, M_CXGBE); REJECT_PASS_ACCEPT(); } - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); inp = lctx->inp; /* listening socket, not owned by TOE */ INP_WLOCK(inp); @@ -1441,7 +1441,7 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss, unsigned int tid = GET_TID(cpl); struct synq_entry *synqe = lookup_tid(sc, tid); struct listen_ctx *lctx = synqe->lctx; - struct inpcb *inp = lctx->inp; + struct inpcb *inp = lctx->inp, *new_inp; struct socket *so; struct tcphdr th; struct tcpopt to; @@ -1459,7 +1459,7 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss, KASSERT(synqe->flags & TPF_SYNQE, ("%s: tid %u (ctx %p) not a synqe", __func__, tid, synqe)); - INP_INFO_WLOCK(&V_tcbinfo); /* for syncache_expand */ + INP_INFO_RLOCK(&V_tcbinfo); /* for syncache_expand */ INP_WLOCK(inp); CTR6(KTR_CXGBE, @@ -1475,7 +1475,7 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss, } INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (0); } @@ -1500,7 +1500,7 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss, */ send_reset_synqe(TOEDEV(ifp), synqe); INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (0); } toep->tid = tid; @@ -1534,6 +1534,10 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss, goto reset; } + /* New connection inpcb is already locked by syncache_expand(). */ + new_inp = sotoinpcb(so); + INP_WLOCK_ASSERT(new_inp); + /* * This is for the unlikely case where the syncache entry that we added * has been evicted from the syncache, but the syncache_expand above @@ -1544,20 +1548,18 @@ do_pass_establish(struct sge_iq *iq, const struct rss_header *rss, * this somewhat defeats the purpose of having a tod_offload_socket :-( */ if (__predict_false(!(synqe->flags & TPF_SYNQE_EXPANDED))) { - struct inpcb *new_inp = sotoinpcb(so); - - INP_WLOCK(new_inp); tcp_timer_activate(intotcpcb(new_inp), TT_KEEP, 0); t4_offload_socket(TOEDEV(ifp), synqe, so); - INP_WUNLOCK(new_inp); } + INP_WUNLOCK(new_inp); + /* Done with the synqe */ TAILQ_REMOVE(&lctx->synq, synqe, link); inp = release_lctx(sc, lctx); if (inp != NULL) INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); release_synqe(synqe); return (0); diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 965932486db3..c721c6dd950c 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -224,6 +224,7 @@ in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name, INP_INFO_LOCK_INIT(pcbinfo, name); INP_HASH_LOCK_INIT(pcbinfo, "pcbinfohash"); /* XXXRW: argument? */ + INP_LIST_LOCK_INIT(pcbinfo, "pcbinfolist"); #ifdef VIMAGE pcbinfo->ipi_vnet = curvnet; #endif @@ -262,6 +263,7 @@ in_pcbinfo_destroy(struct inpcbinfo *pcbinfo) in_pcbgroup_destroy(pcbinfo); #endif uma_zdestroy(pcbinfo->ipi_zone); + INP_LIST_LOCK_DESTROY(pcbinfo); INP_HASH_LOCK_DESTROY(pcbinfo); INP_INFO_LOCK_DESTROY(pcbinfo); } @@ -276,7 +278,14 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo) struct inpcb *inp; int error; - INP_INFO_WLOCK_ASSERT(pcbinfo); +#ifdef INVARIANTS + if (pcbinfo == &V_tcbinfo) { + INP_INFO_RLOCK_ASSERT(pcbinfo); + } else { + INP_INFO_WLOCK_ASSERT(pcbinfo); + } +#endif + error = 0; inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT); if (inp == NULL) @@ -308,6 +317,8 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo) inp->inp_flags |= IN6P_IPV6_V6ONLY; } #endif + INP_WLOCK(inp); + INP_LIST_WLOCK(pcbinfo); LIST_INSERT_HEAD(pcbinfo->ipi_listhead, inp, inp_list); pcbinfo->ipi_count++; so->so_pcb = (caddr_t)inp; @@ -315,9 +326,9 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo) if (V_ip6_auto_flowlabel) inp->inp_flags |= IN6P_AUTOFLOWLABEL; #endif - INP_WLOCK(inp); inp->inp_gencnt = ++pcbinfo->ipi_gencnt; refcount_init(&inp->inp_refcount, 1); /* Reference from inpcbinfo */ + INP_LIST_WUNLOCK(pcbinfo); #if defined(IPSEC) || defined(MAC) out: if (error != 0) { @@ -1246,7 +1257,13 @@ in_pcbfree(struct inpcb *inp) KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__)); - INP_INFO_WLOCK_ASSERT(pcbinfo); +#ifdef INVARIANTS + if (pcbinfo == &V_tcbinfo) { + INP_INFO_RLOCK_ASSERT(pcbinfo); + } else { + INP_INFO_WLOCK_ASSERT(pcbinfo); + } +#endif INP_WLOCK_ASSERT(inp); /* XXXRW: Do as much as possible here. */ @@ -1254,8 +1271,10 @@ in_pcbfree(struct inpcb *inp) if (inp->inp_sp != NULL) ipsec_delete_pcbpolicy(inp); #endif + INP_LIST_WLOCK(pcbinfo); inp->inp_gencnt = ++pcbinfo->ipi_gencnt; in_pcbremlists(inp); + INP_LIST_WUNLOCK(pcbinfo); #ifdef INET6 if (inp->inp_vflag & INP_IPV6PROTO) { ip6_freepcbopts(inp->in6p_outputopts); @@ -1412,7 +1431,7 @@ in_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) struct ip_moptions *imo; int i, gap; - INP_INFO_RLOCK(pcbinfo); + INP_INFO_WLOCK(pcbinfo); LIST_FOREACH(inp, pcbinfo->ipi_listhead, inp_list) { INP_WLOCK(inp); imo = inp->inp_moptions; @@ -1442,7 +1461,7 @@ in_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) } INP_WUNLOCK(inp); } - INP_INFO_RUNLOCK(pcbinfo); + INP_INFO_WUNLOCK(pcbinfo); } /* @@ -2163,8 +2182,16 @@ in_pcbremlists(struct inpcb *inp) { struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; - INP_INFO_WLOCK_ASSERT(pcbinfo); +#ifdef INVARIANTS + if (pcbinfo == &V_tcbinfo) { + INP_INFO_RLOCK_ASSERT(pcbinfo); + } else { + INP_INFO_WLOCK_ASSERT(pcbinfo); + } +#endif + INP_WLOCK_ASSERT(inp); + INP_LIST_WLOCK_ASSERT(pcbinfo); inp->inp_gencnt = ++pcbinfo->ipi_gencnt; if (inp->inp_flags & INP_INHASHLIST) { @@ -2309,13 +2336,13 @@ inp_apply_all(void (*func)(struct inpcb *, void *), void *arg) { struct inpcb *inp; - INP_INFO_RLOCK(&V_tcbinfo); + INP_INFO_WLOCK(&V_tcbinfo); LIST_FOREACH(inp, V_tcbinfo.ipi_listhead, inp_list) { INP_WLOCK(inp); func(inp, arg); INP_WUNLOCK(inp); } - INP_INFO_RUNLOCK(&V_tcbinfo); + INP_INFO_WUNLOCK(&V_tcbinfo); } struct socket * diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 606795a69bb0..2b7932538615 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -130,23 +130,35 @@ struct in_conninfo { struct icmp6_filter; /*- - * struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 - * and IPv6 sockets. In the case of TCP, further per-connection state is + * struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 and + * IPv6 sockets. In the case of TCP and UDP, further per-connection state is * hung off of inp_ppcb most of the time. Almost all fields of struct inpcb * are static after creation or protected by a per-inpcb rwlock, inp_lock. A - * few fields also require the global pcbinfo lock for the inpcb to be held, - * when modified, such as the global connection lists and hashes, as well as - * binding information (which affects which hash a connection is on). This - * model means that connections can be looked up without holding the - * per-connection lock, which is important for performance when attempting to - * find the connection for a packet given its IP and port tuple. Writing to - * these fields that write locks be held on both the inpcb and global locks. + * few fields are protected by multiple locks as indicated in the locking notes + * below. For these fields, all of the listed locks must be write-locked for + * any modifications. However, these fields can be safely read while any one of + * the listed locks are read-locked. This model can permit greater concurrency + * for read operations. For example, connections can be looked up while only + * holding a read lock on the global pcblist lock. This is important for + * performance when attempting to find the connection for a packet given its IP + * and port tuple. + * + * One noteworthy exception is that the global pcbinfo lock follows a different + * set of rules in relation to the inp_list field. Rather than being + * write-locked for modifications and read-locked for list iterations, it must + * be read-locked during modifications and write-locked during list iterations. + * This ensures that the relatively rare global list iterations safely walk a + * stable snapshot of connections while allowing more common list modifications + * to safely grab the pcblist lock just while adding or removing a connection + * from the global list. * * Key: * (c) - Constant after initialization * (g) - Protected by the pcbgroup lock * (i) - Protected by the inpcb lock * (p) - Protected by the pcbinfo lock for the inpcb + * (l) - Protected by the pcblist lock for the inpcb + * (h) - Protected by the pcbhash lock for the inpcb * (s) - Protected by another subsystem's locks * (x) - Undefined locking * @@ -161,15 +173,21 @@ struct icmp6_filter; * socket has been freed), or there may be close(2)-related races. * * The inp_vflag field is overloaded, and would otherwise ideally be (c). + * + * TODO: Currently only the TCP stack is leveraging the global pcbinfo lock + * read-lock usage during modification, this model can be applied to other + * protocols (especially SCTP). */ struct inpcb { - LIST_ENTRY(inpcb) inp_hash; /* (i/p) hash list */ + LIST_ENTRY(inpcb) inp_hash; /* (h/i) hash list */ LIST_ENTRY(inpcb) inp_pcbgrouphash; /* (g/i) hash list */ - LIST_ENTRY(inpcb) inp_list; /* (i/p) list for all PCBs for proto */ + LIST_ENTRY(inpcb) inp_list; /* (p/l) list for all PCBs for proto */ + /* (p[w]) for list iteration */ + /* (p[r]/l) for addition/removal */ void *inp_ppcb; /* (i) pointer to per-protocol pcb */ struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */ struct inpcbgroup *inp_pcbgroup; /* (g/i) PCB group list */ - LIST_ENTRY(inpcb) inp_pcbgroup_wild; /* (g/i/p) group wildcard entry */ + LIST_ENTRY(inpcb) inp_pcbgroup_wild; /* (g/i/h) group wildcard entry */ struct socket *inp_socket; /* (i) back pointer to socket */ struct ucred *inp_cred; /* (c) cache of socket cred */ u_int32_t inp_flow; /* (i) IPv6 flow information */ @@ -188,7 +206,7 @@ struct inpcb { * general use */ /* Local and foreign ports, local and foreign addr. */ - struct in_conninfo inp_inc; /* (i/p) list for PCB's local port */ + struct in_conninfo inp_inc; /* (i) list for PCB's local port */ /* MAC and IPSEC policy information. */ struct label *inp_label; /* (i) MAC label */ @@ -213,8 +231,8 @@ struct inpcb { int inp6_cksum; short inp6_hops; } inp_depend6; - LIST_ENTRY(inpcb) inp_portlist; /* (i/p) */ - struct inpcbport *inp_phd; /* (i/p) head of this list */ + LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */ + struct inpcbport *inp_phd; /* (i/h) head of this list */ #define inp_zero_size offsetof(struct inpcb, inp_gencnt) inp_gen_t inp_gencnt; /* (c) generation count */ struct llentry *inp_lle; /* cached L2 information */ @@ -279,37 +297,46 @@ struct inpcbport { * Global data structure for each high-level protocol (UDP, TCP, ...) in both * IPv4 and IPv6. Holds inpcb lists and information for managing them. * - * Each pcbinfo is protected by two locks: ipi_lock and ipi_hash_lock, - * the former covering mutable global fields (such as the global pcb list), - * and the latter covering the hashed lookup tables. The lock order is: + * Each pcbinfo is protected by three locks: ipi_lock, ipi_hash_lock and + * ipi_list_lock: + * - ipi_lock covering the global pcb list stability during loop iteration, + * - ipi_hash_lock covering the hashed lookup tables, + * - ipi_list_lock covering mutable global fields (such as the global + * pcb list) * - * ipi_lock (before) inpcb locks (before) {ipi_hash_lock, pcbgroup locks} + * The lock order is: + * + * ipi_lock (before) + * inpcb locks (before) + * ipi_list locks (before) + * {ipi_hash_lock, pcbgroup locks} * * Locking key: * * (c) Constant or nearly constant after initialisation * (g) Locked by ipi_lock + * (l) Locked by ipi_list_lock * (h) Read using either ipi_hash_lock or inpcb lock; write requires both * (p) Protected by one or more pcbgroup locks * (x) Synchronisation properties poorly defined */ struct inpcbinfo { /* - * Global lock protecting global inpcb list, inpcb count, etc. + * Global lock protecting full inpcb list traversal */ struct rwlock ipi_lock; /* * Global list of inpcbs on the protocol. */ - struct inpcbhead *ipi_listhead; /* (g) */ - u_int ipi_count; /* (g) */ + struct inpcbhead *ipi_listhead; /* (g/l) */ + u_int ipi_count; /* (l) */ /* * Generation count -- incremented each time a connection is allocated * or freed. */ - u_quad_t ipi_gencnt; /* (g) */ + u_quad_t ipi_gencnt; /* (l) */ /* * Fields associated with port lookup and allocation. @@ -367,6 +394,11 @@ struct inpcbinfo { * general use 2 */ void *ipi_pspare[2]; + + /* + * Global lock protecting global inpcb list, inpcb count, etc. + */ + struct rwlock ipi_list_lock; }; #ifdef _KERNEL @@ -466,6 +498,25 @@ short inp_so_options(const struct inpcb *inp); #define INP_INFO_WLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_WLOCKED) #define INP_INFO_UNLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_UNLOCKED) +#define INP_LIST_LOCK_INIT(ipi, d) \ + rw_init_flags(&(ipi)->ipi_list_lock, (d), 0) +#define INP_LIST_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_list_lock) +#define INP_LIST_RLOCK(ipi) rw_rlock(&(ipi)->ipi_list_lock) +#define INP_LIST_WLOCK(ipi) rw_wlock(&(ipi)->ipi_list_lock) +#define INP_LIST_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_list_lock) +#define INP_LIST_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_list_lock) +#define INP_LIST_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_list_lock) +#define INP_LIST_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_list_lock) +#define INP_LIST_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_list_lock) +#define INP_LIST_LOCK_ASSERT(ipi) \ + rw_assert(&(ipi)->ipi_list_lock, RA_LOCKED) +#define INP_LIST_RLOCK_ASSERT(ipi) \ + rw_assert(&(ipi)->ipi_list_lock, RA_RLOCKED) +#define INP_LIST_WLOCK_ASSERT(ipi) \ + rw_assert(&(ipi)->ipi_list_lock, RA_WLOCKED) +#define INP_LIST_UNLOCK_ASSERT(ipi) \ + rw_assert(&(ipi)->ipi_list_lock, RA_UNLOCKED) + #define INP_HASH_LOCK_INIT(ipi, d) \ rw_init_flags(&(ipi)->ipi_hash_lock, (d), 0) #define INP_HASH_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_hash_lock) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 3ca37b549129..e7ef6dbb80d8 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -608,7 +608,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto) char *s = NULL; /* address and port logging */ int ti_locked; #define TI_UNLOCKED 1 -#define TI_WLOCKED 2 +#define TI_RLOCKED 2 #ifdef TCPDEBUG /* @@ -797,8 +797,8 @@ tcp_input(struct mbuf **mp, int *offp, int proto) * connection in TIMEWAIT and SYNs not targeting a listening socket. */ if ((thflags & (TH_FIN | TH_RST)) != 0) { - INP_INFO_WLOCK(&V_tcbinfo); - ti_locked = TI_WLOCKED; + INP_INFO_RLOCK(&V_tcbinfo); + ti_locked = TI_RLOCKED; } else ti_locked = TI_UNLOCKED; @@ -820,8 +820,8 @@ tcp_input(struct mbuf **mp, int *offp, int proto) findpcb: #ifdef INVARIANTS - if (ti_locked == TI_WLOCKED) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) { + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); } else { INP_INFO_UNLOCK_ASSERT(&V_tcbinfo); } @@ -969,20 +969,20 @@ tcp_input(struct mbuf **mp, int *offp, int proto) relocked: if (inp->inp_flags & INP_TIMEWAIT) { if (ti_locked == TI_UNLOCKED) { - if (INP_INFO_TRY_WLOCK(&V_tcbinfo) == 0) { + if (INP_INFO_TRY_RLOCK(&V_tcbinfo) == 0) { in_pcbref(inp); INP_WUNLOCK(inp); - INP_INFO_WLOCK(&V_tcbinfo); - ti_locked = TI_WLOCKED; + INP_INFO_RLOCK(&V_tcbinfo); + ti_locked = TI_RLOCKED; INP_WLOCK(inp); if (in_pcbrele_wlocked(inp)) { inp = NULL; goto findpcb; } } else - ti_locked = TI_WLOCKED; + ti_locked = TI_RLOCKED; } - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); if (thflags & TH_SYN) tcp_dooptions(&to, optp, optlen, TO_SYN); @@ -991,7 +991,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto) */ if (tcp_twcheck(inp, &to, th, m, tlen)) goto findpcb; - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (IPPROTO_DONE); } /* @@ -1022,16 +1022,16 @@ tcp_input(struct mbuf **mp, int *offp, int proto) */ #ifdef INVARIANTS if ((thflags & (TH_FIN | TH_RST)) != 0) - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); #endif if (!((tp->t_state == TCPS_ESTABLISHED && (thflags & TH_SYN) == 0) || (tp->t_state == TCPS_LISTEN && (thflags & TH_SYN)))) { if (ti_locked == TI_UNLOCKED) { - if (INP_INFO_TRY_WLOCK(&V_tcbinfo) == 0) { + if (INP_INFO_TRY_RLOCK(&V_tcbinfo) == 0) { in_pcbref(inp); INP_WUNLOCK(inp); - INP_INFO_WLOCK(&V_tcbinfo); - ti_locked = TI_WLOCKED; + INP_INFO_RLOCK(&V_tcbinfo); + ti_locked = TI_RLOCKED; INP_WLOCK(inp); if (in_pcbrele_wlocked(inp)) { inp = NULL; @@ -1039,9 +1039,9 @@ tcp_input(struct mbuf **mp, int *offp, int proto) } goto relocked; } else - ti_locked = TI_WLOCKED; + ti_locked = TI_RLOCKED; } - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); } #ifdef MAC @@ -1096,7 +1096,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto) */ if ((thflags & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); /* * Parse the TCP options here because * syncookies need access to the reflected @@ -1148,7 +1148,11 @@ tcp_input(struct mbuf **mp, int *offp, int proto) */ INP_WUNLOCK(inp); /* listen socket */ inp = sotoinpcb(so); - INP_WLOCK(inp); /* new connection */ + /* + * New connection inpcb is already locked by + * syncache_expand(). + */ + INP_WLOCK_ASSERT(inp); tp = intotcpcb(inp); KASSERT(tp->t_state == TCPS_SYN_RECEIVED, ("%s: ", __func__)); @@ -1379,8 +1383,8 @@ tcp_input(struct mbuf **mp, int *offp, int proto) * Entry added to syncache and mbuf consumed. * Only the listen socket is unlocked by syncache_add(). */ - if (ti_locked == TI_WLOCKED) { - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) { + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; } INP_INFO_UNLOCK_ASSERT(&V_tcbinfo); @@ -1429,8 +1433,8 @@ tcp_input(struct mbuf **mp, int *offp, int proto) dropwithreset: TCP_PROBE5(receive, NULL, tp, mtod(m, const char *), tp, th); - if (ti_locked == TI_WLOCKED) { - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) { + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; } #ifdef INVARIANTS @@ -1453,8 +1457,8 @@ tcp_input(struct mbuf **mp, int *offp, int proto) if (m != NULL) TCP_PROBE5(receive, NULL, tp, mtod(m, const char *), tp, th); - if (ti_locked == TI_WLOCKED) { - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) { + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; } #ifdef INVARIANTS @@ -1511,13 +1515,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, */ if ((thflags & (TH_SYN | TH_FIN | TH_RST)) != 0 || tp->t_state != TCPS_ESTABLISHED) { - KASSERT(ti_locked == TI_WLOCKED, ("%s ti_locked %d for " + KASSERT(ti_locked == TI_RLOCKED, ("%s ti_locked %d for " "SYN/FIN/RST/!EST", __func__, ti_locked)); - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); } else { #ifdef INVARIANTS - if (ti_locked == TI_WLOCKED) - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); else { KASSERT(ti_locked == TI_UNLOCKED, ("%s: EST " "ti_locked: %d", __func__, ti_locked)); @@ -1690,8 +1694,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, /* * This is a pure ack for outstanding data. */ - if (ti_locked == TI_WLOCKED) - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; TCPSTAT_INC(tcps_predack); @@ -1794,8 +1798,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * nothing on the reassembly queue and we have enough * buffer space to take it. */ - if (ti_locked == TI_WLOCKED) - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; /* Clean receiver SACK report if present */ @@ -2031,9 +2035,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tcp_state_change(tp, TCPS_SYN_RECEIVED); } - KASSERT(ti_locked == TI_WLOCKED, ("%s: trimthenstep6: " + KASSERT(ti_locked == TI_RLOCKED, ("%s: trimthenstep6: " "ti_locked %d", __func__, ti_locked)); - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(tp->t_inpcb); /* @@ -2106,8 +2110,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) || (tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); - KASSERT(ti_locked == TI_WLOCKED, + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); + KASSERT(ti_locked == TI_RLOCKED, ("%s: TH_RST ti_locked %d, th %p tp %p", __func__, ti_locked, th, tp)); KASSERT(tp->t_state != TCPS_SYN_SENT, @@ -2150,9 +2154,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * Send challenge ACK for any SYN in synchronized state. */ if ((thflags & TH_SYN) && tp->t_state != TCPS_SYN_SENT) { - KASSERT(ti_locked == TI_WLOCKED, + KASSERT(ti_locked == TI_RLOCKED, ("tcp_do_segment: TH_SYN ti_locked %d", ti_locked)); - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); TCPSTAT_INC(tcps_badsyn); if (V_tcp_insecure_syn && @@ -2265,9 +2269,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, */ if ((so->so_state & SS_NOFDREF) && tp->t_state > TCPS_CLOSE_WAIT && tlen) { - KASSERT(ti_locked == TI_WLOCKED, ("%s: SS_NOFDEREF && " + KASSERT(ti_locked == TI_RLOCKED, ("%s: SS_NOFDEREF && " "CLOSE_WAIT && tlen ti_locked %d", __func__, ti_locked)); - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: %s: Received %d bytes of data " @@ -2768,9 +2772,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, */ case TCPS_CLOSING: if (ourfinisacked) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); tcp_twstart(tp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); m_freem(m); return; } @@ -2784,7 +2788,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, */ case TCPS_LAST_ACK: if (ourfinisacked) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); tp = tcp_close(tp); goto drop; } @@ -2999,18 +3003,18 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * standard timers. */ case TCPS_FIN_WAIT_2: - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); - KASSERT(ti_locked == TI_WLOCKED, ("%s: dodata " + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); + KASSERT(ti_locked == TI_RLOCKED, ("%s: dodata " "TCP_FIN_WAIT_2 ti_locked: %d", __func__, ti_locked)); tcp_twstart(tp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return; } } - if (ti_locked == TI_WLOCKED) - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; #ifdef TCPDEBUG @@ -3065,8 +3069,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen, &tcp_savetcp, 0); #endif - if (ti_locked == TI_WLOCKED) - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; tp->t_flags |= TF_ACKNOW; @@ -3076,8 +3080,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, return; dropwithreset: - if (ti_locked == TI_WLOCKED) - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; if (tp != NULL) { @@ -3088,8 +3092,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, return; drop: - if (ti_locked == TI_WLOCKED) { - INP_INFO_WUNLOCK(&V_tcbinfo); + if (ti_locked == TI_RLOCKED) { + INP_INFO_RUNLOCK(&V_tcbinfo); ti_locked = TI_UNLOCKED; } #ifdef INVARIANTS diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 7fe0eba0a310..808eb9736f7c 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -858,7 +858,7 @@ tcp_ccalgounload(struct cc_algo *unload_algo) VNET_LIST_RLOCK(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); - INP_INFO_RLOCK(&V_tcbinfo); + INP_INFO_WLOCK(&V_tcbinfo); /* * New connections already part way through being initialised * with the CC algo we're removing will not race with this code @@ -888,7 +888,7 @@ tcp_ccalgounload(struct cc_algo *unload_algo) } INP_WUNLOCK(inp); } - INP_INFO_RUNLOCK(&V_tcbinfo); + INP_INFO_WUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); } VNET_LIST_RUNLOCK(); @@ -906,7 +906,7 @@ tcp_drop(struct tcpcb *tp, int errno) { struct socket *so = tp->t_inpcb->inp_socket; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(tp->t_inpcb); if (TCPS_HAVERCVDSYN(tp->t_state)) { @@ -1073,7 +1073,7 @@ tcp_timer_discard(struct tcpcb *tp, uint32_t timer_type) struct inpcb *inp; CURVNET_SET(tp->t_vnet); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); inp = tp->t_inpcb; KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp)); @@ -1088,13 +1088,13 @@ tcp_timer_discard(struct tcpcb *tp, uint32_t timer_type) tp->t_inpcb = NULL; uma_zfree(V_tcpcb_zone, tp); if (in_pcbrele_wlocked(inp)) { - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); return; } } INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); } @@ -1108,7 +1108,7 @@ tcp_close(struct tcpcb *tp) struct inpcb *inp = tp->t_inpcb; struct socket *so; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); #ifdef TCP_OFFLOAD @@ -1156,7 +1156,7 @@ tcp_drain(void) * where we're really low on mbufs, this is potentially * useful. */ - INP_INFO_RLOCK(&V_tcbinfo); + INP_INFO_WLOCK(&V_tcbinfo); LIST_FOREACH(inpb, V_tcbinfo.ipi_listhead, inp_list) { if (inpb->inp_flags & INP_TIMEWAIT) continue; @@ -1167,7 +1167,7 @@ tcp_drain(void) } INP_WUNLOCK(inpb); } - INP_INFO_RUNLOCK(&V_tcbinfo); + INP_INFO_WUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); } VNET_LIST_RUNLOCK_NOSLEEP(); @@ -1186,7 +1186,7 @@ tcp_notify(struct inpcb *inp, int error) { struct tcpcb *tp; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); if ((inp->inp_flags & INP_TIMEWAIT) || @@ -1250,10 +1250,10 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS) /* * OK, now we're committed to doing something. */ - INP_INFO_RLOCK(&V_tcbinfo); + INP_LIST_RLOCK(&V_tcbinfo); gencnt = V_tcbinfo.ipi_gencnt; n = V_tcbinfo.ipi_count; - INP_INFO_RUNLOCK(&V_tcbinfo); + INP_LIST_RUNLOCK(&V_tcbinfo); m = syncache_pcbcount(); @@ -1278,7 +1278,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS) if (inp_list == NULL) return (ENOMEM); - INP_INFO_RLOCK(&V_tcbinfo); + INP_INFO_WLOCK(&V_tcbinfo); for (inp = LIST_FIRST(V_tcbinfo.ipi_listhead), i = 0; inp != NULL && i < n; inp = LIST_NEXT(inp, inp_list)) { INP_WLOCK(inp); @@ -1303,7 +1303,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS) } INP_WUNLOCK(inp); } - INP_INFO_RUNLOCK(&V_tcbinfo); + INP_INFO_WUNLOCK(&V_tcbinfo); n = i; error = 0; @@ -1341,14 +1341,14 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS) } else INP_RUNLOCK(inp); } - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); for (i = 0; i < n; i++) { inp = inp_list[i]; INP_RLOCK(inp); if (!in_pcbrele_rlocked(inp)) INP_RUNLOCK(inp); } - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); if (!error) { /* @@ -1358,11 +1358,11 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS) * while we were processing this request, and it * might be necessary to retry. */ - INP_INFO_RLOCK(&V_tcbinfo); + INP_LIST_RLOCK(&V_tcbinfo); xig.xig_gen = V_tcbinfo.ipi_gencnt; xig.xig_sogen = so_gencnt; xig.xig_count = V_tcbinfo.ipi_count + pcb_count; - INP_INFO_RUNLOCK(&V_tcbinfo); + INP_LIST_RUNLOCK(&V_tcbinfo); error = SYSCTL_OUT(req, &xig, sizeof xig); } free(inp_list, M_TEMP); @@ -1518,7 +1518,7 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) - offsetof(struct icmp, icmp_ip)); th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2)); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); inp = in_pcblookup(&V_tcbinfo, faddr, th->th_dport, ip->ip_src, th->th_sport, INPLOOKUP_WLOCKPCB, NULL); if (inp != NULL) { @@ -1578,7 +1578,7 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) inc.inc_laddr = ip->ip_src; syncache_unreach(&inc, th); } - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); } else in_pcbnotifyall(&V_tcbinfo, faddr, inetctlerrmap[cmd], notify); } @@ -1648,9 +1648,9 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d) inc.inc6_faddr = ((struct sockaddr_in6 *)sa)->sin6_addr; inc.inc6_laddr = ip6cp->ip6c_src->sin6_addr; inc.inc_flags |= INC_ISIPV6; - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); syncache_unreach(&inc, &th); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); } else in6_pcbnotify(&V_tcbinfo, sa, 0, (const struct sockaddr *)sa6_src, 0, cmd, NULL, notify); @@ -1783,7 +1783,7 @@ tcp_drop_syn_sent(struct inpcb *inp, int errno) { struct tcpcb *tp; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); if ((inp->inp_flags & INP_TIMEWAIT) || @@ -2341,7 +2341,7 @@ sysctl_drop(SYSCTL_HANDLER_ARGS) default: return (EINVAL); } - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); switch (addrs[0].ss_family) { #ifdef INET6 case AF_INET6: @@ -2380,7 +2380,7 @@ sysctl_drop(SYSCTL_HANDLER_ARGS) INP_WUNLOCK(inp); } else error = ESRCH; - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (error); } diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 7d97ae081a6b..2c853b3b55e2 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -652,6 +652,8 @@ syncache_unreach(struct in_conninfo *inc, struct tcphdr *th) /* * Build a new TCP socket structure from a syncache entry. + * + * On success return the newly created socket with its underlying inp locked. */ static struct socket * syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) @@ -662,7 +664,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) int error; char *s; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); /* * Ok, create the full blown connection, and set things up @@ -693,6 +695,15 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) inp = sotoinpcb(so); inp->inp_inc.inc_fibnum = so->so_fibnum; INP_WLOCK(inp); + /* + * Exclusive pcbinfo lock is not required in syncache socket case even + * if two inpcb locks can be acquired simultaneously: + * - the inpcb in LISTEN state, + * - the newly created inp. + * + * In this case, an inp cannot be at same time in LISTEN state and + * just created by an accept() call. + */ INP_HASH_WLOCK(&V_tcbinfo); /* Insert new socket into PCB hash list. */ @@ -907,8 +918,6 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) tp->t_keepcnt = sototcpcb(lso)->t_keepcnt; tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); - INP_WUNLOCK(inp); - soisconnected(so); TCPSTAT_INC(tcps_accepts); @@ -928,6 +937,9 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) * in the syncache, and if its there, we pull it out of * the cache and turn it into a full-blown connection in * the SYN-RECEIVED state. + * + * On syncache_socket() success the newly created socket + * has its underlying inp locked. */ int syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, @@ -942,7 +954,7 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, * Global TCP locks are held because we manipulate the PCB lists * and create a new socket. */ - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); KASSERT((th->th_flags & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK, ("%s: can handle only ACK", __func__)); diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index d992492cddc7..e0073346a548 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -307,7 +307,7 @@ tcp_timer_2msl(void *xtp) ostate = tp->t_state; #endif - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); inp = tp->t_inpcb; KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp)); INP_WLOCK(inp); @@ -315,14 +315,14 @@ tcp_timer_2msl(void *xtp) if (callout_pending(&tp->t_timers->tt_2msl) || !callout_active(&tp->t_timers->tt_2msl)) { INP_WUNLOCK(tp->t_inpcb); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); return; } callout_deactivate(&tp->t_timers->tt_2msl); if ((inp->inp_flags & INP_DROPPED) != 0) { INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); return; } @@ -363,7 +363,7 @@ tcp_timer_2msl(void *xtp) #endif if (tp != NULL) INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); } @@ -379,21 +379,21 @@ tcp_timer_keep(void *xtp) ostate = tp->t_state; #endif - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); inp = tp->t_inpcb; KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp)); INP_WLOCK(inp); if (callout_pending(&tp->t_timers->tt_keep) || !callout_active(&tp->t_timers->tt_keep)) { INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); return; } callout_deactivate(&tp->t_timers->tt_keep); if ((inp->inp_flags & INP_DROPPED) != 0) { INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); return; } @@ -447,7 +447,7 @@ tcp_timer_keep(void *xtp) PRU_SLOWTIMO); #endif INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); return; @@ -462,7 +462,7 @@ tcp_timer_keep(void *xtp) #endif if (tp != NULL) INP_WUNLOCK(tp->t_inpcb); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); } @@ -477,21 +477,21 @@ tcp_timer_persist(void *xtp) ostate = tp->t_state; #endif - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); inp = tp->t_inpcb; KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp)); INP_WLOCK(inp); if (callout_pending(&tp->t_timers->tt_persist) || !callout_active(&tp->t_timers->tt_persist)) { INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); return; } callout_deactivate(&tp->t_timers->tt_persist); if ((inp->inp_flags & INP_DROPPED) != 0) { INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); return; } @@ -540,7 +540,7 @@ tcp_timer_persist(void *xtp) #endif if (tp != NULL) INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); } @@ -589,22 +589,6 @@ tcp_timer_rexmt(void * xtp) if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) { tp->t_rxtshift = TCP_MAXRXTSHIFT; TCPSTAT_INC(tcps_timeoutdrop); - in_pcbref(inp); - INP_INFO_RUNLOCK(&V_tcbinfo); - INP_WUNLOCK(inp); - INP_INFO_WLOCK(&V_tcbinfo); - INP_WLOCK(inp); - if (in_pcbrele_wlocked(inp)) { - INP_INFO_WUNLOCK(&V_tcbinfo); - CURVNET_RESTORE(); - return; - } - if (inp->inp_flags & INP_DROPPED) { - INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); - CURVNET_RESTORE(); - return; - } tp = tcp_drop(tp, tp->t_softerror ? tp->t_softerror : ETIMEDOUT); @@ -803,7 +787,7 @@ tcp_timer_rexmt(void * xtp) if (tp != NULL) INP_WUNLOCK(inp); if (headlocked) - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); CURVNET_RESTORE(); } diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index 1ba74d86ae68..4685fe734f5e 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -202,10 +202,10 @@ tcp_tw_destroy(void) { struct tcptw *tw; - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); while ((tw = TAILQ_FIRST(&V_twq_2msl)) != NULL) tcp_twclose(tw, 0); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); TW_LOCK_DESTROY(V_tw_lock); uma_zdestroy(V_tcptw_zone); @@ -228,7 +228,7 @@ tcp_twstart(struct tcpcb *tp) int isipv6 = inp->inp_inc.inc_flags & INC_ISIPV6; #endif - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); if (V_nolocaltimewait) { @@ -265,8 +265,8 @@ tcp_twstart(struct tcpcb *tp) * allowed. Remove a connection from TIMEWAIT queue in LRU * fashion to make room for this connection. * - * pcbinfo lock is needed here to prevent deadlock as - * two inpcb locks can be acquired simultaneously. + * XXX: Check if it possible to always have enough room + * in advance based on guarantees provided by uma_zalloc(). */ tw = tcp_tw_2msl_scan(1); if (tw == NULL) { @@ -367,7 +367,7 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to __unused, struct tcphdr *th, int thflags; tcp_seq seq; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); /* @@ -468,7 +468,7 @@ tcp_twclose(struct tcptw *tw, int reuse) inp = tw->tw_inpcb; KASSERT((inp->inp_flags & INP_TIMEWAIT), ("tcp_twclose: !timewait")); KASSERT(intotw(inp) == tw, ("tcp_twclose: inp_ppcb != tw")); - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); /* in_pcbfree() */ + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); /* in_pcbfree() */ INP_WLOCK_ASSERT(inp); tcp_tw_2msl_stop(tw, reuse); @@ -623,7 +623,7 @@ static void tcp_tw_2msl_reset(struct tcptw *tw, int rearm) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(tw->tw_inpcb); TW_WLOCK(V_tw_lock); @@ -641,7 +641,7 @@ tcp_tw_2msl_stop(struct tcptw *tw, int reuse) struct inpcb *inp; int released; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); TW_WLOCK(V_tw_lock); inp = tw->tw_inpcb; @@ -671,13 +671,18 @@ tcp_tw_2msl_scan(int reuse) #ifdef INVARIANTS if (reuse) { /* - * pcbinfo lock is needed in reuse case to prevent deadlock - * as two inpcb locks can be acquired simultaneously: + * Exclusive pcbinfo lock is not required in reuse case even if + * two inpcb locks can be acquired simultaneously: * - the inpcb transitioning to TIME_WAIT state in * tcp_tw_start(), * - the inpcb closed by tcp_twclose(). + * + * It is because only inpcbs in FIN_WAIT2 or CLOSING states can + * transition in TIME_WAIT state. Then a pcbcb cannot be in + * TIME_WAIT list and transitioning to TIME_WAIT state at same + * time. */ - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); } #endif @@ -695,26 +700,26 @@ tcp_tw_2msl_scan(int reuse) in_pcbref(inp); TW_RUNLOCK(V_tw_lock); - if (INP_INFO_TRY_WLOCK(&V_tcbinfo)) { + if (INP_INFO_TRY_RLOCK(&V_tcbinfo)) { INP_WLOCK(inp); tw = intotw(inp); if (in_pcbrele_wlocked(inp)) { KASSERT(tw == NULL, ("%s: held last inp " "reference but tw not NULL", __func__)); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); continue; } if (tw == NULL) { /* tcp_twclose() has already been called */ INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); continue; } tcp_twclose(tw, reuse); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); if (reuse) return tw; } else { diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index de2de94e18e1..36d5312aec26 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -163,7 +163,7 @@ tcp_detach(struct socket *so, struct inpcb *inp) { struct tcpcb *tp; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp")); @@ -192,10 +192,10 @@ tcp_detach(struct socket *so, struct inpcb *inp) * and leave inpcb present until timewait ends * #2 tcp_detach is called at timewait end (or reuse) by * tcp_twclose, then the tcptw has already been discarded - * and inpcb is freed here + * (or reused) and inpcb is freed here * #3 tcp_detach is called() after timewait ends (or reuse) * (e.g. by soclose), then tcptw has already been discarded - * and inpcb is freed here + * (or reused) and inpcb is freed here * * In all three cases the tcptw should not be freed here. */ @@ -244,12 +244,12 @@ tcp_usr_detach(struct socket *so) inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL")); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_detach: inp_socket == NULL")); tcp_detach(so, inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); } #ifdef INET @@ -611,7 +611,7 @@ tcp_usr_disconnect(struct socket *so) int error = 0; TCPDEBUG0; - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL")); INP_WLOCK(inp); @@ -627,7 +627,7 @@ tcp_usr_disconnect(struct socket *so) out: TCPDEBUG2(PRU_DISCONNECT); INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (error); } @@ -742,7 +742,7 @@ tcp_usr_shutdown(struct socket *so) struct tcpcb *tp = NULL; TCPDEBUG0; - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("inp == NULL")); INP_WLOCK(inp); @@ -760,7 +760,7 @@ tcp_usr_shutdown(struct socket *so) out: TCPDEBUG2(PRU_SHUTDOWN); INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (error); } @@ -822,7 +822,7 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, * this call. */ if (flags & PRUS_EOF) - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL")); INP_WLOCK(inp); @@ -883,7 +883,7 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, * Close the send side of the connection after * the data is sent. */ - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); socantsendmore(so); tcp_usrclosed(tp); } @@ -950,7 +950,7 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); INP_WUNLOCK(inp); if (flags & PRUS_EOF) - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (error); } @@ -994,7 +994,7 @@ tcp_usr_abort(struct socket *so) inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_abort: inp == NULL")); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_abort: inp_socket == NULL")); @@ -1016,7 +1016,7 @@ tcp_usr_abort(struct socket *so) inp->inp_flags |= INP_SOCKREF; } INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); } /* @@ -1032,7 +1032,7 @@ tcp_usr_close(struct socket *so) inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL")); - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); KASSERT(inp->inp_socket != NULL, ("tcp_usr_close: inp_socket == NULL")); @@ -1055,7 +1055,7 @@ tcp_usr_close(struct socket *so) inp->inp_flags |= INP_SOCKREF; } INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); } /* @@ -1655,10 +1655,10 @@ tcp_attach(struct socket *so) } so->so_rcv.sb_flags |= SB_AUTOSIZE; so->so_snd.sb_flags |= SB_AUTOSIZE; - INP_INFO_WLOCK(&V_tcbinfo); + INP_INFO_RLOCK(&V_tcbinfo); error = in_pcballoc(so, &V_tcbinfo); if (error) { - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (error); } inp = sotoinpcb(so); @@ -1674,12 +1674,12 @@ tcp_attach(struct socket *so) if (tp == NULL) { in_pcbdetach(inp); in_pcbfree(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (ENOBUFS); } tp->t_state = TCPS_CLOSED; INP_WUNLOCK(inp); - INP_INFO_WUNLOCK(&V_tcbinfo); + INP_INFO_RUNLOCK(&V_tcbinfo); return (0); } @@ -1697,7 +1697,7 @@ tcp_disconnect(struct tcpcb *tp) struct inpcb *inp = tp->t_inpcb; struct socket *so = inp->inp_socket; - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); /* @@ -1735,7 +1735,7 @@ static void tcp_usrclosed(struct tcpcb *tp) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(tp->t_inpcb); switch (tp->t_state) { diff --git a/sys/netinet/toecore.c b/sys/netinet/toecore.c index 1021475f9319..5ca460483537 100644 --- a/sys/netinet/toecore.c +++ b/sys/netinet/toecore.c @@ -339,7 +339,7 @@ toe_syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, struct socket **lsop) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); return (syncache_expand(inc, to, th, lsop, NULL)); } @@ -370,7 +370,7 @@ toe_4tuple_check(struct in_conninfo *inc, struct tcphdr *th, struct ifnet *ifp) if ((inp->inp_flags & INP_TIMEWAIT) && th != NULL) { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); /* for twcheck */ + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); /* for twcheck */ if (!tcp_twcheck(inp, NULL, th, NULL, 0)) return (EADDRINUSE); } else { @@ -571,7 +571,7 @@ toe_connect_failed(struct toedev *tod, struct inpcb *inp, int err) (void) tcp_output(tp); } else { - INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + INP_INFO_RLOCK_ASSERT(&V_tcbinfo); tp = tcp_drop(tp, err); if (tp == NULL) INP_WLOCK(inp); /* re-acquire */ diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 10cd3f2b1bf0..9f876a4cbb92 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -789,7 +789,7 @@ in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) struct ip6_moptions *im6o; int i, gap; - INP_INFO_RLOCK(pcbinfo); + INP_INFO_WLOCK(pcbinfo); LIST_FOREACH(in6p, pcbinfo->ipi_listhead, inp_list) { INP_WLOCK(in6p); im6o = in6p->in6p_moptions; @@ -820,7 +820,7 @@ in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) } INP_WUNLOCK(in6p); } - INP_INFO_RUNLOCK(pcbinfo); + INP_INFO_WUNLOCK(pcbinfo); } /* From f94cc234751d709ff77d849d9cf35661abbafe21 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 3 Aug 2015 12:14:42 +0000 Subject: [PATCH 188/314] Clear the IA32_MISC_ENABLE MSR bit, which limits the max CPUID reported, on APs. We already did this on BSP. Otherwise, the userspace software which depends on the features reported by the high CPUID levels is misbehaving. In particular, AVX detection is non-functional, depending on which CPU thread happens to execute when doing CPUID. Another victim is the libthr signal handlers interposer, which needs to save full FPU extended state. Reported and tested by: Andre Meiser Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/amd64/amd64/mp_machdep.c | 1 + sys/amd64/include/md_var.h | 1 + sys/i386/i386/mp_machdep.c | 2 ++ sys/i386/include/md_var.h | 1 + sys/x86/x86/identcpu.c | 46 +++++++++++++++++++++++------------- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index e91e6d546558..a2ca9e271f60 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -252,6 +252,7 @@ init_secondary(void) wrmsr(MSR_FSBASE, 0); /* User value */ wrmsr(MSR_GSBASE, (u_int64_t)pc); wrmsr(MSR_KGSBASE, (u_int64_t)pc); /* XXX User value while we're in the kernel */ + intel_fix_cpuid(); lidt(&r_idt); diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index 954df3ec9c06..0657deee1283 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -114,6 +114,7 @@ void dump_drop_page(vm_paddr_t); void identify_cpu(void); void initializecpu(void); void initializecpucache(void); +bool intel_fix_cpuid(void); void fillw(int /*u_short*/ pat, void *base, size_t cnt); void fpstate_drop(struct thread *td); int is_physical_memory(vm_paddr_t addr); diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 083aa4af0ec9..09425230eb41 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -247,6 +247,8 @@ init_secondary(void) pc->pc_prvspace = pc; pc->pc_curthread = 0; + intel_fix_cpuid(); + gdt_segs[GPRIV_SEL].ssd_base = (int) pc; gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss; diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h index e6102405d4e3..13655eea7735 100644 --- a/sys/i386/include/md_var.h +++ b/sys/i386/include/md_var.h @@ -118,6 +118,7 @@ void fillw(int /*u_short*/ pat, void *base, size_t cnt); void fill_based_sd(struct segment_descriptor *sdp, uint32_t base); void initializecpu(void); void initializecpucache(void); +bool intel_fix_cpuid(void); void i686_pagezero(void *addr); void sse2_pagezero(void *addr); void init_AMD_Elan_sc520(void); diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c index 548da4a0e10a..4fe3e3cbe99d 100644 --- a/sys/x86/x86/identcpu.c +++ b/sys/x86/x86/identcpu.c @@ -1294,6 +1294,33 @@ identify_hypervisor(void) } } +/* + * Clear "Limit CPUID Maxval" bit and return true if the caller should + * get the largest standard CPUID function number again if it is set + * from BIOS. It is necessary for probing correct CPU topology later + * and for the correct operation of the AVX-aware userspace. + */ +bool +intel_fix_cpuid(void) +{ + uint64_t msr; + + if (cpu_vendor_id != CPU_VENDOR_INTEL) + return (false); + if ((CPUID_TO_FAMILY(cpu_id) == 0xf && + CPUID_TO_MODEL(cpu_id) >= 0x3) || + (CPUID_TO_FAMILY(cpu_id) == 0x6 && + CPUID_TO_MODEL(cpu_id) >= 0xe)) { + msr = rdmsr(MSR_IA32_MISC_ENABLE); + if ((msr & IA32_MISC_EN_LIMCPUID) != 0) { + msr &= ~IA32_MISC_EN_LIMCPUID; + wrmsr(MSR_IA32_MISC_ENABLE, msr); + return (true); + } + } + return (false); +} + /* * Final stage of CPU identification. */ @@ -1328,22 +1355,9 @@ identify_cpu(void) identify_hypervisor(); cpu_vendor_id = find_cpu_vendor_id(); - /* - * Clear "Limit CPUID Maxval" bit and get the largest standard CPUID - * function number again if it is set from BIOS. It is necessary - * for probing correct CPU topology later. - * XXX This is only done on the BSP package. - */ - if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_high > 0 && cpu_high < 4 && - ((CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x3) || - (CPUID_TO_FAMILY(cpu_id) == 0x6 && CPUID_TO_MODEL(cpu_id) >= 0xe))) { - uint64_t msr; - msr = rdmsr(MSR_IA32_MISC_ENABLE); - if ((msr & 0x400000ULL) != 0) { - wrmsr(MSR_IA32_MISC_ENABLE, msr & ~0x400000ULL); - do_cpuid(0, regs); - cpu_high = regs[0]; - } + if (intel_fix_cpuid()) { + do_cpuid(0, regs); + cpu_high = regs[0]; } if (cpu_high >= 5 && (cpu_feature2 & CPUID2_MON) != 0) { From 39f5ebb774f9749b4d966e504580232c6a53c747 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 3 Aug 2015 13:41:47 +0000 Subject: [PATCH 189/314] Add sysent flag to switch to capabilities mode on startup. CloudABI processes should run in capabilities mode automatically. There is no need to switch manually (e.g., by calling cap_enter()). Add a flag, SV_CAPSICUM, that can be used to call into cap_enter() during execve(). Reviewed by: kib --- sys/kern/kern_exec.c | 4 ++++ sys/sys/sysent.h | 11 ++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 517b68978338..56207a00c98c 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -562,6 +562,10 @@ do_execve(td, args, mac_p) goto exec_fail_dealloc; } + /* ABI enforces the use of Capsicum. Switch into capabilities mode. */ + if (SV_PROC_FLAG(p, SV_CAPSICUM)) + sys_cap_enter(td, NULL); + /* * Copy out strings (args and env) and initialize stack base */ diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index 980c79667fbc..db929815ca49 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -139,11 +139,12 @@ struct sysentvec { void (*sv_thread_detach)(struct thread *); }; -#define SV_ILP32 0x000100 -#define SV_LP64 0x000200 -#define SV_IA32 0x004000 -#define SV_AOUT 0x008000 -#define SV_SHP 0x010000 +#define SV_ILP32 0x000100 /* 32-bit executable. */ +#define SV_LP64 0x000200 /* 64-bit executable. */ +#define SV_IA32 0x004000 /* Intel 32-bit executable. */ +#define SV_AOUT 0x008000 /* a.out executable. */ +#define SV_SHP 0x010000 /* Shared page. */ +#define SV_CAPSICUM 0x020000 /* Force cap_enter() on startup. */ #define SV_ABI_MASK 0xff #define SV_PROC_FLAG(p, x) ((p)->p_sysent->sv_flags & (x)) From ee95773383413943122d356c95c2808cc16716c9 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 3 Aug 2015 13:42:52 +0000 Subject: [PATCH 190/314] Let CloudABI use the SV_CAPSICUM flag. CloudABI processes will now start up in capabilities mode. Reviewed by: kib --- sys/amd64/cloudabi64/cloudabi64_sysvec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/amd64/cloudabi64/cloudabi64_sysvec.c b/sys/amd64/cloudabi64/cloudabi64_sysvec.c index 8e0be1e2e00d..36edfc5acc68 100644 --- a/sys/amd64/cloudabi64/cloudabi64_sysvec.c +++ b/sys/amd64/cloudabi64/cloudabi64_sysvec.c @@ -224,7 +224,7 @@ static struct sysentvec cloudabi64_elf_sysvec = { .sv_usrstack = USRSTACK, .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, .sv_copyout_strings = cloudabi64_copyout_strings, - .sv_flags = SV_ABI_CLOUDABI, + .sv_flags = SV_ABI_CLOUDABI | SV_CAPSICUM, .sv_set_syscall_retval = cloudabi64_set_syscall_retval, .sv_fetch_syscall_args = cloudabi64_fetch_syscall_args, .sv_syscallnames = cloudabi64_syscallnames, From 75333e6435aaadc5ae7093d3950b1e40ffd11d17 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 3 Aug 2015 13:49:46 +0000 Subject: [PATCH 191/314] Add pmspvc device back to GENERIC. The issues with the device playing grabby hands with other driver's devices has been solved. MFC After: 3 weeks --- sys/amd64/conf/GENERIC | 3 +-- sys/i386/conf/GENERIC | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 1320ba7c4108..5c7f7c035f43 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -170,8 +170,7 @@ device ida # Compaq Smart RAID device mfi # LSI MegaRAID SAS device mlx # Mylex DAC960 family device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s -#XXX PCI ID conflicts with ahd(4) and mvs(4) -#device pmspcv # PMC-Sierra SAS/SATA Controller driver +device pmspcv # PMC-Sierra SAS/SATA Controller driver #XXX pointer/int warnings #device pst # Promise Supertrak SX6000 device twe # 3ware ATA RAID diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index deed451a2335..dc11f73c4302 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -175,8 +175,7 @@ device ida # Compaq Smart RAID device mfi # LSI MegaRAID SAS device mlx # Mylex DAC960 family device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s -#XXX PCI ID conflicts with ahd(4) and mvs(4) -#device pmspcv # PMC-Sierra SAS/SATA Controller driver +device pmspcv # PMC-Sierra SAS/SATA Controller driver device pst # Promise Supertrak SX6000 device twe # 3ware ATA RAID From 0b501d960c7a604056984bef2e650f08f2cad347 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Mon, 3 Aug 2015 14:31:06 +0000 Subject: [PATCH 192/314] Fix ipfw range deletion. Spotted by: ian,julian --- sbin/ipfw/ipfw2.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 687d707195e6..5dea97470c11 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -3033,9 +3033,10 @@ fill_flags_cmd(ipfw_insn *cmd, enum ipfw_opcodes opcode, void ipfw_delete(char *av[]) { - int i; + int i, j; int exitval = EX_OK; int do_set = 0; + char *sep; ipfw_range_tlv rt; av++; @@ -3053,7 +3054,11 @@ ipfw_delete(char *av[]) /* Rule number */ while (*av && isdigit(**av)) { - i = atoi(*av); av++; + i = strtol(*av, &sep, 10); + j = i; + if (*sep== '-') + j = strtol(sep + 1, NULL, 10); + av++; if (co.do_nat) { exitval = do_cmd(IP_FW_NAT_DEL, &i, sizeof i); if (exitval) { @@ -3068,7 +3073,7 @@ ipfw_delete(char *av[]) rt.flags = IPFW_RCFLAG_SET; } else { rt.start_rule = i & 0xffff; - rt.end_rule = i & 0xffff; + rt.end_rule = j & 0xffff; if (rt.start_rule == 0 && rt.end_rule == 0) rt.flags |= IPFW_RCFLAG_ALL; else From 4cbca60875990089301d4839d2f88892be7cd4ea Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Mon, 3 Aug 2015 14:58:46 +0000 Subject: [PATCH 193/314] Add missing exception number to EL0 sync. abort on ARM64 When doing a data abort from userland it is possible to get more than one data abort inside the same exception level. Add an appropriate exception number to allow nesting of data_abort handler for EL0. Reviewed by: andrew Obtained from: Semihalf Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3276 --- sys/arm64/arm64/trap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index fad842145871..22d49b179d45 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -329,6 +329,7 @@ do_el0_sync(struct trapframe *frame) break; case EXCP_INSN_ABORT_L: case EXCP_DATA_ABORT_L: + case EXCP_DATA_ABORT: data_abort(frame, esr, 1); break; default: From 8d9ed17366b63ab8d96203756453565852f223fc Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 3 Aug 2015 16:27:36 +0000 Subject: [PATCH 194/314] Fix a problem which made loader(8) load non-kld files twice. For example, without this patch, the following three lines in /boot/loader.conf would result in /boot/root.img being preloaded twice, and two md(4) devices - md0 and md1 - being created. initmd_load="YES" initmd_type="md_image" initmd_name="/boot/root.img" Reviewed by: marcel@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3204 --- sys/boot/common/module.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/boot/common/module.c b/sys/boot/common/module.c index b48b4938801b..163814b94b9b 100644 --- a/sys/boot/common/module.c +++ b/sys/boot/common/module.c @@ -102,6 +102,7 @@ COMMAND_SET(load, "load", "load a kernel or module", command_load); static int command_load(int argc, char *argv[]) { + struct preloaded_file *fp; char *typestr; int dofile, dokld, ch, error; @@ -139,6 +140,13 @@ command_load(int argc, char *argv[]) command_errmsg = "invalid load type"; return(CMD_ERROR); } + + fp = file_findfile(argv[1], typestr); + if (fp) { + sprintf(command_errbuf, "warning: file '%s' already loaded", argv[1]); + return (CMD_ERROR); + } + return (file_loadraw(argv[1], typestr, 1) ? CMD_OK : CMD_ERROR); } /* From 6a968be54740aa5b490d21d354b055e0caf23955 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 3 Aug 2015 16:30:47 +0000 Subject: [PATCH 195/314] Document vgonel(9). MFC after: 1 month Sponsored by: The FreeBSD Foundation --- share/man/man9/Makefile | 1 + share/man/man9/vgone.9 | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 695fa23cd2f3..527d399434ac 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1739,6 +1739,7 @@ MLINKS+=vfs_getopt.9 vfs_copyopt.9 \ vfs_getopt.9 vfs_setopt.9 \ vfs_getopt.9 vfs_setopt_part.9 \ vfs_getopt.9 vfs_setopts.9 +MLINKS+=vgone.9 vgonel.9 MLINKS+=vhold.9 vdrop.9 \ vhold.9 vdropl.9 \ vhold.9 vholdl.9 diff --git a/share/man/man9/vgone.9 b/share/man/man9/vgone.9 index dc10cda76e76..5318cb9247a7 100644 --- a/share/man/man9/vgone.9 +++ b/share/man/man9/vgone.9 @@ -37,6 +37,7 @@ .In sys/vnode.h .Ft void .Fn vgone "struct vnode *vp" +.Fn vgonel "struct vnode *vp" .Sh DESCRIPTION The .Fn vgone @@ -56,6 +57,11 @@ The .Fn vgone function takes an exclusively locked vnode, and returns with the vnode exclusively locked. +The +.Fn vgonel +differs from +.Fn vgone +by requiring the vnode interlock to be held. .Sh SEE ALSO .Xr vnode 9 .Sh AUTHORS From d6cc35b287fa47d2f82e8b9c4beef2530fb7e313 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Mon, 3 Aug 2015 16:35:18 +0000 Subject: [PATCH 196/314] Fix panic that would happen on forcibly unmounting devfs (note that as it is now, devfs ignores MNT_FORCE anyway, so it needs to be modified to trigger the panic) with consumers still opened. Note that this still results in a leak of r/w/e counters. It seems to be harmless, though. If anyone knows a better way to approach this - please tell. Discussed with: kib@, mav@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3050 --- sys/geom/geom_dev.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index 2539e1b1d8b8..3df7f3e37efd 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -401,6 +401,20 @@ g_dev_close(struct cdev *dev, int flags, int fmt, struct thread *td) #else e = 0; #endif + + /* + * The vgonel(9) - caused by eg. forced unmount of devfs - calls + * VOP_CLOSE(9) on devfs vnode without any FREAD or FWRITE flags, + * which would result in zero deltas, which in turn would cause + * panic in g_access(9). + * + * Note that we cannot zero the counters (ie. do "r = cp->acr" + * etc) instead, because the consumer might be opened in another + * devfs instance. + */ + if (r + w + e == 0) + return (EINVAL); + sc = cp->private; mtx_lock(&sc->sc_mtx); sc->sc_open += r + w + e; From e5cb6169d3954831ab5bf77b41c12425b0ced9e4 Mon Sep 17 00:00:00 2001 From: Sean Bruno Date: Mon, 3 Aug 2015 16:39:25 +0000 Subject: [PATCH 197/314] A misplaced #endif in ixgbe_ioctl() causes interface MTU to become zero when INET and INET6 are undefined. PR: 162028 Differential Revision: https://reviews.freebsd.org/D3187 Submitted by: hoomanfazaeli@gmail.com pluknet Reviewed by: erj hiren gelbius MFC after: 2 weeks --- sys/dev/ixgbe/if_ix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index 3787db390771..7742eeae9f0b 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -828,9 +828,9 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) struct ifreq *ifr = (struct ifreq *) data; #if defined(INET) || defined(INET6) struct ifaddr *ifa = (struct ifaddr *)data; - bool avoid_reset = FALSE; #endif int error = 0; + bool avoid_reset = FALSE; switch (command) { @@ -843,7 +843,6 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) if (ifa->ifa_addr->sa_family == AF_INET6) avoid_reset = TRUE; #endif -#if defined(INET) || defined(INET6) /* ** Calling init results in link renegotiation, ** so we avoid doing it when possible. @@ -852,11 +851,12 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) ifp->if_flags |= IFF_UP; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) ixgbe_init(adapter); +#if defined(INET) if (!(ifp->if_flags & IFF_NOARP)) arp_ifinit(ifp, ifa); +#endif } else error = ether_ioctl(ifp, command, data); -#endif break; case SIOCSIFMTU: IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); From 1c9a70522356b9b8db3d559c87c2d1011bd38bfc Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 3 Aug 2015 17:39:36 +0000 Subject: [PATCH 198/314] Remove a couple of unused fields from the FBT probe struct. --- sys/cddl/dev/fbt/aarch64/fbt_isa.c | 1 - sys/cddl/dev/fbt/arm/fbt_isa.c | 1 - sys/cddl/dev/fbt/fbt.h | 2 -- sys/cddl/dev/fbt/powerpc/fbt_isa.c | 1 - sys/cddl/dev/fbt/x86/fbt_isa.c | 1 - 5 files changed, 6 deletions(-) diff --git a/sys/cddl/dev/fbt/aarch64/fbt_isa.c b/sys/cddl/dev/fbt/aarch64/fbt_isa.c index 94de1e85904c..627fdf9c30c3 100644 --- a/sys/cddl/dev/fbt/aarch64/fbt_isa.c +++ b/sys/cddl/dev/fbt/aarch64/fbt_isa.c @@ -58,7 +58,6 @@ fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { if ((uintptr_t)fbt->fbtp_patchpoint == addr) { - fbt->fbtp_invop_cnt++; cpu->cpu_dtrace_caller = addr; dtrace_probe(fbt->fbtp_id, frame->tf_x[0], diff --git a/sys/cddl/dev/fbt/arm/fbt_isa.c b/sys/cddl/dev/fbt/arm/fbt_isa.c index 83c28b89edc5..c02c1eccf3b7 100644 --- a/sys/cddl/dev/fbt/arm/fbt_isa.c +++ b/sys/cddl/dev/fbt/arm/fbt_isa.c @@ -56,7 +56,6 @@ fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { if ((uintptr_t)fbt->fbtp_patchpoint == addr) { - fbt->fbtp_invop_cnt++; cpu->cpu_dtrace_caller = addr; /* TODO: Need 5th parameter from stack */ diff --git a/sys/cddl/dev/fbt/fbt.h b/sys/cddl/dev/fbt/fbt.h index 643858317cd5..ea245cb0b8e8 100644 --- a/sys/cddl/dev/fbt/fbt.h +++ b/sys/cddl/dev/fbt/fbt.h @@ -45,8 +45,6 @@ typedef struct fbt_probe { const char *fbtp_name; modctl_t *fbtp_ctl; int fbtp_loadcnt; - int fbtp_primary; - int fbtp_invop_cnt; int fbtp_symindx; struct fbt_probe *fbtp_next; } fbt_probe_t; diff --git a/sys/cddl/dev/fbt/powerpc/fbt_isa.c b/sys/cddl/dev/fbt/powerpc/fbt_isa.c index 0e131bf629e9..d55d553d9cd1 100644 --- a/sys/cddl/dev/fbt/powerpc/fbt_isa.c +++ b/sys/cddl/dev/fbt/powerpc/fbt_isa.c @@ -60,7 +60,6 @@ fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { if ((uintptr_t)fbt->fbtp_patchpoint == addr) { - fbt->fbtp_invop_cnt++; if (fbt->fbtp_roffset == 0) { cpu->cpu_dtrace_caller = addr; diff --git a/sys/cddl/dev/fbt/x86/fbt_isa.c b/sys/cddl/dev/fbt/x86/fbt_isa.c index 160c9b3c6976..4514b34d512a 100644 --- a/sys/cddl/dev/fbt/x86/fbt_isa.c +++ b/sys/cddl/dev/fbt/x86/fbt_isa.c @@ -66,7 +66,6 @@ fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { if ((uintptr_t)fbt->fbtp_patchpoint == addr) { - fbt->fbtp_invop_cnt++; if (fbt->fbtp_roffset == 0) { int i = 0; /* From 8f980c016b0363f782a6289c2f962b61718627f0 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 3 Aug 2015 17:47:02 +0000 Subject: [PATCH 199/314] The mbuf parameter to ip_output_pfil() must be an output parameter since pfil(9) hooks may modify the chain. X-MFC-With: r286028 --- sys/netinet/ip_output.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 079077745e13..086a8c94a604 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -107,18 +107,21 @@ extern int in_mcast_loop; extern struct protosw inetsw[]; static inline int -ip_output_pfil(struct mbuf *m, struct ifnet *ifp, struct inpcb *inp, - struct sockaddr_in *dst, int *fibnum, int *error) +ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, struct inpcb *inp, + struct sockaddr_in *dst, int *fibnum, int *error) { struct m_tag *fwd_tag = NULL; + struct mbuf *m; struct in_addr odst; struct ip *ip; + m = *mp; ip = mtod(m, struct ip *); /* Run through list of hooks for output packets. */ odst.s_addr = ip->ip_dst.s_addr; - *error = pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, inp); + *error = pfil_run_hooks(&V_inet_pfil_hook, mp, ifp, PFIL_OUT, inp); + m = *mp; if ((*error) != 0 || m == NULL) return 1; /* Finished */ @@ -552,7 +555,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, /* Jump over all PFIL processing if hooks are not active. */ if (PFIL_HOOKED(&V_inet_pfil_hook)) { - switch (ip_output_pfil(m, ifp, inp, dst, &fibnum, &error)) { + switch (ip_output_pfil(&m, ifp, inp, dst, &fibnum, &error)) { case 1: /* Finished */ goto done; From 98fa5d858ce656712711aedd432c9963d4b75152 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Mon, 3 Aug 2015 18:22:31 +0000 Subject: [PATCH 200/314] Add a KASSERT() to make sure we wont rotate the buffers twice (rotate the buffers while the hold buffer is in use). Suggested by: ed, ghelmer MFC with: r286142 --- sys/net/bpf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 413ee41081ff..2be4554cbd9e 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -2412,6 +2412,7 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen, ++d->bd_dcount; return; } + KASSERT(!d->bd_hbuf_in_use, ("hold buffer is in use")); ROTATE_BUFFERS(d); do_wakeup = 1; curlen = 0; From 5c23d0ee9847f8f737bbd462d2cfaa4ec17d7715 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Mon, 3 Aug 2015 18:47:45 +0000 Subject: [PATCH 201/314] Remove never used file Obtained from: DragonFlyBSD --- usr.bin/vgrind/vgrindefs.c | 322 ------------------------------------- 1 file changed, 322 deletions(-) delete mode 100644 usr.bin/vgrind/vgrindefs.c diff --git a/usr.bin/vgrind/vgrindefs.c b/usr.bin/vgrind/vgrindefs.c deleted file mode 100644 index 3c310a9b84fc..000000000000 --- a/usr.bin/vgrind/vgrindefs.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -__FBSDID("$FreeBSD$"); - -#define BUFSIZ 1024 -#define MAXHOP 32 /* max number of tc= indirections */ - -#include -#include -#include -#include - -/* - * grindcap - routines for dealing with the language definitions data base - * (code stolen almost totally from termcap) - * - * BUG: Should use a "last" pointer in tbuf, so that searching - * for capabilities alphabetically would not be a n**2/2 - * process when large numbers of capabilities are given. - * Note: If we add a last pointer now we will screw up the - * tc capability. We really should compile termcap. - * - * Essentially all the work here is scanning and decoding escapes - * in string capabilities. We don't use stdio because the editor - * doesn't, and because living w/o it is not hard. - */ - -static char *tbuf; -static char *filename; -static int hopcount; /* detect infinite loops in termcap, init 0 */ - -static int tnchktc(void); -static int tnamatch(char *); -static char *tskip(register char *); -static char *tdecode(register char *, char **); - -/* - * Get an entry for terminal name in buffer bp, - * from the termcap file. Parse is very rudimentary; - * we just notice escaped newlines. - */ -int -tgetent(char *bp, char *name, char *file) -{ - register char *cp; - register int c; - register int i = 0, cnt = 0; - char ibuf[BUFSIZ]; - int tf; - - tbuf = bp; - tf = 0; - filename = file; - tf = open(filename, O_RDONLY); - if (tf < 0) - return (-1); - for (;;) { - cp = bp; - for (;;) { - if (i == cnt) { - cnt = read(tf, ibuf, BUFSIZ); - if (cnt <= 0) { - close(tf); - return (0); - } - i = 0; - } - c = ibuf[i++]; - if (c == '\n') { - if (cp > bp && cp[-1] == '\\'){ - cp--; - continue; - } - break; - } - if (cp >= bp+BUFSIZ) { - write(STDERR_FILENO, "Vgrind entry too long\n", 23); - break; - } else - *cp++ = c; - } - *cp = 0; - - /* - * The real work for the match. - */ - if (tnamatch(name)) { - close(tf); - return(tnchktc()); - } - } -} - -/* - * tnchktc: check the last entry, see if it's tc=xxx. If so, - * recursively find xxx and append that entry (minus the names) - * to take the place of the tc=xxx entry. This allows termcap - * entries to say "like an HP2621 but doesn't turn on the labels". - * Note that this works because of the left to right scan. - */ -static int -tnchktc(void) -{ - register char *p, *q; - char tcname[16]; /* name of similar terminal */ - char tcbuf[BUFSIZ]; - char *holdtbuf = tbuf; - int l; - - p = tbuf + strlen(tbuf) - 2; /* before the last colon */ - while (*--p != ':') - if (p MAXHOP) { - write(STDERR_FILENO, "Infinite tc= loop\n", 18); - return (0); - } - if (tgetent(tcbuf, tcname, filename) != 1) - return(0); - for (q=tcbuf; *q != ':'; q++) - ; - l = p - holdtbuf + strlen(q); - if (l > BUFSIZ) { - write(STDERR_FILENO, "Vgrind entry too long\n", 23); - q[BUFSIZ - (p-tbuf)] = 0; - } - strlcpy(p, q+1, BUFSIZ - (p - holdtbuf)); - tbuf = holdtbuf; - return(1); -} - -/* - * Tnamatch deals with name matching. The first field of the termcap - * entry is a sequence of names separated by |'s, so we compare - * against each such name. The normal : terminator after the last - * name (before the first field) stops us. - */ -static int -tnamatch(char *np) -{ - register char *Np, *Bp; - - Bp = tbuf; - if (*Bp == '#') - return(0); - for (;;) { - for (Np = np; *Np && *Bp == *Np; Bp++, Np++) - continue; - if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0)) - return (1); - while (*Bp && *Bp != ':' && *Bp != '|') - Bp++; - if (*Bp == 0 || *Bp == ':') - return (0); - Bp++; - } -} - -/* - * Skip to the next field. Notice that this is very dumb, not - * knowing about \: escapes or any such. If necessary, :'s can be put - * into the termcap file in octal. - */ -static char * -tskip(register char *bp) -{ - - while (*bp && *bp != ':') - bp++; - if (*bp == ':') - bp++; - return (bp); -} - -/* - * Return the (numeric) option id. - * Numeric options look like - * li#80 - * i.e. the option string is separated from the numeric value by - * a # character. If the option is not found we return -1. - * Note that we handle octal numbers beginning with 0. - */ -int -tgetnum(char *id) -{ - register int i, base; - register char *bp = tbuf; - - for (;;) { - bp = tskip(bp); - if (*bp == 0) - return (-1); - if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) - continue; - if (*bp == '@') - return(-1); - if (*bp != '#') - continue; - bp++; - base = 10; - if (*bp == '0') - base = 8; - i = 0; - while (isdigit(*bp)) - i *= base, i += *bp++ - '0'; - return (i); - } -} - -/* - * Handle a flag option. - * Flag options are given "naked", i.e. followed by a : or the end - * of the buffer. Return 1 if we find the option, or 0 if it is - * not given. - */ -int -tgetflag(char *id) -{ - register char *bp = tbuf; - - for (;;) { - bp = tskip(bp); - if (!*bp) - return (0); - if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { - if (!*bp || *bp == ':') - return (1); - else if (*bp == '@') - return(0); - } - } -} - -/* - * Get a string valued option. - * These are given as - * cl=^Z - * Much decoding is done on the strings, and the strings are - * placed in area, which is a ref parameter which is updated. - * No checking on area overflow. - */ -char * -tgetstr(char *id, char **area) -{ - register char *bp = tbuf; - - for (;;) { - bp = tskip(bp); - if (!*bp) - return (0); - if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) - continue; - if (*bp == '@') - return(0); - if (*bp != '=') - continue; - bp++; - return (tdecode(bp, area)); - } -} - -/* - * Tdecode does the grung work to decode the - * string capability escapes. - */ -static char * -tdecode(register char *str, char **area) -{ - register char *cp; - register int c; - - cp = *area; - while ((c = *str++)) { - if (c == ':' && *(cp-1) != '\\') - break; - *cp++ = c; - } - *cp++ = 0; - str = *area; - *area = cp; - return (str); -} From d8015db3b5208b697663aa7a8eb7948255d4967b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 3 Aug 2015 20:30:27 +0000 Subject: [PATCH 202/314] Refinements to r281079's sequential access optimization: Prefetched pages, which constitute the majority of the pages that are processed by vm_fault_dontneed(), are already near the tail of the inactive queue. Only the pages at faulting virtual addresses are actually moved by vm_page_advise(..., MADV_DONTNEED). However, vm_page_advise(..., MADV_DONTNEED) is simultaneously too aggressive and passive for the moved pages. It makes most of these pages too easily reclaimable, and at the same time it leaves enough pages in the active queue to trigger pageouts by the page daemon. Instead, with this change, the pages at faulting virtual addresses are moved to the tail of the inactive queue, where they are relatively close to the pages prefetched by the same page fault. Discussed with: jeff Sponsored by: EMC / Isilon Storage Division --- sys/vm/vm_fault.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 0d8ceedf7b77..50983ca389f3 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -1081,9 +1081,19 @@ vm_fault_dontneed(const struct faultstate *fs, vm_offset_t vaddr, int ahead) if (m->valid != VM_PAGE_BITS_ALL || vm_page_busied(m)) continue; + + /* + * Don't clear PGA_REFERENCED, since it would + * likely represent a reference by a different + * process. + * + * Typically, at this point, prefetched pages + * are still in the inactive queue. Only + * pages that triggered page faults are in the + * active queue. + */ vm_page_lock(m); - if (m->hold_count == 0 && m->wire_count == 0) - vm_page_advise(m, MADV_DONTNEED); + vm_page_deactivate(m); vm_page_unlock(m); } } From 92de34df2c6334e9925c56997f37da082d739b75 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 3 Aug 2015 20:43:36 +0000 Subject: [PATCH 203/314] kgdb uses td_oncpu to determine if a thread is running and should use a pcb from stoppcbs[] rather than the thread's PCB. However, exited threads retained td_oncpu from the last time they ran, and newborn threads had their CPU fields cleared to zero during fork and thread creation since they are in the set of fields zeroed when threads are setup. To fix, explicitly update the CPU fields for exiting threads in sched_throw() to reflect the switch out and reset the CPU fields for new threads in sched_fork_thread() to NOCPU. Reviewed by: kib MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D3193 --- sys/kern/sched_4bsd.c | 4 ++++ sys/kern/sched_ule.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index 59bd38737118..da77c4be105f 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -792,6 +792,8 @@ sched_fork_thread(struct thread *td, struct thread *childtd) { struct td_sched *ts; + childtd->td_oncpu = NOCPU; + childtd->td_lastcpu = NOCPU; childtd->td_estcpu = td->td_estcpu; childtd->td_lock = &sched_lock; childtd->td_cpuset = cpuset_ref(td->td_cpuset); @@ -1671,6 +1673,8 @@ sched_throw(struct thread *td) } else { lock_profile_release_lock(&sched_lock.lock_object); MPASS(td->td_lock == &sched_lock); + td->td_lastcpu = td->td_oncpu; + td->td_oncpu = NOCPU; } mtx_assert(&sched_lock, MA_OWNED); KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count")); diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index 74ae85f5efcf..708478f27558 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -2080,6 +2080,8 @@ sched_fork_thread(struct thread *td, struct thread *child) */ ts = td->td_sched; ts2 = child->td_sched; + child->td_oncpu = NOCPU; + child->td_lastcpu = NOCPU; child->td_lock = TDQ_LOCKPTR(tdq); child->td_cpuset = cpuset_ref(td->td_cpuset); ts2->ts_cpu = ts->ts_cpu; @@ -2703,6 +2705,8 @@ sched_throw(struct thread *td) MPASS(td->td_lock == TDQ_LOCKPTR(tdq)); tdq_load_rem(tdq, td); lock_profile_release_lock(&TDQ_LOCKPTR(tdq)->lock_object); + td->td_lastcpu = td->td_oncpu; + td->td_oncpu = NOCPU; } KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count")); newtd = choosethread(); From 52942c1eae52930adaa4f1204cde66add18547fe Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 3 Aug 2015 21:11:33 +0000 Subject: [PATCH 204/314] Add missing const keyword to function parameter. The umtx_key_get() function does not dereference the address off the userspace object. The pointer can safely be const. --- sys/kern/kern_umtx.c | 2 +- sys/sys/umtx.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 8ff8f764dedb..cf472912164b 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -793,7 +793,7 @@ umtxq_sleep(struct umtx_q *uq, const char *wmesg, struct abs_timeout *abstime) * Convert userspace address into unique logical address. */ int -umtx_key_get(void *addr, int type, int share, struct umtx_key *key) +umtx_key_get(const void *addr, int type, int share, struct umtx_key *key) { struct thread *td = curthread; vm_map_t map; diff --git a/sys/sys/umtx.h b/sys/sys/umtx.h index 07794dfe038b..145950710a10 100644 --- a/sys/sys/umtx.h +++ b/sys/sys/umtx.h @@ -153,7 +153,7 @@ umtx_key_match(const struct umtx_key *k1, const struct umtx_key *k2) } int umtx_copyin_timeout(const void *, struct timespec *); -int umtx_key_get(void *, int, int, struct umtx_key *); +int umtx_key_get(const void *, int, int, struct umtx_key *); void umtx_key_release(struct umtx_key *); struct umtx_q *umtxq_alloc(void); void umtxq_free(struct umtx_q *); From 1e4d5cf1d6e08c7f2cbeac67e7dbd4768c057635 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Mon, 3 Aug 2015 21:19:31 +0000 Subject: [PATCH 205/314] Clarify pw(8) manual w/respect to required arguments. Break long lines at punctuation while here. Differential Revision: https://reviews.freebsd.org/D2700 Reviewed by: wblock, bapt MFC after: 3 days X-MFC-to: stable/10 --- usr.sbin/pw/pw.8 | 208 +++++++++++++++++++++++++++-------------------- 1 file changed, 118 insertions(+), 90 deletions(-) diff --git a/usr.sbin/pw/pw.8 b/usr.sbin/pw/pw.8 index c29a8a9f40d1..3a9c0b0b87b9 100644 --- a/usr.sbin/pw/pw.8 +++ b/usr.sbin/pw/pw.8 @@ -35,11 +35,9 @@ .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar useradd -.Op name|uid +.Oo Fl n Oc name Oo Fl u Ar uid Oc .Op Fl C Ar config .Op Fl q -.Op Fl n Ar name -.Op Fl u Ar uid .Op Fl c Ar comment .Op Fl d Ar dir .Op Fl e Ar date @@ -61,7 +59,6 @@ .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar useradd -.Op name|uid .Fl D .Op Fl C Ar config .Op Fl q @@ -81,27 +78,23 @@ .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar userdel -.Op name|uid -.Op Fl n Ar name -.Op Fl u Ar uid +.Oo Fl n Oc name|uid | Fl u Ar uid .Op Fl r .Op Fl Y .Nm .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar usermod -.Op name|uid +.Oo Fl n Oc name|uid Oo Fl u Ar newuid Oc | Fl u Ar uid .Op Fl C Ar config .Op Fl q -.Op Fl n Ar name -.Op Fl u Ar uid .Op Fl c Ar comment .Op Fl d Ar dir .Op Fl e Ar date .Op Fl p Ar date .Op Fl g Ar group .Op Fl G Ar grouplist -.Op Fl l Ar name +.Op Fl l Ar newname .Op Fl m .Op Fl M Ar mode .Op Fl k Ar dir @@ -116,9 +109,7 @@ .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar usershow -.Op name|uid -.Op Fl n Ar name -.Op Fl u Ar uid +.Oo Fl n Oc name|uid | Fl u Ar uid .Op Fl F .Op Fl P .Op Fl 7 @@ -133,11 +124,9 @@ .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar groupadd -.Op group|gid +.Oo Fl n Oc name Oo Fl g Ar gid Oc .Op Fl C Ar config .Op Fl q -.Op Fl n Ar group -.Op Fl g Ar gid .Op Fl M Ar members .Op Fl o .Op Fl h Ar fd | Fl H Ar fd @@ -148,20 +137,16 @@ .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar groupdel -.Op group|gid -.Op Fl n Ar name -.Op Fl g Ar gid +.Oo Fl n Oc name|gid | Fl g Ar gid .Op Fl Y .Nm .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar groupmod -.Op group|gid +.Oo Fl n Oc name|gid Oo Fl g Ar newgid Oc | Fl g Ar gid .Op Fl C Ar config .Op Fl q -.Op Fl n Ar name -.Op Fl g Ar gid -.Op Fl l Ar name +.Op Fl l Ar newname .Op Fl M Ar members .Op Fl m Ar newmembers .Op Fl d Ar oldmembers @@ -173,9 +158,7 @@ .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar groupshow -.Op group|gid -.Op Fl n Ar name -.Op Fl g Ar gid +.Oo Fl n Oc name|gid | Fl g Ar gid .Op Fl F .Op Fl P .Op Fl a @@ -189,14 +172,14 @@ .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar lock -.Op name|uid +.Oo Fl n Oc name|uid | Fl u Ar uid .Op Fl C Ar config .Op Fl q .Nm .Op Fl R Ar rootdir .Op Fl V Ar etcdir .Ar unlock -.Op name|uid +.Oo Fl n Oc name|uid | Fl u Ar uid .Op Fl C Ar config .Op Fl q .Sh DESCRIPTION @@ -250,8 +233,9 @@ all mean the same thing.) This flexibility is useful for interactive scripts calling .Nm for user and group database manipulation. -Following these keywords, you may optionally specify the user or group name or numeric -id as an alternative to using the +Following these keywords, +the user or group name or numeric id may be optionally specified as an +alternative to using the .Fl n Ar name , .Fl u Ar uid , .Fl g Ar gid @@ -266,12 +250,13 @@ will operate. Any paths specified will be relative to .Va rootdir . .It Fl V Ar etcdir -This flag sets an alternate location for the password, group and configuration files, -and may be used to maintain a user/group database in an alternate location. +Set an alternate location for the password, group, and configuration files. +Can be used to maintain a user/group database in an alternate location. If this switch is specified, the system .Pa /etc/pw.conf -will not be sourced for default configuration data, but the file pw.conf in the -specified directory will be used instead (or none, if it does not exist). +will not be sourced for default configuration data, +but the file pw.conf in the specified directory will be used instead +.Pq or none, if it does not exist . The .Fl C flag may be used to override this behaviour. @@ -294,7 +279,8 @@ configuration file. .It Fl q Use of this option causes .Nm -to suppress error messages, which may be useful in interactive environments where it +to suppress error messages, +which may be useful in interactive environments where it is preferable to interpret status codes returned by .Nm rather than messing up a carefully formatted display. @@ -338,27 +324,40 @@ and .Ar usermod commands: .Bl -tag -width "-G grouplist" -.It Fl n Ar name +.It Oo Fl n Oc Ar name +Required unless +.Fl u Ar uid +is given. Specify the user/account name. +In the case of +.Ar usermod +can be a uid. .It Fl u Ar uid +Required if +.Ar name +is not given. Specify the user/account numeric id. +In the case of +.Ar usermod +if paired with +.Ar name , +changes the numeric id of the named user/account. .Pp -Usually, you only need to provide one or the other of these options, as the account -name will imply the uid, or vice versa. -However, there are times when you need to provide both. +Usually, only one of these options is required, +as the account name will imply the uid, or vice versa. +However, there are times when both are needed. For example, when changing the uid of an existing user with .Ar usermod , -or overriding the default uid when creating a new account. -If you wish -.Nm -to automatically allocate the uid to a new user with +or overriding the default uid when creating a new account with +.Ar useradd . +To automatically allocate the uid to a new user with .Ar useradd , -then you should +then do .Em not use the .Fl u option. -You may also provide either the account or userid immediately after the +Either the account or userid can also be provided immediately after the .Ar useradd , .Ar userdel , .Ar usermod @@ -372,21 +371,23 @@ options. .El .Bl -tag -width "-G grouplist" .It Fl c Ar comment -This field sets the contents of the passwd GECOS field, which normally contains up -to four comma-separated fields containing the user's full name, office or location, +This field sets the contents of the passwd GECOS field, +which normally contains up to four comma-separated fields containing the +user's full name, office or location, and work and home phone numbers. These sub-fields are used by convention only, however, and are optional. -If this field is to contain spaces, you need to quote the comment itself with double -quotes +If this field is to contain spaces, +the comment must be enclosed in double quotes .Ql \&" . -Avoid using commas in this field as these are used as sub-field separators, and the -colon +Avoid using commas in this field as these are used as sub-field separators, +and the colon .Ql \&: character also cannot be used as this is the field separator for the passwd file itself. .It Fl d Ar dir This option sets the account's home directory. -Normally, you will only use this if the home directory is to be different from the +Normally, +this is only used if the home directory is to be different from the default determined from .Pa /etc/pw.conf - normally @@ -396,13 +397,15 @@ with the account name as a subdirectory. Set the account's expiration date. Format of the date is either a UNIX time in decimal, or a date in .Ql dd-mmm-yy[yy] -format, where dd is the day, mmm is the month, either in numeric or alphabetic format +format, where dd is the day, +mmm is the month, either in numeric or alphabetic format ('Jan', 'Feb', etc) and year is either a two or four digit year. This option also accepts a relative date in the form .Ql \&+n[mhdwoy] where .Ql \&n -is a decimal, octal (leading 0) or hexadecimal (leading 0x) digit followed by the +is a decimal, +octal (leading 0) or hexadecimal (leading 0x) digit followed by the number of Minutes, Hours, Days, Weeks, Months or Years from the current date at which the expiration date is to be set. .It Fl p Ar date @@ -442,8 +445,8 @@ This option instructs to attempt to create the user's home directory. While primarily useful when adding a new account with .Ar useradd , -this may also be of use when moving an existing user's home directory elsewhere on -the file system. +this may also be of use when moving an existing user's home directory elsewhere +on the file system. The new home directory is populated with the contents of the .Ar skeleton directory, which typically contains a set of shell configuration files that the @@ -461,7 +464,8 @@ existing configuration files in the user's home directory are .Em not overwritten from the skeleton files. .Pp -When a user's home directory is created, it will by default be a subdirectory of the +When a user's home directory is created, +it will by default be a subdirectory of the .Ar basehome directory as specified by the .Fl b @@ -599,10 +603,13 @@ The default value for this is but it may be set elsewhere as desired. .It Fl e Ar days Set the default account expiration period in days. -Unlike use without -.Fl D , -the argument must be numeric, which specifies the number of days after creation when -the account is to expire. +When +.Fl D +is used, the +.Ar days +argument is interpreted differently. +It must be numeric and represents the number of days after creation +that the account expires. A value of 0 suppresses automatic calculation of the expiry date. .It Fl p Ar days Set the default password expiration period in days. @@ -615,8 +622,8 @@ with the same name as their login name. If a group is supplied, either its name or uid may be given as an argument. .It Fl G Ar grouplist Set the default groups in which new users are granted membership. -This is a separate set of groups from the primary group, and you should avoid -nominating the same group as both primary and extra groups. +This is a separate set of groups from the primary group. +Avoid nominating the same group as both primary and extra groups. In other words, these extra groups determine membership in groups .Em other than the primary group. @@ -630,7 +637,8 @@ This option sets the default login class for new users. .It Fl k Ar dir Set the default .Em skeleton -directory, from which prototype shell and other initialization files are copied when +directory, +from which prototype shell and other initialization files are copied when .Nm creates a user's home directory. See description of @@ -640,22 +648,24 @@ for naming conventions of these files. .Fl u Ar min , Ns Ar max , .Fl i Ar min , Ns Ar max .Xc -These options set the minimum and maximum user and group ids allocated for new accounts -and groups created by +Set the minimum and maximum user and group ids allocated for new +accounts and groups created by .Nm . The default values for each is 1000 minimum and 32000 maximum. .Ar min and .Ar max -are both numbers, where max must be greater than min, and both must be between 0 -and 32767. -In general, user and group ids less than 100 are reserved for use by the system, -and numbers greater than 32000 may also be reserved for special purposes (used by -some system daemons). +are both numbers, where max must be greater than min, +and both must be between 0 and 32767. +In general, +user and group ids less than 100 are reserved for use by the system, +and numbers greater than 32000 may also be reserved for special purposes +.Pq used by some system daemons . .It Fl w Ar method The .Fl w -option sets the default method used to set passwords for newly created user accounts. +option selects the default method used to set passwords for newly created user +accounts. .Ar method is one of: .Pp @@ -676,9 +686,11 @@ or .Ql \&no methods are the most secure; in the former case, .Nm -generates a password and prints it to stdout, which is suitable where you issue -users with passwords to access their accounts rather than having the user nominate -their own (possibly poorly chosen) password. +generates a password and prints it to stdout, +which is suitable when users are issued passwords rather than being allowed +to select their own +.Pq possibly poorly chosen +password. The .Ql \&no method requires that the superuser use @@ -699,7 +711,7 @@ servers. .Pp The .Ar userdel -command has only three valid options. +command has three distinct options. The .Fl n Ar name and @@ -714,7 +726,8 @@ to remove the user's home directory and all of its contents. The .Nm utility errs on the side of caution when removing files from the system. -Firstly, it will not do so if the uid of the account being removed is also used by +Firstly, +it will not do so if the uid of the account being removed is also used by another account on the system, and the 'home' directory in the password file is a valid path that commences with the character .Ql \&/ . @@ -725,20 +738,20 @@ will be removed. If any additional cleanup work is required, this is left to the administrator. .El .Pp -Mail spool files and crontabs are always removed when an account is deleted as these -are unconditionally attached to the user name. +Mail spool files and crontabs are always removed when an account is deleted as +these are unconditionally attached to the user name. Jobs queued for processing by .Ar at -are also removed if the user's uid is unique and not also used by another account on the -system. +are also removed if the user's uid is unique and not also used by another +account on the system. .Pp The .Ar usermod command adds one additional option: .Bl -tag -width "-G grouplist" -.It Fl l Ar name +.It Fl l Ar newname This option allows changing of an existing account name to -.Ql \&name . +.Ql \&newname . The new name must not already exist, and any attempt to duplicate an existing account name will be rejected. .El @@ -782,10 +795,24 @@ options (explained at the start of the previous section) are available with the group manipulation commands. Other common options to all group-related commands are: .Bl -tag -width "-m newmembers" -.It Fl n Ar name +.It Oo Fl n Oc Ar name +Required unless +.Fl g Ar gid +is given. Specify the group name. +In the case of +.Ar groupmod +can be a gid. .It Fl g Ar gid +Required if +.Ar name +is not given. Specify the group numeric id. +In the case of +.Ar groupmod +if paired with +.Ar name , +changes the numeric id of the named group. .Pp As with the account name and id fields, you will usually only need to supply one of these, as the group name implies the uid and vice @@ -822,18 +849,19 @@ silently eliminated. also has a .Fl o option that allows allocation of an existing group id to a new group. -The default action is to reject an attempt to add a group, and this option overrides -the check for duplicate group ids. +The default action is to reject an attempt to add a group, +and this option overrides the check for duplicate group ids. There is rarely any need to duplicate a group id. .Pp The .Ar groupmod command adds one additional option: .Bl -tag -width "-m newmembers" -.It Fl l Ar name +.It Fl l Ar newname This option allows changing of an existing group name to -.Ql \&name . -The new name must not already exist, and any attempt to duplicate an existing group +.Ql \&newname . +The new name must not already exist, +and any attempt to duplicate an existing group name will be rejected. .El .Pp From fc6ab770113e1401ad4e8dc50bd4d585fecf9770 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 3 Aug 2015 22:07:50 +0000 Subject: [PATCH 206/314] Avoid calling strlen() where we can use the strspn() return value. --- usr.sbin/pw/pw_group.c | 8 ++++---- usr.sbin/pw/pw_user.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c index df2d76da4a1e..711ef68b0cca 100644 --- a/usr.sbin/pw/pw_group.c +++ b/usr.sbin/pw/pw_group.c @@ -297,7 +297,7 @@ pw_group_show(int argc, char **argv, char *arg1) }; if (arg1 != NULL) { - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, GID_MAX); else name = arg1; @@ -360,7 +360,7 @@ pw_group_del(int argc, char **argv, char *arg1) bool nis = false; if (arg1 != NULL) { - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, GID_MAX); else name = arg1; @@ -491,7 +491,7 @@ pw_group_add(int argc, char **argv, char *arg1) quiet = precrypted = dryrun = pretty = nis = false; if (arg1 != NULL) { - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, GID_MAX); else name = arg1; @@ -577,7 +577,7 @@ pw_group_mod(int argc, char **argv, char *arg1) quiet = pretty = dryrun = nis = precrypted = false; if (arg1 != NULL) { - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, GID_MAX); else name = arg1; diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index b51a6cbbabf9..d9bce87f619f 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -214,7 +214,7 @@ pw_userlock(char *arg1, int mode) if (arg1 == NULL) errx(EX_DATAERR, "username or id required"); - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, UID_MAX); else name = arg1; @@ -709,7 +709,7 @@ pw_user_show(int argc, char **argv, char *arg1) bool quiet = false; if (arg1 != NULL) { - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, UID_MAX); else name = arg1; @@ -793,7 +793,7 @@ pw_user_del(int argc, char **argv, char *arg1) bool quiet = false; if (arg1 != NULL) { - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, UID_MAX); else name = arg1; @@ -1124,7 +1124,7 @@ pw_user_add(int argc, char **argv, char *arg1) err(EXIT_FAILURE, "calloc()"); if (arg1 != NULL) { - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, UID_MAX); else name = arg1; @@ -1435,7 +1435,7 @@ pw_user_mod(int argc, char **argv, char *arg1) edited = docreatehome = false; if (arg1 != NULL) { - if (strspn(arg1, "0123456789") == strlen(arg1)) + if (arg1[strspn(arg1, "0123456789")] == '\0') id = pw_checkid(arg1, UID_MAX); else name = arg1; From 9224217213dbf5ffc74bc54b83aff584304f0677 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Mon, 3 Aug 2015 22:14:45 +0000 Subject: [PATCH 207/314] Remove the mtx_sleep() from the kqueue f_event filter. The filter is called from the network hot path and must not sleep. The filter runs with the descriptor lock held and does not manipulates the buffers, so it is not necessary sleep when the hold buffer is in use. Just ignore the hold buffer contents when it is being copied to user space (when hold buffer in use is set). This fix the "Sleeping thread owns a non-sleepable lock" panic when the userland thread is too busy reading the packets from bpf(4). PR: 200323 MFC after: 2 weeks Sponsored by: Rubicon Communications (Netgate) --- sys/net/bpf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 2be4554cbd9e..985208b1975a 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -2035,10 +2035,10 @@ filt_bpfread(struct knote *kn, long hint) ready = bpf_ready(d); if (ready) { kn->kn_data = d->bd_slen; - while (d->bd_hbuf_in_use) - mtx_sleep(&d->bd_hbuf_in_use, &d->bd_lock, - PRINET, "bd_hbuf", 0); - if (d->bd_hbuf) + /* + * Ignore the hold buffer if it is being copied to user space. + */ + if (!d->bd_hbuf_in_use && d->bd_hbuf) kn->kn_data += d->bd_hlen; } else if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) { callout_reset(&d->bd_callout, d->bd_rtout, From 45c2c9a84a7bf9df33c9a4239692256aa2ece3ca Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Tue, 4 Aug 2015 00:11:39 +0000 Subject: [PATCH 208/314] Always define __va_list for amd64 and restore pre-r232261 behavior for i386. Note it allows exotic compilers, e.g., TCC, to build with our stdio.h, etc. PR: 201749 MFC after: 1 week --- sys/x86/include/_types.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sys/x86/include/_types.h b/sys/x86/include/_types.h index 816a30123270..20a2bf766225 100644 --- a/sys/x86/include/_types.h +++ b/sys/x86/include/_types.h @@ -152,8 +152,17 @@ typedef int ___wchar_t; */ #ifdef __GNUCLIKE_BUILTIN_VARARGS typedef __builtin_va_list __va_list; /* internally known to gcc */ -#elif defined(lint) -typedef char * __va_list; /* pretend */ +#else +#ifdef __LP64__ +typedef struct { + unsigned int __gpo; + unsigned int __fpo; + void *__oaa; + void *__rsa; +} __va_list; +#else +typedef char * __va_list; +#endif #endif #if defined(__GNUC_VA_LIST_COMPATIBILITY) && !defined(__GNUC_VA_LIST) \ && !defined(__NO_GNUC_VA_LIST) From eb2e6d158d0218f48be0e133f73258871a00a89c Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Tue, 4 Aug 2015 02:34:51 +0000 Subject: [PATCH 209/314] Remove the 3rd clause of BSD LICENSE. Sync the code with the OpenBSD version. Differential Revision: D3213 Reviewed by: rodrigc, bapt Obtained from: OpenBSD Sponsored by: gandi.net --- usr.bin/ypmatch/ypmatch.c | 80 +++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/usr.bin/ypmatch/ypmatch.c b/usr.bin/ypmatch/ypmatch.c index ff4253fbaf0c..66fa84aae100 100644 --- a/usr.bin/ypmatch/ypmatch.c +++ b/usr.bin/ypmatch/ypmatch.c @@ -1,5 +1,8 @@ +/* $OpenBSD: ypmatch.c,v 1.16 2015/02/08 23:40:35 deraadt Exp $ */ +/* $NetBSD: ypmatch.c,v 1.8 1996/05/07 01:24:52 jtc Exp $ */ + /* - * Copyright (c) 1992/3 Theo de Raadt + * Copyright (c) 1992, 1993, 1996 Theo de Raadt * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,9 +13,6 @@ * 2. 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -34,18 +34,19 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include +void usage(void); static const struct ypalias { char *alias, *name; @@ -62,30 +63,37 @@ static const struct ypalias { { "ethers", "ethers.byname" }, }; -static void +void usage(void) { - fprintf(stderr, "%s\n%s\n", - "usage: ypmatch [-kt] [-d domainname] key ... mapname", - " ypmatch -x"); + fprintf(stderr, + "usage: ypmatch [-kt] [-d domain] key ... mapname\n" + " ypmatch -x\n"); + fprintf(stderr, + "where\n" + "\tmapname may be either a mapname or a nickname for a map.\n" + "\t-k prints keys as well as values.\n" + "\t-t inhibits map nickname translation.\n" + "\t-x dumps the map nickname translation table.\n"); exit(1); } int main(int argc, char *argv[]) { - char *domainname = NULL; - char *inkey, *inmap, *outbuf; - int outbuflen, key, notrans; + char *domainname, *inkey, *inmap, *outbuf; + extern char *optarg; + extern int optind; + int outbuflen, key, notrans, rval; int c, r; u_int i; + domainname = NULL; notrans = key = 0; - - while ((c = getopt(argc, argv, "xd:kt")) != -1) + while ((c=getopt(argc, argv, "xd:kt")) != -1) switch (c) { case 'x': - for (i = 0; i Date: Tue, 4 Aug 2015 02:41:14 +0000 Subject: [PATCH 210/314] Remove the 3rd clause of BSD LICENSE. Sync the code with the OpenBSD version. Small style(9) fix up. Differential Revision: D3212 Reviewed by: rodrigc, bapt Obtained from: OpenBSD Sponsored by: gandi.net --- usr.bin/ypcat/ypcat.c | 77 +++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/usr.bin/ypcat/ypcat.c b/usr.bin/ypcat/ypcat.c index d3a7f4177997..60acca0726b4 100644 --- a/usr.bin/ypcat/ypcat.c +++ b/usr.bin/ypcat/ypcat.c @@ -1,5 +1,7 @@ +/* $OpenBSD: ypcat.c,v 1.16 2015/02/08 23:40:35 deraadt Exp $ */ + /* - * Copyright (c) 1992/3 Theo de Raadt + * Copyright (c) 1992, 1993, 1996 Theo de Raadt * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,9 +12,6 @@ * 2. 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -34,18 +33,20 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include +#include +#include +#include #include #include -#include +#include #include -#include -#include -#include -#include -#include -#include +void usage(void); +int printit(u_long, char *, int, char *, int, void *); static const struct ypalias { char *alias, *name; @@ -64,17 +65,18 @@ static const struct ypalias { static int key; -static void +void usage(void) { - fprintf(stderr, "%s\n%s\n", - "usage: ypcat [-kt] [-d domainname] mapname", - " ypcat -x"); + fprintf(stderr, + "usage: ypcat [-kt] [-d domainname] mapname\n" + " ypcat -x\n"); exit(1); } -static int -printit(unsigned long instatus, char *inkey, int inkeylen, char *inval, int invallen, void *dummy __unused) +int +printit(u_long instatus, char *inkey, int inkeylen, char *inval, int invallen, + void *indata) { if (instatus != YP_TRUE) return (instatus); @@ -87,31 +89,29 @@ printit(unsigned long instatus, char *inkey, int inkeylen, char *inval, int inva int main(int argc, char *argv[]) { - char *domainname = NULL; + char *domain = NULL, *inmap; struct ypall_callback ypcb; - char *inmap; - int notrans; - int c, r; + extern char *optarg; + extern int optind; + int notrans, c, r; u_int i; notrans = key = 0; - while ((c = getopt(argc, argv, "xd:kt")) != -1) switch (c) { case 'x': - for (i = 0; i Date: Tue, 4 Aug 2015 02:56:31 +0000 Subject: [PATCH 211/314] Revert r286144 leaving the original fix to the buffer overflow. Some developers consider the new code unnecessarily obfuscated. There was also a benign off-by-one. Discussed with: bde, vangyzen, jmallett --- usr.bin/wall/ttymsg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/usr.bin/wall/ttymsg.c b/usr.bin/wall/ttymsg.c index afa3d266ad3a..1317a4b0cb60 100644 --- a/usr.bin/wall/ttymsg.c +++ b/usr.bin/wall/ttymsg.c @@ -62,7 +62,7 @@ ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) struct iovec localiov[7]; ssize_t left, wret; int cnt, fd; - char device[MAXNAMLEN]; + char device[MAXNAMLEN] = _PATH_DEV; static char errbuf[1024]; char *p; int forked; @@ -71,9 +71,8 @@ ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0]))) return ("too many iov's (change code in wall/ttymsg.c)"); - strlcpy(device, _PATH_DEV, sizeof(device)); + strlcat(device, line, sizeof(device)); p = device + sizeof(_PATH_DEV) - 1; - strlcpy(p, line, sizeof(device) - sizeof(_PATH_DEV)); if (strncmp(p, "pts/", 4) == 0) p += 4; if (strchr(p, '/') != NULL) { From dc4b53247968c2ea07d8ccbafa8cd8c5eeaca0ff Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 4 Aug 2015 06:01:13 +0000 Subject: [PATCH 212/314] Fix bad arithmetic in umtx_key_get() to compute object offset. It looks like umtx_key_get() has the addition and subtraction the wrong way around, meaning that it fails to match in certain cases. This causes the cloudlibc unit tests to deadlock in certain cases. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D3287 --- sys/kern/kern_umtx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index cf472912164b..a40aa5a358c8 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -820,8 +820,8 @@ umtx_key_get(const void *addr, int type, int share, struct umtx_key *key) (share == AUTO_SHARE && VM_INHERIT_SHARE == entry->inheritance)) { key->shared = 1; - key->info.shared.offset = entry->offset + entry->start - - (vm_offset_t)addr; + key->info.shared.offset = (vm_offset_t)addr - + entry->start + entry->offset; vm_object_reference(key->info.shared.object); } else { key->shared = 0; From 0c0964844e7bd9571a3766092d10dd1002e210df Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 4 Aug 2015 06:02:03 +0000 Subject: [PATCH 213/314] Let the CloudABI futex code use umtx_keys. The CloudABI kernel still passes all of the cloudlibc unit tests. Reviewed by: vangyzen Differential Revision: https://reviews.freebsd.org/D3286 --- sys/compat/cloudabi/cloudabi_futex.c | 83 ++++------------------------ 1 file changed, 11 insertions(+), 72 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_futex.c b/sys/compat/cloudabi/cloudabi_futex.c index 802509062e67..aec2f3318f34 100644 --- a/sys/compat/cloudabi/cloudabi_futex.c +++ b/sys/compat/cloudabi/cloudabi_futex.c @@ -35,13 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include - -#include -#include -#include -#include -#include -#include +#include #include #include @@ -105,13 +99,7 @@ struct futex_waiter; /* Identifier of a location in memory. */ struct futex_address { - /* For process-private objects: address space of the process. */ - struct vmspace * fa_vmspace; - /* For process-shared objects: VM object containing the object. */ - struct vm_object * fa_vmobject; - - /* Memory address within address space or offset within VM object. */ - uintptr_t fa_offset; + struct umtx_key fa_key; }; /* A set of waiting threads. */ @@ -225,61 +213,16 @@ static int futex_address_create(struct futex_address *fa, struct thread *td, const void *object, cloudabi_mflags_t scope) { - struct vmspace *vs; - struct vm_object *vo; - vm_map_t map; - vm_map_entry_t entry; - vm_pindex_t pindex; - vm_prot_t prot; - boolean_t wired; - /* - * Most of the time objects are stored in privately mapped - * anonymous memory. For these objects we wouldn't need to look - * up the corresponding VM object. The scope hint provided by - * userspace allows us to skip the VM map lookup for the common - * case. - * - * POSIX does permit enabling PTHREAD_PROCESS_SHARED on a lock - * stored in a private mapping, at the cost of additional - * performance overhead. Fall back to identifying the object by - * virtual memory address if the mapping isn't shared. - */ - vs = td->td_proc->p_vmspace; + KASSERT(td == curthread, + ("Can only create umtx keys for the current thread")); switch (scope) { - case CLOUDABI_MAP_SHARED: - map = &vs->vm_map; - if (vm_map_lookup(&map, (vm_offset_t)object, - VM_PROT_COPY | VM_PROT_WRITE, &entry, &vo, &pindex, &prot, - &wired) != KERN_SUCCESS) - return (EFAULT); - - if (entry->inheritance == VM_INHERIT_SHARE) { - /* - * Address corresponds to a shared mapping. - * Identify the address by its VM object. - */ - fa->fa_vmspace = NULL; - fa->fa_vmobject = vo; - vm_object_reference(vo); - fa->fa_offset = entry->offset - entry->start + - (vm_offset_t)object; - vm_map_lookup_done(map, entry); - return (0); - } - vm_map_lookup_done(map, entry); - /* FALLTHROUGH */ case CLOUDABI_MAP_PRIVATE: - /* - * Address corresponds to a private mapping. Never - * identify the address by its VM object, as shadow - * objects may get inserted if another thread forks. - * Simply use the VM space instead. - */ - fa->fa_vmspace = vs; - fa->fa_vmobject = NULL; - fa->fa_offset = (uintptr_t)object; - return (0); + return (umtx_key_get(object, TYPE_FUTEX, THREAD_SHARE, + &fa->fa_key)); + case CLOUDABI_MAP_SHARED: + return (umtx_key_get(object, TYPE_FUTEX, AUTO_SHARE, + &fa->fa_key)); default: return (EINVAL); } @@ -289,8 +232,7 @@ static void futex_address_free(struct futex_address *fa) { - if (fa->fa_vmobject != NULL) - vm_object_deallocate(fa->fa_vmobject); + umtx_key_release(&fa->fa_key); } static bool @@ -298,10 +240,7 @@ futex_address_match(const struct futex_address *fa1, const struct futex_address *fa2) { - /* Either fa_vmspace or fa_vmobject is NULL. */ - return (fa1->fa_vmspace == fa2->fa_vmspace && - fa1->fa_vmobject == fa2->fa_vmobject && - fa1->fa_offset == fa2->fa_offset); + return (umtx_key_match(&fa1->fa_key, &fa2->fa_key)); } /* From c52bab11351fe73fc581f0fbd1743f102cd4466c Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Tue, 4 Aug 2015 07:04:36 +0000 Subject: [PATCH 214/314] Get it closes to style(9). Staticization usage() and printit(). Fix the usage of err(3). Reviewed by: bde --- usr.bin/ypcat/ypcat.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/usr.bin/ypcat/ypcat.c b/usr.bin/ypcat/ypcat.c index 60acca0726b4..aad07cc21db9 100644 --- a/usr.bin/ypcat/ypcat.c +++ b/usr.bin/ypcat/ypcat.c @@ -33,21 +33,19 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include -#include + #include #include +#include +#include +#include +#include #include #include #include #include -void usage(void); -int printit(u_long, char *, int, char *, int, void *); - static const struct ypalias { char *alias, *name; } ypaliases[] = { @@ -65,16 +63,16 @@ static const struct ypalias { static int key; -void +static void usage(void) { - fprintf(stderr, - "usage: ypcat [-kt] [-d domainname] mapname\n" - " ypcat -x\n"); + fprintf(stderr, "%s\n%s\n", + "usage: ypcat [-kt] [-d domainname] mapname", + " ypcat -x"); exit(1); } -int +static int printit(u_long instatus, char *inkey, int inkeylen, char *inval, int invallen, void *indata) { @@ -91,9 +89,7 @@ main(int argc, char *argv[]) { char *domain = NULL, *inmap; struct ypall_callback ypcb; - extern char *optarg; - extern int optind; - int notrans, c, r; + int c, notrans, r; u_int i; notrans = key = 0; @@ -120,7 +116,7 @@ main(int argc, char *argv[]) if (optind + 1 != argc) usage(); - if (!domain) + if (domain == NULL) yp_get_default_domain(&domain); inmap = argv[optind]; @@ -137,12 +133,10 @@ main(int argc, char *argv[]) case 0: break; case YPERR_YPBIND: - errx(1, "ypcat: not running ypbind\n"); - exit(1); + errx(1, "not running ypbind"); default: - errx(1, "No such map %s. Reason: %s\n", + errx(1, "no such map %s. Reason: %s", inmap, yperr_string(r)); - exit(1); } exit(0); } From cdc3449233ab9eae923ea8cc4c30ed19112256af Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 4 Aug 2015 08:16:18 +0000 Subject: [PATCH 215/314] Revert r286236; vgonel() is a static function. Sponsored by: The FreeBSD Foundation --- share/man/man9/Makefile | 1 - share/man/man9/vgone.9 | 6 ------ 2 files changed, 7 deletions(-) diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 527d399434ac..695fa23cd2f3 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1739,7 +1739,6 @@ MLINKS+=vfs_getopt.9 vfs_copyopt.9 \ vfs_getopt.9 vfs_setopt.9 \ vfs_getopt.9 vfs_setopt_part.9 \ vfs_getopt.9 vfs_setopts.9 -MLINKS+=vgone.9 vgonel.9 MLINKS+=vhold.9 vdrop.9 \ vhold.9 vdropl.9 \ vhold.9 vholdl.9 diff --git a/share/man/man9/vgone.9 b/share/man/man9/vgone.9 index 5318cb9247a7..dc10cda76e76 100644 --- a/share/man/man9/vgone.9 +++ b/share/man/man9/vgone.9 @@ -37,7 +37,6 @@ .In sys/vnode.h .Ft void .Fn vgone "struct vnode *vp" -.Fn vgonel "struct vnode *vp" .Sh DESCRIPTION The .Fn vgone @@ -57,11 +56,6 @@ The .Fn vgone function takes an exclusively locked vnode, and returns with the vnode exclusively locked. -The -.Fn vgonel -differs from -.Fn vgone -by requiring the vnode interlock to be held. .Sh SEE ALSO .Xr vnode 9 .Sh AUTHORS From 57a73b26e074ab0767c052b1e1686071291eb431 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 4 Aug 2015 08:51:56 +0000 Subject: [PATCH 216/314] Mark vgonel() as static. It was already declared static earlier; no idea why compilers don't warn about this. MFC after: 1 month Sponsored by: The FreeBSD Foundation --- sys/kern/vfs_subr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index b24a6aeb761a..42cab157573a 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2850,7 +2850,7 @@ vfs_notify_upper(struct vnode *vp, int event) /* * vgone, with the vp interlock held. */ -void +static void vgonel(struct vnode *vp) { struct thread *td; From 5884383f1936225da7d53d98fd1a41eeb26672ca Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Tue, 4 Aug 2015 09:45:10 +0000 Subject: [PATCH 217/314] Avoid calling into the random subsystem before it is initialized. Sponsored by: Mellanox Technologies --- sys/ofed/drivers/net/mlx4/en_tx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/ofed/drivers/net/mlx4/en_tx.c b/sys/ofed/drivers/net/mlx4/en_tx.c index 2d7e8a8c3530..2565f514e9b1 100644 --- a/sys/ofed/drivers/net/mlx4/en_tx.c +++ b/sys/ofed/drivers/net/mlx4/en_tx.c @@ -701,9 +701,13 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct mbuf *mb, static uint32_t hashrandom; static void hashrandom_init(void *arg) { + /* + * It is assumed that the random subsystem has been + * initialized when this function is called: + */ hashrandom = m_ether_tcpip_hash_init(); } -SYSINIT(hashrandom_init, SI_SUB_KLD, SI_ORDER_SECOND, &hashrandom_init, NULL); +SYSINIT(hashrandom_init, SI_SUB_RANDOM, SI_ORDER_ANY, &hashrandom_init, NULL); u16 mlx4_en_select_queue(struct net_device *dev, struct mbuf *mb) { From 72800098bf2c1a4d8aa83cddbc032f754e073f68 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 4 Aug 2015 10:40:08 +0000 Subject: [PATCH 218/314] Fix panic triggered by code like this: open("/dev/md0", O_EXEC); Discussed with: kib@, mav@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3051 --- sys/geom/geom_dev.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index 3df7f3e37efd..0d34ef5a51d5 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -358,6 +358,13 @@ g_dev_open(struct cdev *dev, int flags, int fmt, struct thread *td) #else e = 0; #endif + + /* + * This happens on attempt to open a device node with O_EXEC. + */ + if (r + w + e == 0) + return (EINVAL); + if (w) { /* * When running in very secure mode, do not allow From 35dfc644f50f12f7da6edcd2c87c6e26808e8e08 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 4 Aug 2015 12:33:51 +0000 Subject: [PATCH 219/314] Copy the fencing of the algorithm to do lock-less update and reading of the timehands, from the kern_tc.c implementation to vdso. Add comments giving hints where to look for the algorithm explanation. To compensate the removal of rmb() in userspace binuptime(), add explicit lfence instruction before rdtsc. On i386, add usual complications to detect SSE2 presence; assume that old CPUs which do not implement SSE2 also execute rdtsc almost in order. Reviewed by: alc, bde (previous version) Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- lib/libc/amd64/sys/__vdso_gettc.c | 16 +++++++-- lib/libc/i386/sys/__vdso_gettc.c | 58 ++++++++++++++++++++++++++++-- lib/libc/sys/__vdso_gettimeofday.c | 25 +++++++------ sys/kern/kern_sharedpage.c | 42 +++++++++++++++------- 4 files changed, 112 insertions(+), 29 deletions(-) diff --git a/lib/libc/amd64/sys/__vdso_gettc.c b/lib/libc/amd64/sys/__vdso_gettc.c index c6f2dfb3556a..1899b213e2f6 100644 --- a/lib/libc/amd64/sys/__vdso_gettc.c +++ b/lib/libc/amd64/sys/__vdso_gettc.c @@ -36,19 +36,29 @@ __FBSDID("$FreeBSD$"); static u_int __vdso_gettc_low(const struct vdso_timehands *th) { - uint32_t rv; + u_int rv; - __asm __volatile("rdtsc; shrd %%cl, %%edx, %0" + __asm __volatile("lfence; rdtsc; shrd %%cl, %%edx, %0" : "=a" (rv) : "c" (th->th_x86_shift) : "edx"); return (rv); } +static u_int +__vdso_rdtsc32(void) +{ + u_int rv; + + __asm __volatile("lfence;rdtsc" : "=a" (rv) : : "edx"); + return (rv); +} + #pragma weak __vdso_gettc u_int __vdso_gettc(const struct vdso_timehands *th) { - return (th->th_x86_shift > 0 ? __vdso_gettc_low(th) : rdtsc32()); + return (th->th_x86_shift > 0 ? __vdso_gettc_low(th) : + __vdso_rdtsc32()); } #pragma weak __vdso_gettimekeep diff --git a/lib/libc/i386/sys/__vdso_gettc.c b/lib/libc/i386/sys/__vdso_gettc.c index c6f2dfb3556a..1454f16699d2 100644 --- a/lib/libc/i386/sys/__vdso_gettc.c +++ b/lib/libc/i386/sys/__vdso_gettc.c @@ -31,24 +31,78 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "libc_private.h" +static int lfence_works = -1; + +static int +get_lfence_usage(void) +{ + u_int cpuid_supported, p[4]; + + if (lfence_works == -1) { + __asm __volatile( + " pushfl\n" + " popl %%eax\n" + " movl %%eax,%%ecx\n" + " xorl $0x200000,%%eax\n" + " pushl %%eax\n" + " popfl\n" + " pushfl\n" + " popl %%eax\n" + " xorl %%eax,%%ecx\n" + " je 1f\n" + " movl $1,%0\n" + " jmp 2f\n" + "1: movl $0,%0\n" + "2:\n" + : "=r" (cpuid_supported) : : "eax", "ecx"); + if (cpuid_supported) { + __asm __volatile( + " pushl %%ebx\n" + " cpuid\n" + " movl %%ebx,%1\n" + " popl %%ebx\n" + : "=a" (p[0]), "=r" (p[1]), "=c" (p[2]), "=d" (p[3]) + : "0" (0x1)); + lfence_works = (p[3] & CPUID_SSE2) != 0; + } else + lfence_works = 0; + } + return (lfence_works); +} + static u_int __vdso_gettc_low(const struct vdso_timehands *th) { - uint32_t rv; + u_int rv; + if (get_lfence_usage() == 1) + lfence(); __asm __volatile("rdtsc; shrd %%cl, %%edx, %0" : "=a" (rv) : "c" (th->th_x86_shift) : "edx"); return (rv); } +static u_int +__vdso_rdtsc32(void) +{ + u_int rv; + + if (get_lfence_usage() == 1) + lfence(); + rv = rdtsc32(); + return (rv); +} + #pragma weak __vdso_gettc u_int __vdso_gettc(const struct vdso_timehands *th) { - return (th->th_x86_shift > 0 ? __vdso_gettc_low(th) : rdtsc32()); + return (th->th_x86_shift > 0 ? __vdso_gettc_low(th) : + __vdso_rdtsc32()); } #pragma weak __vdso_gettimekeep diff --git a/lib/libc/sys/__vdso_gettimeofday.c b/lib/libc/sys/__vdso_gettimeofday.c index a305173b3ed8..b3527fa4de53 100644 --- a/lib/libc/sys/__vdso_gettimeofday.c +++ b/lib/libc/sys/__vdso_gettimeofday.c @@ -42,6 +42,15 @@ tc_delta(const struct vdso_timehands *th) th->th_counter_mask); } +/* + * Calculate the absolute or boot-relative time from the + * machine-specific fast timecounter and the published timehands + * structure read from the shared page. + * + * The lockless reading scheme is similar to the one used to read the + * in-kernel timehands, see sys/kern/kern_tc.c:binuptime(). This code + * is based on the kernel implementation. + */ static int binuptime(struct bintime *bt, struct vdso_timekeep *tk, int abs) { @@ -52,27 +61,21 @@ binuptime(struct bintime *bt, struct vdso_timekeep *tk, int abs) if (!tk->tk_enabled) return (ENOSYS); - /* - * XXXKIB. The load of tk->tk_current should use - * atomic_load_acq_32 to provide load barrier. But - * since tk points to r/o mapped page, x86 - * implementation of atomic_load_acq faults. - */ - curr = tk->tk_current; - rmb(); + curr = atomic_load_acq_32(&tk->tk_current); th = &tk->tk_th[curr]; if (th->th_algo != VDSO_TH_ALGO_1) return (ENOSYS); - gen = th->th_gen; + gen = atomic_load_acq_32(&th->th_gen); *bt = th->th_offset; bintime_addx(bt, th->th_scale * tc_delta(th)); if (abs) bintime_add(bt, &th->th_boottime); /* - * Barrier for load of both tk->tk_current and th->th_gen. + * Ensure that the load of th_offset is completed + * before the load of th_gen. */ - rmb(); + atomic_thread_fence_acq(); } while (curr != tk->tk_current || gen == 0 || gen != th->th_gen); return (0); } diff --git a/sys/kern/kern_sharedpage.c b/sys/kern/kern_sharedpage.c index fd619cd32e08..6ad2ed8bde4b 100644 --- a/sys/kern/kern_sharedpage.c +++ b/sys/kern/kern_sharedpage.c @@ -119,6 +119,13 @@ shared_page_init(void *dummy __unused) SYSINIT(shp, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t)shared_page_init, NULL); +/* + * Push the timehands update to the shared page. + * + * The lockless update scheme is similar to the one used to update the + * in-kernel timehands, see sys/kern/kern_tc.c:tc_windup() (which + * calls us after the timehands are updated). + */ static void timehands_update(struct sysentvec *sv) { @@ -127,47 +134,56 @@ timehands_update(struct sysentvec *sv) uint32_t enabled, idx; enabled = tc_fill_vdso_timehands(&th); - tk = (struct vdso_timekeep *)(shared_page_mapping + - sv->sv_timekeep_off); + th.th_gen = 0; idx = sv->sv_timekeep_curr; - atomic_store_rel_32(&tk->tk_th[idx].th_gen, 0); if (++idx >= VDSO_TH_NUM) idx = 0; sv->sv_timekeep_curr = idx; if (++sv->sv_timekeep_gen == 0) sv->sv_timekeep_gen = 1; - th.th_gen = 0; + + tk = (struct vdso_timekeep *)(shared_page_mapping + + sv->sv_timekeep_off); + tk->tk_th[idx].th_gen = 0; + atomic_thread_fence_rel(); if (enabled) tk->tk_th[idx] = th; - tk->tk_enabled = enabled; atomic_store_rel_32(&tk->tk_th[idx].th_gen, sv->sv_timekeep_gen); - tk->tk_current = idx; + atomic_store_rel_32(&tk->tk_current, idx); + + /* + * The ordering of the assignment to tk_enabled relative to + * the update of the vdso_timehands is not important. + */ + tk->tk_enabled = enabled; } #ifdef COMPAT_FREEBSD32 static void timehands_update32(struct sysentvec *sv) { - struct vdso_timekeep32 *tk; struct vdso_timehands32 th; + struct vdso_timekeep32 *tk; uint32_t enabled, idx; enabled = tc_fill_vdso_timehands32(&th); - tk = (struct vdso_timekeep32 *)(shared_page_mapping + - sv->sv_timekeep_off); + th.th_gen = 0; idx = sv->sv_timekeep_curr; - atomic_store_rel_32(&tk->tk_th[idx].th_gen, 0); if (++idx >= VDSO_TH_NUM) idx = 0; sv->sv_timekeep_curr = idx; if (++sv->sv_timekeep_gen == 0) sv->sv_timekeep_gen = 1; - th.th_gen = 0; + + tk = (struct vdso_timekeep32 *)(shared_page_mapping + + sv->sv_timekeep_off); + tk->tk_th[idx].th_gen = 0; + atomic_thread_fence_rel(); if (enabled) tk->tk_th[idx] = th; - tk->tk_enabled = enabled; atomic_store_rel_32(&tk->tk_th[idx].th_gen, sv->sv_timekeep_gen); - tk->tk_current = idx; + atomic_store_rel_32(&tk->tk_current, idx); + tk->tk_enabled = enabled; } #endif From 1da17fb7be15ddef4be7defb7a2b845ce3e40355 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Tue, 4 Aug 2015 13:40:26 +0000 Subject: [PATCH 220/314] Ensure the local MANIFEST is always used when verifying remote distribution sets. MFC after: immediately Sponsored by: The FreeBSD Foundation --- usr.sbin/bsdinstall/scripts/auto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/bsdinstall/scripts/auto b/usr.sbin/bsdinstall/scripts/auto index 891419ae37e9..166823d51333 100755 --- a/usr.sbin/bsdinstall/scripts/auto +++ b/usr.sbin/bsdinstall/scripts/auto @@ -284,7 +284,7 @@ if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then DISTDIR_IS_UNIONFS=1 mount_nullfs -o union "$BSDINSTALL_FETCHDEST" "$BSDINSTALL_DISTDIR" else - export DISTRIBUTIONS="MANIFEST $ALL_DISTRIBUTIONS" + export DISTRIBUTIONS="$ALL_DISTRIBUTIONS" export BSDINSTALL_DISTDIR="$BSDINSTALL_FETCHDEST" fi From 3208d3ff4695a322ed9ab7bbd38445a5fc7efd51 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 4 Aug 2015 13:50:52 +0000 Subject: [PATCH 221/314] Give large kernel stack to the initial thread . Otherwise, ZFS overflows the stack during root mount in some configurations. Tested by: Fabian Keil (previous version) Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/i386/i386/genassym.c | 1 + sys/i386/i386/locore.s | 4 ++-- sys/i386/i386/machdep.c | 2 +- sys/i386/include/param.h | 5 +++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index 7a00740a998c..6a00d2361539 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -103,6 +103,7 @@ ASSYM(V_SYSCALL, offsetof(struct vmmeter, v_syscall)); ASSYM(V_INTR, offsetof(struct vmmeter, v_intr)); /* ASSYM(UPAGES, UPAGES);*/ ASSYM(KSTACK_PAGES, KSTACK_PAGES); +ASSYM(TD0_KSTACK_PAGES, TD0_KSTACK_PAGES); ASSYM(PAGE_SIZE, PAGE_SIZE); ASSYM(NPTEPG, NPTEPG); ASSYM(NPDEPG, NPDEPG); diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s index 5bf7944568e9..4d8e22fc3002 100644 --- a/sys/i386/i386/locore.s +++ b/sys/i386/i386/locore.s @@ -731,7 +731,7 @@ no_kernend: movl %esi,R(IdlePTD) /* Allocate KSTACK */ - ALLOCPAGES(KSTACK_PAGES) + ALLOCPAGES(TD0_KSTACK_PAGES) movl %esi,R(p0kpa) addl $KERNBASE, %esi movl %esi, R(proc0kstack) @@ -800,7 +800,7 @@ no_kernend: /* Map proc0's KSTACK in the physical way ... */ movl R(p0kpa), %eax - movl $(KSTACK_PAGES), %ecx + movl $(TD0_KSTACK_PAGES), %ecx fillkptphys($PG_RW) /* Map ISA hole */ diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 2be5dbc5070e..76790f0d5c31 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -2445,7 +2445,7 @@ init386(first) #endif thread0.td_kstack = proc0kstack; - thread0.td_kstack_pages = KSTACK_PAGES; + thread0.td_kstack_pages = TD0_KSTACK_PAGES; /* * This may be done better later if it gets more high level diff --git a/sys/i386/include/param.h b/sys/i386/include/param.h index b3fd85f45344..f7968f830800 100644 --- a/sys/i386/include/param.h +++ b/sys/i386/include/param.h @@ -114,6 +114,11 @@ #define KSTACK_PAGES 2 /* Includes pcb! */ #endif #define KSTACK_GUARD_PAGES 1 /* pages of kstack guard; 0 disables */ +#if KSTACK_PAGES < 4 +#define TD0_KSTACK_PAGES 4 +#else +#define TD0_KSTACK_PAGES KSTACK_PAGES +#endif /* * Ceiling on amount of swblock kva space, can be changed via From e896b4a4f0d1661e21940ab1b5db53287ffd4be0 Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Tue, 4 Aug 2015 14:27:25 +0000 Subject: [PATCH 222/314] xargs now takes -P0, creating as many concurrent processes as possible PR: 199976 Submitted by: Nikolai Lifanov Reviewed by: mjg, bjk Approved by: bapt (mentor) MFC after: 1 month Relnotes: yes Sponsored by: ScaleEngine Inc. Differential Revision: https://reviews.freebsd.org/D2616 --- usr.bin/xargs/xargs.1 | 7 ++++++- usr.bin/xargs/xargs.c | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/usr.bin/xargs/xargs.1 b/usr.bin/xargs/xargs.1 index 934d6ed4dd0d..607b966af451 100644 --- a/usr.bin/xargs/xargs.1 +++ b/usr.bin/xargs/xargs.1 @@ -33,7 +33,7 @@ .\" $FreeBSD$ .\" $xMach: xargs.1,v 1.2 2002/02/23 05:23:37 tim Exp $ .\" -.Dd March 16, 2012 +.Dd August 4, 2015 .Dt XARGS 1 .Os .Sh NAME @@ -207,6 +207,11 @@ Parallel mode: run at most invocations of .Ar utility at once. +If +.Ar maxprocs +is set to 0, +.Nm +will run as many processes as possible. .It Fl p Echo each command to be executed and ask the user whether it should be executed. diff --git a/usr.bin/xargs/xargs.c b/usr.bin/xargs/xargs.c index b95c7d47bb60..c69a23a8b441 100644 --- a/usr.bin/xargs/xargs.c +++ b/usr.bin/xargs/xargs.c @@ -46,9 +46,11 @@ static char sccsid[] = "@(#)xargs.c 8.1 (Berkeley) 6/6/93"; #include __FBSDID("$FreeBSD$"); -#include +#include #include - +#include +#include +#include #include #include #include @@ -100,6 +102,7 @@ main(int argc, char *argv[]) long arg_max; int ch, Jflag, nargs, nflag, nline; size_t linelen; + struct rlimit rl; char *endptr; const char *errstr; @@ -166,6 +169,14 @@ main(int argc, char *argv[]) maxprocs = strtonum(optarg, 1, INT_MAX, &errstr); if (errstr) errx(1, "-P %s: %s", optarg, errstr); + if (getrlimit(RLIMIT_NPROC, &rl) != 0) + errx(1, "getrlimit failed"); + if (*endptr != '\0') + errx(1, "invalid number for -P option"); + if (maxprocs < 0) + errx(1, "value for -P option should be >= 0"); + if (maxprocs == 0 || maxprocs > rl.rlim_cur) + maxprocs = rl.rlim_cur; break; case 'p': pflag = 1; From 3072411ee89c5e374c9f75836d2410266297d7d1 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Tue, 4 Aug 2015 15:04:28 +0000 Subject: [PATCH 223/314] Add support for Planex GW-NS300N. --- share/man/man4/ral.4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/man/man4/ral.4 b/share/man/man4/ral.4 index 29aaa8ca6453..7ca2699a84a6 100644 --- a/share/man/man4/ral.4 +++ b/share/man/man4/ral.4 @@ -14,7 +14,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 10, 2012 +.Dd August 4, 2015 .Dt RAL 4 .Os .Sh NAME @@ -184,6 +184,7 @@ chipsets, including: .It "MSI PC54G2" Ta RT2560 Ta PCI .It "OvisLink EVO-W54PCI" Ta RT2560 Ta PCI .It "PheeNet HWL-PCIG/RA" Ta RT2560 Ta PCI +.It "Planex GW-NS300N" Ta RT2860 Ta CardBus .It "Pro-Nets CB80211G" Ta RT2560 Ta CardBus .It "Pro-Nets PC80211G" Ta RT2560 Ta PCI .It "Repotec RP-WB7108" Ta RT2560 Ta CardBus From a2bc81bf7cb660cadbbbcea20d92234e725177b7 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Tue, 4 Aug 2015 17:47:11 +0000 Subject: [PATCH 224/314] Make IPsec work with AES-GCM and AES-ICM (aka CTR) in OCF... IPsec defines the keys differently than NIST does, so we have to muck with key lengths and nonce/IVs to be standard compliant... Remove the iv from secasvar as it was unused... Add a counter protected by a mutex to ensure that the counter for GCM and ICM will never be repeated.. This is a requirement for security.. I would use atomics, but we don't have a 64bit one on all platforms.. Fix a bug where IPsec was depending upon the OCF to ensure that the blocksize was always at least 4 bytes to maintain alignment... Move this logic into IPsec so changes to OCF won't break IPsec... In one place, espx was always non-NULL, so don't test that it's non-NULL before doing work.. minor style cleanups... drop setting key and klen as they were not used... Enforce that OCF won't pass invalid key lengths to AES that would panic the machine... This was has been tested by others too... I tested this against NetBSD 6.1.5 using mini-test suite in https://github.com/jmgurney/ipseccfgs and the only things that don't pass are keyed md5 and sha1, and 3des-deriv (setkey syntax error), all other modes listed in setkey's man page... The nice thing is that NetBSD uses setkey, so same config files were used on both... Reviewed by: gnn --- sys/netipsec/key.c | 2 - sys/netipsec/key_debug.c | 5 -- sys/netipsec/keydb.h | 8 +- sys/netipsec/xform_esp.c | 172 +++++++++++++++++++----------------- sys/opencrypto/cryptodev.h | 10 +-- sys/opencrypto/cryptosoft.c | 8 +- sys/opencrypto/xform.c | 13 +-- 7 files changed, 115 insertions(+), 103 deletions(-) diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 34e8c413f274..9927509a4524 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -2835,7 +2835,6 @@ key_cleansav(struct secasvar *sav) sav->tdb_xform->xf_zeroize(sav); sav->tdb_xform = NULL; } else { - KASSERT(sav->iv == NULL, ("iv but no xform")); if (sav->key_auth != NULL) bzero(sav->key_auth->key_data, _KEYLEN(sav->key_auth)); if (sav->key_enc != NULL) @@ -3013,7 +3012,6 @@ key_setsaval(struct secasvar *sav, struct mbuf *m, sav->key_enc = NULL; sav->sched = NULL; sav->schedlen = 0; - sav->iv = NULL; sav->lft_c = NULL; sav->lft_h = NULL; sav->lft_s = NULL; diff --git a/sys/netipsec/key_debug.c b/sys/netipsec/key_debug.c index 97ac0616a11d..b5bdb0ed42ca 100644 --- a/sys/netipsec/key_debug.c +++ b/sys/netipsec/key_debug.c @@ -577,11 +577,6 @@ kdebug_secasv(struct secasvar *sav) kdebug_sadb_key((struct sadb_ext *)sav->key_auth); if (sav->key_enc != NULL) kdebug_sadb_key((struct sadb_ext *)sav->key_enc); - if (sav->iv != NULL) { - printf(" iv="); - ipsec_hexdump(sav->iv, sav->ivlen ? sav->ivlen : 8); - printf("\n"); - } if (sav->replay != NULL) kdebug_secreplay(sav->replay); diff --git a/sys/netipsec/keydb.h b/sys/netipsec/keydb.h index 15dbc9cf502c..3fe28eb6c155 100644 --- a/sys/netipsec/keydb.h +++ b/sys/netipsec/keydb.h @@ -122,10 +122,10 @@ struct secasvar { struct seckey *key_auth; /* Key for Authentication */ struct seckey *key_enc; /* Key for Encryption */ - caddr_t iv; /* Initilization Vector */ u_int ivlen; /* length of IV */ void *sched; /* intermediate encryption key */ size_t schedlen; + uint64_t cntr; /* counter for GCM and CTR */ struct secreplay *replay; /* replay prevention */ time_t created; /* for lifetime */ @@ -163,6 +163,12 @@ struct secasvar { #define SECASVAR_UNLOCK(_sav) mtx_unlock(&(_sav)->lock) #define SECASVAR_LOCK_DESTROY(_sav) mtx_destroy(&(_sav)->lock) #define SECASVAR_LOCK_ASSERT(_sav) mtx_assert(&(_sav)->lock, MA_OWNED) +#define SAV_ISGCM(_sav) \ + ((_sav)->alg_enc == SADB_X_EALG_AESGCM8 || \ + (_sav)->alg_enc == SADB_X_EALG_AESGCM12 || \ + (_sav)->alg_enc == SADB_X_EALG_AESGCM16) +#define SAV_ISCTR(_sav) ((_sav)->alg_enc == SADB_X_EALG_AESCTR) +#define SAV_ISCTRORGCM(_sav) (SAV_ISCTR((_sav)) || SAV_ISGCM((_sav))) /* replay prevention */ struct secreplay { diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index d8182dfdf588..a48c0386b9af 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include #include @@ -182,12 +184,14 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) __func__, txform->name)); return EINVAL; } - if ((sav->flags&(SADB_X_EXT_OLD|SADB_X_EXT_IV4B)) == SADB_X_EXT_IV4B) { + if ((sav->flags & (SADB_X_EXT_OLD | SADB_X_EXT_IV4B)) == + SADB_X_EXT_IV4B) { DPRINTF(("%s: 4-byte IV not supported with protocol\n", __func__)); return EINVAL; } - keylen = _KEYLEN(sav->key_enc); + /* subtract off the salt, RFC4106, 8.1 and RFC3686, 5.1 */ + keylen = _KEYLEN(sav->key_enc) - SAV_ISCTRORGCM(sav) * 4; if (txform->minkey > keylen || keylen > txform->maxkey) { DPRINTF(("%s: invalid key length %u, must be in the range " "[%u..%u] for algorithm %s\n", __func__, @@ -202,9 +206,10 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) * the ESP header will be processed incorrectly. The * compromise is to force it to zero here. */ - sav->ivlen = (txform == &enc_xform_null ? 0 : txform->ivsize); - sav->iv = (caddr_t) malloc(sav->ivlen, M_XDATA, M_WAITOK); - key_randomfill(sav->iv, sav->ivlen); /*XXX*/ + if (SAV_ISCTRORGCM(sav)) + sav->ivlen = 8; /* RFC4106 3.1 and RFC3686 3.1 */ + else + sav->ivlen = (txform == &enc_xform_null ? 0 : txform->ivsize); /* * Setup AH-related state. @@ -226,15 +231,15 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) */ if (sav->alg_enc == SADB_X_EALG_AESGCM16) { switch (keylen) { - case AES_128_HMAC_KEY_LEN: + case AES_128_GMAC_KEY_LEN: sav->alg_auth = SADB_X_AALG_AES128GMAC; sav->tdb_authalgxform = &auth_hash_nist_gmac_aes_128; break; - case AES_192_HMAC_KEY_LEN: + case AES_192_GMAC_KEY_LEN: sav->alg_auth = SADB_X_AALG_AES192GMAC; sav->tdb_authalgxform = &auth_hash_nist_gmac_aes_192; break; - case AES_256_HMAC_KEY_LEN: + case AES_256_GMAC_KEY_LEN: sav->alg_auth = SADB_X_AALG_AES256GMAC; sav->tdb_authalgxform = &auth_hash_nist_gmac_aes_256; break; @@ -246,19 +251,15 @@ esp_init(struct secasvar *sav, struct xformsw *xsp) } bzero(&cria, sizeof(cria)); cria.cri_alg = sav->tdb_authalgxform->type; - cria.cri_klen = _KEYBITS(sav->key_enc) + 4; cria.cri_key = sav->key_enc->key_data; + cria.cri_klen = _KEYBITS(sav->key_enc) - SAV_ISGCM(sav) * 32; } /* Initialize crypto session. */ - bzero(&crie, sizeof (crie)); + bzero(&crie, sizeof(crie)); crie.cri_alg = sav->tdb_encalgxform->type; - crie.cri_klen = _KEYBITS(sav->key_enc); crie.cri_key = sav->key_enc->key_data; - if (sav->alg_enc == SADB_X_EALG_AESGCM16) - arc4rand(crie.cri_iv, sav->ivlen, 0); - - /* XXX Rounds ? */ + crie.cri_klen = _KEYBITS(sav->key_enc) - SAV_ISCTRORGCM(sav) * 32; if (sav->tdb_authalgxform && sav->tdb_encalgxform) { /* init both auth & enc */ @@ -291,10 +292,6 @@ esp_zeroize(struct secasvar *sav) if (sav->key_enc) bzero(sav->key_enc->key_data, _KEYLEN(sav->key_enc)); - if (sav->iv) { - free(sav->iv, M_XDATA); - sav->iv = NULL; - } sav->tdb_encalgxform = NULL; sav->tdb_xform = NULL; return error; @@ -310,6 +307,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) struct auth_hash *esph; struct enc_xform *espx; struct tdb_crypto *tc; + uint8_t *ivp; int plen, alen, hlen; struct newesp *esp; struct cryptodesc *crde; @@ -350,15 +348,13 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) */ plen = m->m_pkthdr.len - (skip + hlen + alen); if ((plen & (espx->blocksize - 1)) || (plen <= 0)) { - if (!espx || sav->alg_enc != SADB_X_EALG_AESGCM16) { - DPRINTF(("%s: payload of %d octets not a multiple of %d octets," - " SA %s/%08lx\n", __func__, - plen, espx->blocksize, ipsec_address(&sav->sah->saidx.dst, - buf, sizeof(buf)), (u_long) ntohl(sav->spi))); - ESPSTAT_INC(esps_badilen); - m_freem(m); - return EINVAL; - } + DPRINTF(("%s: payload of %d octets not a multiple of %d octets," + " SA %s/%08lx\n", __func__, plen, espx->blocksize, + ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), + (u_long)ntohl(sav->spi))); + ESPSTAT_INC(esps_badilen); + m_freem(m); + return EINVAL; } /* @@ -404,20 +400,13 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) /* Authentication descriptor */ crda->crd_skip = skip; - if (espx && espx->type == CRYPTO_AES_NIST_GCM_16) - crda->crd_len = hlen - sav->ivlen; + if (SAV_ISGCM(sav)) + crda->crd_len = 8; /* RFC4106 5, SPI + SN */ else crda->crd_len = m->m_pkthdr.len - (skip + alen); crda->crd_inject = m->m_pkthdr.len - alen; crda->crd_alg = esph->type; - if (espx && (espx->type == CRYPTO_AES_NIST_GCM_16)) { - crda->crd_key = sav->key_enc->key_data; - crda->crd_klen = _KEYBITS(sav->key_enc); - } else { - crda->crd_key = sav->key_auth->key_data; - crda->crd_klen = _KEYBITS(sav->key_auth); - } /* Copy the authenticator */ m_copydata(m, m->m_pkthdr.len - alen, alen, @@ -452,13 +441,26 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen); crde->crd_inject = skip + hlen - sav->ivlen; - crde->crd_alg = espx->type; - crde->crd_key = sav->key_enc->key_data; - crde->crd_klen = _KEYBITS(sav->key_enc); - if (espx && (espx->type == CRYPTO_AES_NIST_GCM_16)) - crde->crd_flags |= CRD_F_IV_EXPLICIT; + if (SAV_ISCTRORGCM(sav)) { + ivp = &crde->crd_iv[0]; - /* XXX Rounds ? */ + /* GCM IV Format: RFC4106 4 */ + /* CTR IV Format: RFC3686 4 */ + /* Salt is last four bytes of key, RFC4106 8.1 */ + /* Nonce is last four bytes of key, RFC3686 5.1 */ + memcpy(ivp, sav->key_enc->key_data + + _KEYLEN(sav->key_enc) - 4, 4); + + if (SAV_ISCTR(sav)) { + /* Initial block counter is 1, RFC3686 4 */ + be32enc(&ivp[sav->ivlen + 4], 1); + } + + m_copydata(m, skip + hlen - sav->ivlen, sav->ivlen, &ivp[4]); + crde->crd_flags |= CRD_F_IV_EXPLICIT; + } + + crde->crd_alg = espx->type; return (crypto_dispatch(crp)); } @@ -664,6 +666,8 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, char buf[INET6_ADDRSTRLEN]; struct enc_xform *espx; struct auth_hash *esph; + uint8_t *ivp; + uint64_t cntr; int hlen, rlen, padding, blks, alen, i, roff; struct mbuf *mo = (struct mbuf *) NULL; struct tdb_crypto *tc; @@ -689,10 +693,9 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, rlen = m->m_pkthdr.len - skip; /* Raw payload length. */ /* - * NB: The null encoding transform has a blocksize of 4 - * so that headers are properly aligned. + * RFC4303 2.4 Requires 4 byte alignment. */ - blks = espx->ivsize; /* IV blocksize */ + blks = MAX(4, espx->blocksize); /* Cipher blocksize */ /* XXX clamp padding length a la KAME??? */ padding = ((blks - ((rlen + 2) % blks)) % blks) + 2; @@ -816,7 +819,7 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, m_copyback(m, protoff, sizeof(u_int8_t), (u_char *) &prot); /* Get crypto descriptors. */ - crp = crypto_getreq(esph && espx ? 2 : 1); + crp = crypto_getreq(esph != NULL ? 2 : 1); if (crp == NULL) { DPRINTF(("%s: failed to acquire crypto descriptors\n", __func__)); @@ -825,29 +828,9 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, goto bad; } - if (espx) { - crde = crp->crp_desc; - crda = crde->crd_next; - - /* Encryption descriptor. */ - crde->crd_skip = skip + hlen; - crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen); - crde->crd_flags = CRD_F_ENCRYPT; - crde->crd_inject = skip + hlen - sav->ivlen; - - /* Encryption operation. */ - crde->crd_alg = espx->type; - crde->crd_key = sav->key_enc->key_data; - crde->crd_klen = _KEYBITS(sav->key_enc); - if (espx->type == CRYPTO_AES_NIST_GCM_16) - crde->crd_flags |= CRD_F_IV_EXPLICIT; - /* XXX Rounds ? */ - } else - crda = crp->crp_desc; - /* IPsec-specific opaque crypto info. */ tc = (struct tdb_crypto *) malloc(sizeof(struct tdb_crypto), - M_XDATA, M_NOWAIT|M_ZERO); + M_XDATA, M_NOWAIT|M_ZERO); if (tc == NULL) { crypto_freereq(crp); DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__)); @@ -856,6 +839,40 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, goto bad; } + crde = crp->crp_desc; + crda = crde->crd_next; + + /* Encryption descriptor. */ + crde->crd_skip = skip + hlen; + crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen); + crde->crd_flags = CRD_F_ENCRYPT; + crde->crd_inject = skip + hlen - sav->ivlen; + + /* Encryption operation. */ + crde->crd_alg = espx->type; + if (SAV_ISCTRORGCM(sav)) { + ivp = &crde->crd_iv[0]; + + /* GCM IV Format: RFC4106 4 */ + /* CTR IV Format: RFC3686 4 */ + /* Salt is last four bytes of key, RFC4106 8.1 */ + /* Nonce is last four bytes of key, RFC3686 5.1 */ + memcpy(ivp, sav->key_enc->key_data + + _KEYLEN(sav->key_enc) - 4, 4); + SECASVAR_LOCK(sav); + cntr = sav->cntr++; + SECASVAR_UNLOCK(sav); + be64enc(&ivp[4], cntr); + + if (SAV_ISCTR(sav)) { + /* Initial block counter is 1, RFC3686 4 */ + be32enc(&ivp[sav->ivlen + 4], 1); + } + + m_copyback(m, skip + hlen - sav->ivlen, sav->ivlen, &ivp[4]); + crde->crd_flags |= CRD_F_IV_EXPLICIT|CRD_F_IV_PRESENT; + } + /* Callback parameters */ tc->tc_isr = isr; KEY_ADDREFSA(sav); @@ -874,23 +891,13 @@ esp_output(struct mbuf *m, struct ipsecrequest *isr, struct mbuf **mp, if (esph) { /* Authentication descriptor. */ + crda->crd_alg = esph->type; crda->crd_skip = skip; - if (espx && espx->type == CRYPTO_AES_NIST_GCM_16) - crda->crd_len = hlen - sav->ivlen; + if (SAV_ISGCM(sav)) + crda->crd_len = 8; /* RFC4106 5, SPI + SN */ else crda->crd_len = m->m_pkthdr.len - (skip + alen); crda->crd_inject = m->m_pkthdr.len - alen; - - /* Authentication operation. */ - crda->crd_alg = esph->type; - if (espx && espx->type == CRYPTO_AES_NIST_GCM_16) { - crda->crd_key = sav->key_enc->key_data; - crda->crd_klen = _KEYBITS(sav->key_enc); - } else { - crda->crd_key = sav->key_auth->key_data; - crda->crd_klen = _KEYBITS(sav->key_auth); - } - } return crypto_dispatch(crp); @@ -921,7 +928,8 @@ esp_output_cb(struct cryptop *crp) IPSEC_ASSERT(isr->sp != NULL, ("NULL isr->sp")); IPSECREQUEST_LOCK(isr); sav = tc->tc_sav; - /* With the isr lock released SA pointer can be updated. */ + + /* With the isr lock released, SA pointer may have changed. */ if (sav != isr->sav) { ESPSTAT_INC(esps_notdb); DPRINTF(("%s: SA gone during crypto (SA %s/%08lx proto %u)\n", diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h index 5aa450f6a44b..d14fb3a81376 100644 --- a/sys/opencrypto/cryptodev.h +++ b/sys/opencrypto/cryptodev.h @@ -78,7 +78,7 @@ #define SHA2_512_HASH_LEN 64 #define MD5_KPDK_HASH_LEN 16 #define SHA1_KPDK_HASH_LEN 20 -#define AES_HASH_LEN 16 +#define AES_GMAC_HASH_LEN 16 /* Maximum hash algorithm result length */ #define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */ @@ -102,12 +102,12 @@ #define SHA2_256_HMAC_KEY_LEN 32 #define SHA2_384_HMAC_KEY_LEN 48 #define SHA2_512_HMAC_KEY_LEN 64 -#define AES_128_HMAC_KEY_LEN 16 -#define AES_192_HMAC_KEY_LEN 24 -#define AES_256_HMAC_KEY_LEN 32 +#define AES_128_GMAC_KEY_LEN 16 +#define AES_192_GMAC_KEY_LEN 24 +#define AES_256_GMAC_KEY_LEN 32 /* Encryption algorithm block sizes */ -#define NULL_BLOCK_LEN 4 +#define NULL_BLOCK_LEN 4 /* IPsec to maintain alignment */ #define DES_BLOCK_LEN 8 #define DES3_BLOCK_LEN 8 #define BLOWFISH_BLOCK_LEN 8 diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index 77ab5076be26..052916b8b683 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -711,6 +711,7 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) struct enc_xform *txf; struct comp_algo *cxf; u_int32_t i; + int len; int error; if (sid == NULL || cri == NULL) @@ -928,6 +929,10 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) case CRYPTO_AES_256_NIST_GMAC: axf = &auth_hash_nist_gmac_aes_256; auth4common: + len = cri->cri_klen / 8; + if (len != 16 && len != 24 && len != 32) + return EINVAL; + (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { @@ -936,8 +941,7 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) return ENOBUFS; } axf->Init((*swd)->sw_ictx); - axf->Setkey((*swd)->sw_ictx, cri->cri_key, - cri->cri_klen / 8); + axf->Setkey((*swd)->sw_ictx, cri->cri_key, len); (*swd)->sw_axf = axf; break; diff --git a/sys/opencrypto/xform.c b/sys/opencrypto/xform.c index 9e8a1c1afec8..cb44bfad029a 100644 --- a/sys/opencrypto/xform.c +++ b/sys/opencrypto/xform.c @@ -139,7 +139,7 @@ static int SHA512Update_int(void *, const u_int8_t *, u_int16_t); static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **); static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **); -#define AESICM_BLOCKSIZE 16 +#define AESICM_BLOCKSIZE AES_BLOCK_LEN struct aes_icm_ctx { u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)]; @@ -353,7 +353,7 @@ struct auth_hash auth_hash_hmac_sha2_512 = { struct auth_hash auth_hash_nist_gmac_aes_128 = { CRYPTO_AES_128_NIST_GMAC, "GMAC-AES-128", - AES_128_HMAC_KEY_LEN, AES_HASH_LEN, sizeof(struct aes_gmac_ctx), + AES_128_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx), GMAC_BLOCK_LEN, (void (*)(void *)) AES_GMAC_Init, (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey, @@ -364,7 +364,7 @@ struct auth_hash auth_hash_nist_gmac_aes_128 = { struct auth_hash auth_hash_nist_gmac_aes_192 = { CRYPTO_AES_192_NIST_GMAC, "GMAC-AES-192", - AES_192_HMAC_KEY_LEN, AES_HASH_LEN, sizeof(struct aes_gmac_ctx), + AES_192_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx), GMAC_BLOCK_LEN, (void (*)(void *)) AES_GMAC_Init, (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey, @@ -375,7 +375,7 @@ struct auth_hash auth_hash_nist_gmac_aes_192 = { struct auth_hash auth_hash_nist_gmac_aes_256 = { CRYPTO_AES_256_NIST_GMAC, "GMAC-AES-256", - AES_256_HMAC_KEY_LEN, AES_HASH_LEN, sizeof(struct aes_gmac_ctx), + AES_256_GMAC_KEY_LEN, AES_GMAC_HASH_LEN, sizeof(struct aes_gmac_ctx), GMAC_BLOCK_LEN, (void (*)(void *)) AES_GMAC_Init, (void (*)(void *, const u_int8_t *, u_int16_t)) AES_GMAC_Setkey, @@ -719,6 +719,9 @@ aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len) { struct aes_icm_ctx *ctx; + if (len != 16 && len != 24 && len != 32) + return EINVAL; + *sched = malloc(sizeof(struct aes_icm_ctx), M_CRYPTO_DATA, M_NOWAIT | M_ZERO); if (*sched == NULL) @@ -726,8 +729,6 @@ aes_icm_setkey(u_int8_t **sched, u_int8_t *key, int len) ctx = (struct aes_icm_ctx *)*sched; ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, (u_char *)key, len * 8); - if (ctx->ac_nr == 0) - return EINVAL; return 0; } From ca23ca33f2791b64293c2c0878e9f8191674d1b5 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Tue, 4 Aug 2015 18:59:54 +0000 Subject: [PATCH 225/314] Fix style(9) bugs. --- sys/x86/include/_types.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sys/x86/include/_types.h b/sys/x86/include/_types.h index 20a2bf766225..7266d76b4ee0 100644 --- a/sys/x86/include/_types.h +++ b/sys/x86/include/_types.h @@ -154,12 +154,11 @@ typedef int ___wchar_t; typedef __builtin_va_list __va_list; /* internally known to gcc */ #else #ifdef __LP64__ -typedef struct { - unsigned int __gpo; - unsigned int __fpo; - void *__oaa; - void *__rsa; -} __va_list; +struct __s_va_list { + __uint32_t pad1[2]; /* gp_offset, fp_offset */ + __uint64_t pad2[2]; /* overflow_arg_area, reg_save_area */ +}; +typedef struct __s_va_list __va_list; #else typedef char * __va_list; #endif From 7b80d5ad137bb60c73b4ff98de215d676132b6a2 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Tue, 4 Aug 2015 19:04:02 +0000 Subject: [PATCH 226/314] BEAGLEBONE: remove dtrace from MODULES_EXTRA. This config is already building all modules, so we don't need the MODULES_EXTRA definition. It was also causing problems to users who rely on MODULES_OVERRIDE to do the right thing. Discussed with: ian --- sys/arm/conf/BEAGLEBONE | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE index bee9427a19d5..a0ca1b61dad1 100644 --- a/sys/arm/conf/BEAGLEBONE +++ b/sys/arm/conf/BEAGLEBONE @@ -32,7 +32,6 @@ makeoptions MODULES_EXTRA="dtb/am335x" options KDTRACE_HOOKS # Kernel DTrace hooks options DDB_CTF # all architectures - kernel ELF linker loads CTF data makeoptions WITH_CTF=1 -makeoptions MODULES_EXTRA+="opensolaris dtrace dtrace/profile dtrace/fbt" options HZ=100 options SCHED_4BSD # 4BSD scheduler From 713841afb2eb70491250d181f10318f03add42fc Mon Sep 17 00:00:00 2001 From: "Jason A. Harmening" Date: Tue, 4 Aug 2015 19:46:13 +0000 Subject: [PATCH 227/314] Add two new pmap functions: vm_offset_t pmap_quick_enter_page(vm_page_t m) void pmap_quick_remove_page(vm_offset_t kva) These will create and destroy a temporary, CPU-local KVA mapping of a specified page. Guarantees: --Will not sleep and will not fail. --Safe to call under a non-sleepable lock or from an ithread Restrictions: --Not guaranteed to be safe to call from an interrupt filter or under a spin mutex on all platforms --Current implementation does not guarantee more than one page of mapping space across all platforms. MI code should not make nested calls to pmap_quick_enter_page. --MI code should not perform locking while holding onto a mapping created by pmap_quick_enter_page The idea is to use this in busdma, for bounce buffer copies as well as virtually-indexed cache maintenance on mips and arm. NOTE: the non-i386, non-amd64 implementations of these functions still need review and testing. Reviewed by: kib Approved by: kib (mentor) Differential Revision: http://reviews.freebsd.org/D3013 --- sys/amd64/amd64/pmap.c | 12 +++++ sys/arm/arm/pmap-v6-new.c | 52 +++++++++++++++++++ sys/arm/arm/pmap-v6.c | 69 ++++++++++++++++++++++++++ sys/arm/arm/pmap.c | 36 +++++++++++++- sys/arm/include/pcpu.h | 8 ++- sys/arm64/arm64/pmap.c | 12 +++++ sys/i386/i386/pmap.c | 49 ++++++++++++++++++ sys/i386/include/pcpu.h | 3 +- sys/mips/mips/pmap.c | 56 +++++++++++++++++++++ sys/powerpc/aim/mmu_oea.c | 16 ++++++ sys/powerpc/aim/mmu_oea64.c | 71 ++++++++++++++++++++++++++ sys/powerpc/booke/pmap.c | 77 +++++++++++++++++++++++++++++ sys/powerpc/include/pcpu.h | 12 ++++- sys/powerpc/powerpc/mmu_if.m | 23 +++++++++ sys/powerpc/powerpc/pmap_dispatch.c | 14 ++++++ sys/sparc64/include/pcpu.h | 3 +- sys/sparc64/sparc64/pmap.c | 68 +++++++++++++++++++++++++ sys/vm/pmap.h | 2 + 18 files changed, 575 insertions(+), 8 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 6a3de60af982..780d0e37959e 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -6940,6 +6940,18 @@ pmap_unmap_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count, } } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ + + return (PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m))); +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ +} + #include "opt_ddb.h" #ifdef DDB #include diff --git a/sys/arm/arm/pmap-v6-new.c b/sys/arm/arm/pmap-v6-new.c index 1549cc1e1851..b18648f072e7 100644 --- a/sys/arm/arm/pmap-v6-new.c +++ b/sys/arm/arm/pmap-v6-new.c @@ -1156,6 +1156,22 @@ pmap_bootstrap(vm_offset_t firstaddr) virtual_end = vm_max_kernel_address; } +static void +pmap_init_qpages(void) +{ + struct pcpu *pc; + int i; + + CPU_FOREACH(i) { + pc = pcpu_find(i); + pc->pc_qmap_addr = kva_alloc(PAGE_SIZE); + if (pc->pc_qmap_addr == 0) + panic("pmap_init_qpages: unable to allocate KVA"); + } +} + +SYSINIT(qpages_init, SI_SUB_CPU, SI_ORDER_ANY, pmap_init_qpages, NULL); + /* * The function can already be use in second initialization stage. * As such, the function DOES NOT call pmap_growkernel() where PT2 @@ -5709,6 +5725,42 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[], mtx_unlock(&sysmaps->lock); } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ + pt2_entry_t *pte; + vm_offset_t qmap_addr; + + critical_enter(); + + qmap_addr = PCPU_GET(qmap_addr); + pte = pt2map_entry(qmap_addr); + + KASSERT(*pte == 0, ("pmap_quick_enter_page: PTE busy")); + + pte2_store(pte, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), + PTE2_AP_KRW, pmap_page_get_memattr(m))); + tlb_flush_local(qmap_addr); + + return (qmap_addr); +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ + pt2_entry_t *pte; + vm_offset_t qmap_addr; + + qmap_addr = PCPU_GET(qmap_addr); + pte = pt2map_entry(qmap_addr); + + KASSERT(addr == qmap_addr, ("pmap_quick_remove_page: invalid address")); + KASSERT(*pte != 0, ("pmap_quick_remove_page: PTE not in use")); + + pte2_clear(pte); + critical_exit(); +} + /* * Copy the range specified by src_addr/len * from the source map to the range dst_addr/len diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index a9421aa00e57..50172f253f54 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -1979,6 +1979,7 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt) pmap_set_pcb_pagedir(kernel_pmap, thread0.td_pcb); } + /*************************************************** * Pmap allocation/deallocation routines. ***************************************************/ @@ -2306,6 +2307,31 @@ pmap_remove_pages(pmap_t pmap) PMAP_UNLOCK(pmap); } +static void +pmap_init_qpages(void) +{ + struct pcpu *pc; + struct l2_bucket *l2b; + int i; + + CPU_FOREACH(i) { + pc = pcpu_find(i); + pc->pc_qmap_addr = kva_alloc(PAGE_SIZE); + if (pc->pc_qmap_addr == 0) + panic("pmap_init_qpages: unable to allocate KVA"); + + l2b = pmap_get_l2_bucket(pmap_kernel(), pc->pc_qmap_addr); + if (l2b == NULL) + l2b = pmap_grow_l2_bucket(pmap_kernel(), + pc->pc_qmap_addr); + if (l2b == NULL) + panic("pmap_alloc_specials: no l2b for 0x%x", + pc->pc_qmap_addr); + pc->pc_qmap_pte = &l2b->l2b_kva[l2pte_index(pc->pc_qmap_addr)]; + } +} + +SYSINIT(qpages_init, SI_SUB_CPU, SI_ORDER_ANY, pmap_init_qpages, NULL); /*************************************************** * Low level mapping routines..... @@ -4678,6 +4704,49 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) pmap_copy_page_generic(VM_PAGE_TO_PHYS(src), VM_PAGE_TO_PHYS(dst)); } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ + pt_entry_t *qmap_pte; + vm_offset_t qmap_addr; + + critical_enter(); + + qmap_addr = PCPU_GET(qmap_addr); + qmap_pte = PCPU_GET(qmap_pte); + + KASSERT(*qmap_pte == 0, ("pmap_quick_enter_page: PTE busy")); + + *qmap_pte = L2_S_PROTO | VM_PAGE_TO_PHYS(m) | L2_S_REF; + if (m->md.pv_memattr != VM_MEMATTR_UNCACHEABLE) + *qmap_pte |= pte_l2_s_cache_mode; + pmap_set_prot(qmap_pte, VM_PROT_READ | VM_PROT_WRITE, 0); + PTE_SYNC(qmap_pte); + cpu_tlb_flushD_SE(qmap_addr); + cpu_cpwait(); + + return (qmap_addr); +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ + pt_entry_t *qmap_pte; + + qmap_pte = PCPU_GET(qmap_pte); + + KASSERT(addr == PCPU_GET(qmap_addr), + ("pmap_quick_remove_page: invalid address")); + KASSERT(*qmap_pte != 0, + ("pmap_quick_remove_page: PTE not in use")); + + cpu_idcache_wbinv_range(addr, PAGE_SIZE); + pmap_l2cache_wbinv_range(addr, *qmap_pte & L2_S_FRAME, PAGE_SIZE); + *qmap_pte = 0; + PTE_SYNC(qmap_pte); + critical_exit(); +} + /* * this routine returns true if a physical page resides * in the given pmap. diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c index dfd5bcb39ef0..daaa0ee906e5 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -227,8 +227,8 @@ vm_offset_t vm_max_kernel_address; struct pmap kernel_pmap_store; static pt_entry_t *csrc_pte, *cdst_pte; -static vm_offset_t csrcp, cdstp; -static struct mtx cmtx; +static vm_offset_t csrcp, cdstp, qmap_addr; +static struct mtx cmtx, qmap_mtx; static void pmap_init_l1(struct l1_ttable *, pd_entry_t *); /* @@ -2155,6 +2155,7 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt) pd_entry_t pde; pd_entry_t *kernel_l1pt = (pd_entry_t *)l1pt->pv_va; pt_entry_t *ptep; + pt_entry_t *qmap_pte; vm_paddr_t pa; vm_offset_t va; vm_size_t size; @@ -2276,6 +2277,8 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt) pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)csrc_pte); pmap_alloc_specials(&virtual_avail, 1, &cdstp, &cdst_pte); pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)cdst_pte); + pmap_alloc_specials(&virtual_avail, 1, &qmap_addr, &qmap_pte); + pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)qmap_pte); size = ((vm_max_kernel_address - pmap_curmaxkvaddr) + L1_S_OFFSET) / L1_S_SIZE; pmap_alloc_specials(&virtual_avail, @@ -2302,6 +2305,7 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt) virtual_end = vm_max_kernel_address; kernel_vm_end = pmap_curmaxkvaddr; mtx_init(&cmtx, "TMP mappings mtx", NULL, MTX_DEF); + mtx_init(&qmap_mtx, "quick mapping mtx", NULL, MTX_DEF); pmap_set_pcb_pagedir(kernel_pmap, thread0.td_pcb); } @@ -4343,6 +4347,34 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[], } } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ + /* + * Don't bother with a PCPU pageframe, since we don't support + * SMP for anything pre-armv7. Use pmap_kenter() to ensure + * caching is handled correctly for multiple mappings of the + * same physical page. + */ + + mtx_assert(&qmap_mtx, MA_NOTOWNED); + mtx_lock(&qmap_mtx); + + pmap_kenter(qmap_addr, VM_PAGE_TO_PHYS(m)); + + return (qmap_addr); +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ + KASSERT(addr == qmap_addr, + ("pmap_quick_remove_page: invalid address")); + mtx_assert(&qmap_mtx, MA_OWNED); + pmap_kremove(addr); + mtx_unlock(&qmap_mtx); +} + /* * this routine returns true if a physical page resides * in the given pmap. diff --git a/sys/arm/include/pcpu.h b/sys/arm/include/pcpu.h index 73400c59fefa..d98d6390c144 100644 --- a/sys/arm/include/pcpu.h +++ b/sys/arm/include/pcpu.h @@ -47,10 +47,14 @@ struct vmspace; unsigned int pc_vfpmvfr0; \ unsigned int pc_vfpmvfr1; \ struct pmap *pc_curpmap; \ - char __pad[141] + vm_offset_t pc_qmap_addr; \ + void *pc_qmap_pte; \ + char __pad[133] #else #define PCPU_MD_FIELDS \ - char __pad[157] + vm_offset_t qmap_addr; \ + void *pc_qmap_pte; \ + char __pad[149] #endif #ifdef _KERNEL diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 2a2c37cc4814..c2bccb84173e 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -2441,6 +2441,18 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[], } } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ + + return (PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m))); +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ +} + /* * Returns true if the pmap's pv is one of the first * 16 pvs linked to from this page. This count may diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index b02311eae8cb..efd44b3964a7 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -512,6 +512,22 @@ pmap_bootstrap(vm_paddr_t firstaddr) pmap_set_pg(); } +static void +pmap_init_qpages(void) +{ + struct pcpu *pc; + int i; + + CPU_FOREACH(i) { + pc = pcpu_find(i); + pc->pc_qmap_addr = kva_alloc(PAGE_SIZE); + if (pc->pc_qmap_addr == 0) + panic("pmap_init_qpages: unable to allocate KVA"); + } +} + +SYSINIT(qpages_init, SI_SUB_CPU, SI_ORDER_ANY, pmap_init_qpages, NULL); + /* * Setup the PAT MSR. */ @@ -5400,6 +5416,39 @@ pmap_align_superpage(vm_object_t object, vm_ooffset_t offset, *addr = ((*addr + PDRMASK) & ~PDRMASK) + superpage_offset; } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ + vm_offset_t qaddr; + pt_entry_t *pte; + + critical_enter(); + qaddr = PCPU_GET(qmap_addr); + pte = vtopte(qaddr); + + KASSERT(*pte == 0, ("pmap_quick_enter_page: PTE busy")); + *pte = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M | + pmap_cache_bits(pmap_page_get_memattr(m), 0); + invlpg(qaddr); + + return (qaddr); +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ + vm_offset_t qaddr; + pt_entry_t *pte; + + qaddr = PCPU_GET(qmap_addr); + pte = vtopte(qaddr); + + KASSERT(*pte != 0, ("pmap_quick_remove_page: PTE not in use")); + KASSERT(addr == qaddr, ("pmap_quick_remove_page: invalid address")); + + *pte = 0; + critical_exit(); +} #if defined(PMAP_DEBUG) pmap_pid_dump(int pid) diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h index 231f80f6a303..cfd8d03c2e6d 100644 --- a/sys/i386/include/pcpu.h +++ b/sys/i386/include/pcpu.h @@ -58,7 +58,8 @@ int pc_private_tss; /* Flag indicating private tss*/\ u_int pc_cmci_mask; /* MCx banks for CMCI */ \ u_int pc_vcpu_id; /* Xen vCPU ID */ \ - char __pad[233] + vm_offset_t pc_qmap_addr; /* KVA for temporary mappings */\ + char __pad[229] #ifdef _KERNEL diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 50b57d22329d..0d126e4b4962 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -2638,6 +2638,62 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[], } } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ +#if defined(__mips_n64) + return MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(m)); +#else + vm_paddr_t pa; + struct local_sysmaps *sysm; + pt_entry_t *pte; + + pa = VM_PAGE_TO_PHYS(m); + + if (MIPS_DIRECT_MAPPABLE(pa)) + return (MIPS_PHYS_TO_DIRECT(pa)); + + critical_enter(); + sysm = &sysmap_lmem[PCPU_GET(cpuid)]; + + KASSERT(sysm->valid1 == 0, ("pmap_quick_enter_page: PTE busy")); + + pte = pmap_pte(kernel_pmap, sysm->base); + *pte = TLBLO_PA_TO_PFN(pa) | PTE_D | PTE_V | PTE_G | + (is_cacheable_mem(pa) ? PTE_C_CACHE : PTE_C_UNCACHED); + sysm->valid1 = 1; + + return (sysm->base); +#endif +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ + mips_dcache_wbinv_range(addr, PAGE_SIZE); + +#if !defined(__mips_n64) + struct local_sysmaps *sysm; + pt_entry_t *pte; + + if (addr >= MIPS_KSEG0_START && addr < MIPS_KSEG0_END) + return; + + sysm = &sysmap_lmem[PCPU_GET(cpuid)]; + + KASSERT(sysm->valid1 != 0, + ("pmap_quick_remove_page: PTE not in use")); + KASSERT(sysm->base == addr, + ("pmap_quick_remove_page: invalid address")); + + pte = pmap_pte(kernel_pmap, addr); + *pte = PTE_G; + tlb_invalidate_address(kernel_pmap, addr); + sysm->valid1 = 0; + critical_exit(); +#endif +} + /* * Returns true if the pmap's pv is one of the first * 16 pvs linked to from this page. This count may diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index 6d4ddebb77d5..473473846026 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -316,6 +316,8 @@ boolean_t moea_dev_direct_mapped(mmu_t, vm_paddr_t, vm_size_t); static void moea_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t); void moea_dumpsys_map(mmu_t mmu, vm_paddr_t pa, size_t sz, void **va); void moea_scan_init(mmu_t mmu); +vm_offset_t moea_quick_enter_page(mmu_t mmu, vm_page_t m); +void moea_quick_remove_page(mmu_t mmu, vm_offset_t addr); static mmu_method_t moea_methods[] = { MMUMETHOD(mmu_clear_modify, moea_clear_modify), @@ -351,6 +353,8 @@ static mmu_method_t moea_methods[] = { MMUMETHOD(mmu_activate, moea_activate), MMUMETHOD(mmu_deactivate, moea_deactivate), MMUMETHOD(mmu_page_set_memattr, moea_page_set_memattr), + MMUMETHOD(mmu_quick_enter_page, moea_quick_enter_page), + MMUMETHOD(mmu_quick_remove_page, moea_quick_remove_page), /* Internal interfaces */ MMUMETHOD(mmu_bootstrap, moea_bootstrap), @@ -1082,6 +1086,18 @@ moea_zero_page_idle(mmu_t mmu, vm_page_t m) moea_zero_page(mmu, m); } +vm_offset_t +moea_quick_enter_page(mmu_t mmu, vm_page_t m) +{ + + return (VM_PAGE_TO_PHYS(m)); +} + +void +moea_quick_remove_page(mmu_t mmu, vm_offset_t addr) +{ +} + /* * Map the given physical page at the specified virtual address in the * target pmap with the protection requested. If specified the page diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 9471c24fb839..44caec686d72 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -227,6 +228,7 @@ static u_int moea64_clear_bit(mmu_t, vm_page_t, uint64_t); static void moea64_kremove(mmu_t, vm_offset_t); static void moea64_syncicache(mmu_t, pmap_t pmap, vm_offset_t va, vm_paddr_t pa, vm_size_t sz); +static void moea64_pmap_init_qpages(void); /* * Kernel MMU interface @@ -278,6 +280,8 @@ static void moea64_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t); void moea64_dumpsys_map(mmu_t mmu, vm_paddr_t pa, size_t sz, void **va); void moea64_scan_init(mmu_t mmu); +vm_offset_t moea64_quick_enter_page(mmu_t mmu, vm_page_t m); +void moea64_quick_remove_page(mmu_t mmu, vm_offset_t addr); static mmu_method_t moea64_methods[] = { MMUMETHOD(mmu_clear_modify, moea64_clear_modify), @@ -314,6 +318,8 @@ static mmu_method_t moea64_methods[] = { MMUMETHOD(mmu_activate, moea64_activate), MMUMETHOD(mmu_deactivate, moea64_deactivate), MMUMETHOD(mmu_page_set_memattr, moea64_page_set_memattr), + MMUMETHOD(mmu_quick_enter_page, moea64_quick_enter_page), + MMUMETHOD(mmu_quick_remove_page, moea64_quick_remove_page), /* Internal interfaces */ MMUMETHOD(mmu_mapdev, moea64_mapdev), @@ -974,6 +980,29 @@ moea64_late_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend } } +static void +moea64_pmap_init_qpages(void) +{ + struct pcpu *pc; + int i; + + if (hw_direct_map) + return; + + CPU_FOREACH(i) { + pc = pcpu_find(i); + pc->pc_qmap_addr = kva_alloc(PAGE_SIZE); + if (pc->pc_qmap_addr == 0) + panic("pmap_init_qpages: unable to allocate KVA"); + PMAP_LOCK(kernel_pmap); + pc->pc_qmap_pvo = moea64_pvo_find_va(kernel_pmap, pc->pc_qmap_addr); + PMAP_UNLOCK(kernel_pmap); + mtx_init(&pc->pc_qmap_lock, "qmap lock", NULL, MTX_DEF); + } +} + +SYSINIT(qpages_init, SI_SUB_CPU, SI_ORDER_ANY, moea64_pmap_init_qpages, NULL); + /* * Activate a user pmap. This mostly involves setting some non-CPU * state. @@ -1206,6 +1235,48 @@ moea64_zero_page_idle(mmu_t mmu, vm_page_t m) moea64_zero_page(mmu, m); } +vm_offset_t +moea64_quick_enter_page(mmu_t mmu, vm_page_t m) +{ + struct pvo_entry *pvo; + vm_paddr_t pa = VM_PAGE_TO_PHYS(m); + + if (hw_direct_map) + return (pa); + + /* + * MOEA64_PTE_REPLACE does some locking, so we can't just grab + * a critical section and access the PCPU data like on i386. + * Instead, pin the thread and grab the PCPU lock to prevent + * a preempting thread from using the same PCPU data. + */ + sched_pin(); + + mtx_assert(PCPU_PTR(qmap_lock), MA_NOTOWNED); + pvo = PCPU_GET(qmap_pvo); + + mtx_lock(PCPU_PTR(qmap_lock)); + pvo->pvo_pte.pa = moea64_calc_wimg(pa, pmap_page_get_memattr(m)) | + (uint64_t)pa; + MOEA64_PTE_REPLACE(mmu, pvo, MOEA64_PTE_INVALIDATE); + isync(); + + return (PCPU_GET(qmap_addr)); +} + +void +moea64_quick_remove_page(mmu_t mmu, vm_offset_t addr) +{ + if (hw_direct_map) + return; + + mtx_assert(PCPU_PTR(qmap_lock), MA_OWNED); + KASSERT(PCPU_GET(qmap_addr) == addr, + ("moea64_quick_remove_page: invalid address")); + mtx_unlock(PCPU_PTR(qmap_lock)); + sched_unpin(); +} + /* * Map the given physical page at the specified virtual address in the * target pmap with the protection requested. If specified the page diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 656b7a336fb3..275ae8dee895 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -246,6 +246,8 @@ static void pv_free(pv_entry_t); static void pv_insert(pmap_t, vm_offset_t, vm_page_t); static void pv_remove(pmap_t, vm_offset_t, vm_page_t); +static void booke_pmap_init_qpages(void); + /* Number of kva ptbl buffers, each covering one ptbl (PTBL_PAGES). */ #define PTBL_BUFS (128 * 16) @@ -332,6 +334,8 @@ static void mmu_booke_dumpsys_map(mmu_t, vm_paddr_t pa, size_t, static void mmu_booke_dumpsys_unmap(mmu_t, vm_paddr_t pa, size_t, void *); static void mmu_booke_scan_init(mmu_t); +static vm_offset_t mmu_booke_quick_enter_page(mmu_t mmu, vm_page_t m); +static void mmu_booke_quick_remove_page(mmu_t mmu, vm_offset_t addr); static mmu_method_t mmu_booke_methods[] = { /* pmap dispatcher interface */ @@ -371,6 +375,8 @@ static mmu_method_t mmu_booke_methods[] = { MMUMETHOD(mmu_zero_page_idle, mmu_booke_zero_page_idle), MMUMETHOD(mmu_activate, mmu_booke_activate), MMUMETHOD(mmu_deactivate, mmu_booke_deactivate), + MMUMETHOD(mmu_quick_enter_page, mmu_booke_quick_enter_page), + MMUMETHOD(mmu_quick_remove_page, mmu_booke_quick_remove_page), /* Internal interfaces */ MMUMETHOD(mmu_bootstrap, mmu_booke_bootstrap), @@ -1351,6 +1357,22 @@ pmap_bootstrap_ap(volatile uint32_t *trcp __unused) } #endif +static void +booke_pmap_init_qpages(void) +{ + struct pcpu *pc; + int i; + + CPU_FOREACH(i) { + pc = pcpu_find(i); + pc->pc_qmap_addr = kva_alloc(PAGE_SIZE); + if (pc->pc_qmap_addr == 0) + panic("pmap_init_qpages: unable to allocate KVA"); + } +} + +SYSINIT(qpages_init, SI_SUB_CPU, SI_ORDER_ANY, booke_pmap_init_qpages, NULL); + /* * Get the physical page address for the given pmap/virtual address. */ @@ -2272,6 +2294,61 @@ mmu_booke_zero_page_idle(mmu_t mmu, vm_page_t m) mmu_booke_kremove(mmu, va); } +static vm_offset_t +mmu_booke_quick_enter_page(mmu_t mmu, vm_page_t m) +{ + vm_paddr_t paddr; + vm_offset_t qaddr; + uint32_t flags; + pte_t *pte; + + paddr = VM_PAGE_TO_PHYS(m); + + flags = PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | PTE_VALID; + flags |= tlb_calc_wimg(paddr, pmap_page_get_memattr(m)); + + critical_enter(); + qaddr = PCPU_GET(qmap_addr); + + pte = &(kernel_pmap->pm_pdir[PDIR_IDX(qaddr)][PTBL_IDX(qaddr)]); + + KASSERT(pte->flags == 0, ("mmu_booke_quick_enter_page: PTE busy")); + + /* + * XXX: tlbivax is broadcast to other cores, but qaddr should + * not be present in other TLBs. Is there a better instruction + * sequence to use? Or just forget it & use mmu_booke_kenter()... + */ + __asm __volatile("tlbivax 0, %0" :: "r"(qaddr & MAS2_EPN_MASK)); + __asm __volatile("isync; msync"); + + pte->rpn = paddr & ~PTE_PA_MASK; + pte->flags = flags; + + /* Flush the real memory from the instruction cache. */ + if ((flags & (PTE_I | PTE_G)) == 0) + __syncicache((void *)qaddr, PAGE_SIZE); + + return (qaddr); +} + +static void +mmu_booke_quick_remove_page(mmu_t mmu, vm_offset_t addr) +{ + pte_t *pte; + + pte = &(kernel_pmap->pm_pdir[PDIR_IDX(addr)][PTBL_IDX(addr)]); + + KASSERT(PCPU_GET(qmap_addr) == addr, + ("mmu_booke_quick_remove_page: invalid address")); + KASSERT(pte->flags != 0, + ("mmu_booke_quick_remove_page: PTE not in use")); + + pte->flags = 0; + pte->rpn = 0; + critical_exit(); +} + /* * Return whether or not the specified physical page was modified * in any of physical maps. diff --git a/sys/powerpc/include/pcpu.h b/sys/powerpc/include/pcpu.h index 79b2d96709fd..2c79cd696e72 100644 --- a/sys/powerpc/include/pcpu.h +++ b/sys/powerpc/include/pcpu.h @@ -35,6 +35,7 @@ #include struct pmap; +struct pvo_entry; #define CPUSAVE_LEN 9 #define PCPU_MD_COMMON_FIELDS \ @@ -53,6 +54,9 @@ struct pmap; void *pc_restore; #define PCPU_MD_AIM32_FIELDS \ + vm_offset_t pc_qmap_addr; \ + struct pvo_entry *pc_qmap_pvo; \ + struct mtx pc_qmap_lock; \ /* char __pad[0] */ #define PCPU_MD_AIM64_FIELDS \ @@ -60,7 +64,10 @@ struct pmap; struct slb **pc_userslb; \ register_t pc_slbsave[18]; \ uint8_t pc_slbstack[1024]; \ - char __pad[1137] + vm_offset_t pc_qmap_addr; \ + struct pvo_entry *pc_qmap_pvo; \ + struct mtx pc_qmap_lock; \ + char __pad[1121 - sizeof(struct mtx)] #ifdef __powerpc64__ #define PCPU_MD_AIM_FIELDS PCPU_MD_AIM64_FIELDS @@ -78,9 +85,10 @@ struct pmap; register_t pc_booke_mchksave[CPUSAVE_LEN]; \ register_t pc_booke_tlbsave[BOOKE_TLBSAVE_LEN]; \ register_t pc_booke_tlb_level; \ + vm_offset_t pc_qmap_addr; \ uint32_t *pc_booke_tlb_lock; \ int pc_tid_next; \ - char __pad[173] + char __pad[165] /* Definitions for register offsets within the exception tmp save areas */ #define CPUSAVE_R27 0 /* where r27 gets saved */ diff --git a/sys/powerpc/powerpc/mmu_if.m b/sys/powerpc/powerpc/mmu_if.m index 0089d76a5413..6c41c74a5dc5 100644 --- a/sys/powerpc/powerpc/mmu_if.m +++ b/sys/powerpc/powerpc/mmu_if.m @@ -933,3 +933,26 @@ METHOD void dumpsys_unmap { METHOD void scan_init { mmu_t _mmu; }; + +/** + * @brief Create a temporary thread-local KVA mapping of a single page. + * + * @param _pg The physical page to map + * + * @retval addr The temporary KVA + */ +METHOD vm_offset_t quick_enter_page { + mmu_t _mmu; + vm_page_t _pg; +}; + +/** + * @brief Undo a mapping created by quick_enter_page + * + * @param _va The mapped KVA + */ +METHOD void quick_remove_page { + mmu_t _mmu; + vm_offset_t _va; +}; + diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c index a27eb82400a0..a0718994dd07 100644 --- a/sys/powerpc/powerpc/pmap_dispatch.c +++ b/sys/powerpc/powerpc/pmap_dispatch.c @@ -550,6 +550,20 @@ dumpsys_pa_init(void) return (MMU_SCAN_INIT(mmu_obj)); } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ + CTR2(KTR_PMAP, "%s(%p)", __func__, m); + return (MMU_QUICK_ENTER_PAGE(mmu_obj, m)); +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ + CTR2(KTR_PMAP, "%s(%#x)", __func__, addr); + MMU_QUICK_REMOVE_PAGE(mmu_obj, addr); +} + /* * MMU install routines. Highest priority wins, equal priority also * overrides allowing last-set to win. diff --git a/sys/sparc64/include/pcpu.h b/sys/sparc64/include/pcpu.h index dbcc59c6cd4b..df43810ef0b5 100644 --- a/sys/sparc64/include/pcpu.h +++ b/sys/sparc64/include/pcpu.h @@ -51,6 +51,7 @@ struct pmap; struct intr_request *pc_irfree; \ struct pmap *pc_pmap; \ vm_offset_t pc_addr; \ + vm_offset_t pc_qmap_addr; \ u_long pc_tickref; \ u_long pc_tickadj; \ u_long pc_tickincrement; \ @@ -61,7 +62,7 @@ struct pmap; u_int pc_tlb_ctx; \ u_int pc_tlb_ctx_max; \ u_int pc_tlb_ctx_min; \ - char __pad[405] + char __pad[397] #ifdef _KERNEL diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index f10678eb79dc..e0dca86e69b2 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -143,6 +143,7 @@ static int pmap_protect_tte(struct pmap *pm1, struct pmap *pm2, struct tte *tp, vm_offset_t va); static int pmap_unwire_tte(pmap_t pm, pmap_t pm2, struct tte *tp, vm_offset_t va); +static void pmap_init_qpages(void); /* * Map the given physical page at the specified virtual address in the @@ -680,6 +681,25 @@ pmap_bootstrap(u_int cpu_impl) tlb_flush_nonlocked(); } +static void +pmap_init_qpages(void) +{ + struct pcpu *pc; + int i; + + if (dcache_color_ignore != 0) + return; + + CPU_FOREACH(i) { + pc = pcpu_find(i); + pc->pc_qmap_addr = kva_alloc(PAGE_SIZE * DCACHE_COLORS); + if (pc->pc_qmap_addr == 0) + panic("pmap_init_qpages: unable to allocate KVA"); + } +} + +SYSINIT(qpages_init, SI_SUB_CPU, SI_ORDER_ANY, pmap_init_qpages, NULL); + /* * Map the 4MB kernel TSB pages. */ @@ -1934,6 +1954,54 @@ pmap_copy_page(vm_page_t msrc, vm_page_t mdst) } } +vm_offset_t +pmap_quick_enter_page(vm_page_t m) +{ + vm_paddr_t pa; + vm_offset_t qaddr; + struct tte *tp; + + pa = VM_PAGE_TO_PHYS(m); + if (dcache_color_ignore != 0 || m->md.color == DCACHE_COLOR(pa)) + return (TLB_PHYS_TO_DIRECT(pa)); + + critical_enter(); + qaddr = PCPU_GET(qmap_addr); + qaddr += (PAGE_SIZE * ((DCACHE_COLORS + DCACHE_COLOR(pa) - + DCACHE_COLOR(qaddr)) % DCACHE_COLORS)); + tp = tsb_kvtotte(qaddr); + + KASSERT(tp->tte_data == 0, ("pmap_quick_enter_page: PTE busy")); + + tp->tte_data = TD_V | TD_8K | TD_PA(pa) | TD_CP | TD_CV | TD_W; + tp->tte_vpn = TV_VPN(qaddr, TS_8K); + + return (qaddr); +} + +void +pmap_quick_remove_page(vm_offset_t addr) +{ + vm_offset_t qaddr; + struct tte *tp; + + if (addr >= VM_MIN_DIRECT_ADDRESS) + return; + + tp = tsb_kvtotte(addr); + qaddr = PCPU_GET(qmap_addr); + + KASSERT((addr >= qaddr) && (addr < (qaddr + (PAGE_SIZE * DCACHE_COLORS))), + ("pmap_quick_remove_page: invalid address")); + KASSERT(tp->tte_data != 0, ("pmap_quick_remove_page: PTE not in use")); + + stxa(TLB_DEMAP_VA(addr) | TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, ASI_DMMU_DEMAP, 0); + stxa(TLB_DEMAP_VA(addr) | TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, ASI_IMMU_DEMAP, 0); + flush(KERNBASE); + TTE_ZERO(tp); + critical_exit(); +} + int unmapped_buf_allowed; void diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index d73babc83ccd..741ba3cd8b8d 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -152,6 +152,8 @@ void pmap_unwire(pmap_t pmap, vm_offset_t start, vm_offset_t end); void pmap_zero_page(vm_page_t); void pmap_zero_page_area(vm_page_t, int off, int size); void pmap_zero_page_idle(vm_page_t); +vm_offset_t pmap_quick_enter_page(vm_page_t); +void pmap_quick_remove_page(vm_offset_t); #define pmap_resident_count(pm) ((pm)->pm_stats.resident_count) #define pmap_wired_count(pm) ((pm)->pm_stats.wired_count) From 6ee5cf50eee7185509874eced0df26b1b07969e5 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Wed, 5 Aug 2015 01:52:11 +0000 Subject: [PATCH 228/314] Remove some unnecessary includes. --- sys/dev/nand/nfc_rb.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sys/dev/nand/nfc_rb.c b/sys/dev/nand/nfc_rb.c index 20a4026304e8..8c0f08a8b281 100644 --- a/sys/dev/nand/nfc_rb.c +++ b/sys/dev/nand/nfc_rb.c @@ -31,16 +31,12 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include -#include #include #include #include #include -#include -#include -#include +#include #include From daebf39a41ea1dc56a12dd3bd230f397e9d7fab9 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Wed, 5 Aug 2015 01:52:52 +0000 Subject: [PATCH 229/314] Remove one more that crept in unnecessarily from previous commit. --- sys/dev/nand/nfc_rb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/dev/nand/nfc_rb.c b/sys/dev/nand/nfc_rb.c index 8c0f08a8b281..38b28445add1 100644 --- a/sys/dev/nand/nfc_rb.c +++ b/sys/dev/nand/nfc_rb.c @@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include From 1b44fd7506f1bc25f179746995de3cab826d4d81 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Wed, 5 Aug 2015 03:03:57 +0000 Subject: [PATCH 230/314] Update the comment about handling old-style rc(5) scripts The old-style (*.sh) scripts in /etc/rc.d are explicitly ignored, whereas other scripts ending in .sh are permitted --- etc/rc.subr | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/etc/rc.subr b/etc/rc.subr index 914d17f87a83..c23c8fd3e32e 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -1266,8 +1266,11 @@ _run_rc_killcmd() # run_rc_script file arg # Start the script `file' with `arg', and correctly handle the # return value from the script. -# If `file' ends with `.sh', it's sourced into the current environment -# when $rc_fast_and_loose is set, otherwise it is run as a child process. +# If `file' ends with `.sh' and lives in /etc/rc.d, ignore it as it's +# an old-style startup file. +# If `file' ends with `.sh' and does not live in /etc/rc.d, it's sourced +# into the current environment if $rc_fast_and_loose is set; otherwise +# it is run as a child process. # If `file' appears to be a backup or scratch file, ignore it. # Otherwise if it is executable run as a child process. # From c1987c285265fbbe08cf6f5fea38df37fb3b3759 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Wed, 5 Aug 2015 03:17:06 +0000 Subject: [PATCH 231/314] Set f_file to -1/F_UNUSED when after closing when possible This will help ensure we don't trash file descriptors that get used later on in the daemon Found via internal Coverity scan MFC after: 2 weeks Discussed with: cem, ed, markj Differential Revision: https://reviews.freebsd.org/D3081 Submitted by: Miles Ohlrich Sponsored by: EMC / Isilon Storage Division --- usr.sbin/syslogd/syslogd.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index ff3e5249fd4c..fa55e9d025c7 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -349,6 +349,18 @@ static int waitdaemon(int, int, int); static void timedout(int); static void increase_rcvbuf(int); +static void +close_filed(struct filed *f) +{ + + if (f == NULL || f->f_file == -1) + return; + + (void)close(f->f_file); + f->f_file = -1; + f->f_type = F_UNUSED; +} + int main(int argc, char *argv[]) { @@ -1024,7 +1036,8 @@ logmsg(int pri, const char *msg, const char *from, int flags) (void)strlcpy(f->f_lasttime, timestamp, sizeof(f->f_lasttime)); fprintlog(f, flags, msg); - (void)close(f->f_file); + close(f->f_file); + f->f_file = -1; } (void)sigsetmask(omask); return; @@ -1313,8 +1326,7 @@ fprintlog(struct filed *f, int flags, const char *msg) */ if (errno != ENOSPC) { int e = errno; - (void)close(f->f_file); - f->f_type = F_UNUSED; + close_filed(f); errno = e; logerror(f->f_un.f_fname); } @@ -1338,7 +1350,7 @@ fprintlog(struct filed *f, int flags, const char *msg) } if (writev(f->f_file, iov, IOV_SIZE) < 0) { int e = errno; - (void)close(f->f_file); + close_filed(f); if (f->f_un.f_pipe.f_pid > 0) deadq_enter(f->f_un.f_pipe.f_pid, f->f_un.f_pipe.f_pname); @@ -1446,7 +1458,7 @@ reapchild(int signo __unused) for (f = Files; f; f = f->f_next) if (f->f_type == F_PIPE && f->f_un.f_pipe.f_pid == pid) { - (void)close(f->f_file); + close_filed(f); f->f_un.f_pipe.f_pid = 0; log_deadchild(pid, status, f->f_un.f_pipe.f_pname); @@ -1550,7 +1562,7 @@ die(int signo) if (f->f_prevcount) fprintlog(f, 0, (char *)NULL); if (f->f_type == F_PIPE && f->f_un.f_pipe.f_pid > 0) { - (void)close(f->f_file); + close_filed(f); f->f_un.f_pipe.f_pid = 0; } } @@ -1634,11 +1646,11 @@ init(int signo) case F_FORW: case F_CONSOLE: case F_TTY: - (void)close(f->f_file); + close_filed(f); break; case F_PIPE: if (f->f_un.f_pipe.f_pid > 0) { - (void)close(f->f_file); + close_filed(f); deadq_enter(f->f_un.f_pipe.f_pid, f->f_un.f_pipe.f_pname); } From 2433a4eb041dd9ac5cd7f905f6948d6b7222adc8 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 07:34:29 +0000 Subject: [PATCH 232/314] Make it possible to implement poll(2) on top of kqueue(2). It looks like EVFILT_READ and EVFILT_WRITE trigger under the same conditions as poll()'s POLLRDNORM and POLLWRNORM as described by POSIX. The only difference is that POLLRDNORM has to be triggered on regular files unconditionally, whereas EVFILT_READ only triggers when not EOF. Introduce a new flag, NOTE_FILE_POLL, that can be used to make EVFILT_READ and EVFILT_WRITE behave identically to poll(). This flag will be used by cloudlibc's poll() function. Reviewed by: jmg Differential Revision: https://reviews.freebsd.org/D3303 --- lib/libc/sys/kqueue.2 | 10 +++++++++- sys/kern/vfs_subr.c | 2 +- sys/sys/event.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2 index c5e8cafd5579..ca94852cba29 100644 --- a/lib/libc/sys/kqueue.2 +++ b/lib/libc/sys/kqueue.2 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 29, 2015 +.Dd August 4, 2015 .Dt KQUEUE 2 .Os .Sh NAME @@ -288,6 +288,14 @@ Returns when the file pointer is not at the end of file. .Va data contains the offset from current position to end of file, and may be negative. +.Pp +This behavior is different from +.Xr poll 2 , +where read events are triggered for regular files unconditionally. +This event can be triggered unconditionally by setting the +.Dv NOTE_FILE_POLL +flag in +.Va fflags . .It "Fifos, Pipes" Returns when the there is data to read; .Va data diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 42cab157573a..3c189d1a2df5 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -4622,7 +4622,7 @@ filt_vfsread(struct knote *kn, long hint) VI_LOCK(vp); kn->kn_data = va.va_size - kn->kn_fp->f_offset; - res = (kn->kn_data != 0); + res = (kn->kn_sfflags & NOTE_FILE_POLL) != 0 || kn->kn_data != 0; VI_UNLOCK(vp); return (res); } diff --git a/sys/sys/event.h b/sys/sys/event.h index 089c9b3874f0..0f132318c827 100644 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -108,6 +108,7 @@ struct kevent { * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace */ #define NOTE_LOWAT 0x0001 /* low water mark */ +#define NOTE_FILE_POLL 0x0002 /* behave like poll() */ /* * data/hint flags for EVFILT_VNODE, shared with userspace From a2034cc98ab0519e76b632773ee9e9d94126f42a Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 07:36:50 +0000 Subject: [PATCH 233/314] Allow the creation of kqueues with a restricted set of Capsicum rights. On CloudABI we want to create file descriptors with just the minimal set of Capsicum rights in place. The reason for this is that it makes it easier to obtain uniform behaviour across different operating systems. By explicitly whitelisting the operations, we can return consistent error codes, but also prevent applications from depending OS-specific behaviour. Extend kern_kqueue() to take an additional struct filecaps that is passed on to falloc_caps(). Update the existing consumers to pass in NULL. Differential Revision: https://reviews.freebsd.org/D3259 --- sys/compat/linux/linux_event.c | 2 +- sys/kern/kern_event.c | 6 +++--- sys/sys/syscallsubr.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c index fcb57533bdc8..b1ceadfde50e 100644 --- a/sys/compat/linux/linux_event.c +++ b/sys/compat/linux/linux_event.c @@ -205,7 +205,7 @@ epoll_create_common(struct thread *td, int flags) { int error; - error = kern_kqueue(td, flags); + error = kern_kqueue(td, flags, NULL); if (error) return (error); diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index f8c6cf099fe5..06cb763b33c0 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -738,11 +738,11 @@ int sys_kqueue(struct thread *td, struct kqueue_args *uap) { - return (kern_kqueue(td, 0)); + return (kern_kqueue(td, 0, NULL)); } int -kern_kqueue(struct thread *td, int flags) +kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps) { struct filedesc *fdp; struct kqueue *kq; @@ -760,7 +760,7 @@ kern_kqueue(struct thread *td, int flags) } fdp = p->p_fd; - error = falloc(td, &fp, &fd, flags); + error = falloc_caps(td, &fp, &fd, flags, fcaps); if (error) goto done2; diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 579ac83752d1..ce68ba80a085 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -126,7 +126,7 @@ int kern_kevent(struct thread *td, int fd, int nchanges, int nevents, int kern_kevent_fp(struct thread *td, struct file *fp, int nchanges, int nevents, struct kevent_copyops *k_ops, const struct timespec *timeout); -int kern_kqueue(struct thread *td, int flags); +int kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps); int kern_kldload(struct thread *td, const char *file, int *fileid); int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat); int kern_kldunload(struct thread *td, int fileid, int flags); From 4958fab8cd74f644947444102e6b51ef329407d6 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 07:37:06 +0000 Subject: [PATCH 234/314] Allow the creation of polling descriptors (kqueues) on CloudABI. --- sys/compat/cloudabi/cloudabi_fd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index d2004a9e27d1..03d65bd4e8f0 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -104,6 +104,9 @@ cloudabi_sys_fd_create1(struct thread *td, }; switch (uap->type) { + case CLOUDABI_FILETYPE_POLL: + cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_KQUEUE); + return (kern_kqueue(td, 0, &fcaps)); case CLOUDABI_FILETYPE_SHARED_MEMORY: cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_FTRUNCATE, CAP_MMAP_RWX); From db1c8ee585bce622fb2ea4d8d8f190f3a675c430 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 08:18:05 +0000 Subject: [PATCH 235/314] Add the remaining pointer size independent CloudABI socket system calls. CloudABI uses a structure called cloudabi_sockstat_t. Think of it as 'struct stat' for sockets. It is used by functions such as getsockname(), getpeername(), some of the getsockopt() values, etc. This change implements the sock_stat_get() system call that returns a copy of this structure. The accept() system call should also return a full copy of this structure eventually, but for now we're only interested in the peer address. Add a TODO() to make sure this is patched up later on. Differential Revision: https://reviews.freebsd.org/D3218 --- sys/compat/cloudabi/cloudabi_sock.c | 118 +++++++++++++++++++++++++++- sys/compat/cloudabi/cloudabi_util.h | 6 ++ 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_sock.c b/sys/compat/cloudabi/cloudabi_sock.c index 877571c144c0..1cfff92449a3 100644 --- a/sys/compat/cloudabi/cloudabi_sock.c +++ b/sys/compat/cloudabi/cloudabi_sock.c @@ -27,14 +27,62 @@ __FBSDID("$FreeBSD$"); #include +#include +#include +#include +#include +#include #include +#include #include #include #include #include +#include + +#include + #include #include +#include + +/* Converts FreeBSD's struct sockaddr to CloudABI's cloudabi_sockaddr_t. */ +void +cloudabi_convert_sockaddr(const struct sockaddr *sa, socklen_t sal, + cloudabi_sockaddr_t *rsa) +{ + const struct sockaddr_in *sin; + const struct sockaddr_in6 *sin6; + + /* Zero-sized socket address. */ + if (sal < offsetof(struct sockaddr, sa_family) + sizeof(sa->sa_family)) + return; + + switch (sa->sa_family) { + case AF_INET: + if (sal < sizeof(struct sockaddr_in)) + return; + sin = (const struct sockaddr_in *)sa; + rsa->sa_family = CLOUDABI_AF_INET; + memcpy(&rsa->sa_inet.addr, &sin->sin_addr, + sizeof(rsa->sa_inet.addr)); + rsa->sa_inet.port = ntohs(sin->sin_port); + return; + case AF_INET6: + if (sal < sizeof(struct sockaddr_in6)) + return; + sin6 = (const struct sockaddr_in6 *)sa; + rsa->sa_family = CLOUDABI_AF_INET6; + memcpy(&rsa->sa_inet6.addr, &sin6->sin6_addr, + sizeof(rsa->sa_inet6.addr)); + rsa->sa_inet6.port = ntohs(sin6->sin6_port); + return; + case AF_UNIX: + rsa->sa_family = CLOUDABI_AF_UNIX; + return; + } +} /* Copies a pathname into a UNIX socket address structure. */ static int @@ -62,9 +110,27 @@ int cloudabi_sys_sock_accept(struct thread *td, struct cloudabi_sys_sock_accept_args *uap) { + struct sockaddr *sa; + cloudabi_sockstat_t ss = {}; + socklen_t sal; + int error; - /* Not implemented. */ - return (ENOSYS); + if (uap->buf == NULL) { + /* Only return the new file descriptor number. */ + return (kern_accept(td, uap->s, NULL, NULL, NULL)); + } else { + /* Also return properties of the new socket descriptor. */ + sal = MAX(sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6)); + error = kern_accept(td, uap->s, (void *)&sa, &sal, NULL); + if (error != 0) + return (error); + + /* TODO(ed): Fill the other members of cloudabi_sockstat_t. */ + cloudabi_convert_sockaddr(sa, sal, &ss.ss_peername); + free(sa, M_SONAME); + return (copyout(&ss, uap->buf, sizeof(ss))); + } } int @@ -134,7 +200,51 @@ int cloudabi_sys_sock_stat_get(struct thread *td, struct cloudabi_sys_sock_stat_get_args *uap) { + cloudabi_sockstat_t ss = {}; + cap_rights_t rights; + struct file *fp; + struct sockaddr *sa; + struct socket *so; + int error; - /* Not implemented. */ - return (ENOSYS); + error = getsock_cap(td, uap->fd, cap_rights_init(&rights, + CAP_GETSOCKOPT | CAP_GETPEERNAME | CAP_GETSOCKNAME), &fp, NULL); + if (error != 0) + return (error); + so = fp->f_data; + + CURVNET_SET(so->so_vnet); + + /* Set ss_sockname. */ + error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + if (error == 0) { + cloudabi_convert_sockaddr(sa, sa->sa_len, &ss.ss_sockname); + free(sa, M_SONAME); + } + + /* Set ss_peername. */ + if ((so->so_state & (SS_ISCONNECTED | SS_ISCONFIRMING)) != 0) { + error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa); + if (error == 0) { + cloudabi_convert_sockaddr(sa, sa->sa_len, + &ss.ss_peername); + free(sa, M_SONAME); + } + } + + CURVNET_RESTORE(); + + /* Set ss_error. */ + SOCK_LOCK(so); + ss.ss_error = so->so_error; + if ((uap->flags & CLOUDABI_SOCKSTAT_CLEAR_ERROR) != 0) + so->so_error = 0; + SOCK_UNLOCK(so); + + /* Set ss_state. */ + if ((so->so_options & SO_ACCEPTCONN) != 0) + ss.ss_state |= CLOUDABI_SOCKSTAT_ACCEPTCONN; + + fdrop(fp, td); + return (copyout(&ss, uap->buf, sizeof(ss))); } diff --git a/sys/compat/cloudabi/cloudabi_util.h b/sys/compat/cloudabi/cloudabi_util.h index 557cf1759037..a263c94cf146 100644 --- a/sys/compat/cloudabi/cloudabi_util.h +++ b/sys/compat/cloudabi/cloudabi_util.h @@ -28,6 +28,8 @@ #ifndef _CLOUDABI_UTIL_H_ #define _CLOUDABI_UTIL_H_ +#include + #include struct file; @@ -41,6 +43,10 @@ int cloudabi_clock_time_get(struct thread *, cloudabi_clockid_t, /* Converts a FreeBSD errno to a CloudABI errno. */ cloudabi_errno_t cloudabi_convert_errno(int); +/* Converts FreeBSD's struct sockaddr to CloudABI's cloudabi_sockaddr_t. */ +void cloudabi_convert_sockaddr(const struct sockaddr *, socklen_t, + cloudabi_sockaddr_t *); + /* Converts a file descriptor to a CloudABI file descriptor type. */ cloudabi_filetype_t cloudabi_convert_filetype(const struct file *); From 0a3e154709b6189c43e5f36e588ef219f18f0951 Mon Sep 17 00:00:00 2001 From: "Jason A. Harmening" Date: Wed, 5 Aug 2015 10:48:32 +0000 Subject: [PATCH 236/314] Properly sort the function declarations added in r286296 Submitted by: alc Approved by: kib (mentor) --- sys/vm/pmap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index 741ba3cd8b8d..1d18823a6a19 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -141,6 +141,8 @@ void pmap_pinit0(pmap_t); void pmap_protect(pmap_t, vm_offset_t, vm_offset_t, vm_prot_t); void pmap_qenter(vm_offset_t, vm_page_t *, int); void pmap_qremove(vm_offset_t, int); +vm_offset_t pmap_quick_enter_page(vm_page_t); +void pmap_quick_remove_page(vm_offset_t); void pmap_release(pmap_t); void pmap_remove(pmap_t, vm_offset_t, vm_offset_t); void pmap_remove_all(vm_page_t m); @@ -152,8 +154,6 @@ void pmap_unwire(pmap_t pmap, vm_offset_t start, vm_offset_t end); void pmap_zero_page(vm_page_t); void pmap_zero_page_area(vm_page_t, int off, int size); void pmap_zero_page_idle(vm_page_t); -vm_offset_t pmap_quick_enter_page(vm_page_t); -void pmap_quick_remove_page(vm_offset_t); #define pmap_resident_count(pm) ((pm)->pm_stats.resident_count) #define pmap_wired_count(pm) ((pm)->pm_stats.wired_count) From c8fbdcc10d7aa456110255e71785bdd32b9ceebf Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 5 Aug 2015 10:50:33 +0000 Subject: [PATCH 237/314] Fix UP build after r286296, ensure that CPU_FOREACH() is defined. Sponsored by: The FreeBSD Foundation --- sys/i386/i386/pmap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index efd44b3964a7..f8ae6d957729 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -118,11 +118,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef SMP #include -#else -#include -#endif #include #include From ddab05272565776816bfc2da307cbb231285673e Mon Sep 17 00:00:00 2001 From: Eric van Gyzen Date: Wed, 5 Aug 2015 12:53:55 +0000 Subject: [PATCH 238/314] Disable SSE in libthr Clang emits SSE instructions on amd64 in the common path of pthread_mutex_unlock. If the thread does not otherwise use SSE, this usage incurs a context-switch of the FPU/SSE state, which reduces the performance of multiple real-world applications by a non-trivial amount (3-5% in one application). Instead of this change, I experimented with eagerly switching the FPU state at context-switch time. This did not help. Most of the cost seems to be in the read/write of memory--as kib@ stated--and not in the #NM handling. I tested on machines with and without XSAVEOPT. One counter-argument to this change is that most applications already use SIMD, and the number of applications and amount of SIMD usage are only increasing. This is absolutely true. I agree that--in general and in principle--this change is in the wrong direction. However, there are applications that do not use enough SSE to offset the extra context-switch cost. SSE does not provide a clear benefit in the current libthr code with the current compiler, but it does provide a clear loss in some cases. Therefore, disabling SSE in libthr is a non-loss for most, and a gain for some. I refrained from disabling SSE in libc--as was suggested--because I can't make the above argument for libc. It provides a wide variety of code; each case should be analyzed separately. https://lists.freebsd.org/pipermail/freebsd-current/2015-March/055193.html Suggestions from: dim, jmg, rpaulo Approved by: kib (mentor) MFC after: 2 weeks Sponsored by: Dell Inc. --- lib/libthr/arch/amd64/Makefile.inc | 6 ++++++ lib/libthr/arch/i386/Makefile.inc | 6 ++++++ libexec/rtld-elf/amd64/Makefile.inc | 2 +- libexec/rtld-elf/i386/Makefile.inc | 2 +- share/mk/bsd.cpu.mk | 21 +++++++++++++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/libthr/arch/amd64/Makefile.inc b/lib/libthr/arch/amd64/Makefile.inc index 797618d4183a..43f6e839ff10 100644 --- a/lib/libthr/arch/amd64/Makefile.inc +++ b/lib/libthr/arch/amd64/Makefile.inc @@ -1,3 +1,9 @@ #$FreeBSD$ SRCS+= _umtx_op_err.S + +# With the current compiler and libthr code, using SSE in libthr +# does not provide enough performance improvement to outweigh +# the extra context switch cost. This can measurably impact +# performance when the application also does not use enough SSE. +CFLAGS+=${CFLAGS_NO_SIMD} diff --git a/lib/libthr/arch/i386/Makefile.inc b/lib/libthr/arch/i386/Makefile.inc index bdab0bc90fe6..23a95498f443 100644 --- a/lib/libthr/arch/i386/Makefile.inc +++ b/lib/libthr/arch/i386/Makefile.inc @@ -1,3 +1,9 @@ # $FreeBSD$ SRCS+= _umtx_op_err.S + +# With the current compiler and libthr code, using SSE in libthr +# does not provide enough performance improvement to outweigh +# the extra context switch cost. This can measurably impact +# performance when the application also does not use enough SSE. +CFLAGS+=${CFLAGS_NO_SIMD} diff --git a/libexec/rtld-elf/amd64/Makefile.inc b/libexec/rtld-elf/amd64/Makefile.inc index 7528dbe1e670..a09db6f60956 100644 --- a/libexec/rtld-elf/amd64/Makefile.inc +++ b/libexec/rtld-elf/amd64/Makefile.inc @@ -1,6 +1,6 @@ # $FreeBSD$ -CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float +CFLAGS+= ${CFLAGS_NO_SIMD} -msoft-float # Uncomment this to build the dynamic linker as an executable instead # of a shared library: #LDSCRIPT= ${.CURDIR}/${MACHINE_CPUARCH}/elf_rtld.x diff --git a/libexec/rtld-elf/i386/Makefile.inc b/libexec/rtld-elf/i386/Makefile.inc index 7528dbe1e670..a09db6f60956 100644 --- a/libexec/rtld-elf/i386/Makefile.inc +++ b/libexec/rtld-elf/i386/Makefile.inc @@ -1,6 +1,6 @@ # $FreeBSD$ -CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float +CFLAGS+= ${CFLAGS_NO_SIMD} -msoft-float # Uncomment this to build the dynamic linker as an executable instead # of a shared library: #LDSCRIPT= ${.CURDIR}/${MACHINE_CPUARCH}/elf_rtld.x diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk index 6ba87cc3486e..7d776bce5637 100644 --- a/share/mk/bsd.cpu.mk +++ b/share/mk/bsd.cpu.mk @@ -282,6 +282,27 @@ _CPUCFLAGS += -mfloat-abi=softfp CFLAGS += ${_CPUCFLAGS} .endif +# +# Prohibit the compiler from emitting SIMD instructions. +# These flags are added to CFLAGS in areas where the extra context-switch +# cost outweighs the advantages of SIMD instructions. +# +# gcc: +# Setting -mno-mmx implies -mno-3dnow +# Setting -mno-sse implies -mno-sse2, -mno-sse3, -mno-ssse3 and -mfpmath=387 +# +# clang: +# Setting -mno-mmx implies -mno-3dnow and -mno-3dnowa +# Setting -mno-sse implies -mno-sse2, -mno-sse3, -mno-ssse3, -mno-sse41 and +# -mno-sse42 +# (-mfpmath= is not supported) +# +.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" +CFLAGS_NO_SIMD.clang= -mno-avx +CFLAGS_NO_SIMD= -mno-mmx -mno-sse +.endif +CFLAGS_NO_SIMD += ${CFLAGS_NO_SIMD.${COMPILER_TYPE}} + # Add in any architecture-specific CFLAGS. # These come from make.conf or the command line or the environment. CFLAGS += ${CFLAGS.${MACHINE_ARCH}} From 2837d9ed4377cc7ca812c9d31a255146d2f5d8e0 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 13:09:46 +0000 Subject: [PATCH 239/314] Import the latest CloudABI system call definitions and table. We're going to need these for next code I'm going to send out for review: support for poll() and kqueue() on CloudABI. --- sys/compat/cloudabi64/cloudabi64_poll.c | 9 +++++++++ sys/compat/cloudabi64/syscalls.master | 12 +++++++++--- sys/contrib/cloudabi/syscalldefs_md.h | 6 +++++- sys/contrib/cloudabi/syscalldefs_mi.h | 9 ++++++--- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/sys/compat/cloudabi64/cloudabi64_poll.c b/sys/compat/cloudabi64/cloudabi64_poll.c index 544886dc33b4..0a18838033d3 100644 --- a/sys/compat/cloudabi64/cloudabi64_poll.c +++ b/sys/compat/cloudabi64/cloudabi64_poll.c @@ -36,3 +36,12 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) /* Not implemented. */ return (ENOSYS); } + +int +cloudabi64_sys_poll_fd(struct thread *td, + struct cloudabi64_sys_poll_fd_args *uap) +{ + + /* Not implemented. */ + return (ENOSYS); +} diff --git a/sys/compat/cloudabi64/syscalls.master b/sys/compat/cloudabi64/syscalls.master index 21deffb24ee4..5fd6f7eb3dfb 100644 --- a/sys/compat/cloudabi64/syscalls.master +++ b/sys/compat/cloudabi64/syscalls.master @@ -157,11 +157,9 @@ void * addr, size_t len); } 39 AUE_NULL STD { cloudabi64_size_t cloudabi64_sys_poll( \ - cloudabi_fd_t fd, \ const cloudabi64_subscription_t *in, \ - cloudabi64_size_t nin, \ cloudabi64_event_t *out, \ - cloudabi64_size_t nout); } + cloudabi64_size_t nevents); } 40 AUE_NULL STD { void cloudabi_sys_proc_exec( \ cloudabi_fd_t fd, const void *data, \ @@ -212,3 +210,11 @@ cloudabi_mflags_t scope); } 55 AUE_NULL STD { void cloudabi_sys_thread_tcb_set(void *tcb); } 56 AUE_NULL STD { void cloudabi_sys_thread_yield(); } + +57 AUE_NULL STD { cloudabi64_size_t cloudabi64_sys_poll_fd( \ + cloudabi_fd_t fd, \ + const cloudabi64_subscription_t *in, \ + cloudabi64_size_t nin, \ + cloudabi64_event_t *out, \ + cloudabi64_size_t nout, \ + const cloudabi64_subscription_t *timeout); } diff --git a/sys/contrib/cloudabi/syscalldefs_md.h b/sys/contrib/cloudabi/syscalldefs_md.h index a7045c2d7e6b..f2e37058846f 100644 --- a/sys/contrib/cloudabi/syscalldefs_md.h +++ b/sys/contrib/cloudabi/syscalldefs_md.h @@ -186,6 +186,7 @@ typedef struct { MEMBER(cloudabi_clockid_t) clock_id; MEMBER(cloudabi_timestamp_t) timeout; MEMBER(cloudabi_timestamp_t) precision; + MEMBER(uint16_t) flags; } clock; // CLOUDABI_EVENTTYPE_CONDVAR: Release a lock and wait on a @@ -202,6 +203,7 @@ typedef struct { // called without blocking. struct { MEMBER(cloudabi_fd_t) fd; + MEMBER(uint16_t) flags; } fd_readwrite; // CLOUDABI_EVENT_LOCK_RDLOCK and CLOUDABI_EVENT_LOCK_WRLOCK: Wait @@ -224,15 +226,17 @@ ASSERT_OFFSET(subscription_t, clock.identifier, 16, 16); ASSERT_OFFSET(subscription_t, clock.clock_id, 24, 24); ASSERT_OFFSET(subscription_t, clock.timeout, 32, 32); ASSERT_OFFSET(subscription_t, clock.precision, 40, 40); +ASSERT_OFFSET(subscription_t, clock.flags, 48, 48); ASSERT_OFFSET(subscription_t, condvar.condvar, 16, 16); ASSERT_OFFSET(subscription_t, condvar.lock, 20, 24); ASSERT_OFFSET(subscription_t, condvar.condvar_scope, 24, 32); ASSERT_OFFSET(subscription_t, condvar.lock_scope, 25, 33); ASSERT_OFFSET(subscription_t, fd_readwrite.fd, 16, 16); +ASSERT_OFFSET(subscription_t, fd_readwrite.flags, 20, 20); ASSERT_OFFSET(subscription_t, lock.lock, 16, 16); ASSERT_OFFSET(subscription_t, lock.lock_scope, 20, 24); ASSERT_OFFSET(subscription_t, proc_terminate.fd, 16, 16); -ASSERT_SIZE(subscription_t, 48, 48); +ASSERT_SIZE(subscription_t, 56, 56); typedef struct { MEMBER(PTR(IDENT(threadentry_t))) entry_point; // Entry point. diff --git a/sys/contrib/cloudabi/syscalldefs_mi.h b/sys/contrib/cloudabi/syscalldefs_mi.h index 151a3dcc59b9..adce208cb1d6 100644 --- a/sys/contrib/cloudabi/syscalldefs_mi.h +++ b/sys/contrib/cloudabi/syscalldefs_mi.h @@ -204,9 +204,6 @@ #define CLOUDABI_O_EXCL 0x4 #define CLOUDABI_O_TRUNC 0x8 -// File descriptor passed to poll() to poll just once. -#define CLOUDABI_POLL_ONCE 0xffffffff - // File descriptor returned to pdfork()'s child process. #define CLOUDABI_PROCESS_CHILD 0xffffffff @@ -326,6 +323,12 @@ #define CLOUDABI_SUBSCRIPTION_ENABLE 0x10 #define CLOUDABI_SUBSCRIPTION_ONESHOT 0x20 +// cloudabi_subscription_t::clock.flags. +#define CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME 0x1 + +// cloudabi_subscription_t::fd_readwrite.flags. +#define CLOUDABI_SUBSCRIPTION_FD_READWRITE_POLL 0x1 + // unlinkat(). #define CLOUDABI_UNLINK_REMOVEDIR 0x1 From 2412ae2b8e3af7ec2e08b9081d14b9c57bfac857 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 13:10:13 +0000 Subject: [PATCH 240/314] Regenerate the system call table. --- sys/compat/cloudabi64/cloudabi64_proto.h | 16 +++-- sys/compat/cloudabi64/cloudabi64_syscall.h | 5 +- sys/compat/cloudabi64/cloudabi64_syscalls.c | 3 +- sys/compat/cloudabi64/cloudabi64_sysent.c | 3 +- .../cloudabi64/cloudabi64_systrace_args.c | 62 ++++++++++++++----- 5 files changed, 67 insertions(+), 22 deletions(-) diff --git a/sys/compat/cloudabi64/cloudabi64_proto.h b/sys/compat/cloudabi64/cloudabi64_proto.h index dd86bc982cc1..8c65fe3c7364 100644 --- a/sys/compat/cloudabi64/cloudabi64_proto.h +++ b/sys/compat/cloudabi64/cloudabi64_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/cloudabi64/syscalls.master 285906 2015-07-27 10:04:06Z ed + * created from FreeBSD: head/sys/compat/cloudabi64/syscalls.master 286318 2015-08-05 13:09:46Z ed */ #ifndef _CLOUDABI64_SYSPROTO_H_ @@ -232,11 +232,9 @@ struct cloudabi_sys_mem_unmap_args { char len_l_[PADL_(size_t)]; size_t len; char len_r_[PADR_(size_t)]; }; struct cloudabi64_sys_poll_args { - char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)]; char in_l_[PADL_(const cloudabi64_subscription_t *)]; const cloudabi64_subscription_t * in; char in_r_[PADR_(const cloudabi64_subscription_t *)]; - char nin_l_[PADL_(cloudabi64_size_t)]; cloudabi64_size_t nin; char nin_r_[PADR_(cloudabi64_size_t)]; char out_l_[PADL_(cloudabi64_event_t *)]; cloudabi64_event_t * out; char out_r_[PADR_(cloudabi64_event_t *)]; - char nout_l_[PADL_(cloudabi64_size_t)]; cloudabi64_size_t nout; char nout_r_[PADR_(cloudabi64_size_t)]; + char nevents_l_[PADL_(cloudabi64_size_t)]; cloudabi64_size_t nevents; char nevents_r_[PADR_(cloudabi64_size_t)]; }; struct cloudabi_sys_proc_exec_args { char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)]; @@ -310,6 +308,14 @@ struct cloudabi_sys_thread_tcb_set_args { struct cloudabi_sys_thread_yield_args { register_t dummy; }; +struct cloudabi64_sys_poll_fd_args { + char fd_l_[PADL_(cloudabi_fd_t)]; cloudabi_fd_t fd; char fd_r_[PADR_(cloudabi_fd_t)]; + char in_l_[PADL_(const cloudabi64_subscription_t *)]; const cloudabi64_subscription_t * in; char in_r_[PADR_(const cloudabi64_subscription_t *)]; + char nin_l_[PADL_(cloudabi64_size_t)]; cloudabi64_size_t nin; char nin_r_[PADR_(cloudabi64_size_t)]; + char out_l_[PADL_(cloudabi64_event_t *)]; cloudabi64_event_t * out; char out_r_[PADR_(cloudabi64_event_t *)]; + char nout_l_[PADL_(cloudabi64_size_t)]; cloudabi64_size_t nout; char nout_r_[PADR_(cloudabi64_size_t)]; + char timeout_l_[PADL_(const cloudabi64_subscription_t *)]; const cloudabi64_subscription_t * timeout; char timeout_r_[PADR_(const cloudabi64_subscription_t *)]; +}; int cloudabi_sys_clock_res_get(struct thread *, struct cloudabi_sys_clock_res_get_args *); int cloudabi_sys_clock_time_get(struct thread *, struct cloudabi_sys_clock_time_get_args *); int cloudabi_sys_condvar_signal(struct thread *, struct cloudabi_sys_condvar_signal_args *); @@ -367,6 +373,7 @@ int cloudabi64_sys_thread_create(struct thread *, struct cloudabi64_sys_thread_c int cloudabi_sys_thread_exit(struct thread *, struct cloudabi_sys_thread_exit_args *); int cloudabi_sys_thread_tcb_set(struct thread *, struct cloudabi_sys_thread_tcb_set_args *); int cloudabi_sys_thread_yield(struct thread *, struct cloudabi_sys_thread_yield_args *); +int cloudabi64_sys_poll_fd(struct thread *, struct cloudabi64_sys_poll_fd_args *); #ifdef COMPAT_43 @@ -448,6 +455,7 @@ int cloudabi_sys_thread_yield(struct thread *, struct cloudabi_sys_thread_yield_ #define CLOUDABI64_SYS_AUE_cloudabi_sys_thread_exit AUE_NULL #define CLOUDABI64_SYS_AUE_cloudabi_sys_thread_tcb_set AUE_NULL #define CLOUDABI64_SYS_AUE_cloudabi_sys_thread_yield AUE_NULL +#define CLOUDABI64_SYS_AUE_cloudabi64_sys_poll_fd AUE_NULL #undef PAD_ #undef PADL_ diff --git a/sys/compat/cloudabi64/cloudabi64_syscall.h b/sys/compat/cloudabi64/cloudabi64_syscall.h index 176519053e7b..40c017a41900 100644 --- a/sys/compat/cloudabi64/cloudabi64_syscall.h +++ b/sys/compat/cloudabi64/cloudabi64_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/cloudabi64/syscalls.master 285906 2015-07-27 10:04:06Z ed + * created from FreeBSD: head/sys/compat/cloudabi64/syscalls.master 286318 2015-08-05 13:09:46Z ed */ #define CLOUDABI64_SYS_cloudabi_sys_clock_res_get 0 @@ -63,4 +63,5 @@ #define CLOUDABI64_SYS_cloudabi_sys_thread_exit 54 #define CLOUDABI64_SYS_cloudabi_sys_thread_tcb_set 55 #define CLOUDABI64_SYS_cloudabi_sys_thread_yield 56 -#define CLOUDABI64_SYS_MAXSYSCALL 57 +#define CLOUDABI64_SYS_cloudabi64_sys_poll_fd 57 +#define CLOUDABI64_SYS_MAXSYSCALL 58 diff --git a/sys/compat/cloudabi64/cloudabi64_syscalls.c b/sys/compat/cloudabi64/cloudabi64_syscalls.c index e44e6eaecb3f..5c0732b34636 100644 --- a/sys/compat/cloudabi64/cloudabi64_syscalls.c +++ b/sys/compat/cloudabi64/cloudabi64_syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/cloudabi64/syscalls.master 285906 2015-07-27 10:04:06Z ed + * created from FreeBSD: head/sys/compat/cloudabi64/syscalls.master 286318 2015-08-05 13:09:46Z ed */ const char *cloudabi64_syscallnames[] = { @@ -64,4 +64,5 @@ const char *cloudabi64_syscallnames[] = { "cloudabi_sys_thread_exit", /* 54 = cloudabi_sys_thread_exit */ "cloudabi_sys_thread_tcb_set", /* 55 = cloudabi_sys_thread_tcb_set */ "cloudabi_sys_thread_yield", /* 56 = cloudabi_sys_thread_yield */ + "cloudabi64_sys_poll_fd", /* 57 = cloudabi64_sys_poll_fd */ }; diff --git a/sys/compat/cloudabi64/cloudabi64_sysent.c b/sys/compat/cloudabi64/cloudabi64_sysent.c index 1048e4e7d136..2ed5042b8107 100644 --- a/sys/compat/cloudabi64/cloudabi64_sysent.c +++ b/sys/compat/cloudabi64/cloudabi64_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/cloudabi64/syscalls.master 285906 2015-07-27 10:04:06Z ed + * created from FreeBSD: head/sys/compat/cloudabi64/syscalls.master 286318 2015-08-05 13:09:46Z ed */ #include @@ -72,4 +72,5 @@ struct sysent cloudabi64_sysent[] = { { AS(cloudabi_sys_thread_exit_args), (sy_call_t *)cloudabi_sys_thread_exit, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 54 = cloudabi_sys_thread_exit */ { AS(cloudabi_sys_thread_tcb_set_args), (sy_call_t *)cloudabi_sys_thread_tcb_set, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 55 = cloudabi_sys_thread_tcb_set */ { 0, (sy_call_t *)cloudabi_sys_thread_yield, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 56 = cloudabi_sys_thread_yield */ + { AS(cloudabi64_sys_poll_fd_args), (sy_call_t *)cloudabi64_sys_poll_fd, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 57 = cloudabi64_sys_poll_fd */ }; diff --git a/sys/compat/cloudabi64/cloudabi64_systrace_args.c b/sys/compat/cloudabi64/cloudabi64_systrace_args.c index 311a14c20b1d..b3176aa3018e 100644 --- a/sys/compat/cloudabi64/cloudabi64_systrace_args.c +++ b/sys/compat/cloudabi64/cloudabi64_systrace_args.c @@ -367,12 +367,10 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) /* cloudabi64_sys_poll */ case 39: { struct cloudabi64_sys_poll_args *p = params; - iarg[0] = p->fd; /* cloudabi_fd_t */ - uarg[1] = (intptr_t) p->in; /* const cloudabi64_subscription_t * */ - iarg[2] = p->nin; /* cloudabi64_size_t */ - uarg[3] = (intptr_t) p->out; /* cloudabi64_event_t * */ - iarg[4] = p->nout; /* cloudabi64_size_t */ - *n_args = 5; + uarg[0] = (intptr_t) p->in; /* const cloudabi64_subscription_t * */ + uarg[1] = (intptr_t) p->out; /* cloudabi64_event_t * */ + iarg[2] = p->nevents; /* cloudabi64_size_t */ + *n_args = 3; break; } /* cloudabi_sys_proc_exec */ @@ -511,6 +509,18 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 0; break; } + /* cloudabi64_sys_poll_fd */ + case 57: { + struct cloudabi64_sys_poll_fd_args *p = params; + iarg[0] = p->fd; /* cloudabi_fd_t */ + uarg[1] = (intptr_t) p->in; /* const cloudabi64_subscription_t * */ + iarg[2] = p->nin; /* cloudabi64_size_t */ + uarg[3] = (intptr_t) p->out; /* cloudabi64_event_t * */ + iarg[4] = p->nout; /* cloudabi64_size_t */ + uarg[5] = (intptr_t) p->timeout; /* const cloudabi64_subscription_t * */ + *n_args = 6; + break; + } default: *n_args = 0; break; @@ -1155,18 +1165,12 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) case 39: switch(ndx) { case 0: - p = "cloudabi_fd_t"; - break; - case 1: p = "const cloudabi64_subscription_t *"; break; - case 2: - p = "cloudabi64_size_t"; - break; - case 3: + case 1: p = "cloudabi64_event_t *"; break; - case 4: + case 2: p = "cloudabi64_size_t"; break; default: @@ -1392,6 +1396,31 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) /* cloudabi_sys_thread_yield */ case 56: break; + /* cloudabi64_sys_poll_fd */ + case 57: + switch(ndx) { + case 0: + p = "cloudabi_fd_t"; + break; + case 1: + p = "const cloudabi64_subscription_t *"; + break; + case 2: + p = "cloudabi64_size_t"; + break; + case 3: + p = "cloudabi64_event_t *"; + break; + case 4: + p = "cloudabi64_size_t"; + break; + case 5: + p = "const cloudabi64_subscription_t *"; + break; + default: + break; + }; + break; default: break; }; @@ -1682,6 +1711,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; /* cloudabi_sys_thread_yield */ case 56: + /* cloudabi64_sys_poll_fd */ + case 57: + if (ndx == 0 || ndx == 1) + p = "cloudabi64_size_t"; + break; default: break; }; From 73942c5ce0c95dec6d2c02a2c8558f648243c03c Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 5 Aug 2015 13:46:15 +0000 Subject: [PATCH 241/314] Issue all reads of single XCOPY segment simultaneously. During vMotion and Clone VMware by default runs multiple sequential 4MB XCOPY requests same time. If CTL issues reads sequentially in 1MB chunks for each XCOPY command, reads from different commands are not detected as sequential by serseq option code and allowed to execute simultaneously. Such read pattern confused ZFS prefetcher, causing suboptimal disk access. Issuing all reads same time make serseq code work properly, serializing reads both within each XCOPY command and between them. My tests with ZFS pool of 14 disks in RAID10 shows prefetcher efficiency improved from 37% to 99.7%, copying speed improved by 10-60%, average read latency reduced twice on HDD layer and by five times on zvol layer. MFC after: 2 weeks Sponsored by: iXsystems, Inc. --- sys/cam/ctl/ctl_tpc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c index 490cddd510b7..662ee3d064a0 100644 --- a/sys/cam/ctl/ctl_tpc.c +++ b/sys/cam/ctl/ctl_tpc.c @@ -817,7 +817,7 @@ tpc_process_b2b(struct tpc_list *list) struct scsi_ec_segment_b2b *seg; struct scsi_ec_cscd_dtsp *sdstp, *ddstp; struct tpc_io *tior, *tiow; - struct runl run, *prun; + struct runl run; uint64_t sl, dl; off_t srclba, dstlba, numbytes, donebytes, roundbytes; int numlba; @@ -889,8 +889,7 @@ tpc_process_b2b(struct tpc_list *list) list->segsectors = numbytes / dstblock; donebytes = 0; TAILQ_INIT(&run); - prun = &run; - list->tbdio = 1; + list->tbdio = 0; while (donebytes < numbytes) { roundbytes = numbytes - donebytes; if (roundbytes > TPC_MAX_IO_SIZE) { @@ -942,8 +941,8 @@ tpc_process_b2b(struct tpc_list *list) tiow->io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = tiow; TAILQ_INSERT_TAIL(&tior->run, tiow, rlinks); - TAILQ_INSERT_TAIL(prun, tior, rlinks); - prun = &tior->run; + TAILQ_INSERT_TAIL(&run, tior, rlinks); + list->tbdio++; donebytes += roundbytes; srclba += roundbytes / srcblock; dstlba += roundbytes / dstblock; From 79b7e3e2c2e4a701c7b7a89986812c4a7d651d93 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Wed, 5 Aug 2015 14:45:52 +0000 Subject: [PATCH 242/314] Fix `make depend` in sys/modules Reviewed by: delphij Differential Revision: https://reviews.freebsd.org/D3291 --- sys/modules/zfs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index 05d226c1fb13..ffbd9ba6ce9e 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -4,7 +4,7 @@ SYSDIR?=${.CURDIR}/../.. KMOD= zfs -SRCS= bus_if.h device_if.h vnode_if.h +SRCS= bus_if.h device_if.h vnode_if.h opt_kstack_pages.h SUNW= ${SYSDIR}/cddl/contrib/opensolaris From 36310bcd1d6cca2cd4d95529ba1db92f0116e893 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 16:15:43 +0000 Subject: [PATCH 243/314] Make fcntl(F_SETFL) work. The stat_put() system call can be used to modify file descriptor attributes, such as flags, but also Capsicum permission bits. Support for changing Capsicum bits will be added as soon as its dependent changes have been pushed through code review. Obtained from: https://github.com/NuxiNL/freebsd --- sys/compat/cloudabi/cloudabi_fd.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index 03d65bd4e8f0..1fed2e7dcf4f 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -503,9 +503,26 @@ int cloudabi_sys_fd_stat_put(struct thread *td, struct cloudabi_sys_fd_stat_put_args *uap) { + cloudabi_fdstat_t fsb; + int error, oflags; - /* Not implemented. */ - return (ENOSYS); + error = copyin(uap->buf, &fsb, sizeof(fsb)); + if (error != 0) + return (error); + + if (uap->flags == CLOUDABI_FDSTAT_FLAGS) { + /* Convert flags. */ + oflags = 0; + if (fsb.fs_flags & CLOUDABI_FDFLAG_APPEND) + oflags |= O_APPEND; + if (fsb.fs_flags & CLOUDABI_FDFLAG_NONBLOCK) + oflags |= O_NONBLOCK; + if (fsb.fs_flags & (CLOUDABI_FDFLAG_SYNC | + CLOUDABI_FDFLAG_DSYNC | CLOUDABI_FDFLAG_RSYNC)) + oflags |= O_SYNC; + return (kern_fcntl(td, uap->fd, F_SETFL, oflags)); + } + return (EINVAL); } int From b6efa27589061231f27366a4164be4fc22ad9dcf Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 16:45:47 +0000 Subject: [PATCH 244/314] Add DECLARE_MODULE() to the "cloudabi" kernel module. This kernel module does not require any explicit initialization, but a module declaration is needed to let the "cloudabi64" kernel module automatically pull this in. Obtained from: https://github.com/NuxiNL/freebsd --- sys/compat/cloudabi/cloudabi_proc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sys/compat/cloudabi/cloudabi_proc.c b/sys/compat/cloudabi/cloudabi_proc.c index b071aa390ad3..949e390bc688 100644 --- a/sys/compat/cloudabi/cloudabi_proc.c +++ b/sys/compat/cloudabi/cloudabi_proc.c @@ -30,7 +30,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include @@ -133,3 +135,12 @@ cloudabi_sys_proc_raise(struct thread *td, PROC_UNLOCK(p); return (0); } + +static moduledata_t cloudabi_module = { + "cloudabi", + NULL, + NULL +}; + +DECLARE_MODULE(cloudabi, cloudabi_module, SI_SUB_EXEC, SI_ORDER_ANY); +MODULE_VERSION(cloudabi, 1); From aaf53ab2aa174aaf61da4a6b030e79407b567181 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 5 Aug 2015 16:53:49 +0000 Subject: [PATCH 245/314] Correct the previous commit: remove the DECLARE_MODULE(). It looks like a MODULE_VERSION() can also appear on its own -- there is no need to use explicitly use DECLARE_MODULE(). Looking at other modules, this seems common practice. --- sys/compat/cloudabi/cloudabi_proc.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_proc.c b/sys/compat/cloudabi/cloudabi_proc.c index 949e390bc688..22f199df14f7 100644 --- a/sys/compat/cloudabi/cloudabi_proc.c +++ b/sys/compat/cloudabi/cloudabi_proc.c @@ -30,7 +30,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -136,11 +135,4 @@ cloudabi_sys_proc_raise(struct thread *td, return (0); } -static moduledata_t cloudabi_module = { - "cloudabi", - NULL, - NULL -}; - -DECLARE_MODULE(cloudabi, cloudabi_module, SI_SUB_EXEC, SI_ORDER_ANY); MODULE_VERSION(cloudabi, 1); From 96226a9aa7e9171903cfa2be4c2abb6b663f0663 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 5 Aug 2015 17:05:35 +0000 Subject: [PATCH 246/314] Rationalize BSD license on sys/*/include/float.h Remove the advertising clause from the Regents of the University of California's license, per the letter dated July 22, 1999. Update clause numbering. --- sys/arm/include/float.h | 6 +----- sys/arm64/include/float.h | 4 ---- sys/mips/include/float.h | 2 +- sys/powerpc/include/float.h | 2 +- sys/sparc64/include/float.h | 2 +- sys/x86/include/float.h | 2 +- 6 files changed, 5 insertions(+), 13 deletions(-) diff --git a/sys/arm/include/float.h b/sys/arm/include/float.h index 644b5ff773a1..358a611bd4f7 100644 --- a/sys/arm/include/float.h +++ b/sys/arm/include/float.h @@ -10,11 +10,7 @@ * 2. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/arm64/include/float.h b/sys/arm64/include/float.h index 2bb86bd8472b..0829f6f52aa9 100644 --- a/sys/arm64/include/float.h +++ b/sys/arm64/include/float.h @@ -10,10 +10,6 @@ * 2. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. diff --git a/sys/mips/include/float.h b/sys/mips/include/float.h index 2aa661a7ffcd..86efd02b975c 100644 --- a/sys/mips/include/float.h +++ b/sys/mips/include/float.h @@ -10,7 +10,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/powerpc/include/float.h b/sys/powerpc/include/float.h index 50da262b8013..4eea0bda5870 100644 --- a/sys/powerpc/include/float.h +++ b/sys/powerpc/include/float.h @@ -10,7 +10,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/sparc64/include/float.h b/sys/sparc64/include/float.h index dcc626f801a8..270336922f6d 100644 --- a/sys/sparc64/include/float.h +++ b/sys/sparc64/include/float.h @@ -14,7 +14,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/x86/include/float.h b/sys/x86/include/float.h index 8af3039d0856..32e338efb2c0 100644 --- a/sys/x86/include/float.h +++ b/sys/x86/include/float.h @@ -10,7 +10,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * From fb396e55da906889276d2effe7ef6e9c7c0004e0 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 5 Aug 2015 17:21:42 +0000 Subject: [PATCH 247/314] Fix more style issues. Submitted by: bde --- sys/x86/include/_types.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/x86/include/_types.h b/sys/x86/include/_types.h index 7266d76b4ee0..b130be3d040d 100644 --- a/sys/x86/include/_types.h +++ b/sys/x86/include/_types.h @@ -155,10 +155,10 @@ typedef __builtin_va_list __va_list; /* internally known to gcc */ #else #ifdef __LP64__ struct __s_va_list { - __uint32_t pad1[2]; /* gp_offset, fp_offset */ - __uint64_t pad2[2]; /* overflow_arg_area, reg_save_area */ + __uint32_t _pad1[2]; /* gp_offset, fp_offset */ + __uint64_t _pad2[2]; /* overflow_arg_area, reg_save_area */ }; -typedef struct __s_va_list __va_list; +typedef struct __s_va_list __va_list; #else typedef char * __va_list; #endif From ebce46b2c6c841abd8ac5e5d5e68787322e76333 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Wed, 5 Aug 2015 17:38:02 +0000 Subject: [PATCH 248/314] Make rctl_enable rc variable actually work. To avoid breaking existing setups that worked before, flip the default to "YES". Most people don't have /etc/rctl.conf, so they won't be affected in any way. MFC after: 1 month Sponsored by: The FreeBSD Foundation --- etc/defaults/rc.conf | 2 +- etc/rc.d/rctl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 125d59e17aa9..fbe18db386af 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -664,7 +664,7 @@ opensm_enable="NO" # Opensm(8) for infiniband devices defaults to off casperd_enable="YES" # casperd(8) daemon # rctl(8) requires kernel options RACCT and RCTL -rctl_enable="NO" # Load rctl(8) rules on boot +rctl_enable="YES" # Load rctl(8) rules on boot rctl_rules="/etc/rctl.conf" # rctl(8) ruleset. See rctl.conf(5). iovctl_files="" # Config files for iovctl(8) diff --git a/etc/rc.d/rctl b/etc/rc.d/rctl index 567436be9da6..93b200d475e9 100755 --- a/etc/rc.d/rctl +++ b/etc/rc.d/rctl @@ -10,6 +10,7 @@ . /etc/rc.subr name="rctl" +rcvar="rctl_enable" start_cmd="rctl_start" stop_cmd="rctl_stop" From 7582c8ea088987b3beef638fa995f29b7e607fd7 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 5 Aug 2015 18:10:46 +0000 Subject: [PATCH 249/314] Whitespace fix: remove some spurious spaces before commas. --- usr.bin/truss/syscalls.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index efd27e91fff0..aa4bac5e82a5 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -93,7 +93,7 @@ static const char rcsid[] = */ static struct syscall syscalls[] = { { .name = "fcntl", .ret_type = 1, .nargs = 3, - .args = { { Int, 0 } , { Fcntl, 1 }, { Fcntlflag | OUT, 2 } } }, + .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag | OUT, 2 } } }, { .name = "fork", .ret_type = 1, .nargs = 0 }, { .name = "vfork", .ret_type = 1, .nargs = 0 }, { .name = "rfork", .ret_type = 1, .nargs = 1, @@ -101,9 +101,9 @@ static struct syscall syscalls[] = { { .name = "getegid", .ret_type = 1, .nargs = 0 }, { .name = "geteuid", .ret_type = 1, .nargs = 0 }, { .name = "linux_readlink", .ret_type = 1, .nargs = 3, - .args = { { Name, 0 } , { Name | OUT, 1 }, { Int, 2 }}}, + .args = { { Name, 0 }, { Name | OUT, 1 }, { Int, 2 }}}, { .name = "linux_socketcall", .ret_type = 1, .nargs = 2, - .args = { { Int, 0 } , { LinuxSockArgs, 1 }}}, + .args = { { Int, 0 }, { LinuxSockArgs, 1 }}}, { .name = "getgid", .ret_type = 1, .nargs = 0 }, { .name = "getpid", .ret_type = 1, .nargs = 0 }, { .name = "getpgid", .ret_type = 1, .nargs = 1, @@ -114,7 +114,7 @@ static struct syscall syscalls[] = { .args = { { Int, 0 } } }, { .name = "getuid", .ret_type = 1, .nargs = 0 }, { .name = "readlink", .ret_type = 1, .nargs = 3, - .args = { { Name, 0 } , { Readlinkres | OUT, 1 }, { Int, 2 } } }, + .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Int, 2 } } }, { .name = "lseek", .ret_type = 2, .nargs = 3, .args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, { .name = "linux_lseek", .ret_type = 2, .nargs = 3, @@ -122,13 +122,13 @@ static struct syscall syscalls[] = { { .name = "mmap", .ret_type = 2, .nargs = 6, .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 }, { Int, 4 }, { Quad, 5 + QUAD_ALIGN } } }, { .name = "linux_mkdir", .ret_type = 1, .nargs = 2, - .args = { { Name | IN, 0} , {Int, 1}}}, + .args = { { Name | IN, 0}, {Int, 1}}}, { .name = "mprotect", .ret_type = 1, .nargs = 3, .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } }, { .name = "open", .ret_type = 1, .nargs = 3, - .args = { { Name | IN, 0 } , { Open, 1 }, { Octal, 2 } } }, + .args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } }, { .name = "mkdir", .ret_type = 1, .nargs = 2, - .args = { { Name, 0 } , { Octal, 1 } } }, + .args = { { Name, 0 }, { Octal, 1 } } }, { .name = "linux_open", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } }, { .name = "close", .ret_type = 1, .nargs = 1, @@ -154,7 +154,7 @@ static struct syscall syscalls[] = { { .name = "umount", .ret_type = 0, .nargs = 2, .args = { { Name, 0 }, { Int, 2 } } }, { .name = "fstat", .ret_type = 1, .nargs = 2, - .args = { { Int, 0 }, { Stat | OUT , 1 } } }, + .args = { { Int, 0 }, { Stat | OUT, 1 } } }, { .name = "stat", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, { .name = "lstat", .ret_type = 1, .nargs = 2, @@ -220,7 +220,7 @@ static struct syscall syscalls[] = { { .name = "getitimer", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Itimerval | OUT, 2 } } }, { .name = "setitimer", .ret_type = 1, .nargs = 3, - .args = { { Int, 0 }, { Itimerval, 1 } , { Itimerval | OUT, 2 } } }, + .args = { { Int, 0 }, { Itimerval, 1 }, { Itimerval | OUT, 2 } } }, { .name = "kse_release", .ret_type = 0, .nargs = 1, .args = { { Timespec, 0 } } }, { .name = "kevent", .ret_type = 0, .nargs = 6, @@ -266,9 +266,9 @@ static struct syscall syscalls[] = { { .name = "read", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } }, { .name = "rename", .ret_type = 1, .nargs = 2, - .args = { { Name , 0 } , { Name, 1 } } }, + .args = { { Name, 0 }, { Name, 1 } } }, { .name = "symlink", .ret_type = 1, .nargs = 2, - .args = { { Name , 0 } , { Name, 1 } } }, + .args = { { Name, 0 }, { Name, 1 } } }, { .name = "posix_openpt", .ret_type = 1, .nargs = 1, .args = { { Open, 0 } } }, { .name = "wait4", .ret_type = 1, .nargs = 4, From abb3f965d13ea86c79b56497a9ff022c422840ff Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 5 Aug 2015 18:14:01 +0000 Subject: [PATCH 250/314] Rework get_string() to make it more robust when fetching strings of unknown length. In particular, instead of blinding fetching 1k blocks, do an initial fetch up to the end of the current page followed by page-sized fetches up to the maximum size. Previously if the 1k buffer crossed a page boundary and the second page was not valid, the entire operation would fail. --- usr.bin/truss/syscalls.c | 46 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index aa4bac5e82a5..b758ddbda221 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -539,44 +539,56 @@ get_struct(pid_t pid, void *offset, void *buf, int len) } #define MAXSIZE 4096 -#define BLOCKSIZE 1024 + /* * get_string * Copy a string from the process. Note that it is * expected to be a C string, but if max is set, it will * only get that much. */ - static char * -get_string(pid_t pid, void *offset, int max) +get_string(pid_t pid, void *addr, int max) { struct ptrace_io_desc iorequest; - char *buf; - int diff, i, size, totalsize; + char *buf, *nbuf; + size_t offset, size, totalsize; - diff = 0; - totalsize = size = max ? (max + 1) : BLOCKSIZE; + offset = 0; + if (max) + size = max + 1; + else { + /* Read up to the end of the current page. */ + size = PAGE_SIZE - ((uintptr_t)addr % PAGE_SIZE); + if (size > MAXSIZE) + size = MAXSIZE; + } + totalsize = size; buf = malloc(totalsize); if (buf == NULL) return (NULL); for (;;) { - diff = totalsize - size; iorequest.piod_op = PIOD_READ_D; - iorequest.piod_offs = (char *)offset + diff; - iorequest.piod_addr = buf + diff; + iorequest.piod_offs = (char *)addr + offset; + iorequest.piod_addr = buf + offset; iorequest.piod_len = size; if (ptrace(PT_IO, pid, (caddr_t)&iorequest, 0) < 0) { free(buf); return (NULL); } - for (i = 0 ; i < size; i++) { - if (buf[diff + i] == '\0') + if (memchr(buf + offset, '\0', size) != NULL) + return (buf); + offset += size; + if (totalsize < MAXSIZE && max == 0) { + size = MAXSIZE - totalsize; + if (size > PAGE_SIZE) + size = PAGE_SIZE; + nbuf = realloc(buf, totalsize + size); + if (nbuf == NULL) { + buf[totalsize - 1] = '\0'; return (buf); - } - if (totalsize < MAXSIZE - BLOCKSIZE && max == 0) { - totalsize += BLOCKSIZE; - buf = realloc(buf, totalsize); - size = BLOCKSIZE; + } + buf = nbuf; + totalsize += size; } else { buf[totalsize - 1] = '\0'; return (buf); From f97aa232eb26e433f945e5ca89c25f7fdf9d1e69 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 5 Aug 2015 18:30:00 +0000 Subject: [PATCH 251/314] Remove old GNU Binutils tools now provided by ELF Tool Chain Reviewed by: bapt, brooks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3238 --- UPDATING | 7 +- gnu/usr.bin/binutils/Makefile | 14 - gnu/usr.bin/binutils/addr2line/Makefile | 17 - .../binutils/addr2line/Makefile.depend | 21 - gnu/usr.bin/binutils/addr2line/addr2line.1 | 266 ----------- gnu/usr.bin/binutils/ar/Makefile.depend | 21 - gnu/usr.bin/binutils/nm/Makefile | 18 - gnu/usr.bin/binutils/nm/Makefile.depend | 21 - gnu/usr.bin/binutils/nm/nm.1 | 450 ------------------ gnu/usr.bin/binutils/ranlib/Makefile.depend | 21 - gnu/usr.bin/binutils/readelf/Makefile | 20 - gnu/usr.bin/binutils/readelf/Makefile.depend | 21 - gnu/usr.bin/binutils/readelf/readelf.1 | 377 --------------- gnu/usr.bin/binutils/size/Makefile | 17 - gnu/usr.bin/binutils/size/Makefile.depend | 21 - gnu/usr.bin/binutils/size/size.1 | 263 ---------- gnu/usr.bin/binutils/strings/Makefile | 17 - gnu/usr.bin/binutils/strings/Makefile.depend | 21 - gnu/usr.bin/binutils/strings/strings.1 | 254 ---------- gnu/usr.bin/binutils/strip/Makefile | 18 - gnu/usr.bin/binutils/strip/Makefile.depend | 21 - gnu/usr.bin/binutils/strip/strip.1 | 392 --------------- gnu/usr.bin/cc/Makefile | 3 - gnu/usr.bin/cc/c++filt/Makefile | 19 - gnu/usr.bin/cc/c++filt/Makefile.depend | 23 - tools/build/mk/OptionalObsoleteFiles.inc | 10 +- tools/build/options/WITHOUT_BINUTILS | 3 +- .../build/options/WITHOUT_ELFTOOLCHAIN_TOOLS | 5 +- 28 files changed, 12 insertions(+), 2349 deletions(-) delete mode 100644 gnu/usr.bin/binutils/addr2line/Makefile delete mode 100644 gnu/usr.bin/binutils/addr2line/Makefile.depend delete mode 100644 gnu/usr.bin/binutils/addr2line/addr2line.1 delete mode 100644 gnu/usr.bin/binutils/ar/Makefile.depend delete mode 100644 gnu/usr.bin/binutils/nm/Makefile delete mode 100644 gnu/usr.bin/binutils/nm/Makefile.depend delete mode 100644 gnu/usr.bin/binutils/nm/nm.1 delete mode 100644 gnu/usr.bin/binutils/ranlib/Makefile.depend delete mode 100644 gnu/usr.bin/binutils/readelf/Makefile delete mode 100644 gnu/usr.bin/binutils/readelf/Makefile.depend delete mode 100644 gnu/usr.bin/binutils/readelf/readelf.1 delete mode 100644 gnu/usr.bin/binutils/size/Makefile delete mode 100644 gnu/usr.bin/binutils/size/Makefile.depend delete mode 100644 gnu/usr.bin/binutils/size/size.1 delete mode 100644 gnu/usr.bin/binutils/strings/Makefile delete mode 100644 gnu/usr.bin/binutils/strings/Makefile.depend delete mode 100644 gnu/usr.bin/binutils/strings/strings.1 delete mode 100644 gnu/usr.bin/binutils/strip/Makefile delete mode 100644 gnu/usr.bin/binutils/strip/Makefile.depend delete mode 100644 gnu/usr.bin/binutils/strip/strip.1 delete mode 100644 gnu/usr.bin/cc/c++filt/Makefile delete mode 100644 gnu/usr.bin/cc/c++filt/Makefile.depend diff --git a/UPDATING b/UPDATING index d032144b4e25..3b6c0359ec93 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20150805: + GNU Binutils versions of addr2line, c++filt, nm, readelf, size, + strings and strip have been removed. The src.conf(5) knob + WITHOUT_ELFTOOLCHAIN_TOOLS no longer provides the binutils tools. + 20150728: As ZFS requires more kernel stack pages than is the default on some architectures e.g. i386, it now warns if KSTACK_PAGES is less than @@ -224,7 +229,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: taken from the ELF Tool Chain project rather than GNU binutils. They should be drop-in replacements, with the addition of arm64 support. The WITHOUT_ELFTOOLCHAIN_TOOLS= knob may be used to obtain the - binutils tools, if necessary. + binutils tools, if necessary. See 20150805 for updated information. 20150105: The default Unbound configuration now enables remote control diff --git a/gnu/usr.bin/binutils/Makefile b/gnu/usr.bin/binutils/Makefile index d1241486b46d..d8ebdb1637e1 100644 --- a/gnu/usr.bin/binutils/Makefile +++ b/gnu/usr.bin/binutils/Makefile @@ -7,25 +7,11 @@ SUBDIR= doc\ libbfd \ libopcodes \ libbinutils \ - ${_addr2line} \ as \ ld \ - ${_nm} \ ${_objcopy} \ objdump \ - ${_readelf} \ - ${_size} \ - ${_strings} \ - ${_strip} -.if ${MK_ELFTOOLCHAIN_TOOLS} == "no" -_addr2line= addr2line -_nm= nm -_readelf= readelf -_size= size -_strings= strings -_strip= strip -.endif .if ${MK_ELFTOOLCHAIN_TOOLS} == "no" || ${MK_ELFCOPY_AS_OBJCOPY} == "no" _objcopy= objcopy .endif diff --git a/gnu/usr.bin/binutils/addr2line/Makefile b/gnu/usr.bin/binutils/addr2line/Makefile deleted file mode 100644 index 2380738fa638..000000000000 --- a/gnu/usr.bin/binutils/addr2line/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -.include "../Makefile.inc0" - -.PATH: ${SRCDIR}/binutils ${SRCDIR}/binutils/doc - -PROG= addr2line -SRCS= addr2line.c -CFLAGS+= -D_GNU_SOURCE -CFLAGS+= -I${.CURDIR}/${RELTOP}/libbinutils -CFLAGS+= -I${SRCDIR}/binutils -DPADD= ${RELTOP}/libbinutils/libbinutils.a -DPADD+= ${RELTOP}/libbfd/libbfd.a -DPADD+= ${RELTOP}/libiberty/libiberty.a -LDADD= ${DPADD} - -.include diff --git a/gnu/usr.bin/binutils/addr2line/Makefile.depend b/gnu/usr.bin/binutils/addr2line/Makefile.depend deleted file mode 100644 index b58c9bda263a..000000000000 --- a/gnu/usr.bin/binutils/addr2line/Makefile.depend +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/binutils/libbfd \ - gnu/usr.bin/binutils/libbinutils \ - gnu/usr.bin/binutils/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/binutils/addr2line/addr2line.1 b/gnu/usr.bin/binutils/addr2line/addr2line.1 deleted file mode 100644 index 4f76544fa352..000000000000 --- a/gnu/usr.bin/binutils/addr2line/addr2line.1 +++ /dev/null @@ -1,266 +0,0 @@ -.\" $FreeBSD$ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "ADDR2LINE 1" -.TH ADDR2LINE 1 "2010-10-30" "binutils-2.17.50" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -addr2line \- convert addresses into file names and line numbers -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -addr2line [\fB\-b\fR \fIbfdname\fR|\fB\-\-target=\fR\fIbfdname\fR] - [\fB\-C\fR|\fB\-\-demangle\fR[=\fIstyle\fR]] - [\fB\-e\fR \fIfilename\fR|\fB\-\-exe=\fR\fIfilename\fR] - [\fB\-f\fR|\fB\-\-functions\fR] [\fB\-s\fR|\fB\-\-basename\fR] - [\fB\-i\fR|\fB\-\-inlines\fR] - [\fB\-j\fR|\fB\-\-section=\fR\fIname\fR] - [\fB\-H\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] - [addr addr ...] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\fBaddr2line\fR translates addresses into file names and line numbers. -Given an address in an executable or an offset in a section of a relocatable -object, it uses the debugging information to figure out which file name and -line number are associated with it. -.PP -The executable or relocatable object to use is specified with the \fB\-e\fR -option. The default is the file \fIa.out\fR. The section in the relocatable -object to use is specified with the \fB\-j\fR option. -.PP -\&\fBaddr2line\fR has two modes of operation. -.PP -In the first, hexadecimal addresses are specified on the command line, -and \fBaddr2line\fR displays the file name and line number for each -address. -.PP -In the second, \fBaddr2line\fR reads hexadecimal addresses from -standard input, and prints the file name and line number for each -address on standard output. In this mode, \fBaddr2line\fR may be used -in a pipe to convert dynamically chosen addresses. -.PP -The format of the output is \fB\s-1FILENAME:LINENO\s0\fR. The file name and -line number for each address is printed on a separate line. If the -\&\fB\-f\fR option is used, then each \fB\s-1FILENAME:LINENO\s0\fR line is -preceded by a \fB\s-1FUNCTIONNAME\s0\fR line which is the name of the function -containing the address. -.PP -If the file name or function name can not be determined, -\&\fBaddr2line\fR will print two question marks in their place. If the -line number can not be determined, \fBaddr2line\fR will print 0. -.SH "OPTIONS" -.IX Header "OPTIONS" -The long and short forms of options, shown here as alternatives, are -equivalent. -.IP "\fB\-b\fR \fIbfdname\fR" 4 -.IX Item "-b bfdname" -.PD 0 -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -.PD -Specify that the object-code format for the object files is -\&\fIbfdname\fR. -.IP "\fB\-C\fR" 4 -.IX Item "-C" -.PD 0 -.IP "\fB\-\-demangle[=\fR\fIstyle\fR\fB]\fR" 4 -.IX Item "--demangle[=style]" -.PD -Decode (\fIdemangle\fR) low-level symbol names into user-level names. -Besides removing any initial underscore prepended by the system, this -makes \*(C+ function names readable. Different compilers have different -mangling styles. The optional demangling style argument can be used to -choose an appropriate demangling style for your compiler. -.IP "\fB\-e\fR \fIfilename\fR" 4 -.IX Item "-e filename" -.PD 0 -.IP "\fB\-\-exe=\fR\fIfilename\fR" 4 -.IX Item "--exe=filename" -.PD -Specify the name of the executable for which addresses should be -translated. The default file is \fIa.out\fR. -.IP "\fB\-f\fR" 4 -.IX Item "-f" -.PD 0 -.IP "\fB\-\-functions\fR" 4 -.IX Item "--functions" -.PD -Display function names as well as file and line number information. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-basenames\fR" 4 -.IX Item "--basenames" -.PD -Display only the base of each file name. -.IP "\fB\-i\fR" 4 -.IX Item "-i" -.PD 0 -.IP "\fB\-\-inlines\fR" 4 -.IX Item "--inlines" -.PD -If the address belongs to a function that was inlined, the source -information for all enclosing scopes back to the first non-inlined -function will also be printed. For example, if \f(CW\*(C`main\*(C'\fR inlines -\&\f(CW\*(C`callee1\*(C'\fR which inlines \f(CW\*(C`callee2\*(C'\fR, and address is from -\&\f(CW\*(C`callee2\*(C'\fR, the source information for \f(CW\*(C`callee1\*(C'\fR and \f(CW\*(C`main\*(C'\fR -will also be printed. -.IP "\fB\-j\fR" 4 -.IX Item "-j" -.PD 0 -.IP "\fB\-\-section\fR" 4 -.IX Item "--section" -.PD -Read offsets relative to the specified section instead of absolute addresses. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/gnu/usr.bin/binutils/ar/Makefile.depend b/gnu/usr.bin/binutils/ar/Makefile.depend deleted file mode 100644 index 9a5a4f99aa50..000000000000 --- a/gnu/usr.bin/binutils/ar/Makefile.depend +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DIRDEPS = \ - gnu/usr.bin/binutils/libbfd \ - gnu/usr.bin/binutils/libbinutils \ - gnu/usr.bin/binutils/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/binutils/nm/Makefile b/gnu/usr.bin/binutils/nm/Makefile deleted file mode 100644 index 4ef2b8fdf65a..000000000000 --- a/gnu/usr.bin/binutils/nm/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $FreeBSD$ - -.include "../Makefile.inc0" - -.PATH: ${SRCDIR}/binutils ${SRCDIR}/binutils/doc - -PROG= nm -SRCS= nm.c -CFLAGS+= -D_GNU_SOURCE -CFLAGS+= -I${.CURDIR}/${RELTOP}/libbinutils -CFLAGS+= -I${SRCDIR}/bfd -CFLAGS+= -I${SRCDIR}/binutils -DPADD= ${RELTOP}/libbinutils/libbinutils.a -DPADD+= ${RELTOP}/libbfd/libbfd.a -DPADD+= ${RELTOP}/libiberty/libiberty.a -LDADD= ${DPADD} - -.include diff --git a/gnu/usr.bin/binutils/nm/Makefile.depend b/gnu/usr.bin/binutils/nm/Makefile.depend deleted file mode 100644 index b58c9bda263a..000000000000 --- a/gnu/usr.bin/binutils/nm/Makefile.depend +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/binutils/libbfd \ - gnu/usr.bin/binutils/libbinutils \ - gnu/usr.bin/binutils/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/binutils/nm/nm.1 b/gnu/usr.bin/binutils/nm/nm.1 deleted file mode 100644 index e94e472f21aa..000000000000 --- a/gnu/usr.bin/binutils/nm/nm.1 +++ /dev/null @@ -1,450 +0,0 @@ -.\" $FreeBSD$ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "NM 1" -.TH NM 1 "2010-10-30" "binutils-2.17.50" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -nm \- list symbols from object files -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -nm [\fB\-a\fR|\fB\-\-debug\-syms\fR] [\fB\-g\fR|\fB\-\-extern\-only\fR] - [\fB\-B\fR] [\fB\-C\fR|\fB\-\-demangle\fR[=\fIstyle\fR]] [\fB\-D\fR|\fB\-\-dynamic\fR] - [\fB\-S\fR|\fB\-\-print\-size\fR] [\fB\-s\fR|\fB\-\-print\-armap\fR] - [\fB\-A\fR|\fB\-o\fR|\fB\-\-print\-file\-name\fR][\fB\-\-special\-syms\fR] - [\fB\-n\fR|\fB\-v\fR|\fB\-\-numeric\-sort\fR] [\fB\-p\fR|\fB\-\-no\-sort\fR] - [\fB\-r\fR|\fB\-\-reverse\-sort\fR] [\fB\-\-size\-sort\fR] [\fB\-u\fR|\fB\-\-undefined\-only\fR] - [\fB\-t\fR \fIradix\fR|\fB\-\-radix=\fR\fIradix\fR] [\fB\-P\fR|\fB\-\-portability\fR] - [\fB\-\-target=\fR\fIbfdname\fR] [\fB\-f\fR\fIformat\fR|\fB\-\-format=\fR\fIformat\fR] - [\fB\-\-defined\-only\fR] [\fB\-l\fR|\fB\-\-line\-numbers\fR] [\fB\-\-no\-demangle\fR] - [\fB\-V\fR|\fB\-\-version\fR] [\fB\-X 32_64\fR] [\fB\-\-help\fR] [\fIobjfile\fR...] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\s-1GNU\s0 \fBnm\fR lists the symbols from object files \fIobjfile\fR.... -If no object files are listed as arguments, \fBnm\fR assumes the file -\&\fIa.out\fR. -.PP -For each symbol, \fBnm\fR shows: -.IP "\(bu" 4 -The symbol value, in the radix selected by options (see below), or -hexadecimal by default. -.IP "\(bu" 4 -The symbol type. At least the following types are used; others are, as -well, depending on the object file format. If lowercase, the symbol is -local; if uppercase, the symbol is global (external). -.RS 4 -.ie n .IP """A""" 4 -.el .IP "\f(CWA\fR" 4 -.IX Item "A" -The symbol's value is absolute, and will not be changed by further -linking. -.ie n .IP """B""" 4 -.el .IP "\f(CWB\fR" 4 -.IX Item "B" -The symbol is in the uninitialized data section (known as \s-1BSS\s0). -.ie n .IP """C""" 4 -.el .IP "\f(CWC\fR" 4 -.IX Item "C" -The symbol is common. Common symbols are uninitialized data. When -linking, multiple common symbols may appear with the same name. If the -symbol is defined anywhere, the common symbols are treated as undefined -references. -.ie n .IP """D""" 4 -.el .IP "\f(CWD\fR" 4 -.IX Item "D" -The symbol is in the initialized data section. -.ie n .IP """G""" 4 -.el .IP "\f(CWG\fR" 4 -.IX Item "G" -The symbol is in an initialized data section for small objects. Some -object file formats permit more efficient access to small data objects, -such as a global int variable as opposed to a large global array. -.ie n .IP """I""" 4 -.el .IP "\f(CWI\fR" 4 -.IX Item "I" -The symbol is an indirect reference to another symbol. This is a \s-1GNU\s0 -extension to the a.out object file format which is rarely used. -.ie n .IP """N""" 4 -.el .IP "\f(CWN\fR" 4 -.IX Item "N" -The symbol is a debugging symbol. -.ie n .IP """R""" 4 -.el .IP "\f(CWR\fR" 4 -.IX Item "R" -The symbol is in a read only data section. -.ie n .IP """S""" 4 -.el .IP "\f(CWS\fR" 4 -.IX Item "S" -The symbol is in an uninitialized data section for small objects. -.ie n .IP """T""" 4 -.el .IP "\f(CWT\fR" 4 -.IX Item "T" -The symbol is in the text (code) section. -.ie n .IP """U""" 4 -.el .IP "\f(CWU\fR" 4 -.IX Item "U" -The symbol is undefined. -.ie n .IP """V""" 4 -.el .IP "\f(CWV\fR" 4 -.IX Item "V" -The symbol is a weak object. When a weak defined symbol is linked with -a normal defined symbol, the normal defined symbol is used with no error. -When a weak undefined symbol is linked and the symbol is not defined, -the value of the weak symbol becomes zero with no error. -.ie n .IP """W""" 4 -.el .IP "\f(CWW\fR" 4 -.IX Item "W" -The symbol is a weak symbol that has not been specifically tagged as a -weak object symbol. When a weak defined symbol is linked with a normal -defined symbol, the normal defined symbol is used with no error. -When a weak undefined symbol is linked and the symbol is not defined, -the value of the symbol is determined in a system-specific manner without -error. On some systems, uppercase indicates that a default value has been -specified. -.ie n .IP """\-""" 4 -.el .IP "\f(CW\-\fR" 4 -.IX Item "-" -The symbol is a stabs symbol in an a.out object file. In this case, the -next values printed are the stabs other field, the stabs desc field, and -the stab type. Stabs symbols are used to hold debugging information. -.ie n .IP """?""" 4 -.el .IP "\f(CW?\fR" 4 -.IX Item "?" -The symbol type is unknown, or object file format specific. -.RE -.RS 4 -.RE -.IP "\(bu" 4 -The symbol name. -.SH "OPTIONS" -.IX Header "OPTIONS" -The long and short forms of options, shown here as alternatives, are -equivalent. -.IP "\fB\-A\fR" 4 -.IX Item "-A" -.PD 0 -.IP "\fB\-o\fR" 4 -.IX Item "-o" -.IP "\fB\-\-print\-file\-name\fR" 4 -.IX Item "--print-file-name" -.PD -Precede each symbol by the name of the input file (or archive member) -in which it was found, rather than identifying the input file once only, -before all of its symbols. -.IP "\fB\-a\fR" 4 -.IX Item "-a" -.PD 0 -.IP "\fB\-\-debug\-syms\fR" 4 -.IX Item "--debug-syms" -.PD -Display all symbols, even debugger-only symbols; normally these are not -listed. -.IP "\fB\-B\fR" 4 -.IX Item "-B" -The same as \fB\-\-format=bsd\fR (for compatibility with the \s-1MIPS\s0 \fBnm\fR). -.IP "\fB\-C\fR" 4 -.IX Item "-C" -.PD 0 -.IP "\fB\-\-demangle[=\fR\fIstyle\fR\fB]\fR" 4 -.IX Item "--demangle[=style]" -.PD -Decode (\fIdemangle\fR) low-level symbol names into user-level names. -Besides removing any initial underscore prepended by the system, this -makes \*(C+ function names readable. Different compilers have different -mangling styles. The optional demangling style argument can be used to -choose an appropriate demangling style for your compiler. -.IP "\fB\-\-no\-demangle\fR" 4 -.IX Item "--no-demangle" -Do not demangle low-level symbol names. This is the default. -.IP "\fB\-D\fR" 4 -.IX Item "-D" -.PD 0 -.IP "\fB\-\-dynamic\fR" 4 -.IX Item "--dynamic" -.PD -Display the dynamic symbols rather than the normal symbols. This is -only meaningful for dynamic objects, such as certain types of shared -libraries. -.IP "\fB\-f\fR \fIformat\fR" 4 -.IX Item "-f format" -.PD 0 -.IP "\fB\-\-format=\fR\fIformat\fR" 4 -.IX Item "--format=format" -.PD -Use the output format \fIformat\fR, which can be \f(CW\*(C`bsd\*(C'\fR, -\&\f(CW\*(C`sysv\*(C'\fR, or \f(CW\*(C`posix\*(C'\fR. The default is \f(CW\*(C`bsd\*(C'\fR. -Only the first character of \fIformat\fR is significant; it can be -either upper or lower case. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-\-extern\-only\fR" 4 -.IX Item "--extern-only" -.PD -Display only external symbols. -.IP "\fB\-l\fR" 4 -.IX Item "-l" -.PD 0 -.IP "\fB\-\-line\-numbers\fR" 4 -.IX Item "--line-numbers" -.PD -For each symbol, use debugging information to try to find a filename and -line number. For a defined symbol, look for the line number of the -address of the symbol. For an undefined symbol, look for the line -number of a relocation entry which refers to the symbol. If line number -information can be found, print it after the other symbol information. -.IP "\fB\-n\fR" 4 -.IX Item "-n" -.PD 0 -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.IP "\fB\-\-numeric\-sort\fR" 4 -.IX Item "--numeric-sort" -.PD -Sort symbols numerically by their addresses, rather than alphabetically -by their names. -.IP "\fB\-p\fR" 4 -.IX Item "-p" -.PD 0 -.IP "\fB\-\-no\-sort\fR" 4 -.IX Item "--no-sort" -.PD -Do not bother to sort the symbols in any order; print them in the order -encountered. -.IP "\fB\-P\fR" 4 -.IX Item "-P" -.PD 0 -.IP "\fB\-\-portability\fR" 4 -.IX Item "--portability" -.PD -Use the \s-1POSIX\s0.2 standard output format instead of the default format. -Equivalent to \fB\-f posix\fR. -.IP "\fB\-S\fR" 4 -.IX Item "-S" -.PD 0 -.IP "\fB\-\-print\-size\fR" 4 -.IX Item "--print-size" -.PD -Print size, not the value, of defined symbols for the \f(CW\*(C`bsd\*(C'\fR output format. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-print\-armap\fR" 4 -.IX Item "--print-armap" -.PD -When listing symbols from archive members, include the index: a mapping -(stored in the archive by \fBar\fR or \fBranlib\fR) of which modules -contain definitions for which names. -.IP "\fB\-r\fR" 4 -.IX Item "-r" -.PD 0 -.IP "\fB\-\-reverse\-sort\fR" 4 -.IX Item "--reverse-sort" -.PD -Reverse the order of the sort (whether numeric or alphabetic); let the -last come first. -.IP "\fB\-\-size\-sort\fR" 4 -.IX Item "--size-sort" -Sort symbols by size. The size is computed as the difference between -the value of the symbol and the value of the symbol with the next higher -value. If the \f(CW\*(C`bsd\*(C'\fR output format is used the size of the symbol -is printed, rather than the value, and \fB\-S\fR must be used in order -both size and value to be printed. -.IP "\fB\-\-special\-syms\fR" 4 -.IX Item "--special-syms" -Display symbols which have a target-specific special meaning. These -symbols are usually used by the target for some special processing and -are not normally helpful when included included in the normal symbol -lists. For example for \s-1ARM\s0 targets this option would skip the mapping -symbols used to mark transitions between \s-1ARM\s0 code, \s-1THUMB\s0 code and -data. -.IP "\fB\-t\fR \fIradix\fR" 4 -.IX Item "-t radix" -.PD 0 -.IP "\fB\-\-radix=\fR\fIradix\fR" 4 -.IX Item "--radix=radix" -.PD -Use \fIradix\fR as the radix for printing the symbol values. It must be -\&\fBd\fR for decimal, \fBo\fR for octal, or \fBx\fR for hexadecimal. -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -Specify an object code format other than your system's default format. -.IP "\fB\-u\fR" 4 -.IX Item "-u" -.PD 0 -.IP "\fB\-\-undefined\-only\fR" 4 -.IX Item "--undefined-only" -.PD -Display only undefined symbols (those external to each object file). -.IP "\fB\-\-defined\-only\fR" 4 -.IX Item "--defined-only" -Display only defined symbols for each object file. -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Show the version number of \fBnm\fR and exit. -.IP "\fB\-X\fR" 4 -.IX Item "-X" -This option is ignored for compatibility with the \s-1AIX\s0 version of -\&\fBnm\fR. It takes one parameter which must be the string -\&\fB32_64\fR. The default mode of \s-1AIX\s0 \fBnm\fR corresponds -to \fB\-X 32\fR, which is not supported by \s-1GNU\s0 \fBnm\fR. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Show a summary of the options to \fBnm\fR and exit. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIar\fR\|(1), \fIobjdump\fR\|(1), \fIranlib\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/gnu/usr.bin/binutils/ranlib/Makefile.depend b/gnu/usr.bin/binutils/ranlib/Makefile.depend deleted file mode 100644 index 9a5a4f99aa50..000000000000 --- a/gnu/usr.bin/binutils/ranlib/Makefile.depend +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DIRDEPS = \ - gnu/usr.bin/binutils/libbfd \ - gnu/usr.bin/binutils/libbinutils \ - gnu/usr.bin/binutils/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/binutils/readelf/Makefile b/gnu/usr.bin/binutils/readelf/Makefile deleted file mode 100644 index d90c3bcc9cc9..000000000000 --- a/gnu/usr.bin/binutils/readelf/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# $FreeBSD$ - -.include "../Makefile.inc0" - -.PATH: ${SRCDIR}/binutils ${SRCDIR}/binutils/doc - -# No a.out vs. ELF version so don't install in /usr/libexec/elf -BINDIR=/usr/bin - -PROG= readelf -SRCS= ${PROG}.c -CFLAGS+= -D_GNU_SOURCE -CFLAGS+= -I${.CURDIR}/${RELTOP}/libbinutils -I${SRCDIR}/binutils - -DPADD= ${RELTOP}/libbinutils/libbinutils.a -DPADD+= ${RELTOP}/libbfd/libbfd.a -DPADD+= ${RELTOP}/libiberty/libiberty.a -LDADD= ${DPADD} - -.include diff --git a/gnu/usr.bin/binutils/readelf/Makefile.depend b/gnu/usr.bin/binutils/readelf/Makefile.depend deleted file mode 100644 index b58c9bda263a..000000000000 --- a/gnu/usr.bin/binutils/readelf/Makefile.depend +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/binutils/libbfd \ - gnu/usr.bin/binutils/libbinutils \ - gnu/usr.bin/binutils/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/binutils/readelf/readelf.1 b/gnu/usr.bin/binutils/readelf/readelf.1 deleted file mode 100644 index e246d2ce2884..000000000000 --- a/gnu/usr.bin/binutils/readelf/readelf.1 +++ /dev/null @@ -1,377 +0,0 @@ -.\" $FreeBSD$ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "READELF 1" -.TH READELF 1 "2010-10-30" "binutils-2.17.50" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -readelf \- Displays information about ELF files. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -readelf [\fB\-a\fR|\fB\-\-all\fR] - [\fB\-h\fR|\fB\-\-file\-header\fR] - [\fB\-l\fR|\fB\-\-program\-headers\fR|\fB\-\-segments\fR] - [\fB\-S\fR|\fB\-\-section\-headers\fR|\fB\-\-sections\fR] - [\fB\-g\fR|\fB\-\-section\-groups\fR] - [\fB\-t\fR|\fB\-\-section\-details\fR] - [\fB\-e\fR|\fB\-\-headers\fR] - [\fB\-s\fR|\fB\-\-syms\fR|\fB\-\-symbols\fR] - [\fB\-n\fR|\fB\-\-notes\fR] - [\fB\-r\fR|\fB\-\-relocs\fR] - [\fB\-u\fR|\fB\-\-unwind\fR] - [\fB\-d\fR|\fB\-\-dynamic\fR] - [\fB\-V\fR|\fB\-\-version\-info\fR] - [\fB\-A\fR|\fB\-\-arch\-specific\fR] - [\fB\-D\fR|\fB\-\-use\-dynamic\fR] - [\fB\-x\fR |\fB\-\-hex\-dump=\fR] - [\fB\-w[liaprmfFsoR]\fR| - \fB\-\-debug\-dump\fR[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges]] - [\fB\-I\fR|\fB\-histogram\fR] - [\fB\-v\fR|\fB\-\-version\fR] - [\fB\-W\fR|\fB\-\-wide\fR] - [\fB\-H\fR|\fB\-\-help\fR] - \fIelffile\fR... -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\fBreadelf\fR displays information about one or more \s-1ELF\s0 format object -files. The options control what particular information to display. -.PP -\&\fIelffile\fR... are the object files to be examined. 32\-bit and -64\-bit \s-1ELF\s0 files are supported, as are archives containing \s-1ELF\s0 files. -.PP -This program performs a similar function to \fBobjdump\fR but it -goes into more detail and it exists independently of the \s-1BFD\s0 -library, so if there is a bug in \s-1BFD\s0 then readelf will not be -affected. -.SH "OPTIONS" -.IX Header "OPTIONS" -The long and short forms of options, shown here as alternatives, are -equivalent. At least one option besides \fB\-v\fR or \fB\-H\fR must be -given. -.IP "\fB\-a\fR" 4 -.IX Item "-a" -.PD 0 -.IP "\fB\-\-all\fR" 4 -.IX Item "--all" -.PD -Equivalent to specifying \fB\-\-file\-header\fR, -\&\fB\-\-program\-headers\fR, \fB\-\-sections\fR, \fB\-\-symbols\fR, -\&\fB\-\-relocs\fR, \fB\-\-dynamic\fR, \fB\-\-notes\fR and -\&\fB\-\-version\-info\fR. -.IP "\fB\-h\fR" 4 -.IX Item "-h" -.PD 0 -.IP "\fB\-\-file\-header\fR" 4 -.IX Item "--file-header" -.PD -Displays the information contained in the \s-1ELF\s0 header at the start of the -file. -.IP "\fB\-l\fR" 4 -.IX Item "-l" -.PD 0 -.IP "\fB\-\-program\-headers\fR" 4 -.IX Item "--program-headers" -.IP "\fB\-\-segments\fR" 4 -.IX Item "--segments" -.PD -Displays the information contained in the file's segment headers, if it -has any. -.IP "\fB\-S\fR" 4 -.IX Item "-S" -.PD 0 -.IP "\fB\-\-sections\fR" 4 -.IX Item "--sections" -.IP "\fB\-\-section\-headers\fR" 4 -.IX Item "--section-headers" -.PD -Displays the information contained in the file's section headers, if it -has any. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-\-section\-groups\fR" 4 -.IX Item "--section-groups" -.PD -Displays the information contained in the file's section groups, if it -has any. -.IP "\fB\-t\fR" 4 -.IX Item "-t" -.PD 0 -.IP "\fB\-\-section\-details\fR" 4 -.IX Item "--section-details" -.PD -Displays the detailed section information. Implies \fB\-S\fR. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-symbols\fR" 4 -.IX Item "--symbols" -.IP "\fB\-\-syms\fR" 4 -.IX Item "--syms" -.PD -Displays the entries in symbol table section of the file, if it has one. -.IP "\fB\-e\fR" 4 -.IX Item "-e" -.PD 0 -.IP "\fB\-\-headers\fR" 4 -.IX Item "--headers" -.PD -Display all the headers in the file. Equivalent to \fB\-h \-l \-S\fR. -.IP "\fB\-n\fR" 4 -.IX Item "-n" -.PD 0 -.IP "\fB\-\-notes\fR" 4 -.IX Item "--notes" -.PD -Displays the contents of the \s-1NOTE\s0 segments and/or sections, if any. -.IP "\fB\-r\fR" 4 -.IX Item "-r" -.PD 0 -.IP "\fB\-\-relocs\fR" 4 -.IX Item "--relocs" -.PD -Displays the contents of the file's relocation section, if it has one. -.IP "\fB\-u\fR" 4 -.IX Item "-u" -.PD 0 -.IP "\fB\-\-unwind\fR" 4 -.IX Item "--unwind" -.PD -Displays the contents of the file's unwind section, if it has one. Only -the unwind sections for \s-1IA64\s0 \s-1ELF\s0 files are currently supported. -.IP "\fB\-d\fR" 4 -.IX Item "-d" -.PD 0 -.IP "\fB\-\-dynamic\fR" 4 -.IX Item "--dynamic" -.PD -Displays the contents of the file's dynamic section, if it has one. -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\-info\fR" 4 -.IX Item "--version-info" -.PD -Displays the contents of the version sections in the file, it they -exist. -.IP "\fB\-A\fR" 4 -.IX Item "-A" -.PD 0 -.IP "\fB\-\-arch\-specific\fR" 4 -.IX Item "--arch-specific" -.PD -Displays architecture-specific information in the file, if there -is any. -.IP "\fB\-D\fR" 4 -.IX Item "-D" -.PD 0 -.IP "\fB\-\-use\-dynamic\fR" 4 -.IX Item "--use-dynamic" -.PD -When displaying symbols, this option makes \fBreadelf\fR use the -symbol table in the file's dynamic section, rather than the one in the -symbols section. -.IP "\fB\-x \fR" 4 -.IX Item "-x " -.PD 0 -.IP "\fB\-\-hex\-dump=\fR" 4 -.IX Item "--hex-dump=" -.PD -Displays the contents of the indicated section as a hexadecimal dump. -A number identifies a particular section by index in the section table; -any other string identifies all sections with that name in the object file. -.IP "\fB\-w[liaprmfFsoR]\fR" 4 -.IX Item "-w[liaprmfFsoR]" -.PD 0 -.IP "\fB\-\-debug\-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges]\fR" 4 -.IX Item "--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]" -.PD -Displays the contents of the debug sections in the file, if any are -present. If one of the optional letters or words follows the switch -then only data found in those specific sections will be dumped. -.IP "\fB\-I\fR" 4 -.IX Item "-I" -.PD 0 -.IP "\fB\-\-histogram\fR" 4 -.IX Item "--histogram" -.PD -Display a histogram of bucket list lengths when displaying the contents -of the symbol tables. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Display the version number of readelf. -.IP "\fB\-W\fR" 4 -.IX Item "-W" -.PD 0 -.IP "\fB\-\-wide\fR" 4 -.IX Item "--wide" -.PD -Don't break output lines to fit into 80 columns. By default -\&\fBreadelf\fR breaks section header and segment listing lines for -64\-bit \s-1ELF\s0 files, so that they fit into 80 columns. This option causes -\&\fBreadelf\fR to print each section header resp. each segment one a -single line, which is far more readable on terminals wider than 80 columns. -.IP "\fB\-H\fR" 4 -.IX Item "-H" -.PD 0 -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -.PD -Display the command line options understood by \fBreadelf\fR. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIobjdump\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/gnu/usr.bin/binutils/size/Makefile b/gnu/usr.bin/binutils/size/Makefile deleted file mode 100644 index c5c19c1908e9..000000000000 --- a/gnu/usr.bin/binutils/size/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -.include "../Makefile.inc0" - -.PATH: ${SRCDIR}/binutils ${SRCDIR}/binutils/doc - -PROG= size -SRCS= size.c -CFLAGS+= -D_GNU_SOURCE -CFLAGS+= -I${.CURDIR}/${RELTOP}/libbinutils -CFLAGS+= -I${SRCDIR}/binutils -DPADD= ${RELTOP}/libbinutils/libbinutils.a -DPADD+= ${RELTOP}/libbfd/libbfd.a -DPADD+= ${RELTOP}/libiberty/libiberty.a -LDADD= ${DPADD} - -.include diff --git a/gnu/usr.bin/binutils/size/Makefile.depend b/gnu/usr.bin/binutils/size/Makefile.depend deleted file mode 100644 index b58c9bda263a..000000000000 --- a/gnu/usr.bin/binutils/size/Makefile.depend +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/binutils/libbfd \ - gnu/usr.bin/binutils/libbinutils \ - gnu/usr.bin/binutils/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/binutils/size/size.1 b/gnu/usr.bin/binutils/size/size.1 deleted file mode 100644 index 7064762186ff..000000000000 --- a/gnu/usr.bin/binutils/size/size.1 +++ /dev/null @@ -1,263 +0,0 @@ -.\" $FreeBSD$ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "SIZE 1" -.TH SIZE 1 "2010-10-30" "binutils-2.17.50" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -size \- list section sizes and total size -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -size [\fB\-A\fR|\fB\-B\fR|\fB\-\-format=\fR\fIcompatibility\fR] - [\fB\-\-help\fR] - [\fB\-d\fR|\fB\-o\fR|\fB\-x\fR|\fB\-\-radix=\fR\fInumber\fR] - [\fB\-t\fR|\fB\-\-totals\fR] - [\fB\-\-target=\fR\fIbfdname\fR] [\fB\-V\fR|\fB\-\-version\fR] - [\fIobjfile\fR...] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -The \s-1GNU\s0 \fBsize\fR utility lists the section sizes\-\-\-and the total -size\-\-\-for each of the object or archive files \fIobjfile\fR in its -argument list. By default, one line of output is generated for each -object file or each module in an archive. -.PP -\&\fIobjfile\fR... are the object files to be examined. -If none are specified, the file \f(CW\*(C`a.out\*(C'\fR will be used. -.SH "OPTIONS" -.IX Header "OPTIONS" -The command line options have the following meanings: -.IP "\fB\-A\fR" 4 -.IX Item "-A" -.PD 0 -.IP "\fB\-B\fR" 4 -.IX Item "-B" -.IP "\fB\-\-format=\fR\fIcompatibility\fR" 4 -.IX Item "--format=compatibility" -.PD -Using one of these options, you can choose whether the output from \s-1GNU\s0 -\&\fBsize\fR resembles output from System V \fBsize\fR (using \fB\-A\fR, -or \fB\-\-format=sysv\fR), or Berkeley \fBsize\fR (using \fB\-B\fR, or -\&\fB\-\-format=berkeley\fR). The default is the one-line format similar to -Berkeley's. -.Sp -Here is an example of the Berkeley (default) format of output from -\&\fBsize\fR: -.Sp -.Vb 4 -\& $ size \-\-format=Berkeley ranlib size -\& text data bss dec hex filename -\& 294880 81920 11592 388392 5ed28 ranlib -\& 294880 81920 11888 388688 5ee50 size -.Ve -.Sp -This is the same data, but displayed closer to System V conventions: -.Sp -.Vb 7 -\& $ size \-\-format=SysV ranlib size -\& ranlib : -\& section size addr -\& .text 294880 8192 -\& .data 81920 303104 -\& .bss 11592 385024 -\& Total 388392 -\& -\& -\& size : -\& section size addr -\& .text 294880 8192 -\& .data 81920 303104 -\& .bss 11888 385024 -\& Total 388688 -.Ve -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Show a summary of acceptable arguments and options. -.IP "\fB\-d\fR" 4 -.IX Item "-d" -.PD 0 -.IP "\fB\-o\fR" 4 -.IX Item "-o" -.IP "\fB\-x\fR" 4 -.IX Item "-x" -.IP "\fB\-\-radix=\fR\fInumber\fR" 4 -.IX Item "--radix=number" -.PD -Using one of these options, you can control whether the size of each -section is given in decimal (\fB\-d\fR, or \fB\-\-radix=10\fR); octal -(\fB\-o\fR, or \fB\-\-radix=8\fR); or hexadecimal (\fB\-x\fR, or -\&\fB\-\-radix=16\fR). In \fB\-\-radix=\fR\fInumber\fR, only the three -values (8, 10, 16) are supported. The total size is always given in two -radices; decimal and hexadecimal for \fB\-d\fR or \fB\-x\fR output, or -octal and hexadecimal if you're using \fB\-o\fR. -.IP "\fB\-t\fR" 4 -.IX Item "-t" -.PD 0 -.IP "\fB\-\-totals\fR" 4 -.IX Item "--totals" -.PD -Show totals of all objects listed (Berkeley format listing mode only). -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -Specify that the object-code format for \fIobjfile\fR is -\&\fIbfdname\fR. This option may not be necessary; \fBsize\fR can -automatically recognize many formats. -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Display the version number of \fBsize\fR. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIar\fR\|(1), \fIobjdump\fR\|(1), \fIreadelf\fR\|(1), and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/gnu/usr.bin/binutils/strings/Makefile b/gnu/usr.bin/binutils/strings/Makefile deleted file mode 100644 index a432d51ddf65..000000000000 --- a/gnu/usr.bin/binutils/strings/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -.include "../Makefile.inc0" - -.PATH: ${SRCDIR}/binutils ${SRCDIR}/binutils/doc - -PROG= strings -SRCS= strings.c -CFLAGS+= -D_GNU_SOURCE -CFLAGS+= -I${.CURDIR}/${RELTOP}/libbinutils -CFLAGS+= -I${SRCDIR}/binutils -DPADD= ${RELTOP}/libbinutils/libbinutils.a -DPADD+= ${RELTOP}/libbfd/libbfd.a -DPADD+= ${RELTOP}/libiberty/libiberty.a -LDADD= ${DPADD} - -.include diff --git a/gnu/usr.bin/binutils/strings/Makefile.depend b/gnu/usr.bin/binutils/strings/Makefile.depend deleted file mode 100644 index b58c9bda263a..000000000000 --- a/gnu/usr.bin/binutils/strings/Makefile.depend +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/binutils/libbfd \ - gnu/usr.bin/binutils/libbinutils \ - gnu/usr.bin/binutils/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/binutils/strings/strings.1 b/gnu/usr.bin/binutils/strings/strings.1 deleted file mode 100644 index 075e3a5d8a58..000000000000 --- a/gnu/usr.bin/binutils/strings/strings.1 +++ /dev/null @@ -1,254 +0,0 @@ -.\" $FreeBSD$ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "STRINGS 1" -.TH STRINGS 1 "2010-10-30" "binutils-2.17.50" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -strings \- print the strings of printable characters in files. -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -strings [\fB\-afov\fR] [\fB\-\fR\fImin-len\fR] - [\fB\-n\fR \fImin-len\fR] [\fB\-\-bytes=\fR\fImin-len\fR] - [\fB\-t\fR \fIradix\fR] [\fB\-\-radix=\fR\fIradix\fR] - [\fB\-e\fR \fIencoding\fR] [\fB\-\-encoding=\fR\fIencoding\fR] - [\fB\-\fR] [\fB\-\-all\fR] [\fB\-\-print\-file\-name\fR] - [\fB\-T\fR \fIbfdname\fR] [\fB\-\-target=\fR\fIbfdname\fR] - [\fB\-\-help\fR] [\fB\-\-version\fR] \fIfile\fR... -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -For each \fIfile\fR given, \s-1GNU\s0 \fBstrings\fR prints the printable -character sequences that are at least 4 characters long (or the number -given with the options below) and are followed by an unprintable -character. By default, it only prints the strings from the initialized -and loaded sections of object files; for other types of files, it prints -the strings from the whole file. -.PP -\&\fBstrings\fR is mainly useful for determining the contents of non-text -files. -.SH "OPTIONS" -.IX Header "OPTIONS" -.IP "\fB\-a\fR" 4 -.IX Item "-a" -.PD 0 -.IP "\fB\-\-all\fR" 4 -.IX Item "--all" -.IP "\fB\-\fR" 4 -.IX Item "-" -.PD -Do not scan only the initialized and loaded sections of object files; -scan the whole files. -.IP "\fB\-f\fR" 4 -.IX Item "-f" -.PD 0 -.IP "\fB\-\-print\-file\-name\fR" 4 -.IX Item "--print-file-name" -.PD -Print the name of the file before each string. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Print a summary of the program usage on the standard output and exit. -.IP "\fB\-\fR\fImin-len\fR" 4 -.IX Item "-min-len" -.PD 0 -.IP "\fB\-n\fR \fImin-len\fR" 4 -.IX Item "-n min-len" -.IP "\fB\-\-bytes=\fR\fImin-len\fR" 4 -.IX Item "--bytes=min-len" -.PD -Print sequences of characters that are at least \fImin-len\fR characters -long, instead of the default 4. -.IP "\fB\-o\fR" 4 -.IX Item "-o" -Like \fB\-t o\fR. Some other versions of \fBstrings\fR have \fB\-o\fR -act like \fB\-t d\fR instead. Since we can not be compatible with both -ways, we simply chose one. -.IP "\fB\-t\fR \fIradix\fR" 4 -.IX Item "-t radix" -.PD 0 -.IP "\fB\-\-radix=\fR\fIradix\fR" 4 -.IX Item "--radix=radix" -.PD -Print the offset within the file before each string. The single -character argument specifies the radix of the offset\-\-\-\fBo\fR for -octal, \fBx\fR for hexadecimal, or \fBd\fR for decimal. -.IP "\fB\-e\fR \fIencoding\fR" 4 -.IX Item "-e encoding" -.PD 0 -.IP "\fB\-\-encoding=\fR\fIencoding\fR" 4 -.IX Item "--encoding=encoding" -.PD -Select the character encoding of the strings that are to be found. -Possible values for \fIencoding\fR are: \fBs\fR = single\-7\-bit\-byte -characters (\s-1ASCII\s0, \s-1ISO\s0 8859, etc., default), \fBS\fR = -single\-8\-bit\-byte characters, \fBb\fR = 16\-bit bigendian, \fBl\fR = -16\-bit littleendian, \fBB\fR = 32\-bit bigendian, \fBL\fR = 32\-bit -littleendian. Useful for finding wide character strings. -.IP "\fB\-T\fR \fIbfdname\fR" 4 -.IX Item "-T bfdname" -.PD 0 -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -.PD -Specify an object code format other than your system's default format. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Print the program version number on the standard output and exit. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIar\fR\|(1), \fInm\fR\|(1), \fIobjdump\fR\|(1), \fIranlib\fR\|(1), \fIreadelf\fR\|(1) -and the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/gnu/usr.bin/binutils/strip/Makefile b/gnu/usr.bin/binutils/strip/Makefile deleted file mode 100644 index d3cf8c454cdc..000000000000 --- a/gnu/usr.bin/binutils/strip/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $FreeBSD$ - -.include "../Makefile.inc0" - -.PATH: ${SRCDIR}/binutils ${SRCDIR}/binutils/doc - -PROG= strip -SRCS= objcopy.c is-strip.c -CFLAGS+= -D_GNU_SOURCE -CFLAGS+= -I${.CURDIR}/${RELTOP}/libbinutils -CFLAGS+= -I${SRCDIR}/binutils -I${SRCDIR}/bfd -DPADD= ${RELTOP}/libbinutils/libbinutils.a -DPADD+= ${RELTOP}/libbfd/libbfd.a -DPADD+= ${RELTOP}/libiberty/libiberty.a -LDADD= ${DPADD} -INSTALLFLAGS= -S - -.include diff --git a/gnu/usr.bin/binutils/strip/Makefile.depend b/gnu/usr.bin/binutils/strip/Makefile.depend deleted file mode 100644 index b58c9bda263a..000000000000 --- a/gnu/usr.bin/binutils/strip/Makefile.depend +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/binutils/libbfd \ - gnu/usr.bin/binutils/libbinutils \ - gnu/usr.bin/binutils/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/binutils/strip/strip.1 b/gnu/usr.bin/binutils/strip/strip.1 deleted file mode 100644 index 3f0d7a3e3db8..000000000000 --- a/gnu/usr.bin/binutils/strip/strip.1 +++ /dev/null @@ -1,392 +0,0 @@ -.\" $FreeBSD$ -.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "STRIP 1" -.TH STRIP 1 "2010-10-30" "binutils-2.17.50" "GNU Development Tools" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -strip \- Discard symbols from object files -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -strip [\fB\-F\fR \fIbfdname\fR |\fB\-\-target=\fR\fIbfdname\fR] - [\fB\-I\fR \fIbfdname\fR |\fB\-\-input\-target=\fR\fIbfdname\fR] - [\fB\-O\fR \fIbfdname\fR |\fB\-\-output\-target=\fR\fIbfdname\fR] - [\fB\-s\fR|\fB\-\-strip\-all\fR] - [\fB\-S\fR|\fB\-g\fR|\fB\-d\fR|\fB\-\-strip\-debug\fR] - [\fB\-K\fR \fIsymbolname\fR |\fB\-\-keep\-symbol=\fR\fIsymbolname\fR] - [\fB\-N\fR \fIsymbolname\fR |\fB\-\-strip\-symbol=\fR\fIsymbolname\fR] - [\fB\-w\fR|\fB\-\-wildcard\fR] - [\fB\-x\fR|\fB\-\-discard\-all\fR] [\fB\-X\fR |\fB\-\-discard\-locals\fR] - [\fB\-R\fR \fIsectionname\fR |\fB\-\-remove\-section=\fR\fIsectionname\fR] - [\fB\-o\fR \fIfile\fR] [\fB\-p\fR|\fB\-\-preserve\-dates\fR] - [\fB\-\-keep\-file\-symbols\fR] - [\fB\-\-only\-keep\-debug\fR] - [\fB\-v\fR |\fB\-\-verbose\fR] [\fB\-V\fR|\fB\-\-version\fR] - [\fB\-\-help\fR] [\fB\-\-info\fR] - \fIobjfile\fR... -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -\&\s-1GNU\s0 \fBstrip\fR discards all symbols from object files -\&\fIobjfile\fR. The list of object files may include archives. -At least one object file must be given. -.PP -\&\fBstrip\fR modifies the files named in its argument, -rather than writing modified copies under different names. -.SH "OPTIONS" -.IX Header "OPTIONS" -.IP "\fB\-F\fR \fIbfdname\fR" 4 -.IX Item "-F bfdname" -.PD 0 -.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 -.IX Item "--target=bfdname" -.PD -Treat the original \fIobjfile\fR as a file with the object -code format \fIbfdname\fR, and rewrite it in the same format. -.IP "\fB\-\-help\fR" 4 -.IX Item "--help" -Show a summary of the options to \fBstrip\fR and exit. -.IP "\fB\-\-info\fR" 4 -.IX Item "--info" -Display a list showing all architectures and object formats available. -.IP "\fB\-I\fR \fIbfdname\fR" 4 -.IX Item "-I bfdname" -.PD 0 -.IP "\fB\-\-input\-target=\fR\fIbfdname\fR" 4 -.IX Item "--input-target=bfdname" -.PD -Treat the original \fIobjfile\fR as a file with the object -code format \fIbfdname\fR. -.IP "\fB\-O\fR \fIbfdname\fR" 4 -.IX Item "-O bfdname" -.PD 0 -.IP "\fB\-\-output\-target=\fR\fIbfdname\fR" 4 -.IX Item "--output-target=bfdname" -.PD -Replace \fIobjfile\fR with a file in the output format \fIbfdname\fR. -.IP "\fB\-R\fR \fIsectionname\fR" 4 -.IX Item "-R sectionname" -.PD 0 -.IP "\fB\-\-remove\-section=\fR\fIsectionname\fR" 4 -.IX Item "--remove-section=sectionname" -.PD -Remove any section named \fIsectionname\fR from the output file. This -option may be given more than once. Note that using this option -inappropriately may make the output file unusable. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -.PD 0 -.IP "\fB\-\-strip\-all\fR" 4 -.IX Item "--strip-all" -.PD -Remove all symbols. -.IP "\fB\-g\fR" 4 -.IX Item "-g" -.PD 0 -.IP "\fB\-S\fR" 4 -.IX Item "-S" -.IP "\fB\-d\fR" 4 -.IX Item "-d" -.IP "\fB\-\-strip\-debug\fR" 4 -.IX Item "--strip-debug" -.PD -Remove debugging symbols only. -.IP "\fB\-\-strip\-unneeded\fR" 4 -.IX Item "--strip-unneeded" -Remove all symbols that are not needed for relocation processing. -.IP "\fB\-K\fR \fIsymbolname\fR" 4 -.IX Item "-K symbolname" -.PD 0 -.IP "\fB\-\-keep\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--keep-symbol=symbolname" -.PD -When stripping symbols, keep symbol \fIsymbolname\fR even if it would -normally be stripped. This option may be given more than once. -.IP "\fB\-N\fR \fIsymbolname\fR" 4 -.IX Item "-N symbolname" -.PD 0 -.IP "\fB\-\-strip\-symbol=\fR\fIsymbolname\fR" 4 -.IX Item "--strip-symbol=symbolname" -.PD -Remove symbol \fIsymbolname\fR from the source file. This option may be -given more than once, and may be combined with strip options other than -\&\fB\-K\fR. -.IP "\fB\-o\fR \fIfile\fR" 4 -.IX Item "-o file" -Put the stripped output in \fIfile\fR, rather than replacing the -existing file. When this argument is used, only one \fIobjfile\fR -argument may be specified. -.IP "\fB\-p\fR" 4 -.IX Item "-p" -.PD 0 -.IP "\fB\-\-preserve\-dates\fR" 4 -.IX Item "--preserve-dates" -.PD -Preserve the access and modification dates of the file. -.IP "\fB\-w\fR" 4 -.IX Item "-w" -.PD 0 -.IP "\fB\-\-wildcard\fR" 4 -.IX Item "--wildcard" -.PD -Permit regular expressions in \fIsymbolname\fRs used in other command -line options. The question mark (?), asterisk (*), backslash (\e) and -square brackets ([]) operators can be used anywhere in the symbol -name. If the first character of the symbol name is the exclamation -point (!) then the sense of the switch is reversed for that symbol. -For example: -.Sp -.Vb 1 -\& \-w \-K !foo \-K fo* -.Ve -.Sp -would cause strip to only keep symbols that start with the letters -\&\*(L"fo\*(R", but to discard the symbol \*(L"foo\*(R". -.IP "\fB\-x\fR" 4 -.IX Item "-x" -.PD 0 -.IP "\fB\-\-discard\-all\fR" 4 -.IX Item "--discard-all" -.PD -Remove non-global symbols. -.IP "\fB\-X\fR" 4 -.IX Item "-X" -.PD 0 -.IP "\fB\-\-discard\-locals\fR" 4 -.IX Item "--discard-locals" -.PD -Remove compiler-generated local symbols. -(These usually start with \fBL\fR or \fB.\fR.) -.IP "\fB\-\-keep\-file\-symbols\fR" 4 -.IX Item "--keep-file-symbols" -When stripping a file, perhaps with \fB\-\-strip\-debug\fR or -\&\fB\-\-strip\-unneeded\fR, retain any symbols specifying source file names, -which would otherwise get stripped. -.IP "\fB\-\-only\-keep\-debug\fR" 4 -.IX Item "--only-keep-debug" -Strip a file, removing contents of any sections that would not be -stripped by \fB\-\-strip\-debug\fR and leaving the debugging sections -intact. In \s-1ELF\s0 files, this preserves all note sections in the output. -.Sp -The intention is that this option will be used in conjunction with -\&\fB\-\-add\-gnu\-debuglink\fR to create a two part executable. One a -stripped binary which will occupy less space in \s-1RAM\s0 and in a -distribution and the second a debugging information file which is only -needed if debugging abilities are required. The suggested procedure -to create these files is as follows: -.RS 4 -.IP "1." 4 -.IX Item "1." -\&\f(CW\*(C`foo\*(C'\fR then... -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -create a file containing the debugging info. -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -stripped executable. -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -to add a link to the debugging info into the stripped executable. -.RE -.RS 4 -.Sp -Note \- the choice of \f(CW\*(C`.dbg\*(C'\fR as an extension for the debug info -file is arbitrary. Also the \f(CW\*(C`\-\-only\-keep\-debug\*(C'\fR step is -optional. You could instead do this: -.IP "1." 4 -.IX Item "1." -.PD 0 -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.ie n .IP "1." 4 -.el .IP "1." 4 -.IX Item "1." -.RE -.RS 4 -.PD -.Sp -ie the file pointed to by the \fB\-\-add\-gnu\-debuglink\fR can be the -full executable. It does not have to be a file created by the -\&\fB\-\-only\-keep\-debug\fR switch. -.Sp -Note \- this switch is only intended for use on fully linked files. It -does not make sense to use it on object files where the debugging -information may be incomplete. Besides the gnu_debuglink feature -currently only supports the presence of one filename containing -debugging information, not multiple filenames on a one-per-object-file -basis. -.RE -.IP "\fB\-V\fR" 4 -.IX Item "-V" -.PD 0 -.IP "\fB\-\-version\fR" 4 -.IX Item "--version" -.PD -Show the version number for \fBstrip\fR. -.IP "\fB\-v\fR" 4 -.IX Item "-v" -.PD 0 -.IP "\fB\-\-verbose\fR" 4 -.IX Item "--verbose" -.PD -Verbose output: list all object files modified. In the case of -archives, \fBstrip \-v\fR lists all members of the archive. -.IP "\fB@\fR\fIfile\fR" 4 -.IX Item "@file" -Read command-line options from \fIfile\fR. The options read are -inserted in place of the original @\fIfile\fR option. If \fIfile\fR -does not exist, or cannot be read, then the option will be treated -literally, and not removed. -.Sp -Options in \fIfile\fR are separated by whitespace. A whitespace -character may be included in an option by surrounding the entire -option in either single or double quotes. Any character (including a -backslash) may be included by prefixing the character to be included -with a backslash. The \fIfile\fR may itself contain additional -@\fIfile\fR options; any such options will be processed recursively. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -the Info entries for \fIbinutils\fR. -.SH "COPYRIGHT" -.IX Header "COPYRIGHT" -Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. -.PP -Permission is granted to copy, distribute and/or modify this document -under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1 -or any later version published by the Free Software Foundation; -with no Invariant Sections, with no Front-Cover Texts, and with no -Back-Cover Texts. A copy of the license is included in the -section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". diff --git a/gnu/usr.bin/cc/Makefile b/gnu/usr.bin/cc/Makefile index 65dc0871f3ee..41349cfa1b9b 100644 --- a/gnu/usr.bin/cc/Makefile +++ b/gnu/usr.bin/cc/Makefile @@ -13,9 +13,6 @@ SUBDIR+= cpp .if ${MK_CXX} != "no" SUBDIR+= cc1plus c++ -.if ${MK_ELFTOOLCHAIN_TOOLS} == "no" -SUBDIR+= c++filt -.endif .endif .if ${MK_GCOV} != "no" diff --git a/gnu/usr.bin/cc/c++filt/Makefile b/gnu/usr.bin/cc/c++filt/Makefile deleted file mode 100644 index b9daaf0f1287..000000000000 --- a/gnu/usr.bin/cc/c++filt/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ - -MAN= -.include - -.include "../Makefile.inc" -.include "../Makefile.fe" - -.PATH: ${GCCLIB}/libiberty - -PROG= c++filt -SRCS= cp-demangle.c - -CFLAGS+= -DSTANDALONE_DEMANGLER -DVERSION=\"$(GCC_VERSION)\" - -DPADD= ${LIBIBERTY} -LDADD= ${LIBIBERTY} - -.include diff --git a/gnu/usr.bin/cc/c++filt/Makefile.depend b/gnu/usr.bin/cc/c++filt/Makefile.depend deleted file mode 100644 index 0f7485ddb163..000000000000 --- a/gnu/usr.bin/cc/c++filt/Makefile.depend +++ /dev/null @@ -1,23 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/cc/cc_tools \ - gnu/usr.bin/cc/libiberty \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libc_nonshared \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index cc0ccf67cf3e..82c43e35b1b6 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1025,9 +1025,6 @@ OLD_DIRS+=usr/include/fs/cuse .if ${MK_CXX} == no OLD_FILES+=usr/bin/CC OLD_FILES+=usr/bin/c++ -.if ${MK_ELFTOOLCHAIN_TOOLS} == no -OLD_FILES+=usr/bin/c++filt -.endif OLD_FILES+=usr/bin/g++ OLD_FILES+=usr/libexec/cc1plus .endif @@ -1656,14 +1653,16 @@ OLD_FILES+=usr/bin/elfcopy OLD_FILES+=usr/share/man/man1/elfcopy.1.gz .endif -.if ${MK_ELFTOOLCHAIN_TOOLS} == no && ${MK_BINUTILS} == no +.if ${MK_ELFTOOLCHAIN_TOOLS} == no OLD_FILES+=usr/bin/addr2line +OLD_FILES+=usr/bin/c++filt OLD_FILES+=usr/bin/nm OLD_FILES+=usr/bin/readelf OLD_FILES+=usr/bin/size OLD_FILES+=usr/bin/strings OLD_FILES+=usr/bin/strip OLD_FILES+=usr/share/man/man1/addr2line.1.gz +OLD_FILES+=usr/share/man/man1/c++filt.1.gz OLD_FILES+=usr/share/man/man1/nm.1.gz OLD_FILES+=usr/share/man/man1/readelf.1.gz OLD_FILES+=usr/share/man/man1/size.1.gz @@ -1753,9 +1752,6 @@ OLD_FILES+=usr/share/man/man8/unstr.8.gz .endif .if ${MK_GCC} == no -.if ${MK_ELFTOOLCHAIN_TOOLS} == no -OLD_FILES+=usr/bin/c++filt -.endif OLD_FILES+=usr/bin/g++ OLD_FILES+=usr/bin/gcc OLD_FILES+=usr/bin/gcov diff --git a/tools/build/options/WITHOUT_BINUTILS b/tools/build/options/WITHOUT_BINUTILS index 014f4b3a8620..b68aa52c049e 100644 --- a/tools/build/options/WITHOUT_BINUTILS +++ b/tools/build/options/WITHOUT_BINUTILS @@ -1,5 +1,4 @@ .\" $FreeBSD$ -Set to not build or install binutils (as, c++-filt, -ld, nm, objcopy, objdump, readelf, size and strip) as part +Set to not build or install binutils (as, ld, objcopy, and objdump ) as part of the normal system build. The resulting system cannot build programs from source. diff --git a/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS b/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS index 7871e86369d5..e30f48d3762e 100644 --- a/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS +++ b/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS @@ -1,5 +1,5 @@ .\" $FreeBSD$ -Set to use +Set to avoid building ELF Tool Chain tools .Xr addr2line 1 , .Xr c++filt 1 , .Xr nm 1 , @@ -7,5 +7,4 @@ Set to use .Xr size 1 , .Xr strings 1 , and -.Xr strip 1 -from GNU binutils instead of the ELF Tool Chain project. +.Xr strip 1 . From 5fad3f770bd6df9d51a480a9a6342d3cfbbd9d1c Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 5 Aug 2015 18:55:40 +0000 Subject: [PATCH 252/314] Remove empty directories left by r286332 Reported by: garga From fc8c85602972504f59bea085d089c5aa66fa1a0a Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 5 Aug 2015 19:05:12 +0000 Subject: [PATCH 253/314] Rationalize BSD license on sys/*/include/in_cksum.h Remove the advertising clause from the Regents of the University of California's license, per the letter dated July 22, 1999. Update clause numbering. --- sys/amd64/include/in_cksum.h | 2 +- sys/arm64/include/in_cksum.h | 6 +----- sys/i386/include/in_cksum.h | 2 +- sys/mips/include/in_cksum.h | 2 +- sys/powerpc/include/in_cksum.h | 2 +- sys/sparc64/include/in_cksum.h | 2 +- 6 files changed, 6 insertions(+), 10 deletions(-) diff --git a/sys/amd64/include/in_cksum.h b/sys/amd64/include/in_cksum.h index 156035e8918b..d76b48a8863f 100644 --- a/sys/amd64/include/in_cksum.h +++ b/sys/amd64/include/in_cksum.h @@ -10,7 +10,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/arm64/include/in_cksum.h b/sys/arm64/include/in_cksum.h index 40524e4d145e..522ba005a0e4 100644 --- a/sys/arm64/include/in_cksum.h +++ b/sys/arm64/include/in_cksum.h @@ -10,11 +10,7 @@ * 2. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/i386/include/in_cksum.h b/sys/i386/include/in_cksum.h index 34d85be25a1f..8816f3c8ddea 100644 --- a/sys/i386/include/in_cksum.h +++ b/sys/i386/include/in_cksum.h @@ -10,7 +10,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/mips/include/in_cksum.h b/sys/mips/include/in_cksum.h index 633efa1ff21d..72edfba91041 100644 --- a/sys/mips/include/in_cksum.h +++ b/sys/mips/include/in_cksum.h @@ -10,7 +10,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/powerpc/include/in_cksum.h b/sys/powerpc/include/in_cksum.h index 4fe1b4023f7b..37bfb20034ae 100644 --- a/sys/powerpc/include/in_cksum.h +++ b/sys/powerpc/include/in_cksum.h @@ -10,7 +10,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/sys/sparc64/include/in_cksum.h b/sys/sparc64/include/in_cksum.h index d5d167f54a02..b13882e0820e 100644 --- a/sys/sparc64/include/in_cksum.h +++ b/sys/sparc64/include/in_cksum.h @@ -10,7 +10,7 @@ * 2. 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * From 711b0fa04520d6b16065d05c9102b825c42a8dfa Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 5 Aug 2015 19:32:35 +0000 Subject: [PATCH 254/314] Add TXOP enforce support to the AR9300 HAL. This is required for (more) correct TDMA support. Without it, the code tries to calculate the required guard interval based on the current rate, and since this is an 11n NIC and people try using 11n, it calls ath_hal_computetxtime() on an 11n rate which then panics. This doesn't fix TDMA slave mode on AR9300 - it just makes it have one less bug. Reported by: Berislav Purgar --- .../dev/ath/ath_hal/ar9300/ar9300_misc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c index e9caa4325ebe..6972200d68f0 100644 --- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c +++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c @@ -940,6 +940,13 @@ ar9300_get_capability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, return HAL_OK; } return HAL_EINVAL; + case HAL_CAP_ENFORCE_TXOP: + if (capability == 0) + return (HAL_OK); + if (capability != 1) + return (HAL_ENOTSUPP); + (*result) = !! (ahp->ah_misc_mode & AR_PCU_TXOP_TBTT_LIMIT_ENA); + return (HAL_OK); default: return ath_hal_getcapability(ah, type, capability, result); } @@ -1041,6 +1048,18 @@ ar9300_set_capability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, OS_REG_WRITE(ah, AR_DATABUF, ahp->rx_buf_size); return AH_TRUE; + case HAL_CAP_ENFORCE_TXOP: + if (capability != 1) + return AH_FALSE; + if (setting) { + ahp->ah_misc_mode |= AR_PCU_TXOP_TBTT_LIMIT_ENA; + OS_REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_TXOP_TBTT_LIMIT_ENA); + } else { + ahp->ah_misc_mode &= ~AR_PCU_TXOP_TBTT_LIMIT_ENA; + OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_TXOP_TBTT_LIMIT_ENA); + } + return AH_TRUE; + /* fall thru... */ default: return ath_hal_setcapability(ah, type, capability, setting, status); From d94b89b9157c0080139141d74885290a0e4b4167 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Wed, 5 Aug 2015 19:45:11 +0000 Subject: [PATCH 255/314] cxgbe(4): Update T5 and T4 firmwares bundled with the driver to 1.14.4.0. The changes in the firmwares since 1.11.27.0 are listed here (straight copy-paste from the "Release Notes.txt" accompanying the Chelsio Unified Wire 2.11.1.0 release on the website). 22.1. T5 Firmware +++++++++++++++++++++++++++++++++ Version : 1.14.4.0 Date : 08/05/2015 ================================================================================ FIXES ----- BASE: - Fixes a potential data path hang by properly programming PMTX congestion threshold settings. - Fixes a potential initialization error when accessing a configuration file stored on the flash. - Fixes a regression where SGE resources can be miss-sized if iWARP is disabled. ETH: - Fixes a timing issue that would prevent CR4 links from coming up with some switches. FOFCoE: - Defers fcoe linkdown mailbox command handling till LOGO is sent. - Updates vlan prio for all outstanding IOs during dcbx update. ENHANCEMENTS ------------ BASE: - Adds support for PAUSE OFF watchdog. - Reports devlog access information in PCIE_FW_PF register 7. ETH: - Enhances segmentation offload to include VxLAN and Geneve. - Adds PTP support. - Adds new interface to allow the driver to query the VI rss table base addresses. - Allows the driver to program the SGE ingrext contxt CongDrop field. OFLD: - Adds new interface for the driver to specify offloaded connections TCP snd and rcv scale factors. iSCSI: - Adds support for iscsi segmentatation offload (ISO). - Adds support for iscsi t10-dif offload. FOiSCSI: - Sets FORCE_BIT for cut through processing for FOiSCSI. FOFCoE: - Adds support for FCoE BB6. - Improves WRITE performance. ================================================================================ ================================================================================ Version : 1.13.32.0 Date : 03/25/2015 ================================================================================ FIXES ----- BASE: - Fixes FW_CAPS_CONFIG_CMD return value on error (was positive instead of negative) - Fixes FW_PARAMS_PARAM_DEV_FLOWC_BUFFIFO_SZ indication (was wrong on certain adapter configurations) - Fixes config file based PL_TIMEOUT register programming ETH: - Fixes a potential EO UDP SEG header corruption - Fixes an issue where 1000Base-X was not enabled correctly when using QSA modules OFLD: - Fixes timeout issue with half-open connections - Fixes FW_FLOWC_WR processing when state is set to finwait1 FOFCoE: - Fixes fcoe xchg leaks in linkdown/peer down path - Fixes cleanup in FCoE linkdown and fixed buf timer flowid abuse - Fixes fw crash by clearing fcf flowc during bye FOiSCSI: - Don't create a new tcp socket if ERL0 attempt has timed out. ENHANCEMENTS ------------ BASE: - Adds support for VFs on PFs 4 to 7 - Adds support for QPs/CQs on any physical and virtual function ETH: - Stops sending LACP frames on loopback interface - Adds an AUTOEQU indication to CPL_SGE_EGR_UPDATE - Adds support for CR4 links (BEAN/AEC on 40G TwinAx cables) OFLD: - Improves default settings of LAN and CLUSTER TCP timer settings - Sends Negative Advice CPLs to software FOISCSI: - Adds IPv6 support for foiscsi. Keeps backward compatibility with old foiscsi drivers which doesn't support ipv6. FOFCoE: - Added fcoe debug support in flowc dump ================================================================================ ================================================================================ Version : 1.12.25.0 Date : 10/22/2014 ================================================================================ FIXES ----- BASE: - Improves precision of the Weight Round Robing Traffic Management Algorithm - Fixes an issue where the link would intermittently fail to come up - Fixes an issue where adapters with an external PHY couldn't run at 100Mbps - Fixes an issue where active optical cables were not recognized - Fixes link advertising issues on T520-BT (speed and pause frames) that would cause the link to negotiate unexpected settings - Forces link restart when auto-negotiation is disabled - Fix an issue where pause frames wouldn't be fully disabled even if requested ETH: - Fixes NVGRE Segmentation Offload network header generation. DCBX: - Fixes an issue where some settings were not being sent to the switch correctly - Fixes an issue where back-to-back DCBX port updates could get overwritten by FW - Fixes a firmware crash on DCBX APP information request before link up FOiSCSI: - Fixes abort task leak in tmf response handling - Fixes TCP RST handling while in iSCSI ERL0 - Fixes a firmware crash on BYE without INIT ENHANCEMENTS ------------- BASE: - Adds link partner settings reporting when available - Adds QSA support (in conjunction with QSA VPD) - Adds T520-BT LED support - Reports NOTSUPPORTED for modules with an unhandled identifier DCBX: - Adds version reporting (indicating which version FW is trying to negotiate) - Adds IEEE support - Reports LLDP time outs FOiSCSI: - Add support for multiple iSCSI DDP client - Sends DHCP renew request when lease expires ================================================================================ 22.2. T4 Firmware +++++++++++++++++ Version : 1.14.4.0 Date : 08/05/2015 ================================================================================ FIXES ----- BASE: - Fixes a potential initialization error when accessing a configuration file stored on the flash. - Initialize PCIE_DBG_INDIR_REQ.Enable to 0, as hardware failed to do so and register dumps could result in errors. ETH: - Fixes an issue that sometimes prevented the link from coming up in CR adapters. ENHANCEMENTS ------------ BASE: - Adds support for PAUSE OFF watchdog. - Reports devlog access information in PCIE_FW_PF register 7. ETH: - Adds new interface to allow the driver to query the VI rss table base addresses. OFLD: - Adds new interface for the driver to specify offloaded connections TCP snd and rcv scale factors. ================================================================================ ================================================================================ Version : 1.13.32.0 Date : 03/25/2015 ================================================================================ FIXES ----- BASE: - Fixes FW_CAPS_CONFIG_CMD return value on error (was positive instead of negative) - Fixes FW_PARAMS_PARAM_DEV_FLOWC_BUFFIFO_SZ indication (was wrong on certain adapter configurations) - Fixes config file based PL_TIMEOUT register programming ETH: - Fixes a potential EO UDP SEG header corruption OFLD: - Fixes timeout issue with half-open connections - Fixes FW_FLOWC_WR processing when state is set to finwait1 FOiSCSI: - Don't create a new tcp socket if ERL0 attempt has timed out. ENHANCEMENTS ------------ ETH: - Stops sending LACP frames on loopback interface - Adds an AUTOEQU indication to CPL_SGE_EGR_UPDATE OFLD: - Improves default settings of LAN and CLUSTER TCP timer settings - Sends Negative Advice CPLs to software ================================================================================ ================================================================================ Version : 1.12.25.0 Date : 10/22/2014 ================================================================================ FIXES ----- BASE: - Improves precision of the Weight Round Robing Traffic Management Algorithm - Forces link restart when auto-negotiation is disabled - Fix an issue where pause frames wouldn't be fully disabled even if requested DCBX: - Fixes an issue where some settings were not being sent to the switch correctly - Fixes an issue where back-to-back DCBX port updates could get overwritten by FW - Fixes a firmware crash on DCBX APP information request before link up FOiSCSI: - Fixes abort task leak in tmf response handling - Fixes TCP RST handling while in iSCSI ERL0 - Fixes a firmware crash on BYE without INIT ENHANCEMENTS ------------ BASE: - Adds link partner settings reporting when available - Firmware now reports NOTSUPPORTED for modules with an unhandled identifier DCBX: - Adds version reporting (indicating which version FW is trying to negotiate) - Adds IEEE support - Reports LLDP time outs FOiSCSI: - Adds support for multiple iSCSI DDP clients - Sends DHCP renew request when lease expires ================================================================================ Obtained from: Chelsio Communications MFC after: 2 weeks Sponsored by: Chelsio Communications --- sys/conf/files | 4 +- ...w-1.14.2.0.bin.uu => t4fw-1.14.4.0.bin.uu} | 4397 ++++---- sys/dev/cxgbe/firmware/t4fw_interface.h | 4 +- ...w-1.14.2.0.bin.uu => t5fw-1.14.4.0.bin.uu} | 9748 ++++++++--------- sys/modules/cxgbe/t4_firmware/Makefile | 2 +- sys/modules/cxgbe/t5_firmware/Makefile | 2 +- 6 files changed, 7083 insertions(+), 7074 deletions(-) rename sys/dev/cxgbe/firmware/{t4fw-1.14.2.0.bin.uu => t4fw-1.14.4.0.bin.uu} (77%) rename sys/dev/cxgbe/firmware/{t5fw-1.14.2.0.bin.uu => t5fw-1.14.4.0.bin.uu} (58%) diff --git a/sys/conf/files b/sys/conf/files index d1060bc01750..fecb8b189675 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1203,7 +1203,7 @@ t4fw.fwo optional cxgbe \ no-implicit-rule \ clean "t4fw.fwo" t4fw.fw optional cxgbe \ - dependency "$S/dev/cxgbe/firmware/t4fw-1.14.2.0.bin.uu" \ + dependency "$S/dev/cxgbe/firmware/t4fw-1.14.4.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t4fw.fw" @@ -1227,7 +1227,7 @@ t5fw.fwo optional cxgbe \ no-implicit-rule \ clean "t5fw.fwo" t5fw.fw optional cxgbe \ - dependency "$S/dev/cxgbe/firmware/t5fw-1.14.2.0.bin.uu" \ + dependency "$S/dev/cxgbe/firmware/t5fw-1.14.4.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t5fw.fw" diff --git a/sys/dev/cxgbe/firmware/t4fw-1.14.2.0.bin.uu b/sys/dev/cxgbe/firmware/t4fw-1.14.4.0.bin.uu similarity index 77% rename from sys/dev/cxgbe/firmware/t4fw-1.14.2.0.bin.uu rename to sys/dev/cxgbe/firmware/t4fw-1.14.4.0.bin.uu index c868045fb05d..e3f3f779d8af 100644 --- a/sys/dev/cxgbe/firmware/t4fw-1.14.2.0.bin.uu +++ b/sys/dev/cxgbe/firmware/t4fw-1.14.4.0.bin.uu @@ -24,15 +24,15 @@ * SUCH DAMAGE. */ begin-base64 644 t4fw -AAAEHQEOAgAAAQkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAEHgEOBAAAAQkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAABAAEDwQXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAABAEEEAQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IE1vbiBKdWwgMTMgMjE6 -MTU6MDkgUERUIDIwMTUgb24gY2xlb3BhdHJhLmFzaWNkZXNpZ25lcnMuY29tOi9ob21lL2Zpcm13 -YXJlL2N2cy9mdy1yZWxlYXNlKSwgVmVyc2lvbiBUNHh4IDAxLjBlLjAyLjAwAAAAAAAAAAcT5rNg +AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IFRodSBKdWwgMjMgMDA6 +MzA6MTAgUERUIDIwMTUgb24gY2xlb3BhdHJhLmFzaWNkZXNpZ25lcnMuY29tOi9ob21lL2Zpcm13 +YXJlL2N2cy9mdy1yZWxlYXNlKSwgVmVyc2lvbiBUNHh4IDAxLjBlLjA0LjAwAAAAAAAAABlSRz1g AMgA4QB78AAQAADhADC4eP///x/84UCAAAAB4QB7cAAAEAAf//2U4QGUcCAAAADhAZwE4QB5AAAC AEDhAHmAAAYAQAACAAoABgAK4QB5BAAMAACAAAEC4QB7POEAe0ThAHvk4gAAAAABAADhAHuQIAAA AAAAgADhAHsAAABAAeEAe5wAAEAAREREQuAAAADjAARzREREQOMACAAgAAJcAAAAAB//koAAAAAA @@ -67,8 +67,8 @@ nOMAfgQgAAGcIAABpeMAfgggAAG4IAABvOMAfhQgAAG8IAABxeMAfhggAAHYIAAB2OMAfiQgAAHc IAAB4uMAfiQgAAH4IAAB+OMAfiwgAAH8IAAB/OMAfiwgAAIYIAACGOMAfiwgAAIcIAACHOMAfiwg AAI4IAACOOMAfiwgAAI8IAACPOMAfiwgAAJYIAACWOMAfiwgAAJcIAACYuMAfiwgAAJ4IAACeOMA fjQgAAJ8IAACguMAfjQgAAKYIAHzYuMAfjwgAwAAIAMUmOMCbwggAxSYIAMUmOMCg6AgAxSYIAbL -jOMCg6AgBsuQIAbRUOMGOpggCAAAIAgOQOMGQFggCA5AIAkkLuMGTpggCSQwIAkk/OMHZIggCwAA -IAsAAOMHZVQgCwAAIAsAAOMHZVQgCwAAIAuan+MHZVQAAAAAAAAAAAAAAAAgABFWIAARSCAAFTog +jOMCg6AgBsuQIAbRUOMGOpggCAAAIAgOQOMGQFggCA5AIAkkNuMGTpggCSRAIAklDOMHZJggCwAA +IAsAAOMHZWQgCwAAIAsAAOMHZWQgCwAAIAuan+MHZWQAAAAAAAAAAAAAAAAgABFWIAARSCAAFTog ABFIIAAUtSAAEUggABH9IAAUTSAAE9IgABFIIAATfSAAEzQgABLJIAARNSAAEnQgABFIIAARSCAA EUggABIcAAAAAAEQGAEABAAAAAAAAAAAAAD///////8P/P//8P///wD8IACtgyAAruogAK8aIACu 4CAArqEgAK6XIACuYSAArlcgAK5GIACt8iAArxggAK3oIACtuyAArxogAK2xAAAAAAAAAAoAAAAK @@ -78,9 +78,9 @@ AAAAAAAAAAAAAQABAAIAAgADAAMAAwADAAQABAAEAAQABAAFAAUABQAFAAUABQAGAAYABwAHAAAA AgAAAAYAAAAKAAAADgAAABQAAAAcAAAAKAAAADgAAABQAAAAcAAAAKAAAADgAAABQAAAAcAAAAKA AAADgAAABQEAAAcAAAAKAAAADgAAABQAAAAcAAAAKAAAADgAAABQAAAAcAAAAKAAAADgAAABQAAA AcAAAAKAAAADgAD/AAECAgAAAAAAAAAAAAAAECBAAAAAAAAAAAAAAAAAAAQAAgABAACAAEAAIAAQ -AAggQIAAAAAAAAAAAAAAAAAAIAineCAIp3ggCKcxIAinACAIptIgCKamIAimpiAIqFYgCKhWIAim -piAIqFYgCKhWIAimpiAIpqYgCKZaIAioViAIqFYgCKhWIAioViAIqFYgCKhWIAioViAIqFYgCKhW -IAioViAIqFYgCKhWIAioViAIqFYgCKhWIAioViAIpokgAwoIAAAAASADDjgAAAD/IAMH4AAAAP8A +AAggQIAAAAAAAAAAAAAAAAAAIAingCAIp4AgCKc5IAinCCAIptogCKauIAimriAIqF4gCKheIAim +riAIqF4gCKheIAimriAIpq4gCKZiIAioXiAIqF4gCKheIAioXiAIqF4gCKheIAioXiAIqF4gCKhe +IAioXiAIqF4gCKheIAioXiAIqF4gCKheIAioXiAIppEgAwoIAAAAASADDjgAAAD/IAMH4AAAAP8A AAAAAAAAACADCfQAAAACIAMJ+AAAAAMgAwoAAAAABwAAAAAAAAAAIAMJ2AAAAAEgAwncAAAAAiAD CeQAAAAEIAMOOAAAAP8gAwfgAAAA/wAAAAAAAAAAIAMH4AAAAAAgAw44AAAAACADCPAAAAABIAMI +AAAAAQgAwkAAAAACCADCQwAAAAgIAMJHAAAAEAgAwkkAAAAgCADCSwAAAEAIAMJNAAAAgAgAwlI @@ -2914,7 +2914,7 @@ AABDSEFQX0kAAENIQVBfQwAAQ0hBUF9OAABDSEFQX1IAAERpc2NvdmVyeQAAAE5vcm1hbAAATm9u ZQAAAABDUkMzMkMAAENSQzMyQyxOb25lAE5vbmUsQ1JDMzJDAENIQVAAAAAAQ0hBUCxOb25lAAAA Tm9uZSxDSEFQAAAATm90VW5kZXJzdG9vZAAAAElycmVsZXZhbnQAAFJlamVjdAAATm8AADUAAABD SE5ldCAxLjAwAAAAAAAMAAAAAAEAAXwADAEAAAAAEAAAABQgBsboAAADFQ5AAAAf/AAAH/wAAB// -tBAf/7QQIAbRUCAG1RAgCSUAIAklACAKAAAgCoAAIAqAACAK5oAAAEAAAACAAAAACADhAY4AAAGR +tBAf/7QQIAbRUCAG1RAgCSUQIAklECAKAAAgCoAAIAqAACAK5oAAAEAAAACAAAAACADhAY4AAAGR DIAAAAAgC2IAIAthsCALYjD///P/IAth4CALAWAAAEAOH/+S0AAAQBogCwGQAAAQAAAA/+kAAP/g AABQAAAA//gAAEANAAD/9wAAD/8AAA9CAAD/9QAAIEAAACAAAADEEAAAwAEAAMggIAsB8CALAhAA AMQAAADIAAAAxDAAAMQxAAIQCOD//gAgCwIw///3/wAA6AAgCwJQAADIEAAAxEUAABABAAAgfAAA @@ -2948,7 +2948,7 @@ IAslEDAAAAgwAAAMNAAACNAAAAAAAIkUOwAACDSQAAAFXUqAIAREzAAYAAD/B///ADgAAAAwAAAg C3FQBgAAACAEU4T4AAAAAf//5wABwAAgAACABAAQAB//qbDhAZoA4QGaQOEBmjzhAZo44QGaNOEB mjAf/64AgAAAA4AAAAIf/6uY//z//+EBDgAf/60Ef////x//lHwf/5T8IARgzCALdQAgC3VAIAt1 cCALdbAgC3XgIAt2ICALdlAgC3aQIAt00A////D/8AAAIAt3MB//sJAf/5n0IAt28B//qMQgBG1s -IAt4MCALeGAgC3fQIAt3cB//mYQf/5uUAAD/gB//k1AAACMoIAsmACALJjAABAAA//v//+EB4sAf +IAt4MCALeGAgC3fQIAt3cB//mYQf/5ucAAD/gB//k1AAACMoIAsmACALJjAABAAA//v//+EB4sAf /6osH/+rsJAAAPD8/4DAAgAAIP7/gMAgCyaAIAsmwAAA+AAAAgEIAAIBDI////8f/6uk4QGYACAL JxAgCydgIAsnkCALJ9DhAN4AAAIDCAACAgD///AA4QDuAP//f/8AAPwAH/+tHAAA4AAAAAwAAAID BAABERwAAREYABAIAIAACAAAAgEEH/+dkP//wAAAAP/+AAAlgAACAwAf/6uc4P/iwCALeJAgC3kg @@ -4517,12 +4517,12 @@ FeAKVQD4IAYVoBslAFiTCSkSECsSM46XKhIy/AACHe/IBQDt5RQneIEAAAj/Ae0SMSf5AQAAn+mf 6C4SNf4miBXv8goAAABsEAYUqLkOLRGk1CVChAUFSglVEfSgCgeSAJ0AH6ggLPIiZMEqG6hFwJD7 cBAV4AoFAG3JEQCQBAsMG+/HBnTIBQAAsarTD/dACCiSAJ0AFqjB/gACHaALBQD80+gVoAiFAG2K EACwBAwJGQkJQ+nRFHXYEQAA5mwEJ3AFAAD72x4NoAsFAGbgvhqnESqiiyny3KrqCaoRqpkpkTQp -nSMpnCgcqK0CKwkMuwkvsH4D+hz3cBAV4A2lAA2qLQmqNwpaDOagym0wBIAAKfqcCXkdqalmkLov -sH8PPxweqKAN/y0cqJ8Pnzb/7+AV74cFAPfgBAfxiAUA+eBAB7N6jQD44AATs/+NAAf/Ai9GoyzA -gPWABSFSAJ0ALEKIDAxKCcwRZMBDLTx/Dt0B/Y8ADvQPBQDv0lR20/MAAAp+Ev6S5hWgAgUA0Q8A +nSMpnCgcqK0O6wmsuy+wgAP6HPdwUBXgDaUADaotCao3CloM5qDLbTAEgAAp+pwJeR2pqWaQuy+w +gQ8/HB6ooA3/LRyooA+fNv/v4BXvhwUA9+AEB/GIBQD54EAHs3qNAPjgABOz/40AB/8CL0ajLMCA +9YAFKVIAnQAsQogMDEoJzBFkwEQtPH8O3QH9jwAO9A8FAO/SVXbT8wAACn4S/pLmFaACBQDRDwAA +VEOBe/9WgD//NQNoA4FAB+nB/6UZhXgAgUA0Q8AAAD6AIIdoBuFAOyofhloBIAAWJKcBnIS8pLm -FaACBQDRDwAAL7B+J7CA7Kh3GWgEgADosH8p8ASAAPYgJhXgCiUA+CAGFaAbhQBYko7HJNEPACk8 -fw6ZAQlZDGafxeymihTQBwAAKqyACnoSDKoC+pJGFa/8/gAAAABsEAYWprsPAgAoYo0mYpCiiAmI +FaACBQDRDwAAL7CAJ7CC7Kh3GWgEgADosIEp8ASAAPYgJhXgCiUA+CAGFaAbhQBYko7HJNEPACk8 +fw6ZAQlZDGafxeymihTQBwAAKqyACnoSDKoC+pJGFa/8+gAAAABsEAYWprsPAgAoYo0mYpCiiAmI EQhmCCpiByqiDvoAIh3gDAUA5mwwJVALAADqoBclGgEAAFhc+OhsKCsoBIAA6BYAIzhRAADnFgEj OPEAAClQBcqbdlFNihGLEHpRNXtZHywwlf2DICDQBAUA2iD04AAGMAtFAFhc6C0wlbFEfULqJVwU d1nHKTCWy5RokQJokknRD9og+gBiHeAMBQBYXN5j/9wA2iD6AEId4AwFAFhc2dog+gBCHeAMFQBY @@ -6103,37 +6103,37 @@ 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 @@ -6154,7 +6154,7 @@ DwBsEATwRcAN7zKBAPBiEA3gJAUAAohXyoECyVPKmQLqUeSgL2Jb/QAAArQ70kDRDwAAIhH//3AN oBQFAAgiEfSfABWv/1oAAAAMIhH0n4AVr/86AA4tEexM/SIT+QAADcI70Q/AINEPAGwQBBJL0CIi 2NEPAGwQBIIngi6DKIInoyKwItEPAAAAbBAEgieCLoIn0Q8AbBAEEkvFIiLX0Q8AbBAEJfrABSUB JFEVpUQkTQHjJgEiIwEAAJQg0Q8AAABsEASCJ4IugyaCJaMisCLRDwAAAGwQBIIngi6CJdEPAGwQ -BBtOviQ8fwQ6FAuqAftCABWgGwUAWKRwI6UC46UDLRAEgAD07gAOMAsFAPtApB3mQwEA7KUEJWBB +BBtOviQ8fwQ6FAuqAftCABWgGwUAWKRyI6UC46UDLRAEgAD07gAOMAsFAPtApB3mQwEA7KUEJWBB AADspgAiAUGAAPqAaB2gDRUAWvL2aK4V+oBoHaALBQD8QAgVoA0VAFry8Wmu6dEPAGwQBOdLoRkv goAAFk6ip1eTdKZVJFZ/0Q8AAABsEAQZTMWJkBpNeBhMwwqZAfhGAAlwFAUABCQClIATTpcUTXMD IgITTLwEIgHyYAYVoAIFANEPAGwQBBhNjxpMthlLuyaCIR1NaCmSivZCkg2gBwUAJ4LdopkJmRH4 @@ -6397,13 +6397,13 @@ unR70gJ1ugJ0uZQsIh8swhBkwFPqJAAJ2ASAAAvAAGAARyUgIyQgIsCk/mBoHeAbhQDtRAAK8ASA AFgqWMLS/GAEVGIAnQD2f/qtIgCdABg/cgNPEaj/LvKAGD6yCO4C//AGFa/88gDGqmevSdKg0Q/G KtEPAAAUPoItICIlQoskQpCtVQlVEaVEJSAjwKT+YGgd4BuFAO0WACrwBIAAWCo+K0BDwoJ4sTL3 f/eVIgCdAIoQGz9YA6oRq6opooAbPycLmQH5UAYV7/teANpA+qBoHeAMFQBbqttj/sKKEPqgaB3g -DAUAW6rXY/6yAABsEBAXPz0WP3ooIRjyRFAV4AwFACwWBCkgK+00AAQAUYAALyBmZPC38SAFN9AL +DAUAW6rXY/6yAABsEBIXPz0WP3ooIRjyRFAV4AwFACwWBCkgK+00AAQAUYAALyBmZPC38SAFN9AL BQB+lwd9lwR8lwHAsfFpMA3gCgUA9AACHaALBQANuxHrqwIJUASAAFv8NdWg63J9KpHKAAApISAq IgD7TwANdZkBAPUgBhiSAJ0A6z5jFJSRAAD1IBEaEgCdAPUgEZwSAJ0A9SARnZIAnQD1IBMeEgCd ABw+CizCQi066A29LAfMEQ3MLLDMA60Rpt0s1oFa5bj0RWYdoA0VAPxFxh3gAgUA0Q/A4P5FZh2g AgUA0Q8AAC8gbA9PQ2T/PiogQ8Ly/0APNGIAnQD6Q+gV4CiFAPlADoQiAJ0AjLRkwaTrHBApUASA AAvAAIkU+0BPYFIAnQBklPwrIh+Ltcm0AioCC7AA+CCIFeAAOgD6gkgF7/2WAMCg5qeCbSgEgABk -lNopISDTDwkJRR8+9AM0Ea9EKkKA9SAQTBIAnQD1IBmhEgCdAPkgQmDSAJ0ACttS+WBCCdIAnQAt +lNopISDTDwkJRR8+9AM0Ea9EKkKA9SAQTBIAnQD1IBnhEgCdAPkgQmDSAJ0ACttS+WBCCdIAnQAt ICIqICMrIEX1QAvDEgCdAMDJ/UAKdCIAnQD1QAo1EgCdAMDR/EimHeAOFQDx2AAN4AsVAC5CjcCC COoBeOAcwMDpQrclAHmAAHOXB3SfBHqfAcDB2sAZQPwpRreMFOkgKy5nwoAA6soCDceCgAD7BgAN MASFAPVGAAowCwUA/yfgB9DEAQB+l3fxIAm/UgCdAPEgIL8SAJ0A/oKAB9ALFQDA4g5NAX5AB8CE @@ -6411,35 +6411,35 @@ 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 @@ -6517,7 +6517,7 @@ JBEPAgCoRBg5vSRCAAgoCCiAgP8PAAffRAEAGDmMCCgKKIKf+CIABLACBQD7IAQA1IgdAP2AAQHQ CTUAbZon+CIABLS4HQD7IAQA0ZgxAODJGgyBCoAA6TkCDhgKgADzJgAJ9IsdAMGfApkMeT0PsSL8 XoCCUBn1ANEPAAAAAOtEAAlQBIAAW5CbZ6/h0Q/qJAAKWASAAFuQl9EPAAAAbBAEW/9nHDr4/AAC HeADBQD5gGgdoBoVAOzNBCboBQAAbaoKI4ZA44ZBJEAhAAAqChHp2ONuQASAABQ5NvSP6BWgAgUA -Kgr//EBoHaALFQBYkBsqCv9b/zOxImku5txA+gACHeD69QBYkBXZMPh0mAWgGgUAbaoKKYYQ6YYR +Kgr//EBoHaALFQBYkB0qCv9b/zOxImku5txA+gACHeD69QBYkBfZMPh0mAWgGgUAbaoKKYYQ6YYR JEAhAAAYOkeIgBk6RsCiCogCmJDRD2wQBMAw9m8uBe/19QAYOWIMJhGoZidmgyVmgidmgSVmgBQ5 WQQkCyNGgSNGgNEPAGwQCOI3pBlABIAA2TDiAAUIkASAAAICYQICYW+EfxI6NvQgaB2gAzUAbToh 5UIHIRgTAADnQgYhMBEAAOU2ACIj4QAA5W0EIRAhAACXUBI32vR0VgWgA2UAbToP4yIHIRPxAADj @@ -6528,7 +6528,7 @@ NQD7QAQA0AgVAOCIGg0BCoAA/SABBN/69QAKmQMJdwEIdwInRsL0dRQF4RaFAAYmKCRCwqZVJFaf AQUzAiNGwNEPAABsEAQbOdnrsn8p0ASAAFgkXPwBAh3gDAUAWCOF/EBoHeAMBQBYI5DSsNEPAGwQ BPJvPgXgAhUAIjaAIjaB0Q8AbBAEhyD4YAgVr/b1AOZGAwJL/QAACXkBCUkMCWYBBoQMp2bmJgAi gHGAAAVILghIDJgw0Q+UMNEPAAAAbBAGGDpWEzc9GzpV8wGyDaAqBQApMH0KmQIpNH1yuxTaIOwc -BCjYBIAAWI9WiRBokhJolgHRDywwfS0KgA3MAiw0fdEPLjB9xPAP7gIuNH3RDwAAbBAEKAoACOQW +BCjYBIAAWI9YiRBokhJolgHRDywwfS0KgA3MAiw0fdEPLjB9xPAP7gIuNH3RDwAAbBAEKAoACOQW AQIAHTf+AiwJDcwKI8ZkLfrADU0B/KYADvAuBQAO3QItxmUnxmYswmYK6jAbNtEpskErskELmQoK kgoG6jAGJgxqYQ5tCAgO6jAOLgxq4QJj//AI5BbRDwAAAGwQBPgQAh3lSAUA8xEACT+IBQADkzqj JCRNASRMPwhCAdEPAGwQBPpAaB2j64UAWCQHHTa5/agoFeAMBQBYIz3SsNEPbBAE6iQACdgEgABa @@ -6566,11 +6566,11 @@ CBWgDRUAWtxRaa7p0Q+IPyaFBCeFAieFA+SFBSRIQQAA+QAGFe/4igAAAAAAAP/+JA2gChUAbBAE EjakIyKBezYbKSKKCQlV+yAEANAIFQAAiBoiIv4CIhSigtEPABI4VSIhf9EPbBAI5BYCKbgEgABY HKETOF0oMX4bOF3zAB1v0gCdACqykiwxgR44WC8xfygxgC3ilMCw+CQABDH/AQD/TQAO8cwBAO3m lCYdCYAAZIOqHThOGTYD+nCcBaAMRQAs1rDCtyuWECmSESYgDPRBsBWg2QEA/U+GHeDJCQD9T6Yd -oLkRAPtPxh3gmRkAKaR/WJvS5hYALRAEgADmNPgdFAoAAOkyXSIZkYAAGjeIiBCqiCiAfSJiiKSI -qCIJIhGikiIsgBs4MSoyXCuysftAAEVwBDUAWJuqWBsfkhFYmy7mojxtEASAAFiapliZoeaiLm0Q -BIAAWJjH5qIjbRAEgAAsMXvTD37HCliYwOaiEG0QBIAAWJhQ5qIFbRAEgABYmAfmofptEASAAC0x +oLkRAPtPxh3gmRkAKaR/WJvU5hYALRAEgADmNPgdFAoAAOkyXSIZkYAAGjeIiBCqiCiAfSJiiKSI +qCIJIhGikiIsgBs4MSoyXCuysftAAEVwBDUAWJusWBsfkhFYmzDmojxtEASAAFiaqFiZo+aiLm0Q +BIAAWJjJ5qIjbRAEgAAsMXvTD37HCliYwuaiEG0QBIAAWJhS5qIFbRAEgABYmAnmofptEASAAC0x fvOgEX/SAJ0ALjF//oARoKIAnQArMYHB+A8CAPvgEbjiAJ0A+oASuOIAnQAoMYDTD3uHGuoSASvY -BIAA7BICKugEgABYlXnmoaltEASAAFv+rBw4A9MP0w8pwqn2IGYV4AIFAOUWBCSEeYAAFjf/Fzf+ +BIAA7BICKugEgABYlXvmoaltEASAAFv+rBw4A9MP0w8pwqn2IGYV4AIFAOUWBCSEeYAAFjf/Fzf+ 5TW2EyAhAAATN/gYNLQjMl0ogoYmdr4mdr8kdsCoKOR2wSxGQoAAqDMtMAf6YOgVoP7FAP+gBAaw CwUA/EYADvAMFQDtNAclUIEAAFrk8JWgiTAcN+r9QEYVoA4VAOw34xzOAoAADpkCmaEowqknfBTi LAEiIFEAAOgji3MwUQAAhRSHExM0sC0yIC3GUP2gAQfz6IUACNgo6MZNL//CgAD/ieYV4G5FAA7d @@ -6578,9 +6578,9 @@ KC3GTlrh5mWiT8AgZiDHW/325qDBbRAEgABYHAspMH3rN80U6KKAAB00Ryiydin6/QmIASi2di8K AC+2cSzSyB40ZikwfQ7MASzWyHmfIi2ydsfrDt0BLbZ2HDetLMJ/wNDttnImAGGAABg3qsDwL4bA WuHKyaZa4clkoUmDEYs3KjANIzB367IOJQp5gAAYNF8vgq4ZNLMaNDX8aLYF4AsFAPnmAA/wTHUA /xXGFeAeBQBt6gwuoZDs4S51UAkAALG7L9KCGDel+eAEB7AIFQAI/wIv1oJYG9zaUOt0AAlgBIAA -WB6EwCDRD2a/1CrShPtgBADQCRUA/SABBN/89QAMnAMMqgEKmQL5sIYV7/8mAAAAAAAAWJdo563O -bRAEgABj/7EAAFiXVOetyW0QBIAAY/+hAAAAAADqEgEr2ASAAOwSAiroBIAAWJb75q+GbRAEgAAr -MYHTD/qf7Y5iAJ0A6hIBK9gEgADsEgIq6ASAAFiVSeetlm0QBIAAY/9WAABb/wEbN2/7ckYVr/FC +WB6EwCDRD2a/1CrShPtgBADQCRUA/SABBN/89QAMnAMMqgEKmQL5sIYV7/8mAAAAAAAAWJdq563O +bRAEgABj/7EAAFiXVuetyW0QBIAAY/+hAAAAAADqEgEr2ASAAOwSAiroBIAAWJb95q+GbRAEgAAr +MYHTD/qf7Y5iAJ0A6hIBK9gEgADsEgIq6ASAAFiVS+etlm0QBIAAY/9WAABb/wEbN2/7ckYVr/FC AIgQImKHqCIJIhHzIABBP/N2ACvmlSvmlivml/vTBhXv8VoAHTdjK9acK9abK9aa+7OmFe/xFgDA ovxp0gWgCwUAWB/fY/63AAAA+CAoFeAKRQD8abYFoAiFAPhmAAwwblUA6JR3JfgXAAD//oQdoA01 AP/+pB2gCwUAWB/QGzdUK7J/yLQqEgELsADJNsCl/GmaBaALBQD+DIIdoA01AFgfx2P+WYwRLMB3 @@ -6964,7 +6964,7 @@ bBAEEyKgDCIRoyKCINEPAGwQBBUinQwkEaVEI0bAJELA0Q8AbBAEFSKZ+D60BahiHQDqZBELTwKA AOVFCAzPgoAA6JkIBDnBAADnQggBgemAAPZAaB2gA4UADwIAbToQ45IcJMghAAAkkhsklhojlhsG YIYFAmcGQIYFAmUGIIYFAmMGAIYFAmHRDwXghgICbwXAhgICbQWghgICawWAhvIQqB2gA4UADGIR CCIKDwIA0w/TD206EOMiHCEQIQAAJCIbJCYaIyYb0Q8AbBAE8j5iBagyHQAKMxGjIiIscNEPAAAA -bBAEGiJqGyJq7z0QCWQCgADtzAIKbgKAAA3MAliZ2MAg0Q8AbBAEBOowGB6bKIJBAogoqEID6jAD +bBAEGiJqGyJq7z0QCWQCgADtzAIKbgKAAA3MAliZ2sAg0Q8AbBAEBOowGB6bKIJBAogoqEID6jAD IwxqMQ5tCAgJ6jAJKQxqkQJj//DRDwAAAAAAbBAELSANKyAMFB/35x/4FotBgAAocH0uQiCw3wj/ KKvur+4oIAVogyZohHb1AAlqkgCdAPUACkMSAJ0A9QAKk5IAnQBoiAPAINEPwJMpJAUfHqXAMA/u CyriwBgiQQoMSgjMEQjMAgwMT/33ZhWpqmEAbakCI/a8I/a7KuLAGB9/CgxKCMwRCMwC/eAABjAJ @@ -7056,8 +7056,8 @@ uAUAAHKzB/JaABWgAFYAcqsKcsMH8lUgFaAAHgAiLMkCiAn4gAYVoAIFANEPwJD4gAYV4AIFANEP AAAAbBAEIyUC4yUDIWBBAAD8QAYVoAsFAOslBSHB/QAA8sAAAfeIHQDoJQQhgUGAAPpgaB2gDRUA WsDwaK4V+mBoHaALBQD8QAgVoA0VAFrA6mmu6chLKSEEDJkRKZwQmUDRD9EPAGwQBBgZyBIddCiC jyMibAmIEagziDdkgFL8OuAFoApFAPxgCBXgCwUA7zIHKfAEgABYBYOEN+oaiBIgQQAAWlYrHBqF -HRl7Hh1mjzDrpAAKUASAAFpV4YM3IzwQ2jBaVb9ooSrRDwAAAAAAAPoIAh2gSwUAWJXl+mAIFe/8 -9QD6YOYVoA0FAFhyE2P/iwAA2jBaVc8TGcULqBHoMwgFAbGAAAzqMCsyhYuwsKPsuwgJ0ASAAFgG +HRl7Hh1mjzDrpAAKUASAAFpV4YM3IzwQ2jBaVb9ooSrRDwAAAAAAAPoIAh2gSwUAWJXn+mAIFe/8 +9QD6YOYVoA0FAFhyFWP/iwAA2jBaVc8TGcULqBHoMwgFAbGAAAzqMCsyhYuwsKPsuwgJ0ASAAFgG 3SoilPpgBADQCxUAALsaC6oCKiaUWAcT0Q8AAAAA+gDiHaALFQBayCAsMn8sNoPRDwBsEAQTGr4S GdkiNoPRDwAAbBAEEx0nAwCH4wAHAQBJgAACAGHRD9EPbBAEExq0IjK4Ija40Q8AAGwQBB0ZTx4Z nR8dMBkdMhIaShMdLBUdLBwdLiw2jiU2fiI2hSk2cCk2cS82hi42je3SQSTRAQAAKjaA6jaBJNiB @@ -7067,7 +7067,7 @@ APCAcA3josEAKkQA8KBwDemyYQArVQDwwJAN6sIBACxlANEP0Q8AAABsEAQTGnkiNpzRDwBsEATo Gn8RgMGAABUckyiAfSVSf7A0CEQoolKkItEP0Q8AAABsEAQYGQz4NSwF4AX1APcSaBWgCuUACWYB Blo5FBodAyMRpDMrMoIZGS75EmgVr/wFAAy7AQuqAvpwRhWg9gUA+QAEBHDiBQAIYjkkMoIl+g8F RAEEIgLycEYVoAIFANEPAAAAbBAE8jm6BeDJxQAJKSgYGTv4YABB8AoVAPpwRh2gCQUAKTSAKTSD -KTU+KIB9DwIADwIAf4cYAioCWF/04qQADQDmAADAqyo0gNEPAAAAANogWF/e4qQABX9hgADRDwAA +KTU+KIB9DwIADwIAf4cYAioCWF/24qQADQDmAADAqyo0gNEPAAAAANogWF/g4qQABX9hgADRDwAA bBAEwCHRDwBsEAQXGq4pciMUHML5IAgV4MXFAAUlKPSAAEJwmYEAKUSAKHIjiIAIElIiRIEmciOG YAZGUCZEgiVyI4VQ9FYAAvAIFQDlRIMhPK0AACpwgAYsDPWPAA5wAgUA7MwdJQxVAAAAwQToRJ8s WAqAACtGI9EPAMAgIkYj0Q8AbBAEFRjhJFKE+kAEANAHFQDgNhoJAQqAAPzgAQPf+PUACHcDB0QB @@ -7079,12 +7079,12 @@ AGwQBBIYdyIiQ/JDaBWgAxUAAnJWAyIJAgJH0Q9sEARkQFEpIABkkEvAcOgwACIMy4AAeYkqbQga B0YM6GE1Y7gFAABqYg+jeKJ5KZAAKIAAeYkMY//eo3iieSmQACiAAHiTC/kCNg3gAhUAwCDRD8cv 0Q8AwCDRD9EPAABsEAQTHEWjItEPAABsEAQbGFUrskPpLAQp4ASAAPNgAEWx+PUA+QGWDeAKBQD7 YCgVoAASAIuwWAWzC0IB0Q8AbBAEHRw2GBw2+aBoHeG6xQBtqgUIAIYJAmHrHDIe0ASAAFgF3tEP -AGwQBhMYZvQ4AAXgAgUAJDKuGBr0CEgBKDauIlaoIlapIlaqIlarWJvDFxg0KTroKXZBWJudWJuJ -5qDtbRAEgABYm3DmoOJtEASAAFibK+ag120QBIAAWJqL5qDMbRAEgABb/93+gYAIkAYVACtSgNMP +AGwQBhMYZvQ4AAXgAgUAJDKuGBr0CEgBKDauIlaoIlapIlaqIlarWJvFFxg0KTroKXZBWJufWJuL +5qDtbRAEgABYm3LmoOJtEASAAFibLeag120QBIAAWJqN5qDMbRAEgABb/93+gYAIkAYVACtSgNMP f7dFL3JCGBwSKXrQCf8oCEgB6DauL/8CgAAG/wIvNrf+dugVoA0FAA3kMQECACwyt2bAD20IBSoy -t2agBmP/8wAAAADAo1pPIliZzuagaG0QBIAAWJmj5qBdbRAEgABYmUXmoFJtEASAAFiY7eagR20Q -BIAAIjKu0w8PAgB0L0YbGr0LKwErNq5YmK5YmKHmoCVtEASAABoYwRsYwFiUZhwb7OrGfyUGwYAA -GxrbtLxYlDvSoGcgBMChWsZ30Q9j//wAAAAAAPQwZAXickEACHcRBwRHBUQKKELkB4UU6BYAKtAE +t2agBmP/8wAAAADAo1pPIliZ0OagaG0QBIAAWJml5qBdbRAEgABYmUfmoFJtEASAAFiY7+agR20Q +BIAAIjKu0w8PAgB0L0YbGr0LKwErNq5YmLBYmKPmoCVtEASAABoYwRsYwFiUaBwb7OrGfyUGwYAA +GxrbtLxYlD3SoGcgBMChWsZ30Q9j//wAAAAAAPQwZAXickEACHcRBwRHBUQKKELkB4UU6BYAKtAE gAALgAAKCUFokQf5IAVh0gCdAChC6tpwC4AAzamIENpQC4AACglBaJECaZNlKELq2nALgABkr+SW oRwaspygGxvNGhmLiBD6QAQF8pKBACmkgOs2rirQBIAAC4AAKELo06D64GgdoAsVAAuAAPicyBWv +8UA+mAEBfAMpQDsuwIK0ASAAAuAAPJf+niSAJ0AY/8R//54DaAKBQD8N24FoAoVAPoAIh3v/UUA @@ -7190,13 +7190,13 @@ lZAgBpUwAAAAACAGl/ggBpgAIAaKqAAAAAAAAAAAAAAAAAAAAAAgBocAIAaCaAAAAAAgBoJgIAaC WCAGglAAAAAAAAAAAAAAAAAAAAAAIAZ+wCAGfrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBLKgIAS5qCAEunQg BK2AAAAAAAAAAAAgBLvIAAAAAAAAAAAAAAAAIAS5HCAEuHggBL6QIAS8dCAEr4ggBLDgIASxvCAE -ubAgBK8oAAAAACAIIdggCCI4IAMtKCADKoAgAykMAAAAAAAAAAAgAyskAAAAAAAAAAAAAAAAAAAA -AAAAAAAgAyY4IAPAzCADJ/QgAyTYIAMndCADKQQAAAAAIANCyCAIJSQgCCJsIANEMCADNyAgAzFo +ubAgBK8oAAAAACAIIeAgCCJAIAMtKCADKoAgAykMAAAAAAAAAAAgAyskAAAAAAAAAAAAAAAAAAAA +AAAAAAAgAyY4IAPAzCADJ/QgAyTYIAMndCADKQQAAAAAIANCyCAIJSwgCCJ0IANEMCADNyAgAzFo IAM0mCADMjAgAznAIAMt9AAAAAAgAzygIAM7FCADM4AgAzXwIAM9yAAAAAAgAyTYIAMwICADLTAA AAAAAAAAAAAAAQIAAQAAAAAAAAAAAAABAAECAwQFAjIyAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAA AAAAAAAAAxAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAAQAAAAAf/OEwAAAAAOAAAOABAAAAIAkD -wAAAAAEgCQH0AAAAAiAI/UAAAAABIAj6uAAAAAEgCPikAAAAASAI9pgAAAABIAj0BAAAAAEgCOco -AAAAASAI7iAAAAABIAjl8AAAAAEgCOXoAAAAAQAAAAAAAAAAAAEAAQAAAAAAAAAAAAAAAAQAAAAI +yAAAAAEgCQH8AAAAAiAI/UgAAAABIAj6wAAAAAEgCPisAAAAASAI9qAAAAABIAj0DAAAAAEgCOcw +AAAAASAI7igAAAABIAjl+AAAAAEgCOXwAAAAAQAAAAAAAAAAAAEAAQAAAAAAAAAAAAAAAAQAAAAI AIkGAAAAAAAAAAAEAAABCACJFAAAAAAAAAAABAAAAiABDLwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAABAAAAAgAiQYAAAAAAAAAAAQAAAEIAIkUAAAAAAAAAAAEAAACIAEMvAAAAAAAAAAA @@ -7256,17 +7256,17 @@ AAAAAwAAkAQAAAA+AAEQeAD///8AARB8AP///wABEIgAAAAAAACUBAAA//8AAJQQAAD//wAAmFQA AAH/AACYWAAAAf8AAJYIAAAAAAAAlhAAH///AACWGAAf//8AAJYcAA///wAAliQAD///AACWKAD/ //8AAJYwAP///wAA0CAAAAAHAADQJAAAAAcAAhDYAAAAAwACMNgAAAADAAJQ2AAAAAMAAnDYAAAA AwABkFAAAAAvAAGg1AAAAYMAAZCMADgAAAABkJgAOAAAAAB5dAAAAC8AAHlwAAAABQAAefQAAAAv -AAB58AAAAAUgAw7UIAjS5CADDtggCOJIIAMO5CAI4XAgAw7wIAjhICADDwQgCOBwIAMPHCAI3wgg -Aw8sIAjd8CADDzQgCN3IIAMPSCAI3aAgAw9YIAjdcCADD2QgCNxUIAMPbCAI3CwgAw+AIAjb+CAD -D4wgCNqMIAMPlCAI2eQgAw+kIAjY4CADD7AgCNfQIAMPwCAI1sggAw/QIAjVnAAAAAAAAAAAIAMP -6CAI0qwgAw/sIAjSMCADD/QgCNH4IAMP/CAI0cAgAxAIIAjRiCADEAwgCNFQIAMQGCAI0RggAxAc -IAjSaCADECQgCNDgIAMQLCAI0KggAxA0IAjN2CADEDwgCNBYIAMQSCAI0FAgAxBQIAjQGCADEFgg -CM/gIAMQYCAIz6ggAxBoIAjPcCADDqwgCMwAIAMQcCAIy8ggAxB4IAjLkCADEIAgCMtYIAMQkCAI -yyAgAxCYIAjK6CADEKAgCMqwIAMQqCAIyoggAxC0IAjKYCADEMAgCMowIAMQ2CAIygggAxD0IAjJ -4CADEQQgCMm4IAMRFCAIyZAgAxEkIAjJaCADETQgCMlAIAMRRCAIyRggAxFUIAjI8CADEWAgCMjI -IAMRbCAIyKAgAxF4IAjIeCADEYQgCMdYIAMRiCAIxWQgAxGUIAjEgCADEaggCMRQIAMRsCAIxCAg -AxG8IAjD8CADEcAgCMPAIAMRxCAIw5AgAxHIIAjDZCADD1AgCMJ4IAMR2CAIwlAgAxHgIAjCKCAD -DrggCOU4IAMOwCAI5GggAw6kIAjjuCADDswgCOMQAAAQISBCMGNAhFClYMZw54EIkSmhSrFrwYzR +AAB58AAAAAUgAw7UIAjS7CADDtggCOJQIAMO5CAI4XggAw7wIAjhKCADDwQgCOB4IAMPHCAI3xAg +Aw8sIAjd+CADDzQgCN3QIAMPSCAI3aggAw9YIAjdeCADD2QgCNxcIAMPbCAI3DQgAw+AIAjcACAD +D4wgCNqUIAMPlCAI2ewgAw+kIAjY6CADD7AgCNfYIAMPwCAI1tAgAw/QIAjVpAAAAAAAAAAAIAMP +6CAI0rQgAw/sIAjSOCADD/QgCNIAIAMP/CAI0cggAxAIIAjRkCADEAwgCNFYIAMQGCAI0SAgAxAc +IAjScCADECQgCNDoIAMQLCAI0LAgAxA0IAjN4CADEDwgCNBgIAMQSCAI0FggAxBQIAjQICADEFgg +CM/oIAMQYCAIz7AgAxBoIAjPeCADDqwgCMwIIAMQcCAIy9AgAxB4IAjLmCADEIAgCMtgIAMQkCAI +yyggAxCYIAjK8CADEKAgCMq4IAMQqCAIypAgAxC0IAjKaCADEMAgCMo4IAMQ2CAIyhAgAxD0IAjJ +6CADEQQgCMnAIAMRFCAIyZggAxEkIAjJcCADETQgCMlIIAMRRCAIySAgAxFUIAjI+CADEWAgCMjQ +IAMRbCAIyKggAxF4IAjIgCADEYQgCMdgIAMRiCAIxWwgAxGUIAjEiCADEaggCMRYIAMRsCAIxCgg +AxG8IAjD+CADEcAgCMPIIAMRxCAIw5ggAxHIIAjDbCADD1AgCMKAIAMR2CAIwlggAxHgIAjCMCAD +DrggCOVAIAMOwCAI5HAgAw6kIAjjwCADDswgCOMYAAAQISBCMGNAhFClYMZw54EIkSmhSrFrwYzR reHO8e8SMQIQMnMiUlK1QpRy92LWkzmDGLN7o1rTvcOc8//j3iRiNEMEIBQBZOZ0x0SkVIWlarVL hSiVCeXu9c/FrNWNNlMmchYRBjB212b2VpVGtLdbp3qXGYc499/n/tedx7xIxFjlaIZ4pwhAGGEo AjgjyczZ7emO+a+JSJlpqQq5K1r1StR6t2qWGnEKUDozKhLb/cvc+7/rnpt5i1i7O6sabKZ8h0zk @@ -7287,13 +7287,13 @@ QOEAegAgCz6wIAs/ACALP2AAAA//P////yALP8AgC0AwIAtAcCALQLAgC0DwIAtBMCALQXAgC0Gw IAtB8CALQjAf/5usIAMNQCADDOAf/5NU4QGaAB//nBz/wP//ABAAAB//rWQAAAgAAAYIAB//nfAA AZ4M4QGeAAABnnQAAZ6sAAGe1AABnuwAAZ8UIAtCcCALQtAgC4mQIAuJICALiEAgC4iAIAuI0OEA LgAgAw1QAACQAB//lPQALBQAgAAAgOEAWgCB8OCAIAAAAOEAVgAMAAAA//OAAAAMOABGAAAAPz// -/4CAAADz/////+D//wABAAAgCAAAIAgKJAAACyAgCAEA4QGSAOEADgAf/62cH/+baAACAAAAfwBA +/4CAAADz/////+D//wABAAAgCAAAIAgKJAAACyAgCAEA4QGSAOEADgAf/62cH/+bZAACAAAAfwBA AAMAAACAAIAAwQDA//8j/wAAyAAQIAEg4QCKAOEAfgDhAI4APAAAAP//v/9QaOhH+P///wQAAACS AAAA8ADwAJ+///sgAAAEH/+TUH/3//+AAAIA///v////gP//9/9/AAYAAP//8AD/AAAAAEkkkgAA fhgIAQgBEAEQAQAAfkAgASABFRUVFYQhhCEQEBAQ4QGOAAAA/n8EBAGAzMzMzIiIiIhERERE4QDO AOEAjgThAI4I4QCODOD//gCAAAEAIAgExAAAkAgAAAjAgAHEEcQRxBEA/wD/AEAAQP//P/8gC4pA IAuKcP8P//8gC4oACAgICMyIRAAgC4qgREQAAMzMiIj/8P8AAAIAMyoqFRUf/6scH/+YeB//rNAf -/5zQH/+a1B//nZAf/5qcH/+tlAAA//0f/6qU4wACAOL//wAgC0RAIAjjECALi5AAUAAAAKAAACCg +/5zQH/+a1B//nZAf/5qcH/+tlAAA//0f/6qU4wACAOL//wAgC0RAIAjjGCALi5AAUAAAAKAAACCg AADQAAAAIAuK0CALi2AAABAAIAMHmB//r5Af/6uUH/+AsB//q9Af/60AIAuNQCALRoAgC0cAIAtH cCALjPAgC4ywIAuNECALSAAABAAAH/+A4B//gSAf/4FgH/+aDB//qhgf/5TU4QGWAOEB/gDhAl4A 4QI+AOECHgDhAeIA4QEOAOEAkgAIAAAA///w/x//qNAf/5uQ4QEOBOEBDgjhAQ4M//AAAAACgAb/ @@ -7307,1921 +7307,1922 @@ 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 -i4UAW2K5HbsvHL1i7NZDJmALAAAs1kTRD2wQBBq70uus0CENWQAAaCJu5JCEZJAFAAD8QmARUAQV -AGAAOGlkBQWoCCeGAHJLLOo0AApYBIAAW2ar6GEUYiAFAADlqQgLF3QAAPcgBB3v/3oApav3YAYd -7/9SANEPACuieymihKO7CbsR65kIAw3dAABoYnZpZOOlnJfA0Q8AGbvCqTkpkH1oQDbkkGViEAUA -AHJDmWP/wyyyhymihKPM6cwRAiAFAADsmQgDDG0AAGhiHWhkJPKf+6uiAJ0AY/+aZZ9LY/+UpZj3 -AAYd7/+mAKWa90AEHe//fgClm/dgBhXv/1YApZwnxADRD6WdJ9UA0Q/RDwAAIAMOYAzAAAYgBqw8 -IAMOZAjAAAwgBqw8IAMOaCDAABAgBqvEIAMObAbAADggBq2gIAMOcAjAADwgBqw8IAMOdALAAEAg -Bq2gIAMOeAjAAEQgBqw8IAMOfAiAAEggBqzMIAMOgBiAAFwgBqzMIAMOhBiAAGwgBqzMIAMOiBiA -AHwgBqzMIAMOjBiAAIwgBqzMIAMOkBiAANwgBqzMIAMOlBiAAOggBqzMIAMOmBiAAPQgBqzMIAMO -nBiAAQAgBqzMIAMOoAiAATwgBqzMaHdfYmNtODQzNF9jaGVja3JhbTogU3RhcnQKAAAAAABQSFkg -cHJvY2Vzc29yIG5vdCBydW5uaW5nLCBzdGlsbCBpbiByZXNldCBmb3IgNW1zLCBwb3J0X2JpdF9t -YXA9JXUgCgAAAAAAAAAAAAAAAFBIWSBGVyBoYXMgYmFkIENSQywgb2tfY3JjPSV1CgAAUEhZIGZp -cm13YXJlIGxvYWQgc3VjY2Vzc2Z1bCEKAABod19iY204NDgzNF9sb2Fkc2VxdWVuY2U6IFN0YXJ0 -ZWQKAAAAAAAAAAAAAAAAAABod19iY204NDgzNF9sb2Fkc2VxdWVuY2U6IFVwbG9hZCBpbWFnZSB0 -byBQSFkgb24tY2hpcCBtZW1vcgoAAAAAaHdfYmNtODQ4MzRfbG9hZHNlcXVlbmNlOiBkb25lIGxv -YWRpbmcgaW1hZ2UgKGkgPSAldSkKAAAAAAAAAAAAAGh3X2JjbTg0MzRfbG93cG93ZXJbJXVdOiBl -bmFibGU9JWQKAAAAAAAAAAAAAAAAAGh3X2JjbTg0MzRfbG93cG93ZXJbJXVdLCBmYWlsZWQgdG8g -c2V0IDMwLjB4NDAxQWJpdCA3IHNpbmNlIDMwLjB4NDAwRSBiaXQ9MSBhZnRlciA1bXMsCXJlZz0l -eAoAAGh3X2NsNDVfaW5pdFsldV0gYWNhcHMgJSN4CgAAAAAAaHdfY2w0NV91cGRfc3BkX2FkdiAl -I3gKAAAAAAAAAABod19hcTEyMDJfbGlua191cFsldV0gdXAKAAAAAAAAAHBbJXVdIFBIWSBPVkVS -SEVBVEVEIC0gZm9yY2VkIHBvd2VyIGRvd24gKHRlbXA9JWQpCgAAAAAAAAAAAAAAAABGTEFTSCBu -b3QgcmVhZHk6IGkgJXUgbnZyUmVnICUjeAoAAAAAAAAAAAAAAAAAAABBUV9GTEFTSF9SZWFkeSAt -IFRpbWVvdXQgKDEpCgAAAEFRX0ZMQVNIX1JlYWR5IC0gVGltZW91dCAoMikKAAAACUFRX1JldHVy -bkNvbnRyb2xPZkZMQVNICgAAAAAAAABnYXRoZXJfdGFza3NfdG9fdHhfbGlzdDogdGFzayBpbiB1 -c2UgWyV1XQoAAAAAAABnYXRoZXJfdGFza3NfdG9fdHhfbGlzdDogaWR4IFsldV0sIHRhc2sgZmlk -IFsweCV4XSwgdGFzayBzdGF0ZSBbMHgleF0sIHRhc2sgY29ubiBbMHgleF0sIHRhc2sgZmZsYWdz -IFsweCV4XSwgY29ubiBmaWQgWzB4JXhdLCBkZHAgWyVkXQoAAAAAAAAAAABnYXRoZXJfdGFza3Nf -dG9fdHhfbGlzdDogdGFzayBbMHgleF0sIHN0YXRlIFsweCV4XSBvbiBjb25uIFsweCV4XSBub3Qg -dmFsaWQgdG8gZ2F0aGVyLCBza2lwcGluZwoAAAAAAAAAAAAAAAAAAAAAZ2F0aGVyX3Rhc2tzX3Rv -X3R4X2xpc3Q6IHRhc2sgWzB4JXhdLCBzdGlsbCBxdWV1ZWQgb24gdHggcGVuZGluZyBsaXN0LiBS -ZW1vdmluZyBpdC4KAAAAAAAAAAAAAAAAZ2F0aGVyX3Rhc2tzX3RvX3R4X2xpc3Q6IGNvbm5fZmMt -PmZsb3djX2ZsYWdzIFsweCV4XSwgbGlzdF9lbXB0eSBbMHgleF0sIGFkZF90YXNrX2NvdW50IFsw -eCV4XQoAdG9fdHhfbGlzdDogbm8gdGFzayB0byBjbG9zZSBmb3IgY29ubiBbMHgleF0sIGJhaWxp -bmcgdG8gcmVjb3Zlcnkgc3RhdGUgWzB4JXhdCgBhdXRoZW50aWNhdGVfdGFyZ2V0OiBLRVlfQ0hB -UF9SRVNQIC0gWzB4JXgleCV4JXgleCV4JXgleF0KAAAAAAAAYXV0aGVudGljYXRlX3RhcmdldDog -S0VZX0NIQVBfUkVTUCAtIFsweCV4JXgleCV4JXgleCV4JXhdCgAAAAAAAGF1dGhlbnRpY2F0ZV90 -YXJnZXQ6IEluY29ycmVjdCBwYXNzd29yZAoAAAAAAAAAAENIQVBfQzogZGlnZXN0IGV4cGFuc2lv -biBlcnJvcgoAQ0hBUF9OOiBUYXJnZXQgdXNlcmlkIG1pc21hdGNoCgBDSEFQX1I6IGRpZ2VzdCBl -eHBhbnNpb24gZXJyb3IKAGlTQ1NJIFNlYy1wYXJhbXMgcmVjZWl2ZWRoYXZlIGVycm9ycyEhCgAA -AAAAAAAAAFRhcmdldCBtb3ZlZCB0ZW1wLiBjb25uICV4LCBzZXNzICV4CgAAAAAAAAAAAAAAAExv -Z2luIEZhaWxlZCEhLiBjb25uX2ZjIFsweCV4XSwgc2Vzc19mYyBbMHgleF0sIHN0YXR1c19jbGFz -cyBbMHgleF0KAAAAAAAAAAAAAAAAUHJvdG9jb2wgRXJyb3IgY2JpdCAlZCB0Yml0ICVkIGNzZyAl -ZCBuc2cgJWQKAAAAcmVjdl9ub3BpbjogY3RybCB0YXNrIGFscmVhZHkgcGVuZGluZwoAAAAAAAAA -AAAAb2ZsZF9yeF9kYXRhOiBhaWVlLCBpc2NzaSBjb25uIFsweCV4XSBmb3Igc2VzcyBbMHgleF0s -IHR5cGUgWzB4JXhdIHRyYW5zaXRlZCBpbiB0b2UgbW9kZS4gS2lja2luZyByZWNvdmVyeSAKAAAA -AG9mbGRfcnhfZGF0YTogY29ubiB0aWQgWzB4JXhdLCByeF9kYXRhLT5zZXEgWzB4JXhdLCByeF9k -YXRhLT5sZW4gWzB4JXhdLCByeF9kYXRhLT5zdGF0dXMgWzB4JXhdCgAAAAAAAAAAAAAAAAAAAABv -ZmxkX3J4X2RhdGE6IGNzayB7IGlkIFsweCV4XSwgY3NvY2tfb2Zmc2V0IFsweCV4XSwgZGxlbiBb -MHgleF0gfQoAAAAAAAAAAAAAAAAAAGFjdF9lc3Q6IHRjYl9mYyBbMHgleF0sIGZsb3djX2ZvaXNj -c2lfY29ubl9mbGFncyBbMHgleF0KAAAAAAAAAABhY3RfZXN0YWI6IHRjYl9mYy0+Zmxvd2NfYnVm -IFsweCV4XSwgdGNiX2ZjLT5mbG93Y190eXBlIFsweCV4XSB0Y2JfZmMtPmZsb3djX3N0YXRlIFsw -eCV4XSwgbnBhZ2VzIFsweCV4XSwgZmxvd2NfdHBfc25kX21heCBbMHgleF0KAAAAAAAAAAAAAAAA -AABhY3RfZXN0YWI6IGF0aWQgWzB4JXhdLCB0aWQgWzB4JXhdLCBvcCBbMHgleF0sIHJjdl9pc24g -WzB4JXhdLCBzbmRfaXNuIFsweCV4XSwgY3NvY2stPmZsb3djX3N0YXRlIFsweCV4XSwgdGNwX29w -dCBbMHgleF0sIHRjYl9mYy0+Zmxvd2NfaWQgWzB4JXhdIAoAAAAAAAAAAAAAAAAAY3NrX2ZjLT5m -bG93Y19jc29ja19jb29raWUgWzB4JXhdIAoAAAAAAAAAAAAAAAAAY2huZXRfcXVldWVfeG1pdDog -ZmMtPmZsb3djX2lkIFsweCV4XSwgYnVmX2xlbiBbMHgleF0sIGJ1ZmZlcmVkIFsweCV4XSwgZmlm -by5udW1fYnl0ZXMgWyUweF0KAAAAbmV0aWZfZG9fZGhjcDogd3ItPnBhcmFtLnZsYW5pZCBbJXVd -LCBsMmRldl9mYy0+Zmxvd2NfbmV0X2wyZGV2X3ZsYW5kZXYgWzB4JXhdCgBsM2luNF9kZXZfY29u -ZmlnOiB3ci0+cGFyYW0udmxhbmlkIFsldV0sIGwyZGV2X2ZjLT5mbG93Y19uZXRfbDJkZXZfdmxh -bmRldiBbMHgleF0KAAAAAAAAAAAAAAAAAABuZXRfbDNpbjRfZGV2X2NvbmZpZzogbDJkZXZfZmMt -PmZsb3djX2lkIFsweCV4XSwgYWRkcmVzcyBhbHJlYWR5IHVzZWQgYnkgcG9ydCAlZAoAAAAAAAAA -AAAAAAAAAABuZXRfbDNpbjRfZGV2X2NvbmZpZzogIGFkZHIgWzB4JXhdLCBtYXNrIFsweCV4XSwg -Z3cgWzB4JXhdLCByZWZfY250IFsweCV4XSBpbiB1c2UKAAAAAAAAAAAAAAAAAAB3cmhfY2huZXRf -aWZjb25mOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBsMmRldl9mYy0+Zmxvd2NfdHlwZSBb -JTB4XSwgaWZjb25mX3dyLT5zdWJvcCBbMHgleF0KAAAAAAAAAAAAAAAAAAAAd3JoX2NobmV0X2lm -Y29uZjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgdW5rbm93biBzdWJvcCBbMHgleF0KAAAA -AAAAAAAAAAAAAAB3cmhfY2huZXRfaWZjb25mOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBy -YyAlZAoAAAAAAAAAAAAAAAAAbmV0aWZfaXBfY29uZmxpY3RfdGltZXJfY2I6IGwyZGV2X2ZjLT5m -bG93Y19pZCBbMHgleF0sIGluZGV2Y3R4dC0+c3RhdGUgWyVkXSwgaW5kZXZjdHh0LT5yZXRyeV9j -bnQgWyVkXQoAAAAAAAAAAG5ldGlmX2lwX2NvbmZsaWN0X3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxv -d2NfaWQgWzB4JXhdLCBpbmRldmN0eHQgWzB4JXhdLCBpbiBmcmVlIHN0YXRlCgAAAAAAAAAAAGNt -ZGhfY2huZXRfaWZhY2U6IGZjIFsweCV4XSwgZmMtPmZsb3djX2lkIFsweCV4XSwgZmMtPmZsb3dj -X3R5cGUgWzB4JXhdLCBwIFsweCV4XSwgbGVuMTYgWyV1XSwgbG9jIFsweCV4XQoAAAAAAABjbWRo -X2NobmV0X2lmYWNlOmwyZGV2X2ZjIFsweCV4XSwgbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwg -bDJkZXYtPmZsb3djX3R5cGUgWyV1XSwgbDJkZXZfZmMtPmZsb3djX25ldF9sMmRldl9mbGFncyBb -JTB4XQoAAAAAAGNtZGhfY2huZXRfaWZhY2U6IHIyWzBdICV1IHIyWzFdICV1CgAAAAAAAAAAAAAA -AGNtZGhfY2huZXRfaWZhY2U6IGwyZGV2X2ZjLT5mbG93Y19uZXRfbDJkZXZfZmxhZ3MgY2hhbmdl -ZCBmcm9tIFslMHhdIHRvIFslMHhdLCByYyBbJWRdCgAAAAAAAAAAAGNobmV0X2wyZGV2X3VwX21i -X2NiOiByYyBbJWRdLCBwb3J0IFsldV0sIHN0YXRlIFsldV0sIGNvb2tpZSBbMHgleF0KAAAAAAAA -AAAAAAAAZGhjcF9wcm9jZXNzX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBkaGN0eHQt -PnN0YXRlIFslMHhdLCBkaGN0eHQtPnJ0cnlfY250IFsldV0KAAAAAAAAAAAAZGhjcF90aW1lcl9j -YjogREhDUERJU0NPVkVSIHNlbnQsIGJ1dCBubyByZXBseSBmcm9tIGFueSBwb3NzaWJsZSBzZXJ2 -ZXIgb24gdGhlIG5ldHdvcmsuIFJldHJ5aW5nIGFnYWluCgAAAAAAAAAAAGRoY3BfdGltZXJfY2I6 -IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIHNlbmRpbmcgREhDUERJU0NPVkVSIGZvciBkaGN0 -eHQgWzB4JXhdIG9uIHBpZCBbJWRdCgAAAGRoY3BfdGltZXJfY2I6IGwyZGV2X2ZjLT5mbG93Y19p -ZCBbMHgleF0sIERIQ1BPRkZFUiByZWNlaXZlZCBmb3IgZGhjdHh0IFsleF0gcGlkIFslZF0KAAAA -AAAAAAAAAGRoY3BfdGltZXJfY2I6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sICBESENQQUNL -IHJlY2VpdmVkIGZvciBkaGN0eHQgWyV4XSwgcGlkIFslZF0KAAAAAAAAAAAAAGRoY3BfdGltZXJf -Y2I6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIGRoY3R4dC0+aXBhZGRyIFsweCV4XQoAAAAA -AAAAAAAAAAAAAAAAZGhjcF90aW1lcl9jYjogc3RhcnRpbmcgdGltZXIgZm9yIGxlYXNlIFsldV0g -c2Vjb25kcwoAAAAAAAAAAAAAAGRoY3BfdGltZXJfY2I6IGxlYXNlIHRpbWUgb2YgWyV1XSBzZWNv -bmRzIGV4cGlyZWQsIHNlbmRpbmcgcmVuZXcgcmVxdWVzdAoAAAAAAAAAZGhjcF90aW1lcl9jYjog -bDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgbm8gcmVwbHkgZnJvbSBkaGNwIHNlcnZlciwgdGlt -aW5nIG91dAoAAAAAAAAAAAAAAAAAAAAAYXV0aF9uZWdvX3NlY3VyaXR5OiBzZW5kX2ZsYWcgWzB4 -JXhdLCBhdXRoX3BvbGljeSBbMHgleF0KAAAAAAAAAGF1dGhfbmVnb19zZWN1cml0eTogS0VZX0NI -QVBfUkVTUCAtIGhhc2hbMHgleCV4JXgleCV4JXgleCV4XQoAAABhdXRoX25lZ29fc2VjdXJpdHk6 -IEtFWV9DSEFQX1JFU1AgLSBoYXNoWzB4JXgleCV4JXgleCV4JXgleF0KAAAAYXV0aF9uZWdvX3Nl -Y3VyaXR5OiBLRVlfQ0hBUF9SRVNQIC0gZXJyb3IgZW5jb2RpbmcgdG8gaGV4CgAAAAAAAGF1dGhf -bmVnb19zZWN1cml0eTogS0VZX0NIQVBfUkVTUCAtIGVsZW4gWzB4JXhdCgAAAAAAAAAAAAAAAAAA -AABhdXRoX25lZ29fc2VjdXJpdHk6IEtFWV9DSEFQX0NIQUwgLSBlcnJvciBlbmNvZGluZyB0byBo -ZXgKAAAAAAAAYXV0aF9uZWdvX3NlY3VyaXR5OiBLRVlfQ0hBUF9DSEFMIC0gZWxlbiBbMHgleF0K -AAAAAAAAAAAAAAAAAAAAAGxvZ291dF90aW1lZG91dDogbG9nb3V0IHJlcXVlc3QgdGltZWRvdXQs -IHBvc3NpYmxlIG5ldHdvcmsgaXNzdWVzLiBGb3JjZWZ1bGx5IGJyZWFraW5nIHBhdGggZm9yIHNl -c3MgWzB4JXhdCgAAAABwaW5nX3RhcmdldDogcGluZyB0aW1lb3V0LCBraWNraW5nIHJlY292ZXJ5 -IGZvciBzZXNzIFsweCV4XQoAAAAAY3NvY2tfZmFpbGVkOiBjc2tfZmMtPmZsb3djX2lkIFsweCV4 -XSwgY3NrX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIHNlc3NfZmMtPmZsb3djX2lkIFsweCV4XSwg -c2Vzc19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBldnQgWzB4JXhdCgAAAAAAAAAAAAAAcmMgWyVk -XSwgY3NrX2ZjIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0KAAAAAAAAAAAAAAAAAAAA -AHJlY292ZXJ5X3RpbWVvdXQ6IHNlc3MgaWQgWzB4JXhdIHN0YXRlIFsweCV4XSwgcmNvdW50IFsl -ZF0sIGZsYWdzIFsweCV4XQoAAAAAAAAAcmVjb3ZlcnlfdGltZW91dDogc2VzcyBpZCBbMHgleF0g -aW4gbG9nb3V0LCBhYm9ydCB0aGUgY29ubmVjdGlvbgoAAAAAAAAAAAAAAAAAAAByZWNvdmVyeV90 -aW1lb3V0OiBzZXNzX2ZjLT5mbG93Y19mb2lzY3NpX3Nlc3NfZmxhZ3MgWzB4JXhdLCBjb25uZWN0 -aW9uIHJlcXVlc3QgcGVuZGluZywgYmFpbGluZyBvdXQKAAAAAAAAAAAAAAAAZm9pc2NzaTogUmVj -b3ZlcnkgdGltZWQgb3V0IGFmdGVyIFsldV0gcmV0cnksIGJhaWxpbmcgb3V0CgAAAAAAAFRDUCBj -b25uIGVzdGFibGlzaG1lbnQgZmFpbGVkICVkCgAAAAAAAAAAAAAAAAAAAGRpc2NvdmVyeV9kYXRh -OiBzZXNzIHsgaWQgWzB4JXhdLCBmbGFncyBbMHgleF0sIGJ1ZmZlcmVkIFsldV0uIH0KAAAAAAAA -AAAAAAAAAAAAZGlzY292ZXJ5X2RhdGE6IHNlc3MgeyBpZCBbMHgleF0gfSwgdWxwdHhjaCBbJXVd -IG5vIGNyZWRpdHMgYXZhaWxhYmxlLCByZXNjaGVkdWxpbmcgcmVxdWVzdC4KAAAASW52YWxpZCBv -cGNvZGUgMHgleCBpbiBjdHJsIHBhdGgKAAAAAAAAAAAAAAAAAAAARERQIGVycm9yIFsweCV4XSwg -YWJvcnRpbmcgY29ubm4gWzB4JXhdCgAAAAAAAAAAcnhfZGF0YV9kZHA6IFJlc3BvbmNlIHJlY2ll -dmVkIGZvciB0YXNrIFsweCV4XSB3aGlsZSBpbnZhbGlkIHRhc2sgb3IgY29ubmVjdGlvbiBzdGF0 -ZS4gdGFzayBzdGF0ZSBbMHgleF0sIGNvbm4gc3RhdGUgWzB4JXhdLCBjb25uIGZsYWdzIFsweCV4 -XQoAaXNjc2lfaGRyX3J4OiBSZXNwb25jZSByZWNpZXZlZCBmb3IgdGFzayBbMHgleF0gd2hpbGUg -aW52YWxpZCB0YXNrIG9yIGNvbm5lY3Rpb24gc3RhdGUuIHRhc2sgc3RhdGUgWzB4JXhdLCBjb25u -IHN0YXRlIFsweCV4XSwgY29ubiBmbGFncyBbMHgleF0KAAAAAAAAAAAAAAAAAAAAAGlzY3NpX2hk -cl9yeDogSW52YWxpZCB0YXNrIHN0YXRlIDB4JXggZm9yIHRhc2sgMHgleCwgaXR0IFsweCV4XSwg -b3BjIFsweCV4XQoAAAAAcHJvY2Vzc190bWZfcmVzcG9uc2U6IGJ1ZmZlcmVkIFsweCV4XSwgaXN0 -YXNrX2ZjLT5mbG93Y19idWYtPnNjaGVkX25vZGUubmV4dCBbMHgleF0sIGlzdGFza19mYyBbMHgl -eF0sIGlzdGFza19mYy0+Zmxvd2NfaWQgWzB4JXhdCgAAAAAAAAAAAAAAAAAAcHJvY2Vzc190bWZf -cmVzcG9uc2U6IHdyIG9wIFsweCV4XSwgdG1mIG9wIFsweCV4XQoAAAAAAAAAAAAAAAAAAHJldHVy -bl9wZW5kaW5nX3Rhc2s6IGNvb2tpZSBbMHglMDh4XSwgWzB4JTA4eF0KAHJldHVybl9wZW5kaW5n -X3Rhc2s6IGRlbGF5IHByb2Nlc3NpbmcsIGNvbm4gZmxhZ3MgWzB4JXhdCgAAAAAAAAByZXR1cm5f -cGVuZGluZ190YXNrOiBEb25lIHNlbmRpbmcgdGFzayBlcnJvciB0byBob3N0LCB1bHB0eGxlbjE2 -IFsldV0KAAAAAAAAAAAAAHJldHVybl9wZW5kaW5nX3Rhc2s6IGRlcXVldWUgdGFzayBbMHgleF0s -IHN0YXRlIFsweCV4XSBmcm9tIHR4X2xpc3QKAAAAAAAAAAAAAAAAcmV0dXJuX3BlbmRpbmdfdGFz -azogYWxsIHRhc2tzIHJldHVybmVkLCByZWNvdmVyeSBzdGF0ZSB0cmFucyB0byBbMHgleF0KAAAA -AAAAAABjbGVhcl9kZHBfbWFwOiBpc3Rhc2tfZmMgWzB4JXhdLCBpc3Rhc2tfZmMtPmZsb3djX2lk -IFsweCV4XSBidWZmZXJlZCAldQoAAAAAAAAAAGNsZWFyX2RkcF9tYXA6IGlzdGFza19mYy0+Zmxv -d2NfZm9pc2NzaV90YXNrX25wcG9kICV1LCBucHBvZCAldSwgcHBkYWRkciBbMHgleF0KAAAAAAAA -AAAAAAAAAAAAAGNsZWFyX2RkcF9tYXA6IGFsbCByZXR1cm5lZCB0YXNrcyBkZHAgY2xlYXJlZCwg -cmVjb3Zlcnkgc3RhdGUgdHJhbnMgdG8gWzB4JXhdCgAAd3JoX2ZvaXNjc2lfbm9kZTogbm9kZV93 -ci0+Zmxvd2lkX2xlbjE2IDIgWyV4XQoAd3JoX2ZvaXNjc2lfY2hhcDogaWRfbGVuIFsleF0sIHNl -Y19sZW4gWyV4XQoAAAAAd3JoX2ZvaXNjc2lfY2hhcDogdGd0X2lkX2xlbiBbJXhdLCB0Z3Rfc2Vj -X2xlbiBbJXhdCgAAAAAAAAAAAAAAAHNlc3Npb25fYmxvY2s6IHNlc3NfZmMtPmZsb3djX2lkIFsw -eCV4XSwgc2Vzc19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBjb25uX2ZjLT5mbG93Y19pZCBbMHgl -eF0sIGNvbm5fZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0s -IGNza19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdCgAAAAAAAAAAAAAAAAAAAHNlc3Npb25fdW5ibG9j -azogc2Vzc19mYy0+Zmxvd2NfaWQgWzB4JXhdLCBzZXNzX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0s -IGNvbm5fZmMtPmZsb3djX2lkIFsweCV4XSwgY29ubl9mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBj -c2tfZmMtPmZsb3djX2lkIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0KAAAAAAAA -AAAAAAAAAHN0YXJ0X2xvZ291dDogU2Vzcy1pZCBbMHgleF0gYWxyZWFkeSBsb2dnaW4gb3V0LgoA -AAAAAAAAAAAAAAAAAABwZWVyX2NvbjogY3NrX2ZjID0+IGZsb3dpZCBbMHgleF0sIGZsb3djX2J1 -ZiBbMHgleF0KAAAAAAAAAAAAAAAAYWxsb2Nfc2VzczogbG9naW5fcmV0cnkgWyVkXSwgcmVjb3Zf -dGltZW91dCBbJWRdCgAAAAAAAAAAAAAAAAAAAGZvaXNjc2lfY3RybDogc3Vib3AgWzB4JXhdLCBz -ZXNzX3R5cGVfdG9fZXJsIFsweCV4XSwgc2Vzc190eXBlIFsweCV4XQoAAAAAAAAAAAAAZm9pc2Nz -aV9jdHJsOiByZWNlaXZlZCBibG9ja2VkIGZyb20gZHJpdmVyLCB0cmlnZ2VyaW5nIHJldHVybiB0 -YXNrcyBub3cuCgAAAAAAAAB3YXRjaGRvZyBjbWQgaGFuZGxlciAodGltZSAldSBhY3Rpb24gJXUp -CgAAAAAAAAB4Z21hY1sldV0gc2V0dGluZy91bnNldHRpbmcgaHNzIHJlc3luYyBiaXQKAAAAAABX -QVRDSERPRzogZGV2aWNlIHNodXRkb3duCgAAAAAAAFdBVENIRE9HOiBwb3J0WyV1XSBwYXVzZSB3 -YXRjaGRvZyB0aW1lb3V0CgAAAAAAAFdBVENIRE9HOiBieXBhc3MgdGltZW91dAoAAAAAAAAAV0FU -Q0hET0c6IEZMUiAtIG5vdCBpbXBsZW1lbnRlZCB5ZXQKAAAAAAAAAAAAAAAAV0FUQ0hET0c6IHRl -bXBlcmF0dXJlIG9mICVkQyBleGNlZWRzIHRocmVzaG9sZCBvZiAlZEMKAAAAAAAAAAAAAGZpbHRl -cjogcG9yZ3JhbW1pbmcgdGlkICV1IChsZSB0Y2FtIGluZGV4ICV1KS4uLgoAAAAAAAAAAAAAAAAA -AABmaWx0ZXI6IHJlcXVlc3RpbmcgY29tcGxldGlvbi4uLgoAAAAAAAAAAAAAAAAAAABsMmRldl9z -ZW5kX3BvcnRfZXZlbnQ6IHdyIFsweCV4XSBwZW5kaW5nIG9uIHBvcnQgWyVkXSwgY3VycmVudCB0 -cnkgWyVkXQoAAAAAAAAAAEZDT0UgRnJlZTogc3RpbGwgeWllbGRlZCB3aGVuIGZyZWVpbmcuLi5m -bG93Y19pZCAleCBmbG93Y19mbGFncyAleCAKAAAAAAAAAAAAAAAARkNPRSBCUCBXUiBFUlI6IFdS -IHdpdGggY29va2llICV4JXggZXJyb3JlZCBiYWNrIAoAAAAAAAAAAAAAAAAAAHBvcnQgJWQgc2V0 -IHBmY19lbiA9IDB4JXgKAAAAAAAAcG9ydCAlZCBzZXQgcGZjX2VuID0gMHgleAoAAAAAAABldHNf -c2V0X2NmZ19pZWVlWyV1XSB1bmtub3duIFRTQSBhbGcgZm9yIHByaW8gJXU6ICV1CgAAAAAAAAAA -AAAARkNvRSBERFAgZmFpbGVkIDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAARkNvRSBE -RFAgZmFpbGVkIDogRGRwUmVwb3J0IDB4JXggRGRwVmFsaWQgMHgleAoARkMgeGNoZyBhbGxvYyBm -YWlsZWQ6IGF2YWlsICVkCgBmY29lIG5vdGlmeSA6IFVwZGF0ZSBuZXcgRENCWCB2YWx1ZXMgVkkg -c3RhdGUgMHgleCBwcmkgMHgleCBzY2hlZGNsIDB4JXggZGNieF9kb25lIDB4JXgKAAAAAAAAAABm -Y29lIG5vdGlmeSA6IEZDRiBmbG93aWQgMHgleCwgdWxwY2ggMHgleCAKAAAAAABQUkxJIFJzcCB0 -aW1lZG91dCA6IGZsb3djX2lkIDB4JXggb3hfaWQgMHgleCByeF9pZCAweCV4IAoAAAAAAAAAY2Fu -bm90IGFsbG9jYXRlIG9mZmxvYWRlZCBmaWx0ZXIgY29ubmVjdGlvbgoAAAAAY2Fubm90IGFsbG9j -YXRlIG9mZmxvYWRlZCBmaWx0ZXIgSVB2NiBjb25uZWN0aW9uCgAAAAAAAAAAAAAAAAAAAGRpc3Bh -dGNoX2RlZmVycmVkX2NsYXNzX2NsYXNzX3NoYXBpbmdbJXU6JXVdOiBsaXN0X2VtcHR5CgAAAAAA -AABsb29wYmFjayBidWZmZXIgZ3JvdXBbJXVdIGlzIGRpc2FibGVkCgAAAAAAAAAAAABpbnZhbGlk -IGJ1ZmZlciBncm91cFsldV0gY29uZmlndXJhdGlvbjogbXR1ICV1IGx3bSAldSBod20gJXUgZHdt -ICV1CgAAAAAAAAAAAAAAAGZjICV1IHZmICV1IGdvdCBpdmY9MHgleCxyYW5nZTogJSN4LSUjeCAo -JXUvJXUgdXNlZCkKAAAAAAAAAAAAAABWSSAldSBjYW5ub3QgZ2V0IFJTUyBzbGljZTogTm8gbW9y -ZSBzbGljZXMgYXZhaWxhYmxlICh1c2VkICV1LyV1KQoAAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4g -JXUgd2l0aCBwb3J0IG1hc2sgMHgleCBjYW5ub3QgYWNjZXNzIHBvcnQgJXUsIHJldCAlZAoAAAAA -AAAAAAAAAAAAAAAAcGZuICV1IHZmbiAldSBjb3VsZCBub3QgYWxsb2NhdGUgdmlpZCwgcmV0ICVk -CgAAcGZuICV1IHZmbiAldSBjb3VsZCBtYXAgdmlpZCAgMHgleCB0byBmbG93YywgcmV0ICVkCgAA -AAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgY291bGQgbm90IGFsbG9jYXRlIHV3aXJlIGZ1bmMgJWQg -bWFjIGFkZHIsIHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAbWlpX2ZvcmNlX3NwZWVkWyV1XTogcmNh -cHMgMHgleAoAAAAAAAAAAAAAAAAAAAAAbWlpX3Bkb3duWyV1XTogcG93ZXJkb3duIGVuICV1CgBw -b3J0WyV1OjB4JTAyeDoweCUwMnhdOiB1bmtub3duIGFjdGlvbiAweCV4CgAAAABwb3J0WyV1OjB4 -JTAyeDoweCUwMnhdOiB1bmtub3duIHJlYWQgYWN0aW9uIDB4JXgKAAAAAAAAAAAAAAAAAAAAY3Bs -X2Vycl9ub3RpZnk6IHRpZCAldSBjcGwgMHglMDh4JTA4eAoAAAAAAAAAAAAAY3BsX2Vycl9ub3Rp -Znk6IHRpZCAldSBjcGwgMHglMDh4JTA4eCAweCUwOHglMDh4CgAAAAAAAAAAAAAAAAAAAGNwbF9l -cnJfbm90aWZ5OiB0aWQgJXUgbGVuICV1CgAARkNPRSBGcmVlOiBzdGlsbCB5aWVsZGVkIHdoZW4g -ZnJlZWluZy4uLmZsb3djX2lkICV4IGZsb3djX2ZsYWdzICV4IAoAAAAAAAAAAAAAAABzY3NpX2Fi -b3J0OiBFbnRlcmluZyBBYm9ydF90YXNrLCBidWZmZXJlZCBbJXVdCgBzY3NpX2Fib3J0OiByYyBb -MHgleF0gcmVmIHRhc2sgbm90IG91dHN0YW5kaW5nCgBzY3NpX2Fib3J0OiBpZGF0YS0+b3AgWzB4 -JXhdLCBmbGFncyBbMHgleF0sIGZ1bmMgWzB4JXhdLCBsdW5faWR4IFsweCV4XQoAAAAAAAAAAHNj -c2lfYWJvcnQ6IHdyLT5pcWlkIFsweCV4XSwgaXN0YXNrX2ZjLT5mbG93Y19zZ2VfaXFpZCBbMHgl -eF0sIGlzdGFza19mYyB0YXNrIGZsYWdzIFsweCV4XQoAAAAAAHNjc2lfYWJvcnQ6IGNvbm4gWzB4 -JXhdLCBjbWRzbiBbMHgleF0sIHNlbnRfY21kc24gWzB4JXhdLCBtYXhfY21kc24gWzB4JXhdLCBp -dHQgWzB4JXhdCgAAAAAAAAAAAGFib3J0L2Nsb3NlIFdSIHdpdGggY29va2llIDB4JWx4IHdhcyBp -c3N1ZWQgb24gc3NuIDB4JXggaW4gd3Jvbmcgc3RhdGUgMHgleAoAAAAAYWJvcnQgV1Igb24gc3Nu -IDB4JXggZGlkIG5vdCBmaW5kIFdSIHdpdGggY29va2llIDB4JXgleAoAAAAAAAAAAGNsb3NlIFdS -IHdpdGggY29va2llIDB4JWx4IG9uIHNzbiAweCV4O2RpZCBub3QgZmluZCBXUiB3aXRoIGNvb2tp -ZSAweCVseAoAAAAAAAAAYWJvcnQgV1Igb24gc3NuIDB4JXggd2FzIGlzc3VlZCBvbiB4Y2hnIDB4 -JXggd2l0aCByeF9pZCAweCV4IGluIHdyb25nIHN0YXRlIDB4JXgKAAAAAAAAAAAAAAAAAAAAc2Nz -aV9sdXI6IEVudGVyaW5nIExVUiBoYW5kbGVyLCBidWZmZXJlZCBbJXVdCgAAc2NzaV9sdXI6IGlk -YXRhLT5vcCBbMHgleF0sIGZsYWdzIFsweCV4XSwgZnVuYyBbMHgleF0sIGx1bl9pZHggWzB4JXhd -CgAAAAAAAAAAAABzY3NpX2x1cjogd3ItPmlxaWQgWzB4JXhdLCBpc3Rhc2tfZmMtPmZsb3djX3Nn -ZV9pcWlkIFsweCV4XSwgaXN0YXNrX2ZjIHRhc2sgZmxhZ3MgWzB4JXhdCgAAAAAAAABzY3NpX2x1 -cjogY29ubiBbMHgleF0sIGNtZHNuIFsweCV4XSwgc2VudF9jbWRzbiBbMHgleF0sIG1heF9jbWRz -biBbMHgleF0sIGl0dCBbMHgleF0KAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1 -cmVbJXVdIEZFQVRVUkVfTElOS1VQCgBkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIFNF -VF9MT0NBTF9QQVJBTUVURVJTCgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJl -WyV1XSBGRUFUVVJFX05PX0FEVkVSVElTRQoAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0g -RmVhdHVyZVsldV0gRkVBVFVSRV9QRUVSX05PVF9BRFZFUlRJU0VfRENCWAoAAAAAAAAAAAAAAAAA -AAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1BFRVJfTk9UX0FEVkVS -VElTRV9GRUFUVVJFCgAAAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVd -IEZFQVRVUkVfVVBEQVRFX09QRVJfVkVSU0lPTgoAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0 -dXJlWyV1XSBGRUFUVVJFX1BFRVJfVVBEQVRFX09QRVJfVkVSU0lPTgoAAAAAAAAAAAAAAAAAAABk -Y2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfR0VUX1BFRVJfQ0ZHCgAAAAAA -AAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0NGR19OT1RfQ09N -UEFUSUJMRQoAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VU0Vf -TE9DQUxfQ0ZHCgAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRV -UkVfVVNFX1BFRVJfQ0ZHCgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1 -XSBGRUFUVVJFX0ZFQVRVUkVfRElTQUJMRUQKAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVh -dHVyZVsldV0gRkVBVFVSRV9FUlJPUl9DSEFOR0UKAAAAAAAAAAAAAABGZWF0dXJlICV1IHN5bmMn -ZD0ldSAoZXJyb3IgJXUpCgAAAAAAAAAAAAAAAAAAAABjaG5ldF9sMnRfdXBkYXRlOiBsMmRldl9m -YyBbMHgleF0sIGwyZGV2X2ZjLT5mbG93Y19pZCBbJXVdIGwyZGV2X2ZjLT5mbG93Y19mbGFncyBb -MHgleF0sIGludGYgWzB4JXhdCgAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZTogbDJkZXZfZmMt -PmZsb3djX2lkIFsldV0gYWxyZWFkeSBzY2hlZHVsZWQKAAAAAGNobmV0X2wydF91cGRhdGU6IGlu -IGRlbGF5ZWRfcHJvY2Vzc2luZywgbDJ0ZW50IFslMDh4XQoAAAAAAAAAAABjaG5ldF9hcnBfdXBk -YXRlX2NhY2hlOiBhcnAgaXA0IGVudHJ5IGZvdW5kIAoAAABjaG5ldF9hcnBfdXBkYXRlX2NhY2hl -OiBhcnAgaXA2IGVudHJ5IGZvdW5kIAoAAABjaG5ldF9hcnBfdXBkYXRlX2NhY2hlOiBib3RoIGlw -NCBhbmQgaXA2IGFkZHIgY2Fubm90IGJlIG51bGwKAAAAY2huZXRfbDJ0X3VwZGF0ZTogbDJ0X3Vw -ZGF0ZSByZXF1ZXN0IHNlbnQgbDJ0ZW50IFslMDh4XSwgbDJ0ZW50LT5pZHggWyVkXSwgbDJ0ZW50 -LT52bGFuIFslZF0KAAAAbmV0aWZfcHJvY2Vzc19kaGNwOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4 -JXhdLCBwcm9jZXNzaW5nLCBvcHRfbGVuICV1CgAAAAAAAAAAAABjaG5ldF9kaGNwX3JlY3Y6IHZs -YW5pZCBbJXVdLCBsMmRldl9waWRfZmMtPmZsb3djX25ldF9sMmRldl92bGFuZGV2IFsweCV4XSwg -bDJkZXZfZmMgWzB4JXhdCgAAAABjaG5ldF9kaGNwX3JlY3Y6IGwyZGV2X2ZjLT5mbG93Y19pZCBb -MHgleF0sIGRoY3R4dC0+c3RhdGUgWyVkXSwgbWFsYWNpb3VzIGRoY3AgcmVjdiBmb3Igbm8gcmVx -dWVzdAoAAAAAAAAAAAAAAAAAZGhjdHh0LT5zdGF0ZSA6ICVkCgAAAAAAAAAAAAAAAABsMmRldl9m -Yy0+Zmxvd2NfaWQgWzB4JXhdLCBCYWQgREhDUCBjb29raWUgcmVjaWV2ZWQsIGFib3J0aW5nCgAA -Q291bGQgbm8gYWxsb2NhdGUgcGNiISEgRnJlZWluZyBmY2YgISEhCgAAAAAAAAAAdm5fcGFyc2Ug -dW5rbm93biBzdWJjb2RlICV1CgAAAAB2bl9wYXJzZSB1bmtub3duIGR0eXBlICV1CgAAAAAAAGln -bm9yaW5nIGZpcCByZWN2IGZvciBwY2IgZmxvdzoleCBpbiBvZmZsaW5lIHN0YXRlCgAAAAAAAAAA -AAAAAABmaXBfdm4ydm5fcmVjdl9lcnIgCgAAAAAAAAAAAAAAAENvdWxkIG5vdCBhbGxvY2F0ZSBm -bG93YyEhISEKAAAAQ291bGQgbm90IGFsbG9jYXRlIFNDQiBmbG93YyEhISEKAAAAAAAAAAAAAAAA -AAAAQ291bGQgbm90IGZpbmQgcmlnaHQgc2NiIGZvciBsb2dvCgAAAAAAAAAAAAAAAAAAaWdub3Jp -bmcgZmlwIHJlY3YgZm9yIGZjZiBmbG93OiV4IGluIG9mZmxpbmUgc3RhdGUKAAAAAAAAAAAAAAAA -AENvdWxkIG5vdCBmaW5kIHJpZ2h0IHNjYiBmb3IgZmxvZ2kKAAAAAAAAAAAAAAAAAHBvcnQgMHgl -eCwgc3RhdGUgMHgleCwgcmV0cnkgbm90IHN1cHBvcnRlZAoAAAAAAEZsb2dpIHJlc3AgcmN2IHdp -dGggdW5rbm93biB4Y2hnIG94X2lkJXggc2lkICUyeCUyeCUyeCBkaWQgJTJ4JTJ4JTJ4CgAAAAAA -AAAAAAAATl9QT1JUIDB4JXgleCV4IHJlamVjdGVkIFBMT0dJIHdpdGggcmVhc29uIGNvZGUgJXgK -AAAAAAAAAAAAAAAAAEFCVFMgd2hpbGUgYXdhaXRpbmcgUFJMSSBSc3A6IGZsb3djX2lkIDB4JXgg -b3hfaWQgMHgleCByeF9pZCAweCV4IAoAAAAAAAAAAAAAAAAAQUJUUyBmYWtlIFJzcDogbG9jIDB4 -JXggb3hfaWQgMHgleCByeF9pZCAweCV4CgAARkMgZmNiIGFsbG9jIGZhaWxlZDogYXZhaWwgJWQK -AABGQyBmY2IgYWxsb2MgeGlkOiVkIGZsb3dpZCAlZAoAAGxsZHBfcnhfcGt0X2hhbmRsZXJbJXVd -IGRyb3AgcHJlLWluaXQgKGNvdW50ID0gJXUpCgAAAAAAAAAAAAAAAAAleCV4JXggUmVjaWV2ZWQg -TE9HTyBmcm9tICV4JXgleCAKAAAAAAAAAAAAAAAAAABjYW5ub3QgYWxsb2NhdGUgUE9GQ09FIGZp -bHRlciBjb25uZWN0aW9uIGZvciB4X2lkICV4IAoAAAAAAAAAAAAARmFpbGVkIHRvIHBvc3QgeGNo -ZyBlcnI6IHNzbmkgMHgleCBjb29raWUgMHglbHggcnZhbCAleCAKAAAAAAAAAHRjcF9yZWxlYXNl -X3RpZDogdGlkIFsweCV4XSwgZmxvd2MgZmxhZ3MgWzB4JXhdLCBidWZmZXJlZCBbMHgleF0KAAAA -AAAAAAAAAAAAAAAAdGNwX3JlbGVhc2VfdGlkOiBzaXplb2YodGNiX2ZjLT5mbG93Y19mb2lzY3Np -X2Nvbm4pIFsldV0sIGJ5dGVzCgAAAAAAAAAAAAAAAAAAAABhY3Rfb3Blbl9ycGw6IGF0aWQgWzB4 -JXhdLCB0aWQgWzB4JXhdLCB0Y2JfZmMtPnsgaWQgWzB4JXhdLCBzdGF0ZSBbMHgleF0sIHR5cGUg -WzB4JXhdIH0sIGNwbF9vcCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAAAAAAAAAAAGFjdF9vcGVu -X3JwbDogY3NrX2ZjLT57IGlkIFsweCV4XSwgc3RhdGUgWzB4JXhdLCBjc29ja19mbGFncyBbMHgl -eF0gfSAKAAAAAAAAAAAAYWN0X29wZW5fcnBsOiByZWN2ZCBuZWcgYWR2aWNlIFsweCV4XQoAAAAA -AAAAAAAAc2VuZF9hYm9ydF9ycGw6IGNza19mYy0+Zmxvd2NfdHlwZSBbMHgleF0sIGNza19mYy0+ -Zmxvd2NfaWQgWzB4JXhdLCB0aWQgWzB4JXhdLCB1bHB0eGNoIFsldV0sIGJ1ZmZlcmVkIFsldV0K -AAAAAHdyaF9vZmxkX3RjcF9jbG9zZV9jb25fcmVwbHk6IHRjYl9mYy0+Zmxvd2NfaWQgWzB4JXhd -LCB0Y2JfZmMtPmZsb3djX3R5cGUgWzB4JXhdLCBsZW4xNiBbJXVdLCBsb2MgWyV1XQoAAAAAAAAA -AAB3cmhfb2ZsZF90Y3BfY2xvc2VfY29uX3JlcGx5OiBycGwtPm9wX1RpZCBbMHgleF0sIHJwbD5z -dGF0dXMgWzB4JXhdLCBycGwtPnNuZF9ueHQgWzB4JXhdLCBycGwtPnJjdl9ueHQgWzB4JXhdCgAA -dGNwX2Fib3J0X3JwbF9yc3M6IHRpZCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAAdGNwX2Fib3J0 -X3JlcV9yc3M6IHRpZCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAAb2ZsZF9hYm9ydF9yZXFfbmVn -YWR2WyV1XTogd3IgMHglMDh4IGNwbF9hYm9ydF9yZXEgREVMSVZFUkVECgAAAGhvc3Rfd3JbJXVd -OiB3ciAweCUwOHggY3BsX2Fib3J0X3JlcSBzdGF0dXMgMHgleAoAAAAAAAAAAAAAAAAAAABwa3Rz -Y2hlZF9jbF9ybFsldToldV06IG1vZGUgfCB1bml0IHwgcmF0ZSAweCUwNnggbWluICV1IG1heCAl -dSBwa3RzaXplICV1CgAAAAAAAHBhcmFtX2NobmV0WzB4JXg6MHgleF06IGNobmV0IDB4JXggcmVh -ZCAldSBwZiAldSByZXQgJWQKAAAAAAAAAABwYXJhbV9kbWFxWzB4JXg6MHgleF06IGRtYXEgMHgl -eCByZWFkICV1IHBmICV1IHJldCAlZAoAAAAAAAAAAAAATUNbJXVdIGluaXRfc3RhdGVfbWFjaGlu -ZSAweCUwMngKAAAAAAAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24gbm90IGNvbXBsZXRpbmcs -IE1DIGN1cnJlbnQgaW5pdCBzdGF0ZSBpcyAweCUwMngKAAAAAAAAAAAAAAAAAABNQ1sldV0gX2h3 -X21jX2luaXRfbWMKAAAAAAAAAAAAAHBoeTogZmFpbGVkIHRvIGFsbG9jYXRlZCBtZW1vcnkgZm9y -IHBoeSBmdyBmaWxlLCByZXQgJWQKAAAAAAAAAABod19sZV9maWx0ZXJfY3R1cGxlOiB0dXBsZSAl -dSBub3Qgc3BlY2lmaWVkIGJ1dCByZXF1aXJlZCBmb3IgbWFzayAweCV4CgAAAAAAAAAAAGh3X3Rw -X3RjcF9zZXR0aW5nc193OiB0aW1lcl9ycyAldXVzIHRpbWVzdGFtcF9yZXMgJXV1cyBkZWxheWVk -YWNrX3JlcyAldXVzCgAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGRhY2tfdGltZXIgJXV1cyBt -c2wgJXV1cyByeHRfbWluLG1heCAldSwldXVzIHBlcnNfbWluLG1heCAldSwldXVzCgAAAAAAAAAA -aHdfdHBfdGNwX3NldHRpbmdzX3c6IGtlZXBfaWRsZSxpbnR2bCAldSwldXMgbWF4cnR0ICV1dXMg -aW5pdHNydHQgJXV1cyBmaW53YWl0Ml90aW1lciAldXVzCgAAAAAAaHdfdHBfdGNwX3NldHRpbmdz -X3c6IGNhcHBpbmcgZGFja190aW1lciBmcm9tICV1IHRvICV1AAAAAAAAAAAAAGh3X3RwX3RjcF9z -ZXR0aW5nc193OiBjYXBwaW5nIG1zbCBmcm9tICV1IHRvICV1AGh3X3RwX3RjcF9zZXR0aW5nc193 -OiBjYXBwaW5nIHJ4dF9taW4gZnJvbSAldSB0byAldQAAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0 -dGluZ3NfdzogY2FwcGluZyByeHRfbWF4IGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAAAAaHdfdHBf -dGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcGVyc19taW4gZnJvbSAldSB0byAldQAAAAAAAAAAAAAA -AGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHBlcnNfbWF4IGZyb20gJXUgdG8gJXUAAAAA -AAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBrZWVwX2lkbGUgZnJvbSAldSB0 -byAldQAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcga2VlcF9pbnR2bCBm -cm9tICV1IHRvICV1AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGluaXRf -c3J0dF9tYXhydHQgZnJvbSAldSB0byAldQAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGlu -ZyBpbml0X3NydHRfaW5pdHNydHQgZnJvbSAldSB0byAldQAAaHdfdHBfdGNwX3NldHRpbmdzX3c6 -IGNhcHBpbmcgZmlud2FpdDJfdGltZXIgZnJvbSAldSB0byAldQAAAAAAAGxlIGNvbmZpZ3VyYXRp -b246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IGFjdGl2ZSAldSBzZXJ2 -ZXIgJXUgaGFzaCAldQoAAAAAAAAAAAAAAGxlIGNvbmZpZ3VyYXRpb246IG5lbnRyaWVzICV1IHJv -dXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IHNlcnZlciAldSBhY3RpdmUgJXUgaGFzaCAldSBuc2Vy -dmVyc3JhbSAldQoAAAAAAAAAAAAAAABod19zZ2VfcXVldWVfYmFzZV9tYXBbJXVdOiBleGNlZWRl -ZCBudW1iZXIgb2YgZWdyZXNzIHF1ZXVlcywgJXUKAAAAAAAAAAAAAAAAAAAAAGh3X3NnZV9xdWV1 -ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBvZiBpbmdyZXNzIHF1ZXVlcyB3aXRoIGZy -ZWVsaXN0IGFuZCBpbnRlcnJ1cHQsICV1CgAAAGh3X3NnZV9xdWV1ZV9iYXNlX21hcFsldV06IGV4 -Y2VlZGVkIG51bWJlciBvZiBpbmdyZXNzIHF1ZXVlcywgJXUKAAAAAAAAAAAAAAAAAAAAY2ZfcGFy -c2U6IGZpbGUgbWVtdHlwZSAweCV4IG1lbWFkZHIgMHgleCBtYXBwZWQgQCAlcDoKAAAAAAAAAAAA -AGNvbmZpZ3VyZWQgd2l0aCBjYXBzIG5ibXxsaW5rIDB4JTA4eCBzd2l0Y2h8bmljIDB4JTA4eCB0 -b2V8cmRtYSAweCUwOHggaXNjc2l8ZmNvZSAweCUwOHgKAAAAAAAAAG5ldCBWSSBhbGxvY2F0aW9u -IGZhaWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAAAAAAAAAAABuZXQgVkkgbWFj -IGFkZHJlc3MgcHJvZ3JhbW1pbmcgZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAA -AAAAAAAAAAAAAAAAAG5ldCBWSSByeG1vZGUgcHJvZ3JhbW1pbmcgZmFpbGVkIGZvciBmY19pZCAl -dSB3aXRoIGVycm9yICVkCgAAAABuZXQgVkkgcnNzIGluZGlyZWN0aW9uIHRhYmxlIHByb2dyYW1t -aW5nIGZvciBmY19pZCAldSBmYWlsZWQgd2l0aCBlcnJvciAlZAoAAAAAAG5ldCBWSSByc3MgY29u -ZmlnIGNvbW1hbmQgZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAAAABuZXQgVkkg -Y29tbWFuZCBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAAAAAAAAAAAAAAAA -cHJvZ3JhbW1lZCBIVyB0YWdtIFsweCUwOHhdLCBIVyBwZ3N6IGZhY3RvciBbMHglMDh4XSwgRk9p -U0NTSSB0YWdtIFsweCUwOHhdLCBydGFnbSBbMHglMDh4XSwgbWF4c3pfYml0cyBbJXVdLCBzel9i -aXRzIFsldV0uCgAAAABiYXNlIFsgMHglMDh4XSwgbGxpbWl0IFsweCUwOHhdLCB1bGltaXQgWzB4 -JTA4eF0sIHNpemUgWyV1XSwgbWF4X3R4c3ogWyV1XSwgbWF4X3J4c3ogWyV1XSwgaW9zaXplIFsl -dV0KAAAAAAAAAAAAbnBwb2RzIFsldV0sIGlkeF9tYXNrIFsweCUwOHhdLCBpZHhfZmlyc3QgWyV1 -XSwgaWR4X2xhc3QgWyV1XSwgc2NzaV9wbGRfc2l6ZSBbJXVdLCBBTElHTihzY3NpX3BsZF9zaXpl -LCAxNikgWyV1XSwgcHBkX3pvbmVzIFsldV0uCgAAAAAAAAAAAAAAAAAAZm9pc2NzaV9pbml0OiBm -b2lzY3NpX2luaXRfZG9uZSBbJXVdLCBkZXYucmVzLmZvaXNjc2lfbnRhc2tzIFsldV0sIGRldi5y -ZXMuZm9pc2NzaV9uc2VzcyBbJXVdLCBkZXYucmVzLm5jc29jayBbJXVdLCBkZXYucmVzLmZvaXNj -c2lfbmluaXQgWyV1XSwgcmMgWyVkXQoAAAAAAAAAAGNoX2NsX3JhdGVbJXUvJXVdOiBjYXBwZWQg -Y2xhc3MgcmF0ZSBmcm9tIHJlcXVlc3RlZCAldSB0byBjb25maWd1cmVkIChlZmZlY3RpdmUpIGNo -YW5uZWwgcmF0ZSAldQoAAAAAAAAAAAAAAAAAAABjaF9jbF9yYXRlWyV1LyV1XTogaW5jcmVhc2Vk -IGRlZmljaXRfaW5jciBmcm9tIHJlcXVlc3RlZCAldSB0byByZXF1aXJlZCBtaW4gb2YgJXU7IHJh -dGUgJXUgKGVmZiAldSkgZGVmaWNpdF9tYXggJXUKAAAAAAAAAAAAAAAAAHBrdHNjaGVkIGNoYW5u -ZWwgJXUgc2V0cyBzcGVlZCAoZnJvbSAldSkgdG8gJXUga2JwcwoAAAAAAAAAAAAAAABuZXRfbDJk -ZXZfbm90aWZ5OiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBwb3J0IFslZF0sIGV2ZW50IFsw -eCV4XSwgdWxwdHhjaCBbJXVdLCBjbGFzcyBbMHgleF0sIHZwcmlvIFsweCV4XSwgdmlkIFsweCV4 -XSwgdmlfcmVhZHkgWyV1XQoAAAAAAABuZXRfbDJkZXZfbm90aWZ5OiBwZ2lkIFsweCV4XSwgcHJp -byBbMHgleF0sIGNoIFsweCV4XQoAAAAAAAAAAAAAZmNvZSBub3RpZnkgOiBGQ29FIExJTktVUDog -cG9ydCAweCV4LCBldmVudCAweCV4CgAAAAAAAAAAAAAAAAAAAGZjb2Ugbm90aWZ5IDogRkNvRSBM -SU5LRE9XTjogcG9ydCAweCV4LCBldmVudCAweCV4CgAAAAAAAAAAAAAAAABmY29lIG5vdGlmeSA6 -IERDQlggOiBwb3J0IDB4JXgsIHByaW9yaXR5IDB4JXggdWxwdHhjaCAweCV4IGNsYXNzIDB4JXgK -AAAAAAAAAAAAAGRjYnhfdGltZW91dFsldV0KAAAAAAAAAAAAAAAAAAAAcG9ydF9jbWRfaGFuZGxl -cjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgKAAAAAAAAcG9ydFsldV0gbGluayBkb3duICgldSkg -KGxzdGF0dXMgJSN4KQoAAAAAAAAAAAAAaTJjIGVycm9yIGNhdXNlZCBieSBtb2R1bGUgdW5wbHVn -CgAAAAAAAAAAAAAAAAAAc2VuZHRvIHBlbmRpbmc6IHdyX3BlbmQgJXAgZm9yIHBvcnQgJXUsIHdh -bnQgdG8gc2VuZCB0byBwb3J0ICV1CgAAAAAAAAAAAAAAAAAAAABwb3J0WyV1XSB1cGRhdGUgKGZs -b3djaWQgJXUgcmMgJXUpCgAAAAAAAAAAAAAAAABwb3J0X3NldF9sb29wYmFjayBwb3J0ICUjeCBj -dXJyZW50ICUjeCBtb2RlICUjeAoAAAAAAAAAAAAAAAAAAAAAcG9ydFsldV0gc3BlZWQgdXBkYXRl -OiAlI3gKAAAAAABwb3J0WyV1XSBiZWdpbm5pbmcgZGVib3VuY2UKAAAAAHBvcnRfbGlua19zdGF0 -ZV9oYW5kbGVyWyV1XSBwb3dlcmluZyBkb3duCgAAAAAAAHBvcnRfbGlua19zdGF0ZV9oYW5kbGVy -WyV1XSBwb3dlcmluZyB1cAoAAAAAAAAAAHBvcnRfbGlua19zdGF0ZV9oYW5kbGVyWyV1XSB1bmtu -b3duIHN0YXRlIChzdGF0ZSA9ICUjeCkKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlcjog -U29tZXRoaW5nIHdlbnQgdGVycmlibHkgd3JvbmcuIHJldCA9ICVkCgAAAAAAAAAAAAAAAAAAAGxl -IGluaXRpYWxpemF0aW9uOiBuZW50cmllcyAldSByb3V0ZSAldSBjbGlwICV1IGZpbHRlciAldSBh -Y3RpdmUgJXUgc2VydmVyICV1IGhhc2ggJXUKAAAAAAAAAAAAAGxlIGluaXRpYWxpemF0aW9uOiBu -ZW50cmllcyAldSByb3V0ZSAldSBjbGlwICV1IGZpbHRlciAldSBzZXJ2ZXIgJXUgYWN0aXZlICV1 -IGhhc2ggJXUgbnNlcnZlcnNyYW0gJXUKAAAAAAAAAAAAAABod190cF9pbml0OiB0Y2IgcmVnaW9u -IChzdGFydCAweCUwOHMgc2l6ZSAldSkgbXVzdCBiZSBpbiBmaXJzdCAyNTZNQiBvZiBNQSBtZW1v -cnkKAAAAAAAAAAAAAAAAAABod190cF9pbml0OiBwZ21uZ3QgcmVnaW9uIChzdGFydCAweCUwOHMg -c2l6ZSAldSkgbXVzdCBiZSBpbiBmaXJzdCAyNTZNQiBvZiBNQSBtZW1vcnkKAAAAAAAAAAAAAABo -d190cF9pbml0OiBUUCBwZ21uZ3QgaW5pdGlhbGl6YXRpb24gZGlkIG5vdCBjb21wbGV0ZQoAAAAA -AAAAAAAAYnVmbV9pbml0OiBuICV1IGJ1ZmxsNjRpbnRfc2l6ZSAweCV4CgAAAAAAAAAAAAAAYnVm -bV9pbml0OiBub3QgZW5vdWdoIG1lbW9yeSB0byBhbGxvY2F0ZSBpbnRlcm5hbCBidWZsbDY0IGJ1 -ZmZlcnMKAAAAAAAAAAAAAAAAAABidWZtX2luaXQ6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9j -YXRlIGJ1ZmxsNjQgYnVmZmVycwoAAAAAAAAAbWVtX2luaXRfYnVmOiBub3QgZW5vdWdoIG1lbW9y -eSB0byBhbGxvY2F0ZSBmbG93IGJ1ZmZlcnMKAAAAAAAAAG1lbV9pbml0X2J1Zjogbm90IGVub3Vn -aCBtZW1vcnkgdG8gYWxsb2NhdGUgdGNiX2NhY2hlIChvZmZlcmVkICV1IHRyeWluZyB0byB1c2Ug -JXUgYXZhaWxhYmxlICV1KQoAAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX290aGVyczogc3RhcnQg -MHglMDh4IHNpemUgJXUgKHVudXNlZCAldSkKAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9vdGhlcnM6 -IHN0YXJ0IDB4JTA4eCBzaXplICV1ICh1bnVzZWQgJXUpCgAAAAAAAAAAAAAAAG1lbV9pbml0OiBF -REMgb3ZlcmNvbW1pdHRlZCBieSAlZCBieXRlcwoAAAAAAAAAAG1lbV9pbml0OiBub3QgZW5vdWdo -IG1lbW9yeSB0byBhbGxvY2F0ZSBmbG93IHRhYmxlCgAAAAAAAAAAAAAAAABjeGNuaWNfZGV2aWNl -X2luaXQ6IGN4Y25pYyBbMHglMHhdLCBjeGNuaWMtPmZpbHRlciBbJTB4XQoAAAAAAAAAcG9mY29l -IGluaXQgZG9uZQoAAAAAAAAAAAAAAAAAAABQb3J0WyV1XTogVW5rbm93biBTR01JSSBzdWItdHlw -ZSAlI3gKAAAAAAAAAAAAAABQb3J0WyV1XTogVW5rbm93biBCVF9YRkkgc3ViLXR5cGUgJSN4CgAA -AAAAAAAAAABQb3J0WyV1XTogVW5rbm93biBCVF9YQVVJIHN1Yi10eXBlICUjeAoAAAAAAAAAAABw -b3J0X2luaXRbJXVdOiBwb3J0IHR5cGUgMHgleCBpcyBub3Qgc3VwcG9ydGVkCgBtcGFydGl0aW9u -X2luaXQ6IG1vdmVkIHBtcnhfc3RhcnQgZnJvbSAweCUwOHggdG8gMHglMDh4IHRvIG1ha2Ugcm9v -bSBmb3IgTEUgSEFTSCBhbmQvb3IgVFAgVENCcwoAAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9p -bml0OiBtb3ZlZCBwbXJ4X3N0YXJ0IGZyb20gMHglMDh4IHRvIDB4JTA4eCAoRURSQU0pCgAAAAAA -AAAAAAAAAAAAAABFUSBwZm4gJXUgdmZuICV1OiBkZXN0cm95aW5nIGVxaWQgJXUgd2l0aCBwZW5k -aW5nIFdSKHMpIChudW1fYnl0ZXMgJXUgYW5kIGZsYWdzIDB4JTA4eAoAAAAAAAAAAABsMmRldl9m -Yy0+Zmxvd2NfaWQgWyV1XSwgbDJkYy0+cGZuIFsldV0sIGwyZGMtPnZmbiBbJXVdLCBsMmRjLT5s -cG9ydCBbJXVdLCBsMmRldl9mYy0+Zmxvd2lkIFsldV0gbDJkYy0+dHhfY2ggWyV1XSwgZGV2LnZw -ZC5wb3J0dmVjIFsleF0KAAAAAAAAAABwb3J0dmVjIFsldV0KAAAAbDJkZXZfdmlfZnNtOiBtYiBb -MHgleF0sIGRlZmVycmVkLCBzdGF0ZSBbMHgleF0sIHBvcnQgWzB4JXhdCgAAAGwyZGV2X3ZpX2Zz -bTogdmlpZCBbMHgleF0gcG9ydCBbMHgleF0sIG1hYy1pZCBbJTAyeDolMDJ4OiUwMng6JTAyeDol -MDJ4OiUwMnhdLiAKAAAAAAAAAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogc2dlX2VxaWQgWzB4JXhd -LCBzZ2VfaXFpZCBbMHgleF0sIHNnZV9lcWNyIFsweCV4XSwgcnNzX3N6IFsweCV4XQoAbDJkZXZf -dmlfZnNtOiBsMmRldl9mYy0+Zmxvd2NfbmV0X2wyZGV2X210dSBbJXVdLCBtYl9zY3JhdGNoIFsw -eCV4XSwgcG9ydCBbMHgleF0KAAAAAAAAAAAAAAAAAAAAbDJkZXZfdmlfZnNtOiB2aWlkIFslZF0s -IHZpX2ZjLT5mbG93Y192aV9mbGFncyBbMHgleF0KAAAAAAAAAAAAAGwyZGV2X3ZpX2ZzbTogcGZu -IFsweCV4XSwgdmZuIFsweCV4XSwgbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgbHBvcnQgWzB4 -JXhdLCB2aWlkIFsweCV4XSwgZmxhZ3MgWzB4JXhdCgAAAAAAAABsMmRldl92aV9mc206IEVycm9y -IGZyZWVpbmcgVkksIHJjIFsweCV4XQoAAAAAAABsMmRldl92aV9mc206IHBpZCBbMHgleF0sIHZp -aWQgWzB4JXhdLCBtYl9sb2MgWzB4JXhdLCBtYl9vcmlnWzB4JXhdLCBsMmRldl9mbGFncyBbMHgl -eF0sIHJjIFsweCV4XQoAAAAAAAAAAAAAAAAAQWggaGEuLi5kb3VibGUgZnJlZSBveF9pZCAweCV4 -LCByeF9pZCAweCV4CgAAAAAASG9zdCBQUkxJIFJlc3BvbnNlIHRpbWVkb3V0OiBveF9pZCAweCV4 -IHJ4X2lkIDB4JXgKAAAAAAAAAAAAAAAAAEZDT0UgRnJlZTogc3RpbGwgeWllbGRlZCB3aGVuIGZy -ZWVpbmcuLi5mbG93Y19pZCAleCBmbG93Y19mbGFncyAleCAKAAAAAAAAAAAAAAAARkMgeGNoZyBm -cmVlIHhpZDolZCBmbG93aWQgJWQKAABwZm4gJXUgdmZuICV1IHZpYSBjb21tYW5kCgAAAAAAAHNj -aGVkX2lvcXR4X2JwX3ByaW9yaXR5OiBoYXMgJXUgZW50cmllcyBvbmx5LCByZXF1aXJlcyAldSBl -bnRyaWVzCgAAAAAAAAAAAAAAAAAAdHBfYmFja29mZjogcGFyc2VkICVkIGluc3RlYWQgb2YgJXUg -ZW50cmllcwoAAAAAdHBfdGltZXJ2YWxzOiBwYXJzZWQgJWQgaW5zdGVhZCBvZiAldSBlbnRyaWVz -CgAAdHBfdGltZXJyZXM6IHBhcnNlZCAlZCBpbnN0ZWFkIG9mICV1IGVudHJpZXMKAAAAdHBfbXR1 -cyBoYXMgJXUgZW50cmllcyBvbmx5LCByZXF1aXJlcyAldSBlbnRyaWVzCgAAAAAAAAAAAAAAAAAA -AHRwX210dXNbJXVdIGlzICV1IGJ5dGVzIHdoaWNoIGlzIG5vdCBzdXBwb3J0ZWQKAGNvbmZpZ3Vy -YXRpb24gZmlsZSBwYXJzZXI6IHNnZSB0aW1lciB2YWx1ZVslaV0gaXMgdG9vIGxhcmdlLCBjaGFu -Z2luZyBmcm9tICV1IHRvICV1dXNlY3MKAAAAAAAAAGZpbHRlcm1hc2sgMHgleCBpcyBub3QgZXF1 -YWwvc3Vic2V0IHRvL29mIGZpbHRlcm1vZGUKAAAAAAAAAAAAAABod19sZV9jbGlwX2hhbmRsZXI6 -IHJlbW92ZWQgcG9zPSV1ICg9aWR4ICV1KQoAAABod19sZV9jbGlwX2hhbmRsZXI6IGFkZGluZyB0 -byBwb3M9JXUgKD1pZHggJXUpCgBtb2R1bGVbJXVdOiBwb3J0IG1vZHVsZSBpbnNlcnRlZCBhbmQg -cmVhZHkKAAAAAABtb2R1bGVbJXVdOiBwb3J0IG1vZHVsZSByZW1vdmVkCgAAAAAAAAAAAAAAAAAA -AABtb2R1bGVbJXVdOiB1bmtub3duIG1vZHVsZSBpZGVudGlmaWVyIDB4JTAyeAoAAABtb2R1bGVb -JXVdOiBncGlvICV1IHRyYW5zIDEwRyAweCUwMnggMUcgMHglMDJ4IChsZW5ndGggJXUpIGNhYmxl -IDB4JTAyeCAobGVuZ3RoICV1KSBtb2R1bGVfdHlwZSAweCUwMngKAAAAAAAAAAAAbW9kdWxlWyV1 -XTogZ3BpbyAldSB0cmFucyAxMEcgMHglMDJ4IDFHIDB4JTAyeCAobGVuZ3RoICV1KSBjYWJsZSAw -eCUwMnggKGxlbmd0aCAldSkgbW9kdWxlX3R5cGUgMHglMDJ4CgAAAAAAAAAAAGZscl9wZnZmX2Zz -bVsldToldV06IHVua25vd24gc3RhdGUgJXUKAAAAAAAAAAAAAGh3IHBmIGJpdG1hcCAweCUwMngg -dmZpZCBiaXRtYXAgMHglMDh4OjB4JTA4eDoweCUwOHg6MHglMDh4CgAAAABhZnRlciB2ZmlkIGZp -eHVwLCB2ZmlkIGJpdG1hcCAweCUwOHg6MHglMDh4OjB4JTA4eDoweCUwOHgKAAAAAAAAdGltZXIg -cXVldWUgJXUgbG9zdCBhIHRpY2shIG5leHQgJXAgbGFzdCAlcCBudW1lICV1CgAAAAAAAAAAAAAA -AGZscl90aW1lcl9zdGFydDogZmxvd2NfaWQgJXUgJXAgYnVmICVwCgAAAAAAAAAAAHBjaWU6IG5w -ZiAldSAocGZiaXRtYXAgMHglMDJ4KSBudmYgJXUgKHBmIDAuLjcgMHglMDh4JTA4eCkgdmZzdHJp -ZGUgJXUKAAAAAAAAAAAAZmFpbGVkIHRvIGZpbmQgdGhlICVjJWMgVlBEIHBhcmFtZXRlcgoAAAAA -AAAAAAAAZmFpbGVkIHRvIHBhcnNlIHRoZSAlYyVjIFZQRCBwYXJhbWV0ZXIKAAAAAAAAAAAAZmFp -bGVkIHRvIHN1Y2Nlc3NmdWxseSBmaW5kIENoZWxzaW8gVlBECgAAAAAAAAAAbG9nIGluaXRpYWxp -emVkIEAgMHglMDh4IHNpemUgJXUgKCV1IGVudHJpZXMpIGZ3cmV2IDB4JTA4eCBwY2llX2Z3IDB4 -JTA4eAoAAAAAAABnYXRoZXJfdGFza3NfZm9yX3RtZjogaWR4IFsweCV4XSwgdGFzay1pZCBbMHgl -eF0sIGNtZC1pZCBbMHgleF0sIGFjdGl2ZSB0YXNrcyBbMHgleF0uIGNvbm4taWQgWzB4JXhdLCBj -bWQgY29ubi1pZCBbMHgleF0sIHRhc2sgY29ubi1pZCBbMHgleF0KAABnYXRoZXJfdGFza3NfZm9y -X3RtZjogSW52YWxpZCB0eXBlIFsweCV4XSwgYmFpbGluZyBvdXQuCgAAAAAAAAAAZ2F0aGVyX3Rh -c2tzX2Zvcl90bWY6IHRhc2sgaWQgWzB4JXhdLCBzdGF0ZSBbMHgleF0sIGxpZHggWzB4JXhdLCBj -b29raWUgaGkgWzB4JTA4eF0gOiBsbyBbMHglMDh4XQoAAAAAAAAAAAAAAAAAAGdhdGhlcl90YXNr -c19mb3JfdG1mOiByYyBbMHgleF0sIFsweCV4XSB0YXNrIGdhdGhlcmVkIGZvciB0bWYgdHlwZSBb -MHgleF0gcHJvY2Vzc2luZy4KAAAAAAAAAAAAAHNjc2lfZGF0YV9vdXQ6IGNvbm5fZmMgWzB4JXhd -LCBzdGF0ZSBbMHgleF0sIHNlc3NfZmMgWzB4JXhdIGluIHJlY292ZXJ5LiBTa2lwcGluZyBpc3Rh -c2tfZmMgWzB4JXhdIGZyb20gVFguCgAAAABzZW5kX2Fib3J0X3JlcTogY3NrX2ZjLT5mbG93Y190 -eXBlIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIHRpZCBbMHgleF0sIHVscHR4Y2gg -WyV1XSwgYnVmZmVyZWQgWyV1XQoAAAAAaHcgcmVnaXN0ZXIgb3BlcmF0aW9uIG5vdCBjb21wbGV0 -aW5nLCByZWcgMHglMDh4IG1hc2sgMHglMDh4IHZhbHVlIDB4JTA4eCAocmVnIDB4JTA4eCkKAAAA -AAAAAAAATURJTyBDTDQ1OiBmYWlsZWQgdG8gc2V0IHVwIE1NRCBhZGRyCgAAAAAAAAAAAAAATURJ -TzogZmFpbGVkIHRvIHdyaXRlCgAAAAAAAAAAAABNRElPIENMNDU6IGZhaWxlZCB0byBzZXQgdXAg -TU1EIGFkZHIKAAAAAAAAAAAAAABNRElPOiBmYWlsZWQgdG8gcmVhZAoAAAAAAAAAAAAAAAlBUV9U -YWtlQ29udHJvbE9mRkxBU0g6IDFlLmMwMDE9JSN4IDFlLmM0NTA9JSN4IDFlLmM0NTE9JSN4IDFl -LjEwMD0lI3gKAAAAAAAAAAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIEltYWdl -IGludGVncml0eSBjaGVjayBmYWlsZWQgKGNhbGMgJSN4IHZhbCAlI3gpCgAAAAAAAAAAAAAAAAAA -QVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIEltYWdlIGludGVncml0eSBjaGVjayBw -YXNzZWQKAEFRX0FQSV9Xcml0ZUFuZFZlcmlmeUZsYXNoSW1hZ2UgLSBUaW1lb3V0IHdhaXRpbmcg -Zm9yIGZsYXNoIGludGVyZmFjZSAoJXUpCgAAAAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJ -bWFnZSAtIFRpbWVvdXQgd2FpdGluZyBmb3IgZmxhc2ggaW50ZXJmYWNlICgldSkKAAAAAABBUV9B -UElfV3JpdGVBbmRWZXJpZnlGbGFzaEltYWdlIC0gVGltZW91dCB3YWl0aW5nIGZvciBmbGFzaCBp -bnRlcmZhY2UgKCV1KQoAAAAAAEFRX0FQSV9Xcml0ZUFuZFZlcmlmeUZsYXNoSW1hZ2UgLSBUaW1l -b3V0IHdhaXRpbmcgZm9yIGZsYXNoIGludGVyZmFjZSAoJXUpIChwcCAlI3ggYXAgJSN4KQoAAAAA -AEFRX0FQSV9Xcml0ZUFuZFZlcmlmeUZsYXNoSW1hZ2UgLSBUaW1lb3V0IHdhaXRpbmcgZm9yIGZs -YXNoIGludGVyZmFjZSAoJXUpCgAAAAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAt -IFRpbWVvdXQgd2FpdGluZyBmb3IgZmxhc2ggaW50ZXJmYWNlICgldSkKAAAAAABBUV9BUElfV3Jp -dGVBbmRWZXJpZnlGbGFzaEltYWdlIC0gRXJyb3Igb24gYnVybmluZyBGTEFTSCAoY3JjMTYgbWlz -bWF0Y2gpCgAAAAAAAHNlbmRfY2xvc2VfcmVxOiBjc2tfZmMtPmZsb3djX3R5cGUgWzB4JXhdLCBj -c2tfZmMtPmZsb3djX2lkIFsweCV4XSwgY3NrX2ZjLT50Y2Jfc3RhdGUgWzB4JXhdCgAAAHNlbmRf -Y2xvc2VfcmVxOiBjc2tfZmMtPmZsb3djX3R5cGUgWzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsw -eCV4XSwgdGlkIFsweCV4XSwgdWxwdHhjaCBbJXVdLGJ1ZmZlcmVkIFsldV0KAAAAAABvZmxkX3Rj -cF9kb19hY3RpdmVfY2xvc2U6IGNza19mYyBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhd -LCBjc2tfZmMtPnRjYl9zdGF0ZSBbMHgleF0KAAAAAABvZmxkX3RjcF9kb19hY3RpdmVfY2xvc2U6 -IGNza19mYyBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCBjc2tfZmMtPnRjYl9zdGF0 -ZSBbMHgleF0KAAAAAABvZmxkX3RjcF9kaXNjb25uZWN0OiB0Y2JfZmMtPmZsb3djX2lkIFsweCV4 -XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNzay0+dGNiX3N0YXRlIFsweCV4XQoAAABkZWNv -ZGVfYmFzZTY0X3N0cmluZzogZGxlbiBbJWRdCgAAAAAAAAAAAAAAAAAAAABkZWNvZGVfaGV4X3N0 -cmluZzogZGxlbiBbJWRdCgAAAGZvaXNjc2lfdmFsaWRhdGVfbG9naW5fc3RhZ2U6IC0gMQoAAAAA -AAAAAAAAAAAAAGFzeW5jX3BkdTogbG9nb3V0IHJlcXVlc3RlZCBibG9ja2luZyBzZXNzaW9uCgAA -AGFzeW5jX3BkdTogc2Vzcy9jb25uIGRyb3AgcmVxdWVzdGVkIGJsb2NraW5nIHNlc3Npb24KAAAA -AAAAAAAAAABjcGxfdHhfcGt0OiB2bGFuaWQgWzB4JXhdCgAAAAAAAG5ldF9sMmRldl9maW5kX2J5 -X2FkZHI6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIGwyZGMtPmxwb3J0IFsldV0sIGwyZF9m -Yy0+Zmxvd2NfaWQgWzB4JXhdLCBsMmRjLT5pbjRfZGV2LmluX2FkZHIuYWRkciBbMHgleF0sIGFk -ZHIgWzB4JXhdCgAAAG5ldF9sMmRldl9tdHVfY29uZmlnOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4 -JXhdLCBtdHUgJXUKAAAAAAAAAABjcGxfdHhfcGt0OiB2bGFuaWQgWzB4JXhdCgAAAAAAAGVuY29k -ZSBoZXggc3RyaW5nOiBkbGVuIFslZF0KAAAAY2huZXRfZmluZF9sMnRfZW50cnk6IGRhZGRyIFsl -MDh4XSwgWzB4JTA4eF0sIGxvY2FsIG5ldHdvcmsgWyVkXQoAAAAAAAAAAAAAAAAAAABsMnRlbnQg -WyUweF0sIGwydGVudC0+aWR4IFslZF0KAHRjcF9zZW5kX2FvcGVuX3JlcTogY3NrX2ZjLT5mbG93 -Y19pZCBbMHgleF0sIGNza19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBidWZmZXJlZCBbJXVdLCBy -ZXNfY250IFsweCV4XSwgaXFfaWR4IFsweCV4XQoAAAAAAAAAAAAAdGNwX3NlbmRfYW9wZW5fcmVx -OiBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIG5v -IHZhbGlkIGwydF9lbnR5LiBEZWxheWluZyBhbm90aGVyIHJldHJ5IGZvciAxIHNlY29uZHMuCgAA -AAAAAAAAAAAAAAAAYW9wZW5fcmVxOiBod19sZV9maWx0ZXJfY3R1cGxlIGZhaWxlZAoAAAAAAAAA -AAAAb2ZsZF90Y3Bfc2VuZF9hb3Blbl9yZXE6IGNwbF9yZXEtPkZpbHRlciBbMHglMHhdLCBjdHVw -bGVzWzBdIFsweCV4XSwgY3R1cGxlc1sxXSBbMHgleF0KAAAAAAAAAAAAY3NvY2tfYWxsb2M6IHR4 -X2NoIFsweCV4XSwgbHBvcnQgWzB4JXhdLCBjb29raWUgWyUwOHhdCgAAAAAAAAAAAGNzb2NrX2Fs -bG9jOiBhdmFpbGFibGUgWyV1XSwgbmNzb2NrIFsldV0sIHBvczphdGlkIFsweCV4XSwgY3NrX2Zj -IFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIHNwb3J0IFsldV0KAABXQVRDSERPRzog -Tm8gdGVtcGVyYXR1cmUgc2Vuc29yIGF2YWlsYWJsZS4KAAAAAAB3YXRjaGRvZyBjbWQgcmVmcmVz -aCAoYWN0aW9uICV1KQoAAAAAAAAAAAAAAAAAAABXQVRDSERPRzogQWN0aXZhdGluZwoAAAAAAAAA -AAAAAFdBVENIRE9HIC0gRW5hYmxlIGFjdGlvbiAldSB0aW1lICV1CgAAAAAAAAAAAAAAAFdBVENI -RE9HIC0gRGlzYWJsZSBhY3Rpb24gJXUKAAAAV0FUQ0hET0c6IERlLWFjdGl2YXRpbmcKAAAAAAAA -AABwb3J0WyV1XSBzZXQgUEFVU0UgUEFSQU1TOiBwcHBlbiAldSB0eHBlICUjeCByeHBlICUjeAoA -AAAAAAAAAAAAbXBzX2xpbmtfdXBbJXVdIGFjYXBzICUjeCAoODAyLjMgJSN4KSArIGxwYWNhcHMg -JSN4ID0+ICUjeAoAAAAAAGZvaXNjc2kgY29ubl9mYyBbMHgleF0sIGZsb3djX3NjaGVkY2wgWzB4 -JXhdLCBpbmdfY2ggWzB4JXhdLCBlZ3JfY2ggWzB4JXhdCgAAAAAAbDJkZXZfbm90aWZ5IHdpdGgg -dW5rbm93biBmbGFnIFsweCV4XQoAAAAAAAAAAAAARkNvRSBGQ0IgbGlua2Rvd246IGlvX3JlcSAw -eCV4JXggaXFpZCAweCV4IGZsb3dpZCAweCV4IG9wIDB4JXgKAGNhbmNlbCBmY2I6JXggc2NiOiV4 -IHN0YXRlOiV4CgAAUkRFViBtc2cgZmxvd2M6JXggc3RhdGUgMHgleCBldmVudCAweCV4CgAAAAAA -AAAAdm4ydm46IHBvcnQgMHgleCBkaWQ6MHgleCV4JXggVVAKAAAAAAAAAAAAAAAAAAAAdm4ydm46 -IHBvcnQgMHgleCBkaWQ6MHgleCV4JXggRE9XTgoAAAAAAAAAAAAAAAAAZmNfc2VuZF9hbGxvY19j -cGw6IGZhaWxlZCB0byBzZXR1cCBmaWx0ZXIgY3R1cGxlCgAAAAAAAAAAAAAAAAAAAGZjb2VfY29t -cHV0ZV9jdHVwbGUgMHgleDoleAoAAAAAY29tcHV0ZV9jdHVwbGUoKTogZmFpbGVkIHRvIHNldHVw -IGZpbHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAAGZjb2VfY29tcHV0ZV9jdHVwbGUgdmxhbiAl -eCB2aWlkICV4IHBvcnQgJXggbXBzX2lkeCAleAoAAAAAAAAAAABBcHBseSBBUFA6IHBvcnQgJWQg -cHJpb3IgJWQgc2VsZWN0ICVkIHByb3RvY29sSUQgMHglMDR4CgAAAAAAAAAAY2hfY2xfcmF0ZVsl -dS8ldV06IGNhcHBlZCBkZWZpY2l0X2luY3IgZnJvbSByZXF1aXJlZCAldSB0byAldTsgcmF0ZSAl -dSAoZWZmICV1KSBkZWZpY2l0X21heCAldQoAZmNfc2VuZF9hbGxvY19jcGw6IGZhaWxlZCB0byBz -ZXR1cCBmaWx0ZXIgY3R1cGxlCgAAAAAAAAAAAAAAAAAAAGZjb2VfY29tcHV0ZV9jdHVwbGUgMHgl -eDoleAoAAAAAY29tcHV0ZV9jdHVwbGUoKTogZmFpbGVkIHRvIHNldHVwIGZpbHRlciBjdHVwbGUK -AAAAAAAAAAAAAAAAAAAAAEZDb0UgRkNGIHRpbWVyOiBmbG93YyBzdGF0ZSAweCV4LCBwb3J0IDB4 -JXggLGZjZiAweCV4LCBmbG93Y19pZCAweCV4CgAAAAAAAAAAAAAAd29ya2Fyb3VuZDEzNzIzOiBk -ZXRlY3RlZCBXUiBAIDB4JTA4eCBvZiBzaXplICV1IGJ5dGVzLCBkcmliYmxpbmcgaXQgaW4gJXUg -Ynl0ZXMgYXQgYSB0aW1lCgAAAAAAcmlfd3JfaW5pdFsldV06IG1zcyAldSBpcyBub3QgOC1ieXRl -IGFsaWduZWQKAAAAY29yZV9wcm9ncmFtX3RjYjogdGlkICUjeCB0X3N0YXRlICUjeCByY3ZfYWR2 -IDB4JTA4eCByY3Zfc2NhbGUgJSN4IHR4X21heCAlI3ggcmN2X254dCAlI3ggYXRpZCAlI3gKAAAA -AAAAAAAAAAAAAAlvcHQwICUjeCV4IG9wdDIgJSN4IGlwdjYgJSN4IGZsYWdzX3RpbWVyIDB4JTA4 -eAoAAAAAAAAAAAAAAAAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1 -cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlwIDB4JTA4eCUwOHggcGlwIDB4JTA4eCUwOHggZmls -dGVyIDB4JTA4eCBleGlzdHMgQCBMRSBpbmRleCAldQoAAAAAAAAAAAAAAAAAAABvZmxkX2Nvbm5l -Y3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlw -IDB4JTA4eCBwaXAgMHglMDh4IGZpbHRlciAweCUwOHggZXhpc3RzIEAgTEUgaW5kZXggJXUKAAAA -AAAAAG9mbGRfY29ubmVjdGlvbl93cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUgbHAgMHglMDR4 -IGZwIDB4JTA0eCBsaXAgMHglMDh4JTA4eCBwaXAgMHglMDh4JTA4eCBmaWx0ZXIgMHglMDh4CgAA -AABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1LXR1cGxlIGxwIDB4JTA0eCBm -cCAweCUwNHggbGlwIDB4JTA4eCBwaXAgMHglMDh4IGZpbHRlciAweCUwOHgKAAAAAAAAAAAAAAAA -SVFGTElOVCBwZm4gJXUgdmZuICV1OiBpcWVzaXplICV1IHRvbyBzbWFsbAoAAAAASVFGTElOVCBw -Zm4gJXUgdmZuICV1OiBpcWlkICV1IHRvbyBsYXJnZSAobWF4ICV1KQoAAAAAAAAAAAAAAAAAAElR -RkxJTlQgcGZuICV1IHZmbiAldTogaXFpZCAldSBub3QgYWxsb2NhdGVkCgAAAElRRkxJTlQgcGZu -ICV1IHZmbiAldTogZmwwaWQgJXUgdG9vIGxhcmdlIChtYXggJXUpCgAAAAAAAAAAAAAAAABJUUZM -SU5UIHBmbiAldSB2Zm4gJXU6IGZsMGlkICV1IG5vdCBhbGxvY2F0ZWQKAABJUUZMSU5UIHBmbiAl -dSB2Zm4gJXU6IGZsMWlkICV1IHRvbyBsYXJnZSAobWF4ICV1KQoAAAAAAAAAAAAAAAAASVFGTElO -VCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSBub3QgYWxsb2NhdGVkCgAASVFGTElOVCBwZm4gJXUg -dmZuICV1OiBmbDFpZCAldSBpcyB2YWxpZCBidXQgbm90IGZsMGlkICV1CgAAAAAAAElRRkxJTlQg -cGZuICV1IHZmbiAldTogZmwxaWQgJXUgaXMgdmFsaWQgYnV0IGhlYWRlciBzcGxpdCBmZWF0dXJl -IGlzIG5vdCBlbmFibGVkCgAAAAAAAAAAAAAAAAAAAGh3X3VscHR4X3dvcmthcm91bmRfcHIxNjk0 -OV9lbmFibGVkX3BmOiBwZiAldSBlbmFibGVkICV1CgAAAAAAAABod191bHB0eF93b3JrYXJvdW5k -X3ByMTY5NDlfZW5hYmxlZF92ZmlkOiB2ZmlkICV1IGVuYWJsZWQgJXUKAAAARVEgcGZuICV1IHZm -biAldTogY3JlYXRpbmcgRVRIIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1fYnl0ZXMg -JXUgYW5kIGZsYWdzIDB4JTA4eAoAAAAAAAAARVEgcGZuICV1IHZmbiAldTogY3JlYXRpbmcgQ1RS -TCBlcWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFncyAweCUw -OHgKAAAAAAAARVEgcGZuICV1IHZmbiAldTogZXFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAA -RVEgcGZuICV1IHZmbiAldTogZXFpZCAldSBub3QgYWxsb2NhdGVkCgAAAAAAAAAAaHdfY2ltX3Rw -X3dvcmthcm91bmQxMzcyM19lbmFibGU6IHBvcnQgJXUgcHJvdG9jb2wgMHgleCBlbiAldSBjdXJy -ZW50IDB4JXggd29ya2Fyb3VuZF9wcjEzNzIzIDB4JXggbmV4dCAweCV4CgAAAHBvcnRfYmxpbmtf -bGVkX3Jlc3RvcmUKAAAAAAAAAAAAcG9ydF9ibGluazogYmxpbmtkdXI9MHgleCBibGlua19yZWZj -bnQKAAAAAAAAAAAAcG9ydF9ibGluazogCWJsaW5rX3JlZmNudD0weCV4CgBwb3J0X2JsaW5rOiAJ -YmxpbmtfcmVmY250PTB4JXgKAG1paV9hZHZfZmNbJXVdOiByY2FwcyAweCV4CgAAAAAAbWlpX2Fk -dl9zcGVlZFsldV06IHJjYXBzIDB4JXgKAABtaWlfaW5pdFsldV06IGFjYXBzIDB4JXgKAAAAAAAA -AHBvcnRbJXVdOiBnYXZlIHVwIGZpeGluZyBlcnJvcnMhISEKAAAAAAAAAAAAAAAAAG1paV9hbnJl -c3RhcnRbJXVdOiBhY2FwcyAweCV4CgAAaHdfeGdtX3BvcnRfbHBiayBwb3J0ICV1IHB0eXBlICUj -eCBhY3Rpb24gJSN4CgAAcG9ydF9jbWRfaGFuZGxlcjogdW5rbm93biB1LmRjYi50eXBlIDB4JXgK -AAAAAAAAcG9ydFsldToweCUwMng6MHglMDJ4XTogbDFjZmcsIGludmFsaWQgcmVxdWVzdCwgcGNh -cHMgMHgleCBhY2FwcyAweCV4IHJjYXBzIDB4JXgKAAAAAAAAAAAAAAAAAAAAcG9ydFsldToweCUw -Mng6MHglMDJ4XTogbDFjZmcsIHBjYXBzICUjeCBhY2FwcyAlI3ggcmNhcHMgJSN4IG1jYXBzICUj -eAoAAAAAAAAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiBsMWNmZywgbWRpIGlzc3VlIHBjYXBz -IDB4JXggYWNhcHMgMHgleCByY2FwcyAweCV4CgAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06 -IGwxY2ZnLCBjYW5ub3QgZm9yY2Ugbm8vbXVsdGlwbGUgc3BlZWQocyksIHBjYXBzIDB4JXggYWNh -cHMgMHgleCByY2FwcyAweCV4CgAAAAAAAAAAAAAAAABldGhfZmxvd2NfaGFuZGxlclsweCV4XTog -ZmxhZ3MgMHglMDh4IG51bV9ieXRlcyAldSBzY2hlZGNsIDB4JXggLT4gMHgleAoAAAAAAAAAAHNj -c2lfY21kOiByZWNlaXZlZCBUTUYgb3AgWzB4JXhdIGZ1bmMgWzB4JXhdIG9uIGNvbm4gWzB4JXhd -IHRocm91Z2ggY29tbWFuZCBwYXRoLgoAAAAAAAAAAAAAAAAAAHNjc2lfY21kOiBjb25uX2ZjIFsw -eCV4XSwgc3RhdGUgWzB4JXhdLCBzZXNzX2ZjIFsweCV4XSBpbiByZWNvdmVyeS4gU2tpcHBpbmcg -aXN0YXNrX2ZjIFsweCV4XSBmcm9tIFRYLgoAAAAAAAAAAABzY3NpX2NtZDogaVNDU0kgY29tbWFu -ZCBzZXF1ZW5jZSB3aW5kb3cgY2xvc2VkLiBjb25uIFsweCV4XSwgb3AgWzB4JXhdLCAgY21kc24g -WzB4JXhdLCBzZW50X2NtZHNuIFsweCV4XSwgbWF4X2NtZHNuIFsweCV4XSwgaXR0IFsweCV4XQoA -AAAAAAAAAABzY3NpX3JlYWQ6IGNvbm5fZmMgWzB4JXhdLCBzdGF0ZSBbMHgleF0sIHNlc3NfZmMg -WzB4JXhdIGluIHJlY292ZXJ5LiBTa2lwcGluZyBpc3Rhc2tfZmMgWzB4JXhdIGZyb20gVFguCgAA -AAAAAAAAc2NzaV9yZWFkOiBpU0NTSSBjb21tYW5kIHNlcXVlbmNlIHdpbmRvdyBjbG9zZWQuIGNv -bm4gWzB4JXhdLCBjbWRzbiBbMHgleF0sIHNlbnRfY21kc24gWzB4JXhdLCBtYXhfY21kc24gWzB4 -JXhdCgAAAAAAAAAAAAAAAAAAAABzY3NpX3dyaXRlOiBjb25uX2ZjIFsweCV4XSwgc3RhdGUgWzB4 -JXhdLCBzZXNzX2ZjIFsweCV4XSBpbiByZWNvdmVyeS4gU2tpcHBpbmcgaXN0YXNrX2ZjIFsweCV4 -XSBmcm9tIFRYLgoAAAAAAAAAc2NzaV93cml0ZTogaVNDU0kgY29tbWFuZCBzZXF1ZW5jZSB3aW5k -b3cgY2xvc2VkLiBjb25uIFsweCV4XSwgY21kc24gWzB4JXhdLCBzZW50X2NtZHNuIFsweCV4XSwg -bWF4X2NtZHNuIFsweCV4XSwgaXR0IFsweCV4XQoAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRS -T0xfTElOS1VQCgAAAAAAAAAAAAAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfVVBEQVRF -X0RDQlhfVExWCgAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfUEVFUl9OT1RfQURWRVJU -SVNFX0RDQlgKAAAAAAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1VQREFURV9P -UEVSX1ZFUlNJT04KAAAAAAAAAAAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9Q -Uk9DRVNTX1BFRVJfVExWCgAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9BQ0tfUEVFUgoA -AAAAAAAAAAAAAGRjYnhfaWVlZV92YWxpZGF0ZVsldV0gZXJyb3IgKG91aSAlI3ggc3VidHlwZSAl -I3ggbGVuICUjeCkKAAAAAABkY2J4X2NlZV92YWxpZGF0ZVsldV0gZXJyb3IKAAAAAHByb2Nlc3Nf -ZGhjcF9vcHRzOiByb290IHBhdGggbGVuIFslZF0gYnl0ZXMKAAAAAG5ldGlmX3Byb2Nlc3NfZGhj -cF9vcHRzOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBNU0dfVFlQRSBbJWRdLCBkaGN0eHQt -PnN0YXRlIFslZF0KAAAAAAAAAAAAAGljbXBfcmVjdjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4 -XSwgcGlkIFsweCV4XSwgaWNtcCB0eXBlIFsweCV4XQoAAAAAAAAAAAAAAAAAQUJUUyBBQ0MgYXdh -aXRpbmcgUFJMSSBSc3A6IGZsb3djX2lkIDB4JXggb3hfaWQgMHgleCByeF9pZCAweCV4IGlxaWQg -MHgleAoAAAAAAABwb3J0IDB4JXgsIHN0YXRlIDB4JXgsIGNvbW1hbmQgZmFpbGVkIHJldHJpZXMg -MHgleAoAAAAAAAAAAAAAAAAAYXJwX3JlY3Y6IGlwaWQgWzB4JXhdLCBpbl9hZGRyLmFkZHIgWzB4 -JXhdLCBzaXAgWzB4JXhdLCByaXAgWzB4JXhdLCBhcnBfb3AgWzB4JXhdCgAAAAAAAAAAAAAAAAAA -Y2huZXRfYXJwX3JlY3Y6IGlwIGNvbmZsaWN0IGRldGVjdGVkCgAAAAAAAAAAAAAAY2huZXRfYXJw -X3JlY3Y6IHBpZCBbJXVdLCB2bGFuIFsweCV4XSwgYXJwIG9wIFsweCV4XSwgc2lwIFsweCV4XSwg -cmlwIFsweCV4XQoAAABJbnZhbGlkIGRpZDp4JTJ4JTJ4JTJ4IHJjdmQgb24gcG9ydDolZC5Ecm9w -aW5nIGZyYW1lCgAAAAAAAAAAAAAAcmN0OngleCBzaWQ6eCUyeCUyeCUyeCByY3ZkIG9uIGZsb3dj -OiVkLkRyb3BpbmcgZnJhbWUKAAAAAAAAAAAAAGNzb2NrX2ZyZWU6IHNpemVvZihjc2tfZmMtPnUu -Y3NvY2spIFsldV0sIGJ5dGVzCgAAAAAAAAAAAAAAAAAAAABHb3QgQ09OTl9FWElTVCBmb3IgeGlk -OjB4JXgsIHRhZzoweCV4LCByZXRyeWluZy4KAAAAAAAAAAAAAAAAAAAAaHdfdWxwdHhfd29ya2Fy -b3VuZF9wcjE2OTQ5X2VuYWJsZWRfcGZfaXE6IGlxICV1IGVuYWJsZWQgJXUgKHBmICV1KQoAAAAA -AAAAAAAAAABjc29ja19wZWVyX2Nsb3NlOiBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwgdGNiX2Zj -LT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCB0Y2JfZmMtPmZs -b3djX3N0YXRlIFsweCV4XQoAAAAAAGNzb2NrX3BlZXJfY2xvc2U6IGNza19mYy0+Zmxvd2NfaWQg -WzB4JXhdLCBjc2tfZmMtPmZsb3djX3N0YXRlICBbMHgleF0KAAAAAAAAAAAAdGNwX2Nsc19hYnJ0 -X3JwbDogdGNiIHRpZCBbMHglMDZ4XSwgZmxvd2NfdHlwZSBbMHgleF0sIGNwbG9wIFsweCV4XSAK -AAAAAAAAAAAAAABjaF9yYXRlWyV1XTogY2FwcGVkIHRpY2sgZnJvbSByZXF1aXJlZCAldSB0byBz -dXBwb3J0ZWQgJXU7IHJhdGUgJXUgKGVmZiAldSkgZGVmaWNpdF9pbmNyICV1IHRpY2sgJXUKAAAA -AAAAAAAAAAAAcGt0c2NoZWRfY2hfcmxbJXVdOiBjaGFubmVsIHJsIG5vdCBhdmFpbGFibGUgaW4g -Y29uanVuY3Rpb24gd2l0aCBmbG93IHNoYXBpbmcKAABwa3RzY2hlZF9jaF9ybFsldV06IHJhdGUg -JXUgbWF4ICV1CgAAAAAAAAAAAAAAAABwa3RzY2hlZF9jbF93cnJbJXU6JXVdOiB3ZWlnaHQgJXUK -AAAAAAAAAAAAAAAAAABlcV9wYXJhbXNbMHgleDoweCV4XTogZG1hcSAweCV4IHJlYWQgJXUgcGYg -JXUgZXFpZF9hcGkgJXUgcmV0ICVkCgAAAAAAAAAAAAAAAAAAAGh3X21hX2FkZHJfdG9fbWVtX3R5 -cGVfb2ZmOiBNQSBhZGRyZXNzIDB4JTA4eCBpcyBub3QgbWFwcGVkCgAAAABod19tYV9hZGRyX3Rv -X21lbV90eXBlX29mZjogTUEgYWRkcmVzcyAweCUwOHggbWFwcyB0byB0eXBlICV1IG9mZnNldCAw -eCV4CgAAAAAAAG1lbV9tYWxsb2NfdGVtcDogZmFpbGVkIHRvIGFsbG9jYXRlICV1IGJ5dGVzLCBy -ZXR1cm5pbmcgTlVMTAoAAABtZW1fbWFsbG9jOiBmYWlsZWQgdG8gYWxsb2NhdGUgJXUgYnl0ZXMs -IHJldHVybmluZyBOVUxMCgAAAAAAAAAAbGUgY29uZmlndXJhdGlvbjogaGFzaCBtb2RlIHJlcXVp -cmVzIGF0IGxlYXN0IDE2IGVudHJpZXMsIG5oYXNoICV1CgAAAAAAAAAAAAAAAABsZSBjb25maWd1 -cmF0aW9uOiBoYXNoIG1vZGUgcmVxdWlyZXMgYXQgZW50cmllcyB0byBiZSBhIHBvd2VyIG9mIDIs -IG5oYXNoICV1CgAAAGxlIGNvbmZpZ3VyYXRpb246IHJlcXVlc3RlZCAldSB0Y2FtIGVudHJpZXMg -YnV0IG9ubHkgJXUgYXZhaWxhYmxlIChucm91dGUgJXUgbmNsaXAgJXUgbmZpbHRlciAldSBuc2Vy -dmVyICV1CgAAAABsZSBjb25maWd1cmF0aW9uOiB0Y2FtIHJlZ2lvbnMgbXVzdCBoYXZlIG11bHRp -cGxlIG9mIDMyIGVudHJpZXMsIG5yb3V0ZSAldSBuY2xpcCAldSBuZmlsdGVyICV1IG5zZXJ2ZXIg -JXUKAAAAAAAAaHdfdHBfdGNwX3R1bmluZ3M6IHR1bmluZyBmb3IgY2x1c3RlciBlbnZpcm9ubWVu -dAoAAAAAAAAAAAAAAAAAAGh3X3RwX3RjcF90dW5pbmdzOiB0dW5pbmcgZm9yIExBTiBlbnZpcm9u -bWVudAoAAGh3X3RwX3RjcF90dW5pbmdzOiB0dW5pbmcgZm9yIFdBTiBlbnZpcm9ubWVudAoAAGh3 -X3RwX3RjcF90dW5pbmdzOiBtYW51YWwgdHVuaW5nCgAAAAAAAAAAAAAAAAAAAF9od19jaW1fZmxh -c2hfbWVtY3B5OiBtZW1jcHlYIHN0YXJ0CgAAAAAAAAAAAAAAAF9od19jaW1fZmxhc2hfbWVtY3B5 -OiBkc3QgMHglMDggb2Zmc2V0IDB4JTA4eCBzaXplICV1LCB3aWR0aCBvZiAldSBpcyBub3Qgc3Vw -cG9ydGVkCgAAAAAAAAAAAAAAAF9od19jaW1fZmxhc2hfbWVtY3B5OiBtZW1jcHlYIGVuZAoAAAAA -AAAAAAAAAAAAAGNvbmZpZ3VyYXRpb24gZmlsZSBwYXJzZXIgZW5jb3VudGVyZWQgZXJyb3IgQCBs -aW5lICV1OgoAAAAAAAAAAABod19pMmNfdHJhbnNhY3Rpb246IG5kYXRhICV1IGFkZHJfb3AgMHgl -eCBkYXRhWzBdIDB4JXggZGlmZiAldQoAaHdfaTJjX3RyYW5zYWN0aW9uOiBuZGF0YSAldSBhZGRy -X29wIDB4JXggZGF0YVswXSAweCV4IGRpZmYgJXUgZHBvcyAldSBjb250ICV1IGZhaWxlZCB3aXRo -IGVyciAlZAoAAAAAAAAAAAAAAAAAAGkyYyB0cmFuc2FjdGlvbiBmYWlsZWQgdG8gY29tcGxldGUK -AAAAAAAAAAAAAAAAAEhPU1QgUEFHRV9TSVpFIFsweCUwbHhdIHRvbyBzbWFsbCwgbWluIFsweCUw -bHhdIHJlcXVpcmVkCgAAAAAAAABwYWdlIHNpemUgWyVsdV0gbWlzbWF0Y2gKAAAAAAAAAFBBR0Ug -c2l6ZSAlbHUgdW5zdXBwb3J0ZWQsIGRkcCBkaXNhYmxlZAoAAAAAAAAAAEhvc3QgcGFnZV9zaXpl -ICVsdSwgZGRwX2lkeCAldQoARkNvRSBERFAgaW5pdDogZmNvZSBsbGltaXQgMHgleCwgZmNvZSB1 -bGltaXQgMHgleCBnYmwgbGxpbWl0IDB4JXggZ2JsIHVsaW1pdCAweCV4IHBjYnN6ICV4CgAAAAAA -RkNvRSBERFAgaW5pdDogZmNvZSBwcG9kIG9mZiAweCV4LCBmY29lIHN0IHBwb2QgYWRkciAweCV4 -IGZjb2UgbnVtIHBwb2RzIDB4JXgKAABmY29lIHhjaGcgbWdyIGluaXQ6IE51bWJlciBvZiBERFAg -ZXhjaGFuZ2VzIGZvciBGQ29FIGlzICV4CgAAAAAAZmNvZSB4Y2hnIG1nciBpbml0OiBOdW1iZXIg -b2YgdHVubmVsIGV4Y2hzIGZvciBGQ29FIGlzICV4CgAAAAAAAGZjb2VfbDJ0X2luaXQ6IE5vIHVs -cHR4IGNyZWRpdCBjaDpbJXVdCgAAAAAAAAAAAGZjb2VfbDJ0X2luaXQ6IGNoOlsldV0gbDJ0X2lk -eCBbJXVdCgAAAAAAAAAAAAAAAG5vIGwydCBlbnRyaWVzIGNvbmZpZ3VyZWQ7IGZvcmNpbmcgJXUg -ZW50cmllcywgc3RhcnRpbmcgYXQgJXUKAABkY2J4IHVwZGF0ZVsldV0gc2VudCB0byBkcml2ZXIg -KHR5cGUgJSN4IHN1YnR5cGUgJSN4IGZsb3djaWQgJXUpCgAAAAAAAAAAAAAAAAAAAGRjYnhfcnVu -X3ZlcnNpb25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JVTl9JRUVFCgAAAAAAAAAAAAAAAAAAAABk -Y2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fQ0VFCgBkY2J4X3J1bl92 -ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fTk9ORQoAAAAAAAAAAAAAAAAAAAAAcG9y -dFsldV0gbGluayB1cCAoJXUpIChzcGVlZCAlI3ggYWNhcHMgJSN4IGxwY2FwcyAlI3gpCgAAAAAA -AAAAAHBvcnRfaHNzX3NpZ2RldFsldV06IGhzc19zaWdkZXQgY2hhbmdlZCB0byAweCV4CgAAAAAA -AAAAAAAAAAAAAABRU0ZQIG1vZHVsZSB1bnBsdWcgLSByZWluaXRpYWxpemluZyByeF9sb3MgIHRv -IDB4ZmYKAAAAAAAAAAAAAAAAZ3Bpb19xc2ZwX21vZHVsZV91cGRhdGU6IGNoYW5nZWQgcnhfbG9z -IGZyb20gMHgleCB0byAweCV4CgAAAAAAAGdwaW9fcXNmcF9tb2R1bGVfdXBkYXRlOiBjaGFuZ2Vk -IHR4X2RpcyBmcm9tIDB4JXggdG8gMHgleAoAAAAAAABDYWxjdWxhdGlvbiBvdXQgb2YgYm91bmRz -IGZ1cmluZyBpbml0OiAlI3ggJSN4ICUjeAoAAAAAAAAAAAAAAAAAaHdfc2dlX21hbWVtX2luaXQ6 -IGVuY291bnRlcmVkIGVycm9yICVkCgAAAAAAAAAAX2h3X3RwX3BnbW5ndDogdHhfcGFnZV9tYXgg -JXUgcnhfcGFnZV9tYXggJXUgcHN0cnVjdHMgJXUgc2l6ZSAldQoAAAAAAAAAAAAAAAAAAABtcGFy -dGl0aW9uX290aGVyc190b3RhbDogZGRwICV1IGRkcF9pc2NzaSAldSBzdGFnICV1IHBibCAldSBy -cSAldSBycXVkcCAldSAtPiAldQoAAAAAAAAAAAAAAAAAAABfbXBhcnRpdGlvbl9iYW5rc19tY1g6 -IG5iYW5rc19wbXR4ICV1ICgldU1CKSBuYmFua3NfcG1yeCAldSAoJXVNQikgbmJhbmtzX290aGVy -cyAldSAoJXVNQikgbmJhbmtzX2Z3ICV1ICgldU1CKQoAX21wYXJ0aXRpb25fYmFua3NfbWMxOiBu -YmFua3NfcG10eCAldSAoJXVNQikgbmJhbmtzX290aGVycyAldSAoJXVNQikgbmJhbmtzX2Z3ICV1 -ICgldU1CKQoAAAAAAAAAX21wYXJ0aXRpb25fYmFua3NfbWMwOiBuYmFua3NfcG1yeCAldSAoJXVN -QikgbmJhbmtzX290aGVycyAldSAoJXVNQikKAAAAAAAAAAAAAABtZW1fbWFsbG9jX2ludGVybmFs -OiBmYWlsZWQgdG8gYWxsb2NhdGUgJXUgYnl0ZXMsIHJldHVybmluZyBOVUxMCgAAAAAAAAAAAAAA -AAAAAGh3X2VkY19iaXN0WyV1XTogYmlzdF9jbWRbMHglMDh4XSBhZGRyIDB4JXggbGVuIDB4JXgK -AAAAAAAAAAAAAABod19lZGNfYmlzdFsldV06IGRvbmUsIGVuY291bnRlcmVkICV1IGVycm9ycyBv -biBmaXJzdCBhbmQgJXUgZXJyb3JzIG9uIHNlY29uZCBhdHRlbXB0ICgldWdicHMpCgBtZW1faW5p -dF9jYWNoZXM6IGNhY2hlX3NpemUgJXUgZmxvd2NfYnVmX3RjYl9jYWNoZV9zaXplICV1IGJ1Zmxs -NjRfY2FjaGVfc2l6ZSAldQoAAAAAAAAAAAAAAAAAAABxdWV1ZXNfcGVyX3BhZ2U6IHBmICV1IGhh -cyBhIGJhcnNpemUgb2YgJXUtYnl0ZXMsIG9jcV9zaXplICV1CgAAc2dlIHJlcXVpcmUgbmVxICV1 -IG5pcSAldSByb3VuZGluZyB0byAldSAldQoAAAAAbXBhcnRpdGlvbl9wbXR4OiBtIDB4JTA4eCBz -aXplICV1CgAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9wbXJ4OiBtIDB4JTA4eCBzaXplICV1CgAA -AAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9lZGMgKG5vIGV4dG1lbSk6IG0gMHglMDh4IHNpemUgJXUK -AAAAbXBhcnRpdGlvbl9lZGNfZXN0aW1hdGU6IGh3IG1vZHVsZXMgcmVxdWlyZSAlZCBieXRlcyBp -biBFREMKAAAAAGNobmV0X2J5ZTpsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBsMmRldl9mYy0+ -Zmxvd2NfcGNpZV9wZm4gWzB4JXhdLCBsMmRldl9mYy0+Zmxvd2NfcGNpZV92Zm4gWzB4JXhdLCBw -b3J0IFsweCV4XQoAAAAAAAAAAAAAAAAAY2huZXRfYnllOnZsYW5kZXZfZmMtPmZsb3djX2lkIFsw -eCV4XSwgdmxhbmRldl9mYy0+Zmxvd2NfcGNpZV9wZm4gWzB4JXhdLCB2bGFuZGV2X2ZjLT5mbG93 -Y19wY2llX3ZmbiBbMHgleF0sIHBvcnQgWzB4JXhdCgAAAAAAAABjcl9tb2R1bGVfcnhfbG9zWyV1 -XTogcnhfbG9zIGNoYW5nZWQgdG8gJXUKAAAAAABwZm4gJXUgdmZuICV1IGhhcyBwbmR0eG5zICV1 -IGFmdGVyIDEwMG1zCgAAAAAAAABiYWQgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyBv -cGNvZGUgMHgleCA+IExBU1RDMkUgMHgleAoAbWFpbGJveCBjbWQgbm90IHlldCBzdXBwb3J0ZWQ6 -IHBmbiAweCV4IHZmbiAweCV4OyBvcGNvZGUgMHgleAoAAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4 -JXggdmZuIDB4JXg7IG9wY29kZSAweCV4IGlzIHZhbGlkIHBvc3QgZGV2aWNlIGluaXQgb25seQoA -YmFkIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JTAyeCByYW1hc2sg -MHgleCBjbWQgcmFtYXNrIDB4JXgKAABiYWQgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4 -OyBvcGNvZGUgMHglMDJ4IGxlbjE2IDB4JXggdmVyc3VzIGV4cGVjdGVkIGxlbjE2IDB4JXgKAAAA -AAAAAABpbnN1ZmZpY2llbnQgY2FwcyB0byBwcm9jZXNzIG1haWxib3ggY21kOiBwZm4gMHgleCB2 -Zm4gMHgleDsgcl9jYXBzIDB4JXggd3hfY2FwcyAweCV4IHJlcXVpcmVkIHJfY2FwcyAweCV4IHdf -Y2FwcyAweCV4CgAAAAAAAAAAAGluc3VmZmljaWVudCBjYXBzIHRvIHByb2Nlc3MgbWFpbGJveCBj -bWQ6IHBmbiAweCV4IHZmbiAweCV4OyByX2NhcHMgMHgleCB3eF9jYXBzIDB4JXggcmVxdWlyZWQg -cl9jYXBzIDB4JXggd19jYXBzIDB4JXgKAAAAAAAAAAAAVlBEIHJlZ2lvbiBpcyB0b28gc21hbGwg -KFNFUkNGR19TUl9QRk5WUERTSVpFIDB4JXgpCgAAAAAAAAAAAAAAAGNmOiBmYWlsZWQgdG8gYWxs -b2NhdGVkIG1lbW9yeSBmb3IgY29uZmlndXJhdGlvbiBmaWxlLCByZXQgJWQKAAAAAAAAAAAAAAAA +0CALkpAf/5sIH/+bAB//mwQf/6kYH/+pFB//gqAf/6qsH/+boB//m5wf/5uUH/+CwB//qqggAwgA +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 +AAAAACADDmAMwAAGIAasPCADDmQIwAAMIAasPCADDmggwAAQIAarxCADDmwGwAA4IAatoCADDnAI +wAA8IAasPCADDnQCwABAIAatoCADDngIwABEIAasPCADDnwIgABIIAaszCADDoAYgABcIAaszCAD +DoQYgABsIAaszCADDogYgAB8IAaszCADDowYgACMIAaszCADDpAYgADcIAaszCADDpQYgADoIAas +zCADDpgYgAD0IAaszCADDpwYgAEAIAaszCADDqAIgAE8IAaszGh3X2JjbTg0MzRfY2hlY2tyYW06 +IFN0YXJ0CgAAAAAAUEhZIHByb2Nlc3NvciBub3QgcnVubmluZywgc3RpbGwgaW4gcmVzZXQgZm9y +IDVtcywgcG9ydF9iaXRfbWFwPSV1IAoAAAAAAAAAAAAAAABQSFkgRlcgaGFzIGJhZCBDUkMsIG9r +X2NyYz0ldQoAAFBIWSBmaXJtd2FyZSBsb2FkIHN1Y2Nlc3NmdWwhCgAAaHdfYmNtODQ4MzRfbG9h +ZHNlcXVlbmNlOiBTdGFydGVkCgAAAAAAAAAAAAAAAAAAaHdfYmNtODQ4MzRfbG9hZHNlcXVlbmNl +OiBVcGxvYWQgaW1hZ2UgdG8gUEhZIG9uLWNoaXAgbWVtb3IKAAAAAGh3X2JjbTg0ODM0X2xvYWRz +ZXF1ZW5jZTogZG9uZSBsb2FkaW5nIGltYWdlIChpID0gJXUpCgAAAAAAAAAAAABod19iY204NDM0 +X2xvd3Bvd2VyWyV1XTogZW5hYmxlPSVkCgAAAAAAAAAAAAAAAABod19iY204NDM0X2xvd3Bvd2Vy +WyV1XSwgZmFpbGVkIHRvIHNldCAzMC4weDQwMUFiaXQgNyBzaW5jZSAzMC4weDQwMEUgYml0PTEg +YWZ0ZXIgNW1zLAlyZWc9JXgKAABod19jbDQ1X2luaXRbJXVdIGFjYXBzICUjeAoAAAAAAGh3X2Ns +NDVfdXBkX3NwZF9hZHYgJSN4CgAAAAAAAAAAaHdfYXExMjAyX2xpbmtfdXBbJXVdIHVwCgAAAAAA +AABwWyV1XSBQSFkgT1ZFUkhFQVRFRCAtIGZvcmNlZCBwb3dlciBkb3duICh0ZW1wPSVkKQoAAAAA +AAAAAAAAAAAARkxBU0ggbm90IHJlYWR5OiBpICV1IG52clJlZyAlI3gKAAAAAAAAAAAAAAAAAAAA +QVFfRkxBU0hfUmVhZHkgLSBUaW1lb3V0ICgxKQoAAABBUV9GTEFTSF9SZWFkeSAtIFRpbWVvdXQg +KDIpCgAAAAlBUV9SZXR1cm5Db250cm9sT2ZGTEFTSAoAAAAAAAAAZ2F0aGVyX3Rhc2tzX3RvX3R4 +X2xpc3Q6IHRhc2sgaW4gdXNlIFsldV0KAAAAAAAAZ2F0aGVyX3Rhc2tzX3RvX3R4X2xpc3Q6IGlk +eCBbJXVdLCB0YXNrIGZpZCBbMHgleF0sIHRhc2sgc3RhdGUgWzB4JXhdLCB0YXNrIGNvbm4gWzB4 +JXhdLCB0YXNrIGZmbGFncyBbMHgleF0sIGNvbm4gZmlkIFsweCV4XSwgZGRwIFslZF0KAAAAAAAA +AAAAZ2F0aGVyX3Rhc2tzX3RvX3R4X2xpc3Q6IHRhc2sgWzB4JXhdLCBzdGF0ZSBbMHgleF0gb24g +Y29ubiBbMHgleF0gbm90IHZhbGlkIHRvIGdhdGhlciwgc2tpcHBpbmcKAAAAAAAAAAAAAAAAAAAA +AGdhdGhlcl90YXNrc190b190eF9saXN0OiB0YXNrIFsweCV4XSwgc3RpbGwgcXVldWVkIG9uIHR4 +IHBlbmRpbmcgbGlzdC4gUmVtb3ZpbmcgaXQuCgAAAAAAAAAAAAAAAGdhdGhlcl90YXNrc190b190 +eF9saXN0OiBjb25uX2ZjLT5mbG93Y19mbGFncyBbMHgleF0sIGxpc3RfZW1wdHkgWzB4JXhdLCBh +ZGRfdGFza19jb3VudCBbMHgleF0KAHRvX3R4X2xpc3Q6IG5vIHRhc2sgdG8gY2xvc2UgZm9yIGNv +bm4gWzB4JXhdLCBiYWlsaW5nIHRvIHJlY292ZXJ5IHN0YXRlIFsweCV4XQoAYXV0aGVudGljYXRl +X3RhcmdldDogS0VZX0NIQVBfUkVTUCAtIFsweCV4JXgleCV4JXgleCV4JXhdCgAAAAAAAGF1dGhl +bnRpY2F0ZV90YXJnZXQ6IEtFWV9DSEFQX1JFU1AgLSBbMHgleCV4JXgleCV4JXgleCV4XQoAAAAA +AABhdXRoZW50aWNhdGVfdGFyZ2V0OiBJbmNvcnJlY3QgcGFzc3dvcmQKAAAAAAAAAABDSEFQX0M6 +IGRpZ2VzdCBleHBhbnNpb24gZXJyb3IKAENIQVBfTjogVGFyZ2V0IHVzZXJpZCBtaXNtYXRjaAoA +Q0hBUF9SOiBkaWdlc3QgZXhwYW5zaW9uIGVycm9yCgBpU0NTSSBTZWMtcGFyYW1zIHJlY2VpdmVk +aGF2ZSBlcnJvcnMhIQoAAAAAAAAAAABUYXJnZXQgbW92ZWQgdGVtcC4gY29ubiAleCwgc2VzcyAl +eAoAAAAAAAAAAAAAAABMb2dpbiBGYWlsZWQhIS4gY29ubl9mYyBbMHgleF0sIHNlc3NfZmMgWzB4 +JXhdLCBzdGF0dXNfY2xhc3MgWzB4JXhdCgAAAAAAAAAAAAAAAFByb3RvY29sIEVycm9yIGNiaXQg +JWQgdGJpdCAlZCBjc2cgJWQgbnNnICVkCgAAAHJlY3Zfbm9waW46IGN0cmwgdGFzayBhbHJlYWR5 +IHBlbmRpbmcKAAAAAAAAAAAAAG9mbGRfcnhfZGF0YTogYWllZSwgaXNjc2kgY29ubiBbMHgleF0g +Zm9yIHNlc3MgWzB4JXhdLCB0eXBlIFsweCV4XSB0cmFuc2l0ZWQgaW4gdG9lIG1vZGUuIEtpY2tp +bmcgcmVjb3ZlcnkgCgAAAABvZmxkX3J4X2RhdGE6IGNvbm4gdGlkIFsweCV4XSwgcnhfZGF0YS0+ +c2VxIFsweCV4XSwgcnhfZGF0YS0+bGVuIFsweCV4XSwgcnhfZGF0YS0+c3RhdHVzIFsweCV4XQoA +AAAAAAAAAAAAAAAAAAAAb2ZsZF9yeF9kYXRhOiBjc2sgeyBpZCBbMHgleF0sIGNzb2NrX29mZnNl +dCBbMHgleF0sIGRsZW4gWzB4JXhdIH0KAAAAAAAAAAAAAAAAAABhY3RfZXN0OiB0Y2JfZmMgWzB4 +JXhdLCBmbG93Y19mb2lzY3NpX2Nvbm5fZmxhZ3MgWzB4JXhdCgAAAAAAAAAAYWN0X2VzdGFiOiB0 +Y2JfZmMtPmZsb3djX2J1ZiBbMHgleF0sIHRjYl9mYy0+Zmxvd2NfdHlwZSBbMHgleF0gdGNiX2Zj +LT5mbG93Y19zdGF0ZSBbMHgleF0sIG5wYWdlcyBbMHgleF0sIGZsb3djX3RwX3NuZF9tYXggWzB4 +JXhdCgAAAAAAAAAAAAAAAAAAYWN0X2VzdGFiOiBhdGlkIFsweCV4XSwgdGlkIFsweCV4XSwgb3Ag +WzB4JXhdLCByY3ZfaXNuIFsweCV4XSwgc25kX2lzbiBbMHgleF0sIGNzb2NrLT5mbG93Y19zdGF0 +ZSBbMHgleF0sIHRjcF9vcHQgWzB4JXhdLCB0Y2JfZmMtPmZsb3djX2lkIFsweCV4XSAKAAAAAAAA +AAAAAAAAAGNza19mYy0+Zmxvd2NfY3NvY2tfY29va2llIFsweCV4XSAKAAAAAAAAAAAAAAAAAGNo +bmV0X3F1ZXVlX3htaXQ6IGZjLT5mbG93Y19pZCBbMHgleF0sIGJ1Zl9sZW4gWzB4JXhdLCBidWZm +ZXJlZCBbMHgleF0sIGZpZm8ubnVtX2J5dGVzIFslMHhdCgAAAG5ldGlmX2RvX2RoY3A6IHdyLT5w +YXJhbS52bGFuaWQgWyV1XSwgbDJkZXZfZmMtPmZsb3djX25ldF9sMmRldl92bGFuZGV2IFsweCV4 +XQoAbDNpbjRfZGV2X2NvbmZpZzogd3ItPnBhcmFtLnZsYW5pZCBbJXVdLCBsMmRldl9mYy0+Zmxv +d2NfbmV0X2wyZGV2X3ZsYW5kZXYgWzB4JXhdCgAAAAAAAAAAAAAAAAAAbmV0X2wzaW40X2Rldl9j +b25maWc6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIGFkZHJlc3MgYWxyZWFkeSB1c2VkIGJ5 +IHBvcnQgJWQKAAAAAAAAAAAAAAAAAAAAbmV0X2wzaW40X2Rldl9jb25maWc6ICBhZGRyIFsweCV4 +XSwgbWFzayBbMHgleF0sIGd3IFsweCV4XSwgcmVmX2NudCBbMHgleF0gaW4gdXNlCgAAAAAAAAAA +AAAAAAAAd3JoX2NobmV0X2lmY29uZjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgbDJkZXZf +ZmMtPmZsb3djX3R5cGUgWyUweF0sIGlmY29uZl93ci0+c3Vib3AgWzB4JXhdCgAAAAAAAAAAAAAA +AAAAAHdyaF9jaG5ldF9pZmNvbmY6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIHVua25vd24g +c3Vib3AgWzB4JXhdCgAAAAAAAAAAAAAAAAAAd3JoX2NobmV0X2lmY29uZjogbDJkZXZfZmMtPmZs +b3djX2lkIFsweCV4XSwgcmMgJWQKAAAAAAAAAAAAAAAAAG5ldGlmX2lwX2NvbmZsaWN0X3RpbWVy +X2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBpbmRldmN0eHQtPnN0YXRlIFslZF0sIGlu +ZGV2Y3R4dC0+cmV0cnlfY250IFslZF0KAAAAAAAAAABuZXRpZl9pcF9jb25mbGljdF90aW1lcl9j +YjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgaW5kZXZjdHh0IFsweCV4XSwgaW4gZnJlZSBz +dGF0ZQoAAAAAAAAAAABjbWRoX2NobmV0X2lmYWNlOiBmYyBbMHgleF0sIGZjLT5mbG93Y19pZCBb +MHgleF0sIGZjLT5mbG93Y190eXBlIFsweCV4XSwgcCBbMHgleF0sIGxlbjE2IFsldV0sIGxvYyBb +MHgleF0KAAAAAAAAY21kaF9jaG5ldF9pZmFjZTpsMmRldl9mYyBbMHgleF0sIGwyZGV2X2ZjLT5m +bG93Y19pZCBbMHgleF0sIGwyZGV2LT5mbG93Y190eXBlIFsldV0sIGwyZGV2X2ZjLT5mbG93Y19u +ZXRfbDJkZXZfZmxhZ3MgWyUweF0KAAAAAABjbWRoX2NobmV0X2lmYWNlOiByMlswXSAldSByMlsx +XSAldQoAAAAAAAAAAAAAAABjbWRoX2NobmV0X2lmYWNlOiBsMmRldl9mYy0+Zmxvd2NfbmV0X2wy +ZGV2X2ZsYWdzIGNoYW5nZWQgZnJvbSBbJTB4XSB0byBbJTB4XSwgcmMgWyVkXQoAAAAAAAAAAABj +aG5ldF9sMmRldl91cF9tYl9jYjogcmMgWyVkXSwgcG9ydCBbJXVdLCBzdGF0ZSBbJXVdLCBjb29r +aWUgWzB4JXhdCgAAAAAAAAAAAAAAAGRoY3BfcHJvY2Vzc19jYjogbDJkZXZfZmMtPmZsb3djX2lk +IFsweCV4XSwgZGhjdHh0LT5zdGF0ZSBbJTB4XSwgZGhjdHh0LT5ydHJ5X2NudCBbJXVdCgAAAAAA +AAAAAGRoY3BfdGltZXJfY2I6IERIQ1BESVNDT1ZFUiBzZW50LCBidXQgbm8gcmVwbHkgZnJvbSBh +bnkgcG9zc2libGUgc2VydmVyIG9uIHRoZSBuZXR3b3JrLiBSZXRyeWluZyBhZ2FpbgoAAAAAAAAA +AABkaGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBzZW5kaW5nIERIQ1BE +SVNDT1ZFUiBmb3IgZGhjdHh0IFsweCV4XSBvbiBwaWQgWyVkXQoAAABkaGNwX3RpbWVyX2NiOiBs +MmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBESENQT0ZGRVIgcmVjZWl2ZWQgZm9yIGRoY3R4dCBb +JXhdIHBpZCBbJWRdCgAAAAAAAAAAAABkaGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQg +WzB4JXhdLCAgREhDUEFDSyByZWNlaXZlZCBmb3IgZGhjdHh0IFsleF0sIHBpZCBbJWRdCgAAAAAA +AAAAAABkaGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBkaGN0eHQtPmlw +YWRkciBbMHgleF0KAAAAAAAAAAAAAAAAAAAAAGRoY3BfdGltZXJfY2I6IHN0YXJ0aW5nIHRpbWVy +IGZvciBsZWFzZSBbJXVdIHNlY29uZHMKAAAAAAAAAAAAAABkaGNwX3RpbWVyX2NiOiBsZWFzZSB0 +aW1lIG9mIFsldV0gc2Vjb25kcyBleHBpcmVkLCBzZW5kaW5nIHJlbmV3IHJlcXVlc3QKAAAAAAAA +AGRoY3BfdGltZXJfY2I6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIG5vIHJlcGx5IGZyb20g +ZGhjcCBzZXJ2ZXIsIHRpbWluZyBvdXQKAAAAAAAAAAAAAAAAAAAAAGF1dGhfbmVnb19zZWN1cml0 +eTogc2VuZF9mbGFnIFsweCV4XSwgYXV0aF9wb2xpY3kgWzB4JXhdCgAAAAAAAABhdXRoX25lZ29f +c2VjdXJpdHk6IEtFWV9DSEFQX1JFU1AgLSBoYXNoWzB4JXgleCV4JXgleCV4JXgleF0KAAAAYXV0 +aF9uZWdvX3NlY3VyaXR5OiBLRVlfQ0hBUF9SRVNQIC0gaGFzaFsweCV4JXgleCV4JXgleCV4JXhd +CgAAAGF1dGhfbmVnb19zZWN1cml0eTogS0VZX0NIQVBfUkVTUCAtIGVycm9yIGVuY29kaW5nIHRv +IGhleAoAAAAAAABhdXRoX25lZ29fc2VjdXJpdHk6IEtFWV9DSEFQX1JFU1AgLSBlbGVuIFsweCV4 +XQoAAAAAAAAAAAAAAAAAAAAAYXV0aF9uZWdvX3NlY3VyaXR5OiBLRVlfQ0hBUF9DSEFMIC0gZXJy +b3IgZW5jb2RpbmcgdG8gaGV4CgAAAAAAAGF1dGhfbmVnb19zZWN1cml0eTogS0VZX0NIQVBfQ0hB +TCAtIGVsZW4gWzB4JXhdCgAAAAAAAAAAAAAAAAAAAABsb2dvdXRfdGltZWRvdXQ6IGxvZ291dCBy +ZXF1ZXN0IHRpbWVkb3V0LCBwb3NzaWJsZSBuZXR3b3JrIGlzc3Vlcy4gRm9yY2VmdWxseSBicmVh +a2luZyBwYXRoIGZvciBzZXNzIFsweCV4XQoAAAAAcGluZ190YXJnZXQ6IHBpbmcgdGltZW91dCwg +a2lja2luZyByZWNvdmVyeSBmb3Igc2VzcyBbMHgleF0KAAAAAGNzb2NrX2ZhaWxlZDogY3NrX2Zj +LT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBzZXNzX2ZjLT5m +bG93Y19pZCBbMHgleF0sIHNlc3NfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgZXZ0IFsweCV4XQoA +AAAAAAAAAAAAAHJjIFslZF0sIGNza19mYyBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhd +CgAAAAAAAAAAAAAAAAAAAAByZWNvdmVyeV90aW1lb3V0OiBzZXNzIGlkIFsweCV4XSBzdGF0ZSBb +MHgleF0sIHJjb3VudCBbJWRdLCBmbGFncyBbMHgleF0KAAAAAAAAAHJlY292ZXJ5X3RpbWVvdXQ6 +IHNlc3MgaWQgWzB4JXhdIGluIGxvZ291dCwgYWJvcnQgdGhlIGNvbm5lY3Rpb24KAAAAAAAAAAAA +AAAAAAAAcmVjb3ZlcnlfdGltZW91dDogc2Vzc19mYy0+Zmxvd2NfZm9pc2NzaV9zZXNzX2ZsYWdz +IFsweCV4XSwgY29ubmVjdGlvbiByZXF1ZXN0IHBlbmRpbmcsIGJhaWxpbmcgb3V0CgAAAAAAAAAA +AAAAAGZvaXNjc2k6IFJlY292ZXJ5IHRpbWVkIG91dCBhZnRlciBbJXVdIHJldHJ5LCBiYWlsaW5n +IG91dAoAAAAAAABUQ1AgY29ubiBlc3RhYmxpc2htZW50IGZhaWxlZCAlZAoAAAAAAAAAAAAAAAAA +AABkaXNjb3ZlcnlfZGF0YTogc2VzcyB7IGlkIFsweCV4XSwgZmxhZ3MgWzB4JXhdLCBidWZmZXJl +ZCBbJXVdLiB9CgAAAAAAAAAAAAAAAAAAAGRpc2NvdmVyeV9kYXRhOiBzZXNzIHsgaWQgWzB4JXhd +IH0sIHVscHR4Y2ggWyV1XSBubyBjcmVkaXRzIGF2YWlsYWJsZSwgcmVzY2hlZHVsaW5nIHJlcXVl +c3QuCgAAAEludmFsaWQgb3Bjb2RlIDB4JXggaW4gY3RybCBwYXRoCgAAAAAAAAAAAAAAAAAAAERE +UCBlcnJvciBbMHgleF0sIGFib3J0aW5nIGNvbm5uIFsweCV4XQoAAAAAAAAAAHJ4X2RhdGFfZGRw +OiBSZXNwb25jZSByZWNpZXZlZCBmb3IgdGFzayBbMHgleF0gd2hpbGUgaW52YWxpZCB0YXNrIG9y +IGNvbm5lY3Rpb24gc3RhdGUuIHRhc2sgc3RhdGUgWzB4JXhdLCBjb25uIHN0YXRlIFsweCV4XSwg +Y29ubiBmbGFncyBbMHgleF0KAGlzY3NpX2hkcl9yeDogUmVzcG9uY2UgcmVjaWV2ZWQgZm9yIHRh +c2sgWzB4JXhdIHdoaWxlIGludmFsaWQgdGFzayBvciBjb25uZWN0aW9uIHN0YXRlLiB0YXNrIHN0 +YXRlIFsweCV4XSwgY29ubiBzdGF0ZSBbMHgleF0sIGNvbm4gZmxhZ3MgWzB4JXhdCgAAAAAAAAAA +AAAAAAAAAABpc2NzaV9oZHJfcng6IEludmFsaWQgdGFzayBzdGF0ZSAweCV4IGZvciB0YXNrIDB4 +JXgsIGl0dCBbMHgleF0sIG9wYyBbMHgleF0KAAAAAHByb2Nlc3NfdG1mX3Jlc3BvbnNlOiBidWZm +ZXJlZCBbMHgleF0sIGlzdGFza19mYy0+Zmxvd2NfYnVmLT5zY2hlZF9ub2RlLm5leHQgWzB4JXhd +LCBpc3Rhc2tfZmMgWzB4JXhdLCBpc3Rhc2tfZmMtPmZsb3djX2lkIFsweCV4XQoAAAAAAAAAAAAA +AAAAAHByb2Nlc3NfdG1mX3Jlc3BvbnNlOiB3ciBvcCBbMHgleF0sIHRtZiBvcCBbMHgleF0KAAAA +AAAAAAAAAAAAAAByZXR1cm5fcGVuZGluZ190YXNrOiBjb29raWUgWzB4JTA4eF0sIFsweCUwOHhd +CgByZXR1cm5fcGVuZGluZ190YXNrOiBkZWxheSBwcm9jZXNzaW5nLCBjb25uIGZsYWdzIFsweCV4 +XQoAAAAAAAAAcmV0dXJuX3BlbmRpbmdfdGFzazogRG9uZSBzZW5kaW5nIHRhc2sgZXJyb3IgdG8g +aG9zdCwgdWxwdHhsZW4xNiBbJXVdCgAAAAAAAAAAAAByZXR1cm5fcGVuZGluZ190YXNrOiBkZXF1 +ZXVlIHRhc2sgWzB4JXhdLCBzdGF0ZSBbMHgleF0gZnJvbSB0eF9saXN0CgAAAAAAAAAAAAAAAHJl +dHVybl9wZW5kaW5nX3Rhc2s6IGFsbCB0YXNrcyByZXR1cm5lZCwgcmVjb3Zlcnkgc3RhdGUgdHJh +bnMgdG8gWzB4JXhdCgAAAAAAAAAAY2xlYXJfZGRwX21hcDogaXN0YXNrX2ZjIFsweCV4XSwgaXN0 +YXNrX2ZjLT5mbG93Y19pZCBbMHgleF0gYnVmZmVyZWQgJXUKAAAAAAAAAABjbGVhcl9kZHBfbWFw +OiBpc3Rhc2tfZmMtPmZsb3djX2ZvaXNjc2lfdGFza19ucHBvZCAldSwgbnBwb2QgJXUsIHBwZGFk +ZHIgWzB4JXhdCgAAAAAAAAAAAAAAAAAAAABjbGVhcl9kZHBfbWFwOiBhbGwgcmV0dXJuZWQgdGFz +a3MgZGRwIGNsZWFyZWQsIHJlY292ZXJ5IHN0YXRlIHRyYW5zIHRvIFsweCV4XQoAAHdyaF9mb2lz +Y3NpX25vZGU6IG5vZGVfd3ItPmZsb3dpZF9sZW4xNiAyIFsleF0KAHdyaF9mb2lzY3NpX2NoYXA6 +IGlkX2xlbiBbJXhdLCBzZWNfbGVuIFsleF0KAAAAAHdyaF9mb2lzY3NpX2NoYXA6IHRndF9pZF9s +ZW4gWyV4XSwgdGd0X3NlY19sZW4gWyV4XQoAAAAAAAAAAAAAAABzZXNzaW9uX2Jsb2NrOiBzZXNz +X2ZjLT5mbG93Y19pZCBbMHgleF0sIHNlc3NfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgY29ubl9m +Yy0+Zmxvd2NfaWQgWzB4JXhdLCBjb25uX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIGNza19mYy0+ +Zmxvd2NfaWQgWzB4JXhdLCBjc2tfZmMtPmZsb3djX3N0YXRlIFsweCV4XQoAAAAAAAAAAAAAAAAA +AABzZXNzaW9uX3VuYmxvY2s6IHNlc3NfZmMtPmZsb3djX2lkIFsweCV4XSwgc2Vzc19mYy0+Zmxv +d2Nfc3RhdGUgWzB4JXhdLCBjb25uX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNvbm5fZmMtPmZsb3dj +X3N0YXRlIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+Zmxvd2Nfc3Rh +dGUgWzB4JXhdCgAAAAAAAAAAAAAAAABzdGFydF9sb2dvdXQ6IFNlc3MtaWQgWzB4JXhdIGFscmVh +ZHkgbG9nZ2luIG91dC4KAAAAAAAAAAAAAAAAAAAAcGVlcl9jb246IGNza19mYyA9PiBmbG93aWQg +WzB4JXhdLCBmbG93Y19idWYgWzB4JXhdCgAAAAAAAAAAAAAAAGFsbG9jX3Nlc3M6IGxvZ2luX3Jl +dHJ5IFslZF0sIHJlY292X3RpbWVvdXQgWyVkXQoAAAAAAAAAAAAAAAAAAABmb2lzY3NpX2N0cmw6 +IHN1Ym9wIFsweCV4XSwgc2Vzc190eXBlX3RvX2VybCBbMHgleF0sIHNlc3NfdHlwZSBbMHgleF0K +AAAAAAAAAAAAAGZvaXNjc2lfY3RybDogcmVjZWl2ZWQgYmxvY2tlZCBmcm9tIGRyaXZlciwgdHJp +Z2dlcmluZyByZXR1cm4gdGFza3Mgbm93LgoAAAAAAAAAd2F0Y2hkb2cgY21kIGhhbmRsZXIgKHRp +bWUgJXUgYWN0aW9uICV1KQoAAAAAAAAAeGdtYWNbJXVdIHNldHRpbmcvdW5zZXR0aW5nIGhzcyBy +ZXN5bmMgYml0CgAAAAAAV0FUQ0hET0c6IGRldmljZSBzaHV0ZG93bgoAAAAAAABXQVRDSERPRzog +cG9ydFsldV0gcGF1c2Ugd2F0Y2hkb2cgdGltZW91dAoAAAAAAABXQVRDSERPRzogYnlwYXNzIHRp +bWVvdXQKAAAAAAAAAFdBVENIRE9HOiBGTFIgLSBub3QgaW1wbGVtZW50ZWQgeWV0CgAAAAAAAAAA +AAAAAFdBVENIRE9HOiB0ZW1wZXJhdHVyZSBvZiAlZEMgZXhjZWVkcyB0aHJlc2hvbGQgb2YgJWRD +CgAAAAAAAAAAAABmaWx0ZXI6IHBvcmdyYW1taW5nIHRpZCAldSAobGUgdGNhbSBpbmRleCAldSku +Li4KAAAAAAAAAAAAAAAAAAAAZmlsdGVyOiByZXF1ZXN0aW5nIGNvbXBsZXRpb24uLi4KAAAAAAAA +AAAAAAAAAAAAbDJkZXZfc2VuZF9wb3J0X2V2ZW50OiB3ciBbMHgleF0gcGVuZGluZyBvbiBwb3J0 +IFslZF0sIGN1cnJlbnQgdHJ5IFslZF0KAAAAAAAAAABGQ09FIEZyZWU6IHN0aWxsIHlpZWxkZWQg +d2hlbiBmcmVlaW5nLi4uZmxvd2NfaWQgJXggZmxvd2NfZmxhZ3MgJXggCgAAAAAAAAAAAAAAAEZD +T0UgQlAgV1IgRVJSOiBXUiB3aXRoIGNvb2tpZSAleCV4IGVycm9yZWQgYmFjayAKAAAAAAAAAAAA +AAAAAABwb3J0ICVkIHNldCBwZmNfZW4gPSAweCV4CgAAAAAAAHBvcnQgJWQgc2V0IHBmY19lbiA9 +IDB4JXgKAAAAAAAAZXRzX3NldF9jZmdfaWVlZVsldV0gdW5rbm93biBUU0EgYWxnIGZvciBwcmlv +ICV1OiAldQoAAAAAAAAAAAAAAEZDb0UgRERQIGZhaWxlZCA6IG94X2lkIDB4JXggcnhfaWQgMHgl +eAoAAAAAAAAAAEZDb0UgRERQIGZhaWxlZCA6IERkcFJlcG9ydCAweCV4IERkcFZhbGlkIDB4JXgK +AEZDIHhjaGcgYWxsb2MgZmFpbGVkOiBhdmFpbCAlZAoAZmNvZSBub3RpZnkgOiBVcGRhdGUgbmV3 +IERDQlggdmFsdWVzIFZJIHN0YXRlIDB4JXggcHJpIDB4JXggc2NoZWRjbCAweCV4IGRjYnhfZG9u +ZSAweCV4CgAAAAAAAAAAZmNvZSBub3RpZnkgOiBGQ0YgZmxvd2lkIDB4JXgsIHVscGNoIDB4JXgg +CgAAAAAAUFJMSSBSc3AgdGltZWRvdXQgOiBmbG93Y19pZCAweCV4IG94X2lkIDB4JXggcnhfaWQg +MHgleCAKAAAAAAAAAGNhbm5vdCBhbGxvY2F0ZSBvZmZsb2FkZWQgZmlsdGVyIGNvbm5lY3Rpb24K +AAAAAGNhbm5vdCBhbGxvY2F0ZSBvZmZsb2FkZWQgZmlsdGVyIElQdjYgY29ubmVjdGlvbgoAAAAA +AAAAAAAAAAAAAABkaXNwYXRjaF9kZWZlcnJlZF9jbGFzc19jbGFzc19zaGFwaW5nWyV1OiV1XTog +bGlzdF9lbXB0eQoAAAAAAAAAbG9vcGJhY2sgYnVmZmVyIGdyb3VwWyV1XSBpcyBkaXNhYmxlZAoA +AAAAAAAAAAAAaW52YWxpZCBidWZmZXIgZ3JvdXBbJXVdIGNvbmZpZ3VyYXRpb246IG10dSAldSBs +d20gJXUgaHdtICV1IGR3bSAldQoAAAAAAAAAAAAAAABmYyAldSB2ZiAldSBnb3QgaXZmPTB4JXgs +cmFuZ2U6ICUjeC0lI3ggKCV1LyV1IHVzZWQpCgAAAAAAAAAAAAAAVkkgJXUgY2Fubm90IGdldCBS +U1Mgc2xpY2U6IE5vIG1vcmUgc2xpY2VzIGF2YWlsYWJsZSAodXNlZCAldS8ldSkKAAAAAAAAAAAA +AAAAAABwZm4gJXUgdmZuICV1IHdpdGggcG9ydCBtYXNrIDB4JXggY2Fubm90IGFjY2VzcyBwb3J0 +ICV1LCByZXQgJWQKAAAAAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgY291bGQgbm90IGFsbG9j +YXRlIHZpaWQsIHJldCAlZAoAAHBmbiAldSB2Zm4gJXUgY291bGQgbWFwIHZpaWQgIDB4JXggdG8g +Zmxvd2MsIHJldCAlZAoAAAAAAAAAAAAAAABwZm4gJXUgdmZuICV1IGNvdWxkIG5vdCBhbGxvY2F0 +ZSB1d2lyZSBmdW5jICVkIG1hYyBhZGRyLCByZXQgJWQKAAAAAAAAAAAAAAAAAAAAAG1paV9mb3Jj +ZV9zcGVlZFsldV06IHJjYXBzIDB4JXgKAAAAAAAAAAAAAAAAAAAAAG1paV9wZG93blsldV06IHBv +d2VyZG93biBlbiAldQoAcG9ydFsldToweCUwMng6MHglMDJ4XTogdW5rbm93biBhY3Rpb24gMHgl +eAoAAAAAcG9ydFsldToweCUwMng6MHglMDJ4XTogdW5rbm93biByZWFkIGFjdGlvbiAweCV4CgAA +AAAAAAAAAAAAAAAAAGNwbF9lcnJfbm90aWZ5OiB0aWQgJXUgY3BsIDB4JTA4eCUwOHgKAAAAAAAA +AAAAAGNwbF9lcnJfbm90aWZ5OiB0aWQgJXUgY3BsIDB4JTA4eCUwOHggMHglMDh4JTA4eAoAAAAA +AAAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTogdGlkICV1IGxlbiAldQoAAEZDT0UgRnJlZTogc3Rp +bGwgeWllbGRlZCB3aGVuIGZyZWVpbmcuLi5mbG93Y19pZCAleCBmbG93Y19mbGFncyAleCAKAAAA +AAAAAAAAAAAAc2NzaV9hYm9ydDogRW50ZXJpbmcgQWJvcnRfdGFzaywgYnVmZmVyZWQgWyV1XQoA +c2NzaV9hYm9ydDogcmMgWzB4JXhdIHJlZiB0YXNrIG5vdCBvdXRzdGFuZGluZwoAc2NzaV9hYm9y +dDogaWRhdGEtPm9wIFsweCV4XSwgZmxhZ3MgWzB4JXhdLCBmdW5jIFsweCV4XSwgbHVuX2lkeCBb +MHgleF0KAAAAAAAAAABzY3NpX2Fib3J0OiB3ci0+aXFpZCBbMHgleF0sIGlzdGFza19mYy0+Zmxv +d2Nfc2dlX2lxaWQgWzB4JXhdLCBpc3Rhc2tfZmMgdGFzayBmbGFncyBbMHgleF0KAAAAAABzY3Np +X2Fib3J0OiBjb25uIFsweCV4XSwgY21kc24gWzB4JXhdLCBzZW50X2NtZHNuIFsweCV4XSwgbWF4 +X2NtZHNuIFsweCV4XSwgaXR0IFsweCV4XQoAAAAAAAAAAABhYm9ydC9jbG9zZSBXUiB3aXRoIGNv +b2tpZSAweCVseCB3YXMgaXNzdWVkIG9uIHNzbiAweCV4IGluIHdyb25nIHN0YXRlIDB4JXgKAAAA +AGFib3J0IFdSIG9uIHNzbiAweCV4IGRpZCBub3QgZmluZCBXUiB3aXRoIGNvb2tpZSAweCV4JXgK +AAAAAAAAAABjbG9zZSBXUiB3aXRoIGNvb2tpZSAweCVseCBvbiBzc24gMHgleDtkaWQgbm90IGZp +bmQgV1Igd2l0aCBjb29raWUgMHglbHgKAAAAAAAAAGFib3J0IFdSIG9uIHNzbiAweCV4IHdhcyBp +c3N1ZWQgb24geGNoZyAweCV4IHdpdGggcnhfaWQgMHgleCBpbiB3cm9uZyBzdGF0ZSAweCV4CgAA +AAAAAAAAAAAAAAAAAHNjc2lfbHVyOiBFbnRlcmluZyBMVVIgaGFuZGxlciwgYnVmZmVyZWQgWyV1 +XQoAAHNjc2lfbHVyOiBpZGF0YS0+b3AgWzB4JXhdLCBmbGFncyBbMHgleF0sIGZ1bmMgWzB4JXhd +LCBsdW5faWR4IFsweCV4XQoAAAAAAAAAAAAAc2NzaV9sdXI6IHdyLT5pcWlkIFsweCV4XSwgaXN0 +YXNrX2ZjLT5mbG93Y19zZ2VfaXFpZCBbMHgleF0sIGlzdGFza19mYyB0YXNrIGZsYWdzIFsweCV4 +XQoAAAAAAAAAc2NzaV9sdXI6IGNvbm4gWzB4JXhdLCBjbWRzbiBbMHgleF0sIHNlbnRfY21kc24g +WzB4JXhdLCBtYXhfY21kc24gWzB4JXhdLCBpdHQgWzB4JXhdCgAAAAAAAAAAAAAAZGNieF9jZWVf +ZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0xJTktVUAoAZGNieF9jZWVfZmVhX3NtWyV1 +XSBGZWF0dXJlWyV1XSBTRVRfTE9DQUxfUEFSQU1FVEVSUwoAAAAAAAAAAAAAAGRjYnhfY2VlX2Zl +YV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9OT19BRFZFUlRJU0UKAAAAAAAAAAAAAABkY2J4 +X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfUEVFUl9OT1RfQURWRVJUSVNFX0RD +QlgKAAAAAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVS +RV9QRUVSX05PVF9BRFZFUlRJU0VfRkVBVFVSRQoAAAAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3Nt +WyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1VQREFURV9PUEVSX1ZFUlNJT04KAAAAAGRjYnhfY2Vl +X2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9QRUVSX1VQREFURV9PUEVSX1ZFUlNJT04K +AAAAAAAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0dF +VF9QRUVSX0NGRwoAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVB +VFVSRV9DRkdfTk9UX0NPTVBBVElCTEUKAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVb +JXVdIEZFQVRVUkVfVVNFX0xPQ0FMX0NGRwoAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBG +ZWF0dXJlWyV1XSBGRUFUVVJFX1VTRV9QRUVSX0NGRwoAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9z +bVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9GRUFUVVJFX0RJU0FCTEVECgAAAAAAAABkY2J4X2Nl +ZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfRVJST1JfQ0hBTkdFCgAAAAAAAAAAAAAA +RmVhdHVyZSAldSBzeW5jJ2Q9JXUgKGVycm9yICV1KQoAAAAAAAAAAAAAAAAAAAAAY2huZXRfbDJ0 +X3VwZGF0ZTogbDJkZXZfZmMgWzB4JXhdLCBsMmRldl9mYy0+Zmxvd2NfaWQgWyV1XSBsMmRldl9m +Yy0+Zmxvd2NfZmxhZ3MgWzB4JXhdLCBpbnRmIFsweCV4XQoAAAAAAAAAAAAAAGNobmV0X2wydF91 +cGRhdGU6IGwyZGV2X2ZjLT5mbG93Y19pZCBbJXVdIGFscmVhZHkgc2NoZWR1bGVkCgAAAABjaG5l +dF9sMnRfdXBkYXRlOiBpbiBkZWxheWVkX3Byb2Nlc3NpbmcsIGwydGVudCBbJTA4eF0KAAAAAAAA +AAAAY2huZXRfYXJwX3VwZGF0ZV9jYWNoZTogYXJwIGlwNCBlbnRyeSBmb3VuZCAKAAAAY2huZXRf +YXJwX3VwZGF0ZV9jYWNoZTogYXJwIGlwNiBlbnRyeSBmb3VuZCAKAAAAY2huZXRfYXJwX3VwZGF0 +ZV9jYWNoZTogYm90aCBpcDQgYW5kIGlwNiBhZGRyIGNhbm5vdCBiZSBudWxsCgAAAGNobmV0X2wy +dF91cGRhdGU6IGwydF91cGRhdGUgcmVxdWVzdCBzZW50IGwydGVudCBbJTA4eF0sIGwydGVudC0+ +aWR4IFslZF0sIGwydGVudC0+dmxhbiBbJWRdCgAAAG5ldGlmX3Byb2Nlc3NfZGhjcDogbDJkZXZf +ZmMtPmZsb3djX2lkIFsweCV4XSwgcHJvY2Vzc2luZywgb3B0X2xlbiAldQoAAAAAAAAAAAAAY2hu +ZXRfZGhjcF9yZWN2OiB2bGFuaWQgWyV1XSwgbDJkZXZfcGlkX2ZjLT5mbG93Y19uZXRfbDJkZXZf +dmxhbmRldiBbMHgleF0sIGwyZGV2X2ZjIFsweCV4XQoAAAAAY2huZXRfZGhjcF9yZWN2OiBsMmRl +dl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBkaGN0eHQtPnN0YXRlIFslZF0sIG1hbGFjaW91cyBkaGNw +IHJlY3YgZm9yIG5vIHJlcXVlc3QKAAAAAAAAAAAAAAAAAGRoY3R4dC0+c3RhdGUgOiAlZAoAAAAA +AAAAAAAAAAAAbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgQmFkIERIQ1AgY29va2llIHJlY2ll +dmVkLCBhYm9ydGluZwoAAENvdWxkIG5vIGFsbG9jYXRlIHBjYiEhIEZyZWVpbmcgZmNmICEhIQoA +AAAAAAAAAHZuX3BhcnNlIHVua25vd24gc3ViY29kZSAldQoAAAAAdm5fcGFyc2UgdW5rbm93biBk +dHlwZSAldQoAAAAAAABpZ25vcmluZyBmaXAgcmVjdiBmb3IgcGNiIGZsb3c6JXggaW4gb2ZmbGlu +ZSBzdGF0ZQoAAAAAAAAAAAAAAAAAZmlwX3ZuMnZuX3JlY3ZfZXJyIAoAAAAAAAAAAAAAAABDb3Vs +ZCBub3QgYWxsb2NhdGUgZmxvd2MhISEhCgAAAENvdWxkIG5vdCBhbGxvY2F0ZSBTQ0IgZmxvd2Mh +ISEhCgAAAAAAAAAAAAAAAAAAAENvdWxkIG5vdCBmaW5kIHJpZ2h0IHNjYiBmb3IgbG9nbwoAAAAA +AAAAAAAAAAAAAGlnbm9yaW5nIGZpcCByZWN2IGZvciBmY2YgZmxvdzoleCBpbiBvZmZsaW5lIHN0 +YXRlCgAAAAAAAAAAAAAAAABDb3VsZCBub3QgZmluZCByaWdodCBzY2IgZm9yIGZsb2dpCgAAAAAA +AAAAAAAAAABwb3J0IDB4JXgsIHN0YXRlIDB4JXgsIHJldHJ5IG5vdCBzdXBwb3J0ZWQKAAAAAABG +bG9naSByZXNwIHJjdiB3aXRoIHVua25vd24geGNoZyBveF9pZCV4IHNpZCAlMnglMnglMnggZGlk +ICUyeCUyeCUyeAoAAAAAAAAAAAAAAE5fUE9SVCAweCV4JXgleCByZWplY3RlZCBQTE9HSSB3aXRo +IHJlYXNvbiBjb2RlICV4CgAAAAAAAAAAAAAAAABBQlRTIHdoaWxlIGF3YWl0aW5nIFBSTEkgUnNw +OiBmbG93Y19pZCAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleCAKAAAAAAAAAAAAAAAAAEFCVFMg +ZmFrZSBSc3A6IGxvYyAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleAoAAEZDIGZjYiBhbGxvYyBm +YWlsZWQ6IGF2YWlsICVkCgAARkMgZmNiIGFsbG9jIHhpZDolZCBmbG93aWQgJWQKAABsbGRwX3J4 +X3BrdF9oYW5kbGVyWyV1XSBkcm9wIHByZS1pbml0IChjb3VudCA9ICV1KQoAAAAAAAAAAAAAAAAA +JXgleCV4IFJlY2lldmVkIExPR08gZnJvbSAleCV4JXggCgAAAAAAAAAAAAAAAAAAY2Fubm90IGFs +bG9jYXRlIFBPRkNPRSBmaWx0ZXIgY29ubmVjdGlvbiBmb3IgeF9pZCAleCAKAAAAAAAAAAAAAEZh +aWxlZCB0byBwb3N0IHhjaGcgZXJyOiBzc25pIDB4JXggY29va2llIDB4JWx4IHJ2YWwgJXggCgAA +AAAAAAB0Y3BfcmVsZWFzZV90aWQ6IHRpZCBbMHgleF0sIGZsb3djIGZsYWdzIFsweCV4XSwgYnVm +ZmVyZWQgWzB4JXhdCgAAAAAAAAAAAAAAAAAAAHRjcF9yZWxlYXNlX3RpZDogc2l6ZW9mKHRjYl9m +Yy0+Zmxvd2NfZm9pc2NzaV9jb25uKSBbJXVdLCBieXRlcwoAAAAAAAAAAAAAAAAAAAAAYWN0X29w +ZW5fcnBsOiBhdGlkIFsweCV4XSwgdGlkIFsweCV4XSwgdGNiX2ZjLT57IGlkIFsweCV4XSwgc3Rh +dGUgWzB4JXhdLCB0eXBlIFsweCV4XSB9LCBjcGxfb3AgWzB4JXhdLCBzdGF0dXMgWzB4JXhdCgAA +AAAAAAAAAABhY3Rfb3Blbl9ycGw6IGNza19mYy0+eyBpZCBbMHgleF0sIHN0YXRlIFsweCV4XSwg +Y3NvY2tfZmxhZ3MgWzB4JXhdIH0gCgAAAAAAAAAAAGFjdF9vcGVuX3JwbDogcmVjdmQgbmVnIGFk +dmljZSBbMHgleF0KAAAAAAAAAAAAAHNlbmRfYWJvcnRfcnBsOiBjc2tfZmMtPmZsb3djX3R5cGUg +WzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwgdGlkIFsweCV4XSwgdWxwdHhjaCBbJXVd +LCBidWZmZXJlZCBbJXVdCgAAAAB3cmhfb2ZsZF90Y3BfY2xvc2VfY29uX3JlcGx5OiB0Y2JfZmMt +PmZsb3djX2lkIFsweCV4XSwgdGNiX2ZjLT5mbG93Y190eXBlIFsweCV4XSwgbGVuMTYgWyV1XSwg +bG9jIFsldV0KAAAAAAAAAAAAd3JoX29mbGRfdGNwX2Nsb3NlX2Nvbl9yZXBseTogcnBsLT5vcF9U +aWQgWzB4JXhdLCBycGw+c3RhdHVzIFsweCV4XSwgcnBsLT5zbmRfbnh0IFsweCV4XSwgcnBsLT5y +Y3Zfbnh0IFsweCV4XQoAAHRjcF9hYm9ydF9ycGxfcnNzOiB0aWQgWzB4JXhdLCBzdGF0dXMgWzB4 +JXhdCgAAAHRjcF9hYm9ydF9yZXFfcnNzOiB0aWQgWzB4JXhdLCBzdGF0dXMgWzB4JXhdCgAAAG9m +bGRfYWJvcnRfcmVxX25lZ2FkdlsldV06IHdyIDB4JTA4eCBjcGxfYWJvcnRfcmVxIERFTElWRVJF +RAoAAABob3N0X3dyWyV1XTogd3IgMHglMDh4IGNwbF9hYm9ydF9yZXEgc3RhdHVzIDB4JXgKAAAA +AAAAAAAAAAAAAAAAcGt0c2NoZWRfY2xfcmxbJXU6JXVdOiBtb2RlIHwgdW5pdCB8IHJhdGUgMHgl +MDZ4IG1pbiAldSBtYXggJXUgcGt0c2l6ZSAldQoAAAAAAABwYXJhbV9jaG5ldFsweCV4OjB4JXhd +OiBjaG5ldCAweCV4IHJlYWQgJXUgcGYgJXUgcmV0ICVkCgAAAAAAAAAAcGFyYW1fZG1hcVsweCV4 +OjB4JXhdOiBkbWFxIDB4JXggcmVhZCAldSBwZiAldSByZXQgJWQKAAAAAAAAAAAAAE1DWyV1XSBp +bml0X3N0YXRlX21hY2hpbmUgMHglMDJ4CgAAAAAAAAAAAAAAAAAAAE1DIGluaXRpYWxpemF0aW9u +IG5vdCBjb21wbGV0aW5nLCBNQyBjdXJyZW50IGluaXQgc3RhdGUgaXMgMHglMDJ4CgAAAAAAAAAA +AAAAAAAATUNbJXVdIF9od19tY19pbml0X21jCgAAAAAAAAAAAABwaHk6IGZhaWxlZCB0byBhbGxv +Y2F0ZWQgbWVtb3J5IGZvciBwaHkgZncgZmlsZSwgcmV0ICVkCgAAAAAAAAAAaHdfbGVfZmlsdGVy +X2N0dXBsZTogdHVwbGUgJXUgbm90IHNwZWNpZmllZCBidXQgcmVxdWlyZWQgZm9yIG1hc2sgMHgl +eAoAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogdGltZXJfcnMgJXV1cyB0aW1lc3RhbXBf +cmVzICV1dXMgZGVsYXllZGFja19yZXMgJXV1cwoAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBk +YWNrX3RpbWVyICV1dXMgbXNsICV1dXMgcnh0X21pbixtYXggJXUsJXV1cyBwZXJzX21pbixtYXgg +JXUsJXV1cwoAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBrZWVwX2lkbGUsaW50dmwgJXUs +JXVzIG1heHJ0dCAldXVzIGluaXRzcnR0ICV1dXMgZmlud2FpdDJfdGltZXIgJXV1cwoAAAAAAGh3 +X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGRhY2tfdGltZXIgZnJvbSAldSB0byAldQAAAAAA +AAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBtc2wgZnJvbSAldSB0byAldQBod190 +cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyByeHRfbWluIGZyb20gJXUgdG8gJXUAAAAAAAAAAAAA +AAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcnh0X21heCBmcm9tICV1IHRvICV1AAAA +AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHBlcnNfbWluIGZyb20gJXUg +dG8gJXUAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBwZXJzX21heCBm +cm9tICV1IHRvICV1AAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcga2Vl +cF9pZGxlIGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBw +aW5nIGtlZXBfaW50dmwgZnJvbSAldSB0byAldQAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3Nf +dzogY2FwcGluZyBpbml0X3NydHRfbWF4cnR0IGZyb20gJXUgdG8gJXUAAAAAaHdfdHBfdGNwX3Nl +dHRpbmdzX3c6IGNhcHBpbmcgaW5pdF9zcnR0X2luaXRzcnR0IGZyb20gJXUgdG8gJXUAAGh3X3Rw +X3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGZpbndhaXQyX3RpbWVyIGZyb20gJXUgdG8gJXUAAAAA +AABsZSBjb25maWd1cmF0aW9uOiBuZW50cmllcyAldSByb3V0ZSAldSBjbGlwICV1IGZpbHRlciAl +dSBhY3RpdmUgJXUgc2VydmVyICV1IGhhc2ggJXUKAAAAAAAAAAAAAABsZSBjb25maWd1cmF0aW9u +OiBuZW50cmllcyAldSByb3V0ZSAldSBjbGlwICV1IGZpbHRlciAldSBzZXJ2ZXIgJXUgYWN0aXZl +ICV1IGhhc2ggJXUgbnNlcnZlcnNyYW0gJXUKAAAAAAAAAAAAAAAAaHdfc2dlX3F1ZXVlX2Jhc2Vf +bWFwWyV1XTogZXhjZWVkZWQgbnVtYmVyIG9mIGVncmVzcyBxdWV1ZXMsICV1CgAAAAAAAAAAAAAA +AAAAAABod19zZ2VfcXVldWVfYmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgaW5ncmVz +cyBxdWV1ZXMgd2l0aCBmcmVlbGlzdCBhbmQgaW50ZXJydXB0LCAldQoAAABod19zZ2VfcXVldWVf +YmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgaW5ncmVzcyBxdWV1ZXMsICV1CgAAAAAA +AAAAAAAAAAAAAGNmX3BhcnNlOiBmaWxlIG1lbXR5cGUgMHgleCBtZW1hZGRyIDB4JXggbWFwcGVk +IEAgJXA6CgAAAAAAAAAAAABjb25maWd1cmVkIHdpdGggY2FwcyBuYm18bGluayAweCUwOHggc3dp +dGNofG5pYyAweCUwOHggdG9lfHJkbWEgMHglMDh4IGlzY3NpfGZjb2UgMHglMDh4CgAAAAAAAABu +ZXQgVkkgYWxsb2NhdGlvbiBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAAAA +AAAAAAAAbmV0IFZJIG1hYyBhZGRyZXNzIHByb2dyYW1taW5nIGZhaWxlZCBmb3IgZmNfaWQgJXUg +d2l0aCBlcnJvciAlZAoAAAAAAAAAAAAAAAAAAABuZXQgVkkgcnhtb2RlIHByb2dyYW1taW5nIGZh +aWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJvciAlZAoAAAAAbmV0IFZJIHJzcyBpbmRpcmVjdGlv +biB0YWJsZSBwcm9ncmFtbWluZyBmb3IgZmNfaWQgJXUgZmFpbGVkIHdpdGggZXJyb3IgJWQKAAAA +AABuZXQgVkkgcnNzIGNvbmZpZyBjb21tYW5kIGZhaWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJv +ciAlZAoAAAAAbmV0IFZJIGNvbW1hbmQgZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVk +CgAAAAAAAAAAAAAAAAAAAHByb2dyYW1tZWQgSFcgdGFnbSBbMHglMDh4XSwgSFcgcGdzeiBmYWN0 +b3IgWzB4JTA4eF0sIEZPaVNDU0kgdGFnbSBbMHglMDh4XSwgcnRhZ20gWzB4JTA4eF0sIG1heHN6 +X2JpdHMgWyV1XSwgc3pfYml0cyBbJXVdLgoAAAAAYmFzZSBbIDB4JTA4eF0sIGxsaW1pdCBbMHgl +MDh4XSwgdWxpbWl0IFsweCUwOHhdLCBzaXplIFsldV0sIG1heF90eHN6IFsldV0sIG1heF9yeHN6 +IFsldV0sIGlvc2l6ZSBbJXVdCgAAAAAAAAAAAG5wcG9kcyBbJXVdLCBpZHhfbWFzayBbMHglMDh4 +XSwgaWR4X2ZpcnN0IFsldV0sIGlkeF9sYXN0IFsldV0sIHNjc2lfcGxkX3NpemUgWyV1XSwgQUxJ +R04oc2NzaV9wbGRfc2l6ZSwgMTYpIFsldV0sIHBwZF96b25lcyBbJXVdLgoAAAAAAAAAAAAAAAAA +AGZvaXNjc2lfaW5pdDogZm9pc2NzaV9pbml0X2RvbmUgWyV1XSwgZGV2LnJlcy5mb2lzY3NpX250 +YXNrcyBbJXVdLCBkZXYucmVzLmZvaXNjc2lfbnNlc3MgWyV1XSwgZGV2LnJlcy5uY3NvY2sgWyV1 +XSwgZGV2LnJlcy5mb2lzY3NpX25pbml0IFsldV0sIHJjIFslZF0KAAAAAAAAAABjaF9jbF9yYXRl +WyV1LyV1XTogY2FwcGVkIGNsYXNzIHJhdGUgZnJvbSByZXF1ZXN0ZWQgJXUgdG8gY29uZmlndXJl +ZCAoZWZmZWN0aXZlKSBjaGFubmVsIHJhdGUgJXUKAAAAAAAAAAAAAAAAAAAAY2hfY2xfcmF0ZVsl +dS8ldV06IGluY3JlYXNlZCBkZWZpY2l0X2luY3IgZnJvbSByZXF1ZXN0ZWQgJXUgdG8gcmVxdWly +ZWQgbWluIG9mICV1OyByYXRlICV1IChlZmYgJXUpIGRlZmljaXRfbWF4ICV1CgAAAAAAAAAAAAAA +AABwa3RzY2hlZCBjaGFubmVsICV1IHNldHMgc3BlZWQgKGZyb20gJXUpIHRvICV1IGticHMKAAAA +AAAAAAAAAAAAbmV0X2wyZGV2X25vdGlmeTogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgcG9y +dCBbJWRdLCBldmVudCBbMHgleF0sIHVscHR4Y2ggWyV1XSwgY2xhc3MgWzB4JXhdLCB2cHJpbyBb +MHgleF0sIHZpZCBbMHgleF0sIHZpX3JlYWR5IFsldV0KAAAAAAAAbmV0X2wyZGV2X25vdGlmeTog +cGdpZCBbMHgleF0sIHByaW8gWzB4JXhdLCBjaCBbMHgleF0KAAAAAAAAAAAAAGZjb2Ugbm90aWZ5 +IDogRkNvRSBMSU5LVVA6IHBvcnQgMHgleCwgZXZlbnQgMHgleAoAAAAAAAAAAAAAAAAAAABmY29l +IG5vdGlmeSA6IEZDb0UgTElOS0RPV046IHBvcnQgMHgleCwgZXZlbnQgMHgleAoAAAAAAAAAAAAA +AAAAZmNvZSBub3RpZnkgOiBEQ0JYIDogcG9ydCAweCV4LCBwcmlvcml0eSAweCV4IHVscHR4Y2gg +MHgleCBjbGFzcyAweCV4CgAAAAAAAAAAAABkY2J4X3RpbWVvdXRbJXVdCgAAAAAAAAAAAAAAAAAA +AHBvcnRfY21kX2hhbmRsZXI6IHVua25vd24gdS5kY2IudHlwZSAweCV4CgAAAAAAAHBvcnRbJXVd +IGxpbmsgZG93biAoJXUpIChsc3RhdHVzICUjeCkKAAAAAAAAAAAAAGkyYyBlcnJvciBjYXVzZWQg +YnkgbW9kdWxlIHVucGx1ZwoAAAAAAAAAAAAAAAAAAHNlbmR0byBwZW5kaW5nOiB3cl9wZW5kICVw +IGZvciBwb3J0ICV1LCB3YW50IHRvIHNlbmQgdG8gcG9ydCAldQoAAAAAAAAAAAAAAAAAAAAAcG9y +dFsldV0gdXBkYXRlIChmbG93Y2lkICV1IHJjICV1KQoAAAAAAAAAAAAAAAAAcG9ydF9zZXRfbG9v +cGJhY2sgcG9ydCAlI3ggY3VycmVudCAlI3ggbW9kZSAlI3gKAAAAAAAAAAAAAAAAAAAAAHBvcnRb +JXVdIHNwZWVkIHVwZGF0ZTogJSN4CgAAAAAAcG9ydFsldV0gYmVnaW5uaW5nIGRlYm91bmNlCgAA +AABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0gcG93ZXJpbmcgZG93bgoAAAAAAABwb3J0X2xp +bmtfc3RhdGVfaGFuZGxlclsldV0gcG93ZXJpbmcgdXAKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVf +aGFuZGxlclsldV0gdW5rbm93biBzdGF0ZSAoc3RhdGUgPSAlI3gpCgAAAAAAAAAAcG9ydF9saW5r +X3N0YXRlX2hhbmRsZXI6IFNvbWV0aGluZyB3ZW50IHRlcnJpYmx5IHdyb25nLiByZXQgPSAlZAoA +AAAAAAAAAAAAAAAAAABsZSBpbml0aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xp +cCAldSBmaWx0ZXIgJXUgYWN0aXZlICV1IHNlcnZlciAldSBoYXNoICV1CgAAAAAAAAAAAABsZSBp +bml0aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIgJXUgc2Vy +dmVyICV1IGFjdGl2ZSAldSBoYXNoICV1IG5zZXJ2ZXJzcmFtICV1CgAAAAAAAAAAAAAAaHdfdHBf +aW5pdDogdGNiIHJlZ2lvbiAoc3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3Qg +MjU2TUIgb2YgTUEgbWVtb3J5CgAAAAAAAAAAAAAAAAAAaHdfdHBfaW5pdDogcGdtbmd0IHJlZ2lv +biAoc3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2TUIgb2YgTUEgbWVt +b3J5CgAAAAAAAAAAAAAAaHdfdHBfaW5pdDogVFAgcGdtbmd0IGluaXRpYWxpemF0aW9uIGRpZCBu +b3QgY29tcGxldGUKAAAAAAAAAAAAAGJ1Zm1faW5pdDogbiAldSBidWZsbDY0aW50X3NpemUgMHgl +eAoAAAAAAAAAAAAAAGJ1Zm1faW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgaW50 +ZXJuYWwgYnVmbGw2NCBidWZmZXJzCgAAAAAAAAAAAAAAAAAAYnVmbV9pbml0OiBub3QgZW5vdWdo +IG1lbW9yeSB0byBhbGxvY2F0ZSBidWZsbDY0IGJ1ZmZlcnMKAAAAAAAAAG1lbV9pbml0X2J1Zjog +bm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyBidWZmZXJzCgAAAAAAAABtZW1faW5p +dF9idWY6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIHRjYl9jYWNoZSAob2ZmZXJlZCAl +dSB0cnlpbmcgdG8gdXNlICV1IGF2YWlsYWJsZSAldSkKAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlv +bl9vdGhlcnM6IHN0YXJ0IDB4JTA4eCBzaXplICV1ICh1bnVzZWQgJXUpCgAAAAAAAAAAAAAAAG1w +YXJ0aXRpb25fb3RoZXJzOiBzdGFydCAweCUwOHggc2l6ZSAldSAodW51c2VkICV1KQoAAAAAAAAA +AAAAAABtZW1faW5pdDogRURDIG92ZXJjb21taXR0ZWQgYnkgJWQgYnl0ZXMKAAAAAAAAAABtZW1f +aW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyB0YWJsZQoAAAAAAAAAAAAA +AAAAY3hjbmljX2RldmljZV9pbml0OiBjeGNuaWMgWzB4JTB4XSwgY3hjbmljLT5maWx0ZXIgWyUw +eF0KAAAAAAAAAHBvZmNvZSBpbml0IGRvbmUKAAAAAAAAAAAAAAAAAAAAUG9ydFsldV06IFVua25v +d24gU0dNSUkgc3ViLXR5cGUgJSN4CgAAAAAAAAAAAAAAUG9ydFsldV06IFVua25vd24gQlRfWEZJ +IHN1Yi10eXBlICUjeAoAAAAAAAAAAAAAUG9ydFsldV06IFVua25vd24gQlRfWEFVSSBzdWItdHlw +ZSAlI3gKAAAAAAAAAAAAcG9ydF9pbml0WyV1XTogcG9ydCB0eXBlIDB4JXggaXMgbm90IHN1cHBv +cnRlZAoAbXBhcnRpdGlvbl9pbml0OiBtb3ZlZCBwbXJ4X3N0YXJ0IGZyb20gMHglMDh4IHRvIDB4 +JTA4eCB0byBtYWtlIHJvb20gZm9yIExFIEhBU0ggYW5kL29yIFRQIFRDQnMKAAAAAAAAAAAAAAAA +AAAAAG1wYXJ0aXRpb25faW5pdDogbW92ZWQgcG1yeF9zdGFydCBmcm9tIDB4JTA4eCB0byAweCUw +OHggKEVEUkFNKQoAAAAAAAAAAAAAAAAAAAAARVEgcGZuICV1IHZmbiAldTogZGVzdHJveWluZyBl +cWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFncyAweCUwOHgK +AAAAAAAAAAAAbDJkZXZfZmMtPmZsb3djX2lkIFsldV0sIGwyZGMtPnBmbiBbJXVdLCBsMmRjLT52 +Zm4gWyV1XSwgbDJkYy0+bHBvcnQgWyV1XSwgbDJkZXZfZmMtPmZsb3dpZCBbJXVdIGwyZGMtPnR4 +X2NoIFsldV0sIGRldi52cGQucG9ydHZlYyBbJXhdCgAAAAAAAAAAcG9ydHZlYyBbJXVdCgAAAGwy +ZGV2X3ZpX2ZzbTogbWIgWzB4JXhdLCBkZWZlcnJlZCwgc3RhdGUgWzB4JXhdLCBwb3J0IFsweCV4 +XQoAAABsMmRldl92aV9mc206IHZpaWQgWzB4JXhdIHBvcnQgWzB4JXhdLCBtYWMtaWQgWyUwMng6 +JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4XS4gCgAAAAAAAAAAAAAAAAAAAABsMmRldl92aV9mc206 +IHNnZV9lcWlkIFsweCV4XSwgc2dlX2lxaWQgWzB4JXhdLCBzZ2VfZXFjciBbMHgleF0sIHJzc19z +eiBbMHgleF0KAGwyZGV2X3ZpX2ZzbTogbDJkZXZfZmMtPmZsb3djX25ldF9sMmRldl9tdHUgWyV1 +XSwgbWJfc2NyYXRjaCBbMHgleF0sIHBvcnQgWzB4JXhdCgAAAAAAAAAAAAAAAAAAAGwyZGV2X3Zp +X2ZzbTogdmlpZCBbJWRdLCB2aV9mYy0+Zmxvd2NfdmlfZmxhZ3MgWzB4JXhdCgAAAAAAAAAAAABs +MmRldl92aV9mc206IHBmbiBbMHgleF0sIHZmbiBbMHgleF0sIGwyZGV2X2ZjLT5mbG93Y19pZCBb +MHgleF0sIGxwb3J0IFsweCV4XSwgdmlpZCBbMHgleF0sIGZsYWdzIFsweCV4XQoAAAAAAAAAbDJk +ZXZfdmlfZnNtOiBFcnJvciBmcmVlaW5nIFZJLCByYyBbMHgleF0KAAAAAAAAbDJkZXZfdmlfZnNt +OiBwaWQgWzB4JXhdLCB2aWlkIFsweCV4XSwgbWJfbG9jIFsweCV4XSwgbWJfb3JpZ1sweCV4XSwg +bDJkZXZfZmxhZ3MgWzB4JXhdLCByYyBbMHgleF0KAAAAAAAAAAAAAAAAAEFoIGhhLi4uZG91Ymxl +IGZyZWUgb3hfaWQgMHgleCwgcnhfaWQgMHgleAoAAAAAAEhvc3QgUFJMSSBSZXNwb25zZSB0aW1l +ZG91dDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAAAAAAAABGQ09FIEZyZWU6IHN0aWxs +IHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxvd2NfaWQgJXggZmxvd2NfZmxhZ3MgJXggCgAAAAAA +AAAAAAAAAEZDIHhjaGcgZnJlZSB4aWQ6JWQgZmxvd2lkICVkCgAAcGZuICV1IHZmbiAldSB2aWEg +Y29tbWFuZAoAAAAAAABzY2hlZF9pb3F0eF9icF9wcmlvcml0eTogaGFzICV1IGVudHJpZXMgb25s +eSwgcmVxdWlyZXMgJXUgZW50cmllcwoAAAAAAAAAAAAAAAAAAHRwX2JhY2tvZmY6IHBhcnNlZCAl +ZCBpbnN0ZWFkIG9mICV1IGVudHJpZXMKAAAAAHRwX3RpbWVydmFsczogcGFyc2VkICVkIGluc3Rl +YWQgb2YgJXUgZW50cmllcwoAAHRwX3RpbWVycmVzOiBwYXJzZWQgJWQgaW5zdGVhZCBvZiAldSBl +bnRyaWVzCgAAAHRwX210dXMgaGFzICV1IGVudHJpZXMgb25seSwgcmVxdWlyZXMgJXUgZW50cmll +cwoAAAAAAAAAAAAAAAAAAAB0cF9tdHVzWyV1XSBpcyAldSBieXRlcyB3aGljaCBpcyBub3Qgc3Vw +cG9ydGVkCgBjb25maWd1cmF0aW9uIGZpbGUgcGFyc2VyOiBzZ2UgdGltZXIgdmFsdWVbJWldIGlz +IHRvbyBsYXJnZSwgY2hhbmdpbmcgZnJvbSAldSB0byAldXVzZWNzCgAAAAAAAABmaWx0ZXJtYXNr +IDB4JXggaXMgbm90IGVxdWFsL3N1YnNldCB0by9vZiBmaWx0ZXJtb2RlCgAAAAAAAAAAAAAAaHdf +bGVfY2xpcF9oYW5kbGVyOiByZW1vdmVkIHBvcz0ldSAoPWlkeCAldSkKAAAAaHdfbGVfY2xpcF9o +YW5kbGVyOiBhZGRpbmcgdG8gcG9zPSV1ICg9aWR4ICV1KQoAbW9kdWxlWyV1XTogcG9ydCBtb2R1 +bGUgaW5zZXJ0ZWQgYW5kIHJlYWR5CgAAAAAAbW9kdWxlWyV1XTogcG9ydCBtb2R1bGUgcmVtb3Zl +ZAoAAAAAAAAAAAAAAAAAAAAAbW9kdWxlWyV1XTogdW5rbm93biBtb2R1bGUgaWRlbnRpZmllciAw +eCUwMngKAAAAbW9kdWxlWyV1XTogZ3BpbyAldSB0cmFucyAxMEcgMHglMDJ4IDFHIDB4JTAyeCAo +bGVuZ3RoICV1KSBjYWJsZSAweCUwMnggKGxlbmd0aCAldSkgbW9kdWxlX3R5cGUgMHglMDJ4CgAA +AAAAAAAAAG1vZHVsZVsldV06IGdwaW8gJXUgdHJhbnMgMTBHIDB4JTAyeCAxRyAweCUwMnggKGxl +bmd0aCAldSkgY2FibGUgMHglMDJ4IChsZW5ndGggJXUpIG1vZHVsZV90eXBlIDB4JTAyeAoAAAAA +AAAAAABmbHJfcGZ2Zl9mc21bJXU6JXVdOiB1bmtub3duIHN0YXRlICV1CgAAAAAAAAAAAABodyBw +ZiBiaXRtYXAgMHglMDJ4IHZmaWQgYml0bWFwIDB4JTA4eDoweCUwOHg6MHglMDh4OjB4JTA4eAoA +AAAAYWZ0ZXIgdmZpZCBmaXh1cCwgdmZpZCBiaXRtYXAgMHglMDh4OjB4JTA4eDoweCUwOHg6MHgl +MDh4CgAAAAAAAHRpbWVyIHF1ZXVlICV1IGxvc3QgYSB0aWNrISBuZXh0ICVwIGxhc3QgJXAgbnVt +ZSAldQoAAAAAAAAAAAAAAABmbHJfdGltZXJfc3RhcnQ6IGZsb3djX2lkICV1ICVwIGJ1ZiAlcAoA +AAAAAAAAAABwY2llOiBucGYgJXUgKHBmYml0bWFwIDB4JTAyeCkgbnZmICV1IChwZiAwLi43IDB4 +JTA4eCUwOHgpIHZmc3RyaWRlICV1CgAAAAAAAAAAAGZhaWxlZCB0byBmaW5kIHRoZSAlYyVjIFZQ +RCBwYXJhbWV0ZXIKAAAAAAAAAAAAAGZhaWxlZCB0byBwYXJzZSB0aGUgJWMlYyBWUEQgcGFyYW1l +dGVyCgAAAAAAAAAAAGZhaWxlZCB0byBzdWNjZXNzZnVsbHkgZmluZCBDaGVsc2lvIFZQRAoAAAAA +AAAAAGxvZyBpbml0aWFsaXplZCBAIDB4JTA4eCBzaXplICV1ICgldSBlbnRyaWVzKSBmd3JldiAw +eCUwOHggcGNpZV9mdyAweCUwOHgKAAAAAAAAZ2F0aGVyX3Rhc2tzX2Zvcl90bWY6IGlkeCBbMHgl +eF0sIHRhc2staWQgWzB4JXhdLCBjbWQtaWQgWzB4JXhdLCBhY3RpdmUgdGFza3MgWzB4JXhdLiBj +b25uLWlkIFsweCV4XSwgY21kIGNvbm4taWQgWzB4JXhdLCB0YXNrIGNvbm4taWQgWzB4JXhdCgAA +Z2F0aGVyX3Rhc2tzX2Zvcl90bWY6IEludmFsaWQgdHlwZSBbMHgleF0sIGJhaWxpbmcgb3V0LgoA +AAAAAAAAAGdhdGhlcl90YXNrc19mb3JfdG1mOiB0YXNrIGlkIFsweCV4XSwgc3RhdGUgWzB4JXhd +LCBsaWR4IFsweCV4XSwgY29va2llIGhpIFsweCUwOHhdIDogbG8gWzB4JTA4eF0KAAAAAAAAAAAA +AAAAAABnYXRoZXJfdGFza3NfZm9yX3RtZjogcmMgWzB4JXhdLCBbMHgleF0gdGFzayBnYXRoZXJl +ZCBmb3IgdG1mIHR5cGUgWzB4JXhdIHByb2Nlc3NpbmcuCgAAAAAAAAAAAABzY3NpX2RhdGFfb3V0 +OiBjb25uX2ZjIFsweCV4XSwgc3RhdGUgWzB4JXhdLCBzZXNzX2ZjIFsweCV4XSBpbiByZWNvdmVy +eS4gU2tpcHBpbmcgaXN0YXNrX2ZjIFsweCV4XSBmcm9tIFRYLgoAAAAAc2VuZF9hYm9ydF9yZXE6 +IGNza19mYy0+Zmxvd2NfdHlwZSBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCB0aWQg +WzB4JXhdLCB1bHB0eGNoIFsldV0sIGJ1ZmZlcmVkIFsldV0KAAAAAGh3IHJlZ2lzdGVyIG9wZXJh +dGlvbiBub3QgY29tcGxldGluZywgcmVnIDB4JTA4eCBtYXNrIDB4JTA4eCB2YWx1ZSAweCUwOHgg +KHJlZyAweCUwOHgpCgAAAAAAAAAAAE1ESU8gQ0w0NTogZmFpbGVkIHRvIHNldCB1cCBNTUQgYWRk +cgoAAAAAAAAAAAAAAE1ESU86IGZhaWxlZCB0byB3cml0ZQoAAAAAAAAAAAAATURJTyBDTDQ1OiBm +YWlsZWQgdG8gc2V0IHVwIE1NRCBhZGRyCgAAAAAAAAAAAAAATURJTzogZmFpbGVkIHRvIHJlYWQK +AAAAAAAAAAAAAAAJQVFfVGFrZUNvbnRyb2xPZkZMQVNIOiAxZS5jMDAxPSUjeCAxZS5jNDUwPSUj +eCAxZS5jNDUxPSUjeCAxZS4xMDA9JSN4CgAAAAAAAAAAAEFRX0FQSV9Xcml0ZUFuZFZlcmlmeUZs +YXNoSW1hZ2UgLSBJbWFnZSBpbnRlZ3JpdHkgY2hlY2sgZmFpbGVkIChjYWxjICUjeCB2YWwgJSN4 +KQoAAAAAAAAAAAAAAAAAAEFRX0FQSV9Xcml0ZUFuZFZlcmlmeUZsYXNoSW1hZ2UgLSBJbWFnZSBp +bnRlZ3JpdHkgY2hlY2sgcGFzc2VkCgBBUV9BUElfV3JpdGVBbmRWZXJpZnlGbGFzaEltYWdlIC0g +VGltZW91dCB3YWl0aW5nIGZvciBmbGFzaCBpbnRlcmZhY2UgKCV1KQoAAAAAAEFRX0FQSV9Xcml0 +ZUFuZFZlcmlmeUZsYXNoSW1hZ2UgLSBUaW1lb3V0IHdhaXRpbmcgZm9yIGZsYXNoIGludGVyZmFj +ZSAoJXUpCgAAAAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIFRpbWVvdXQgd2Fp +dGluZyBmb3IgZmxhc2ggaW50ZXJmYWNlICgldSkKAAAAAABBUV9BUElfV3JpdGVBbmRWZXJpZnlG +bGFzaEltYWdlIC0gVGltZW91dCB3YWl0aW5nIGZvciBmbGFzaCBpbnRlcmZhY2UgKCV1KSAocHAg +JSN4IGFwICUjeCkKAAAAAABBUV9BUElfV3JpdGVBbmRWZXJpZnlGbGFzaEltYWdlIC0gVGltZW91 +dCB3YWl0aW5nIGZvciBmbGFzaCBpbnRlcmZhY2UgKCV1KQoAAAAAAEFRX0FQSV9Xcml0ZUFuZFZl +cmlmeUZsYXNoSW1hZ2UgLSBUaW1lb3V0IHdhaXRpbmcgZm9yIGZsYXNoIGludGVyZmFjZSAoJXUp +CgAAAAAAQVFfQVBJX1dyaXRlQW5kVmVyaWZ5Rmxhc2hJbWFnZSAtIEVycm9yIG9uIGJ1cm5pbmcg +RkxBU0ggKGNyYzE2IG1pc21hdGNoKQoAAAAAAABzZW5kX2Nsb3NlX3JlcTogY3NrX2ZjLT5mbG93 +Y190eXBlIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+dGNiX3N0YXRl +IFsweCV4XQoAAABzZW5kX2Nsb3NlX3JlcTogY3NrX2ZjLT5mbG93Y190eXBlIFsweCV4XSwgY3Nr +X2ZjLT5mbG93Y19pZCBbMHgleF0sIHRpZCBbMHgleF0sIHVscHR4Y2ggWyV1XSxidWZmZXJlZCBb +JXVdCgAAAAAAb2ZsZF90Y3BfZG9fYWN0aXZlX2Nsb3NlOiBjc2tfZmMgWzB4JXhdLCBjc2tfZmMt +PmZsb3djX2lkIFsweCV4XSwgY3NrX2ZjLT50Y2Jfc3RhdGUgWzB4JXhdCgAAAAAAb2ZsZF90Y3Bf +ZG9fYWN0aXZlX2Nsb3NlOiBjc2tfZmMgWzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwg +Y3NrX2ZjLT50Y2Jfc3RhdGUgWzB4JXhdCgAAAAAAb2ZsZF90Y3BfZGlzY29ubmVjdDogdGNiX2Zj +LT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCBjc2stPnRjYl9zdGF0 +ZSBbMHgleF0KAAAAZGVjb2RlX2Jhc2U2NF9zdHJpbmc6IGRsZW4gWyVkXQoAAAAAAAAAAAAAAAAA +AAAAZGVjb2RlX2hleF9zdHJpbmc6IGRsZW4gWyVkXQoAAABmb2lzY3NpX3ZhbGlkYXRlX2xvZ2lu +X3N0YWdlOiAtIDEKAAAAAAAAAAAAAAAAAABhc3luY19wZHU6IGxvZ291dCByZXF1ZXN0ZWQgYmxv +Y2tpbmcgc2Vzc2lvbgoAAABhc3luY19wZHU6IHNlc3MvY29ubiBkcm9wIHJlcXVlc3RlZCBibG9j +a2luZyBzZXNzaW9uCgAAAAAAAAAAAAAAY3BsX3R4X3BrdDogdmxhbmlkIFsweCV4XQoAAAAAAABu +ZXRfbDJkZXZfZmluZF9ieV9hZGRyOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBsMmRjLT5s +cG9ydCBbJXVdLCBsMmRfZmMtPmZsb3djX2lkIFsweCV4XSwgbDJkYy0+aW40X2Rldi5pbl9hZGRy +LmFkZHIgWzB4JXhdLCBhZGRyIFsweCV4XQoAAABuZXRfbDJkZXZfbXR1X2NvbmZpZzogbDJkZXZf +ZmMtPmZsb3djX2lkIFsweCV4XSwgbXR1ICV1CgAAAAAAAAAAY3BsX3R4X3BrdDogdmxhbmlkIFsw +eCV4XQoAAAAAAABlbmNvZGUgaGV4IHN0cmluZzogZGxlbiBbJWRdCgAAAGNobmV0X2ZpbmRfbDJ0 +X2VudHJ5OiBkYWRkciBbJTA4eF0sIFsweCUwOHhdLCBsb2NhbCBuZXR3b3JrIFslZF0KAAAAAAAA +AAAAAAAAAAAAbDJ0ZW50IFslMHhdLCBsMnRlbnQtPmlkeCBbJWRdCgB0Y3Bfc2VuZF9hb3Blbl9y +ZXE6IGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCBjc2tfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwg +YnVmZmVyZWQgWyV1XSwgcmVzX2NudCBbMHgleF0sIGlxX2lkeCBbMHgleF0KAAAAAAAAAAAAAHRj +cF9zZW5kX2FvcGVuX3JlcTogY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+Zmxvd2Nf +c3RhdGUgWzB4JXhdLCBubyB2YWxpZCBsMnRfZW50eS4gRGVsYXlpbmcgYW5vdGhlciByZXRyeSBm +b3IgMSBzZWNvbmRzLgoAAAAAAAAAAAAAAAAAAGFvcGVuX3JlcTogaHdfbGVfZmlsdGVyX2N0dXBs +ZSBmYWlsZWQKAAAAAAAAAAAAAG9mbGRfdGNwX3NlbmRfYW9wZW5fcmVxOiBjcGxfcmVxLT5GaWx0 +ZXIgWzB4JTB4XSwgY3R1cGxlc1swXSBbMHgleF0sIGN0dXBsZXNbMV0gWzB4JXhdCgAAAAAAAAAA +AGNzb2NrX2FsbG9jOiB0eF9jaCBbMHgleF0sIGxwb3J0IFsweCV4XSwgY29va2llIFslMDh4XQoA +AAAAAAAAAABjc29ja19hbGxvYzogYXZhaWxhYmxlIFsldV0sIG5jc29jayBbJXVdLCBwb3M6YXRp +ZCBbMHgleF0sIGNza19mYyBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCBzcG9ydCBb +JXVdCgAAV0FUQ0hET0c6IE5vIHRlbXBlcmF0dXJlIHNlbnNvciBhdmFpbGFibGUuCgAAAAAAd2F0 +Y2hkb2cgY21kIHJlZnJlc2ggKGFjdGlvbiAldSkKAAAAAAAAAAAAAAAAAAAAV0FUQ0hET0c6IEFj +dGl2YXRpbmcKAAAAAAAAAAAAAABXQVRDSERPRyAtIEVuYWJsZSBhY3Rpb24gJXUgdGltZSAldQoA +AAAAAAAAAAAAAABXQVRDSERPRyAtIERpc2FibGUgYWN0aW9uICV1CgAAAFdBVENIRE9HOiBEZS1h +Y3RpdmF0aW5nCgAAAAAAAAAAcG9ydFsldV0gc2V0IFBBVVNFIFBBUkFNUzogcHBwZW4gJXUgdHhw +ZSAlI3ggcnhwZSAlI3gKAAAAAAAAAAAAAG1wc19saW5rX3VwWyV1XSBhY2FwcyAlI3ggKDgwMi4z +ICUjeCkgKyBscGFjYXBzICUjeCA9PiAlI3gKAAAAAABmb2lzY3NpIGNvbm5fZmMgWzB4JXhdLCBm +bG93Y19zY2hlZGNsIFsweCV4XSwgaW5nX2NoIFsweCV4XSwgZWdyX2NoIFsweCV4XQoAAAAAAGwy +ZGV2X25vdGlmeSB3aXRoIHVua25vd24gZmxhZyBbMHgleF0KAAAAAAAAAAAAAEZDb0UgRkNCIGxp +bmtkb3duOiBpb19yZXEgMHgleCV4IGlxaWQgMHgleCBmbG93aWQgMHgleCBvcCAweCV4CgBjYW5j +ZWwgZmNiOiV4IHNjYjoleCBzdGF0ZToleAoAAFJERVYgbXNnIGZsb3djOiV4IHN0YXRlIDB4JXgg +ZXZlbnQgMHgleAoAAAAAAAAAAHZuMnZuOiBwb3J0IDB4JXggZGlkOjB4JXgleCV4IFVQCgAAAAAA +AAAAAAAAAAAAAHZuMnZuOiBwb3J0IDB4JXggZGlkOjB4JXgleCV4IERPV04KAAAAAAAAAAAAAAAA +AGZjX3NlbmRfYWxsb2NfY3BsOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAA +AAAAAAAAAABmY29lX2NvbXB1dGVfY3R1cGxlIDB4JXg6JXgKAAAAAGNvbXB1dGVfY3R1cGxlKCk6 +IGZhaWxlZCB0byBzZXR1cCBmaWx0ZXIgY3R1cGxlCgAAAAAAAAAAAAAAAAAAAABmY29lX2NvbXB1 +dGVfY3R1cGxlIHZsYW4gJXggdmlpZCAleCBwb3J0ICV4IG1wc19pZHggJXgKAAAAAAAAAAAAQXBw +bHkgQVBQOiBwb3J0ICVkIHByaW9yICVkIHNlbGVjdCAlZCBwcm90b2NvbElEIDB4JTA0eAoAAAAA +AAAAAGNoX2NsX3JhdGVbJXUvJXVdOiBjYXBwZWQgZGVmaWNpdF9pbmNyIGZyb20gcmVxdWlyZWQg +JXUgdG8gJXU7IHJhdGUgJXUgKGVmZiAldSkgZGVmaWNpdF9tYXggJXUKAGZjX3NlbmRfYWxsb2Nf +Y3BsOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAAAAAAAABmY29lX2Nv +bXB1dGVfY3R1cGxlIDB4JXg6JXgKAAAAAGNvbXB1dGVfY3R1cGxlKCk6IGZhaWxlZCB0byBzZXR1 +cCBmaWx0ZXIgY3R1cGxlCgAAAAAAAAAAAAAAAAAAAABGQ29FIEZDRiB0aW1lcjogZmxvd2Mgc3Rh +dGUgMHgleCwgcG9ydCAweCV4ICxmY2YgMHgleCwgZmxvd2NfaWQgMHgleAoAAAAAAAAAAAAAAHdv +cmthcm91bmQxMzcyMzogZGV0ZWN0ZWQgV1IgQCAweCUwOHggb2Ygc2l6ZSAldSBieXRlcywgZHJp +YmJsaW5nIGl0IGluICV1IGJ5dGVzIGF0IGEgdGltZQoAAAAAAHJpX3dyX2luaXRbJXVdOiBtc3Mg +JXUgaXMgbm90IDgtYnl0ZSBhbGlnbmVkCgAAAGNvcmVfcHJvZ3JhbV90Y2I6IHRpZCAlI3ggdF9z +dGF0ZSAlI3ggcmN2X2FkdiAweCUwOHggcmN2X3NjYWxlICUjeCB0eF9tYXggJSN4IHJjdl9ueHQg +JSN4IGF0aWQgJSN4CgAAAAAAAAAAAAAAAAAJb3B0MCAlI3gleCBvcHQyICUjeCBpcHY2ICUjeCBm +bGFnc190aW1lciAweCUwOHgKAAAAAAAAAAAAAAAAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25u +ZWN0aW9uIHdpdGggNS10dXBsZSBscCAweCUwNHggZnAgMHglMDR4IGxpcCAweCUwOHglMDh4IHBp +cCAweCUwOHglMDh4IGZpbHRlciAweCUwOHggZXhpc3RzIEAgTEUgaW5kZXggJXUKAAAAAAAAAAAA +AAAAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10dXBsZSBscCAweCUw +NHggZnAgMHglMDR4IGxpcCAweCUwOHggcGlwIDB4JTA4eCBmaWx0ZXIgMHglMDh4IGV4aXN0cyBA +IExFIGluZGV4ICV1CgAAAAAAAABvZmxkX2Nvbm5lY3Rpb25fd3I6IGNvbm5lY3Rpb24gd2l0aCA1 +LXR1cGxlIGxwIDB4JTA0eCBmcCAweCUwNHggbGlwIDB4JTA4eCUwOHggcGlwIDB4JTA4eCUwOHgg +ZmlsdGVyIDB4JTA4eAoAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10 +dXBsZSBscCAweCUwNHggZnAgMHglMDR4IGxpcCAweCUwOHggcGlwIDB4JTA4eCBmaWx0ZXIgMHgl +MDh4CgAAAAAAAAAAAAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogaXFlc2l6ZSAldSB0b28gc21h +bGwKAAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogaXFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkK +AAAAAAAAAAAAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxaWQgJXUgbm90IGFsbG9jYXRl +ZAoAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMGlkICV1IHRvbyBsYXJnZSAobWF4ICV1KQoA +AAAAAAAAAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDBpZCAldSBub3QgYWxsb2NhdGVk +CgAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAA +AAAAAAAAAAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgbm90IGFsbG9jYXRlZAoA +AElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgaXMgdmFsaWQgYnV0IG5vdCBmbDBpZCAl +dQoAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IGlzIHZhbGlkIGJ1dCBoZWFk +ZXIgc3BsaXQgZmVhdHVyZSBpcyBub3QgZW5hYmxlZAoAAAAAAAAAAAAAAAAAAABod191bHB0eF93 +b3JrYXJvdW5kX3ByMTY5NDlfZW5hYmxlZF9wZjogcGYgJXUgZW5hYmxlZCAldQoAAAAAAAAAaHdf +dWxwdHhfd29ya2Fyb3VuZF9wcjE2OTQ5X2VuYWJsZWRfdmZpZDogdmZpZCAldSBlbmFibGVkICV1 +CgAAAEVRIHBmbiAldSB2Zm4gJXU6IGNyZWF0aW5nIEVUSCBlcWlkICV1IHdpdGggcGVuZGluZyBX +UihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFncyAweCUwOHgKAAAAAAAAAEVRIHBmbiAldSB2Zm4g +JXU6IGNyZWF0aW5nIENUUkwgZXFpZCAldSB3aXRoIHBlbmRpbmcgV1IocykgKG51bV9ieXRlcyAl +dSBhbmQgZmxhZ3MgMHglMDh4CgAAAAAAAEVRIHBmbiAldSB2Zm4gJXU6IGVxaWQgJXUgdG9vIGxh +cmdlIChtYXggJXUpCgAAAEVRIHBmbiAldSB2Zm4gJXU6IGVxaWQgJXUgbm90IGFsbG9jYXRlZAoA +AAAAAAAAAGh3X2NpbV90cF93b3JrYXJvdW5kMTM3MjNfZW5hYmxlOiBwb3J0ICV1IHByb3RvY29s +IDB4JXggZW4gJXUgY3VycmVudCAweCV4IHdvcmthcm91bmRfcHIxMzcyMyAweCV4IG5leHQgMHgl +eAoAAABwb3J0X2JsaW5rX2xlZF9yZXN0b3JlCgAAAAAAAAAAAHBvcnRfYmxpbms6IGJsaW5rZHVy +PTB4JXggYmxpbmtfcmVmY250CgAAAAAAAAAAAHBvcnRfYmxpbms6IAlibGlua19yZWZjbnQ9MHgl +eAoAcG9ydF9ibGluazogCWJsaW5rX3JlZmNudD0weCV4CgBtaWlfYWR2X2ZjWyV1XTogcmNhcHMg +MHgleAoAAAAAAG1paV9hZHZfc3BlZWRbJXVdOiByY2FwcyAweCV4CgAAbWlpX2luaXRbJXVdOiBh +Y2FwcyAweCV4CgAAAAAAAABwb3J0WyV1XTogZ2F2ZSB1cCBmaXhpbmcgZXJyb3JzISEhCgAAAAAA +AAAAAAAAAABtaWlfYW5yZXN0YXJ0WyV1XTogYWNhcHMgMHgleAoAAGh3X3hnbV9wb3J0X2xwYmsg +cG9ydCAldSBwdHlwZSAlI3ggYWN0aW9uICUjeAoAAHBvcnRfY21kX2hhbmRsZXI6IHVua25vd24g +dS5kY2IudHlwZSAweCV4CgAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IGwxY2ZnLCBpbnZh +bGlkIHJlcXVlc3QsIHBjYXBzIDB4JXggYWNhcHMgMHgleCByY2FwcyAweCV4CgAAAAAAAAAAAAAA +AAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IGwxY2ZnLCBwY2FwcyAlI3ggYWNhcHMgJSN4IHJj +YXBzICUjeCBtY2FwcyAlI3gKAAAAAAAAAAAAcG9ydFsldToweCUwMng6MHglMDJ4XTogbDFjZmcs +IG1kaSBpc3N1ZSBwY2FwcyAweCV4IGFjYXBzIDB4JXggcmNhcHMgMHgleAoAAAAAAABwb3J0WyV1 +OjB4JTAyeDoweCUwMnhdOiBsMWNmZywgY2Fubm90IGZvcmNlIG5vL211bHRpcGxlIHNwZWVkKHMp +LCBwY2FwcyAweCV4IGFjYXBzIDB4JXggcmNhcHMgMHgleAoAAAAAAAAAAAAAAAAAZXRoX2Zsb3dj +X2hhbmRsZXJbMHgleF06IGZsYWdzIDB4JTA4eCBudW1fYnl0ZXMgJXUgc2NoZWRjbCAweCV4IC0+ +IDB4JXgKAAAAAAAAAABzY3NpX2NtZDogcmVjZWl2ZWQgVE1GIG9wIFsweCV4XSBmdW5jIFsweCV4 +XSBvbiBjb25uIFsweCV4XSB0aHJvdWdoIGNvbW1hbmQgcGF0aC4KAAAAAAAAAAAAAAAAAABzY3Np +X2NtZDogY29ubl9mYyBbMHgleF0sIHN0YXRlIFsweCV4XSwgc2Vzc19mYyBbMHgleF0gaW4gcmVj +b3ZlcnkuIFNraXBwaW5nIGlzdGFza19mYyBbMHgleF0gZnJvbSBUWC4KAAAAAAAAAAAAc2NzaV9j +bWQ6IGlTQ1NJIGNvbW1hbmQgc2VxdWVuY2Ugd2luZG93IGNsb3NlZC4gY29ubiBbMHgleF0sIG9w +IFsweCV4XSwgIGNtZHNuIFsweCV4XSwgc2VudF9jbWRzbiBbMHgleF0sIG1heF9jbWRzbiBbMHgl +eF0sIGl0dCBbMHgleF0KAAAAAAAAAAAAc2NzaV9yZWFkOiBjb25uX2ZjIFsweCV4XSwgc3RhdGUg +WzB4JXhdLCBzZXNzX2ZjIFsweCV4XSBpbiByZWNvdmVyeS4gU2tpcHBpbmcgaXN0YXNrX2ZjIFsw +eCV4XSBmcm9tIFRYLgoAAAAAAAAAAHNjc2lfcmVhZDogaVNDU0kgY29tbWFuZCBzZXF1ZW5jZSB3 +aW5kb3cgY2xvc2VkLiBjb25uIFsweCV4XSwgY21kc24gWzB4JXhdLCBzZW50X2NtZHNuIFsweCV4 +XSwgbWF4X2NtZHNuIFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAc2NzaV93cml0ZTogY29ubl9mYyBb +MHgleF0sIHN0YXRlIFsweCV4XSwgc2Vzc19mYyBbMHgleF0gaW4gcmVjb3ZlcnkuIFNraXBwaW5n +IGlzdGFza19mYyBbMHgleF0gZnJvbSBUWC4KAAAAAAAAAHNjc2lfd3JpdGU6IGlTQ1NJIGNvbW1h +bmQgc2VxdWVuY2Ugd2luZG93IGNsb3NlZC4gY29ubiBbMHgleF0sIGNtZHNuIFsweCV4XSwgc2Vu +dF9jbWRzbiBbMHgleF0sIG1heF9jbWRzbiBbMHgleF0sIGl0dCBbMHgleF0KAAAAZGNieF9jb250 +cm9sX3NtWyV1XSBDT05UUk9MX0xJTktVUAoAAAAAAAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1 +XSBDT05UUk9MX1VQREFURV9EQ0JYX1RMVgoAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9M +X1BFRVJfTk9UX0FEVkVSVElTRV9EQ0JYCgAAAAAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0g +Q09OVFJPTF9VUERBVEVfT1BFUl9WRVJTSU9OCgAAAAAAAAAAAAAAAAAAAABkY2J4X2NvbnRyb2xf +c21bJXVdIENPTlRST0xfUFJPQ0VTU19QRUVSX1RMVgoAAABkY2J4X2NvbnRyb2xfc21bJXVdIENP +TlRST0xfQUNLX1BFRVIKAAAAAAAAAAAAAABkY2J4X2llZWVfdmFsaWRhdGVbJXVdIGVycm9yIChv +dWkgJSN4IHN1YnR5cGUgJSN4IGxlbiAlI3gpCgAAAAAAZGNieF9jZWVfdmFsaWRhdGVbJXVdIGVy +cm9yCgAAAABwcm9jZXNzX2RoY3Bfb3B0czogcm9vdCBwYXRoIGxlbiBbJWRdIGJ5dGVzCgAAAABu +ZXRpZl9wcm9jZXNzX2RoY3Bfb3B0czogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgTVNHX1RZ +UEUgWyVkXSwgZGhjdHh0LT5zdGF0ZSBbJWRdCgAAAAAAAAAAAABpY21wX3JlY3Y6IGwyZGV2X2Zj +LT5mbG93Y19pZCBbMHgleF0sIHBpZCBbMHgleF0sIGljbXAgdHlwZSBbMHgleF0KAAAAAAAAAAAA +AAAAAEFCVFMgQUNDIGF3YWl0aW5nIFBSTEkgUnNwOiBmbG93Y19pZCAweCV4IG94X2lkIDB4JXgg +cnhfaWQgMHgleCBpcWlkIDB4JXgKAAAAAAAAcG9ydCAweCV4LCBzdGF0ZSAweCV4LCBjb21tYW5k +IGZhaWxlZCByZXRyaWVzIDB4JXgKAAAAAAAAAAAAAAAAAGFycF9yZWN2OiBpcGlkIFsweCV4XSwg +aW5fYWRkci5hZGRyIFsweCV4XSwgc2lwIFsweCV4XSwgcmlwIFsweCV4XSwgYXJwX29wIFsweCV4 +XQoAAAAAAAAAAAAAAAAAAGNobmV0X2FycF9yZWN2OiBpcCBjb25mbGljdCBkZXRlY3RlZAoAAAAA +AAAAAAAAAGNobmV0X2FycF9yZWN2OiBwaWQgWyV1XSwgdmxhbiBbMHgleF0sIGFycCBvcCBbMHgl +eF0sIHNpcCBbMHgleF0sIHJpcCBbMHgleF0KAAAASW52YWxpZCBkaWQ6eCUyeCUyeCUyeCByY3Zk +IG9uIHBvcnQ6JWQuRHJvcGluZyBmcmFtZQoAAAAAAAAAAAAAAHJjdDp4JXggc2lkOnglMnglMngl +MnggcmN2ZCBvbiBmbG93YzolZC5Ecm9waW5nIGZyYW1lCgAAAAAAAAAAAABjc29ja19mcmVlOiBz +aXplb2YoY3NrX2ZjLT51LmNzb2NrKSBbJXVdLCBieXRlcwoAAAAAAAAAAAAAAAAAAAAAR290IENP +Tk5fRVhJU1QgZm9yIHhpZDoweCV4LCB0YWc6MHgleCwgcmV0cnlpbmcuCgAAAAAAAAAAAAAAAAAA +AGh3X3VscHR4X3dvcmthcm91bmRfcHIxNjk0OV9lbmFibGVkX3BmX2lxOiBpcSAldSBlbmFibGVk +ICV1IChwZiAldSkKAAAAAAAAAAAAAAAAY3NvY2tfcGVlcl9jbG9zZTogY3NrX2ZjLT5mbG93Y19p +ZCBbMHgleF0sIHRjYl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBjc2tfZmMtPmZsb3djX3N0YXRlIFsw +eCV4XSwgdGNiX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0KAAAAAABjc29ja19wZWVyX2Nsb3NlOiBj +c2tfZmMtPmZsb3djX2lkIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19zdGF0ZSAgWzB4JXhdCgAAAAAA +AAAAAHRjcF9jbHNfYWJydF9ycGw6IHRjYiB0aWQgWzB4JTA2eF0sIGZsb3djX3R5cGUgWzB4JXhd +LCBjcGxvcCBbMHgleF0gCgAAAAAAAAAAAAAAY2hfcmF0ZVsldV06IGNhcHBlZCB0aWNrIGZyb20g +cmVxdWlyZWQgJXUgdG8gc3VwcG9ydGVkICV1OyByYXRlICV1IChlZmYgJXUpIGRlZmljaXRfaW5j +ciAldSB0aWNrICV1CgAAAAAAAAAAAAAAAHBrdHNjaGVkX2NoX3JsWyV1XTogY2hhbm5lbCBybCBu +b3QgYXZhaWxhYmxlIGluIGNvbmp1bmN0aW9uIHdpdGggZmxvdyBzaGFwaW5nCgAAcGt0c2NoZWRf +Y2hfcmxbJXVdOiByYXRlICV1IG1heCAldQoAAAAAAAAAAAAAAAAAcGt0c2NoZWRfY2xfd3JyWyV1 +OiV1XTogd2VpZ2h0ICV1CgAAAAAAAAAAAAAAAAAAZXFfcGFyYW1zWzB4JXg6MHgleF06IGRtYXEg +MHgleCByZWFkICV1IHBmICV1IGVxaWRfYXBpICV1IHJldCAlZAoAAAAAAAAAAAAAAAAAAABod19t +YV9hZGRyX3RvX21lbV90eXBlX29mZjogTUEgYWRkcmVzcyAweCUwOHggaXMgbm90IG1hcHBlZAoA +AAAAaHdfbWFfYWRkcl90b19tZW1fdHlwZV9vZmY6IE1BIGFkZHJlc3MgMHglMDh4IG1hcHMgdG8g +dHlwZSAldSBvZmZzZXQgMHgleAoAAAAAAABtZW1fbWFsbG9jX3RlbXA6IGZhaWxlZCB0byBhbGxv +Y2F0ZSAldSBieXRlcywgcmV0dXJuaW5nIE5VTEwKAAAAbWVtX21hbGxvYzogZmFpbGVkIHRvIGFs +bG9jYXRlICV1IGJ5dGVzLCByZXR1cm5pbmcgTlVMTAoAAAAAAAAAAGxlIGNvbmZpZ3VyYXRpb246 +IGhhc2ggbW9kZSByZXF1aXJlcyBhdCBsZWFzdCAxNiBlbnRyaWVzLCBuaGFzaCAldQoAAAAAAAAA +AAAAAAAAbGUgY29uZmlndXJhdGlvbjogaGFzaCBtb2RlIHJlcXVpcmVzIGF0IGVudHJpZXMgdG8g +YmUgYSBwb3dlciBvZiAyLCBuaGFzaCAldQoAAABsZSBjb25maWd1cmF0aW9uOiByZXF1ZXN0ZWQg +JXUgdGNhbSBlbnRyaWVzIGJ1dCBvbmx5ICV1IGF2YWlsYWJsZSAobnJvdXRlICV1IG5jbGlwICV1 +IG5maWx0ZXIgJXUgbnNlcnZlciAldQoAAAAAbGUgY29uZmlndXJhdGlvbjogdGNhbSByZWdpb25z +IG11c3QgaGF2ZSBtdWx0aXBsZSBvZiAzMiBlbnRyaWVzLCBucm91dGUgJXUgbmNsaXAgJXUgbmZp +bHRlciAldSBuc2VydmVyICV1CgAAAAAAAGh3X3RwX3RjcF90dW5pbmdzOiB0dW5pbmcgZm9yIGNs +dXN0ZXIgZW52aXJvbm1lbnQKAAAAAAAAAAAAAAAAAABod190cF90Y3BfdHVuaW5nczogdHVuaW5n +IGZvciBMQU4gZW52aXJvbm1lbnQKAABod190cF90Y3BfdHVuaW5nczogdHVuaW5nIGZvciBXQU4g +ZW52aXJvbm1lbnQKAABod190cF90Y3BfdHVuaW5nczogbWFudWFsIHR1bmluZwoAAAAAAAAAAAAA +AAAAAABfaHdfY2ltX2ZsYXNoX21lbWNweTogbWVtY3B5WCBzdGFydAoAAAAAAAAAAAAAAABfaHdf +Y2ltX2ZsYXNoX21lbWNweTogZHN0IDB4JTA4IG9mZnNldCAweCUwOHggc2l6ZSAldSwgd2lkdGgg +b2YgJXUgaXMgbm90IHN1cHBvcnRlZAoAAAAAAAAAAAAAAABfaHdfY2ltX2ZsYXNoX21lbWNweTog +bWVtY3B5WCBlbmQKAAAAAAAAAAAAAAAAAABjb25maWd1cmF0aW9uIGZpbGUgcGFyc2VyIGVuY291 +bnRlcmVkIGVycm9yIEAgbGluZSAldToKAAAAAAAAAAAAaHdfaTJjX3RyYW5zYWN0aW9uOiBuZGF0 +YSAldSBhZGRyX29wIDB4JXggZGF0YVswXSAweCV4IGRpZmYgJXUKAGh3X2kyY190cmFuc2FjdGlv +bjogbmRhdGEgJXUgYWRkcl9vcCAweCV4IGRhdGFbMF0gMHgleCBkaWZmICV1IGRwb3MgJXUgY29u +dCAldSBmYWlsZWQgd2l0aCBlcnIgJWQKAAAAAAAAAAAAAAAAAABpMmMgdHJhbnNhY3Rpb24gZmFp +bGVkIHRvIGNvbXBsZXRlCgAAAAAAAAAAAAAAAABIT1NUIFBBR0VfU0laRSBbMHglMGx4XSB0b28g +c21hbGwsIG1pbiBbMHglMGx4XSByZXF1aXJlZAoAAAAAAAAAcGFnZSBzaXplIFslbHVdIG1pc21h +dGNoCgAAAAAAAABQQUdFIHNpemUgJWx1IHVuc3VwcG9ydGVkLCBkZHAgZGlzYWJsZWQKAAAAAAAA +AABIb3N0IHBhZ2Vfc2l6ZSAlbHUsIGRkcF9pZHggJXUKAEZDb0UgRERQIGluaXQ6IGZjb2UgbGxp +bWl0IDB4JXgsIGZjb2UgdWxpbWl0IDB4JXggZ2JsIGxsaW1pdCAweCV4IGdibCB1bGltaXQgMHgl +eCBwY2JzeiAleAoAAAAAAEZDb0UgRERQIGluaXQ6IGZjb2UgcHBvZCBvZmYgMHgleCwgZmNvZSBz +dCBwcG9kIGFkZHIgMHgleCBmY29lIG51bSBwcG9kcyAweCV4CgAAZmNvZSB4Y2hnIG1nciBpbml0 +OiBOdW1iZXIgb2YgRERQIGV4Y2hhbmdlcyBmb3IgRkNvRSBpcyAleAoAAAAAAGZjb2UgeGNoZyBt +Z3IgaW5pdDogTnVtYmVyIG9mIHR1bm5lbCBleGNocyBmb3IgRkNvRSBpcyAleAoAAAAAAABmY29l +X2wydF9pbml0OiBObyB1bHB0eCBjcmVkaXQgY2g6WyV1XQoAAAAAAAAAAABmY29lX2wydF9pbml0 +OiBjaDpbJXVdIGwydF9pZHggWyV1XQoAAAAAAAAAAAAAAABubyBsMnQgZW50cmllcyBjb25maWd1 +cmVkOyBmb3JjaW5nICV1IGVudHJpZXMsIHN0YXJ0aW5nIGF0ICV1CgAAZGNieCB1cGRhdGVbJXVd +IHNlbnQgdG8gZHJpdmVyICh0eXBlICUjeCBzdWJ0eXBlICUjeCBmbG93Y2lkICV1KQoAAAAAAAAA +AAAAAAAAAABkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fSUVFRQoA +AAAAAAAAAAAAAAAAAAAAZGNieF9ydW5fdmVyc2lvbl9zbVsldV0gRENCWF9WRVJfU1RBVEVfUlVO +X0NFRQoAZGNieF9ydW5fdmVyc2lvbl9zbVsldV0gRENCWF9WRVJfU1RBVEVfUlVOX05PTkUKAAAA +AAAAAAAAAAAAAAAAAHBvcnRbJXVdIGxpbmsgdXAgKCV1KSAoc3BlZWQgJSN4IGFjYXBzICUjeCBs +cGNhcHMgJSN4KQoAAAAAAAAAAABwb3J0X2hzc19zaWdkZXRbJXVdOiBoc3Nfc2lnZGV0IGNoYW5n +ZWQgdG8gMHgleAoAAAAAAAAAAAAAAAAAAAAAUVNGUCBtb2R1bGUgdW5wbHVnIC0gcmVpbml0aWFs +aXppbmcgcnhfbG9zICB0byAweGZmCgAAAAAAAAAAAAAAAGdwaW9fcXNmcF9tb2R1bGVfdXBkYXRl +OiBjaGFuZ2VkIHJ4X2xvcyBmcm9tIDB4JXggdG8gMHgleAoAAAAAAABncGlvX3FzZnBfbW9kdWxl +X3VwZGF0ZTogY2hhbmdlZCB0eF9kaXMgZnJvbSAweCV4IHRvIDB4JXgKAAAAAAAAQ2FsY3VsYXRp +b24gb3V0IG9mIGJvdW5kcyBmdXJpbmcgaW5pdDogJSN4ICUjeCAlI3gKAAAAAAAAAAAAAAAAAGh3 +X3NnZV9tYW1lbV9pbml0OiBlbmNvdW50ZXJlZCBlcnJvciAlZAoAAAAAAAAAAF9od190cF9wZ21u +Z3Q6IHR4X3BhZ2VfbWF4ICV1IHJ4X3BhZ2VfbWF4ICV1IHBzdHJ1Y3RzICV1IHNpemUgJXUKAAAA +AAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9vdGhlcnNfdG90YWw6IGRkcCAldSBkZHBfaXNjc2kgJXUg +c3RhZyAldSBwYmwgJXUgcnEgJXUgcnF1ZHAgJXUgLT4gJXUKAAAAAAAAAAAAAAAAAAAAX21wYXJ0 +aXRpb25fYmFua3NfbWNYOiBuYmFua3NfcG10eCAldSAoJXVNQikgbmJhbmtzX3BtcnggJXUgKCV1 +TUIpIG5iYW5rc19vdGhlcnMgJXUgKCV1TUIpIG5iYW5rc19mdyAldSAoJXVNQikKAF9tcGFydGl0 +aW9uX2JhbmtzX21jMTogbmJhbmtzX3BtdHggJXUgKCV1TUIpIG5iYW5rc19vdGhlcnMgJXUgKCV1 +TUIpIG5iYW5rc19mdyAldSAoJXVNQikKAAAAAAAAAF9tcGFydGl0aW9uX2JhbmtzX21jMDogbmJh +bmtzX3BtcnggJXUgKCV1TUIpIG5iYW5rc19vdGhlcnMgJXUgKCV1TUIpCgAAAAAAAAAAAAAAbWVt +X21hbGxvY19pbnRlcm5hbDogZmFpbGVkIHRvIGFsbG9jYXRlICV1IGJ5dGVzLCByZXR1cm5pbmcg +TlVMTAoAAAAAAAAAAAAAAAAAAABod19lZGNfYmlzdFsldV06IGJpc3RfY21kWzB4JTA4eF0gYWRk +ciAweCV4IGxlbiAweCV4CgAAAAAAAAAAAAAAaHdfZWRjX2Jpc3RbJXVdOiBkb25lLCBlbmNvdW50 +ZXJlZCAldSBlcnJvcnMgb24gZmlyc3QgYW5kICV1IGVycm9ycyBvbiBzZWNvbmQgYXR0ZW1wdCAo +JXVnYnBzKQoAbWVtX2luaXRfY2FjaGVzOiBjYWNoZV9zaXplICV1IGZsb3djX2J1Zl90Y2JfY2Fj +aGVfc2l6ZSAldSBidWZsbDY0X2NhY2hlX3NpemUgJXUKAAAAAAAAAAAAAAAAAAAAcXVldWVzX3Bl +cl9wYWdlOiBwZiAldSBoYXMgYSBiYXJzaXplIG9mICV1LWJ5dGVzLCBvY3Ffc2l6ZSAldQoAAHNn +ZSByZXF1aXJlIG5lcSAldSBuaXEgJXUgcm91bmRpbmcgdG8gJXUgJXUKAAAAAG1wYXJ0aXRpb25f +cG10eDogbSAweCUwOHggc2l6ZSAldQoAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fcG1yeDogbSAw +eCUwOHggc2l6ZSAldQoAAAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25fZWRjIChubyBleHRtZW0pOiBt +IDB4JTA4eCBzaXplICV1CgAAAG1wYXJ0aXRpb25fZWRjX2VzdGltYXRlOiBodyBtb2R1bGVzIHJl +cXVpcmUgJWQgYnl0ZXMgaW4gRURDCgAAAABjaG5ldF9ieWU6bDJkZXZfZmMtPmZsb3djX2lkIFsw +eCV4XSwgbDJkZXZfZmMtPmZsb3djX3BjaWVfcGZuIFsweCV4XSwgbDJkZXZfZmMtPmZsb3djX3Bj +aWVfdmZuIFsweCV4XSwgcG9ydCBbMHgleF0KAAAAAAAAAAAAAAAAAGNobmV0X2J5ZTp2bGFuZGV2 +X2ZjLT5mbG93Y19pZCBbMHgleF0sIHZsYW5kZXZfZmMtPmZsb3djX3BjaWVfcGZuIFsweCV4XSwg +dmxhbmRldl9mYy0+Zmxvd2NfcGNpZV92Zm4gWzB4JXhdLCBwb3J0IFsweCV4XQoAAAAAAAAAY3Jf +bW9kdWxlX3J4X2xvc1sldV06IHJ4X2xvcyBjaGFuZ2VkIHRvICV1CgAAAAAAcGZuICV1IHZmbiAl +dSBoYXMgcG5kdHhucyAldSBhZnRlciAxMDBtcwoAAAAAAAAAYmFkIG1haWxib3ggY21kOiBwZm4g +MHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JXggPiBMQVNUQzJFIDB4JXgKAG1haWxib3ggY21kIG5v +dCB5ZXQgc3VwcG9ydGVkOiBwZm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JXgKAABiYWQgbWFp +bGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyBvcGNvZGUgMHgleCBpcyB2YWxpZCBwb3N0IGRl +dmljZSBpbml0IG9ubHkKAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29k +ZSAweCUwMnggcmFtYXNrIDB4JXggY21kIHJhbWFzayAweCV4CgAAYmFkIG1haWxib3ggY21kOiBw +Zm4gMHgleCB2Zm4gMHgleDsgb3Bjb2RlIDB4JTAyeCBsZW4xNiAweCV4IHZlcnN1cyBleHBlY3Rl +ZCBsZW4xNiAweCV4CgAAAAAAAAAAaW5zdWZmaWNpZW50IGNhcHMgdG8gcHJvY2VzcyBtYWlsYm94 +IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IHJfY2FwcyAweCV4IHd4X2NhcHMgMHgleCByZXF1aXJl +ZCByX2NhcHMgMHgleCB3X2NhcHMgMHgleAoAAAAAAAAAAABpbnN1ZmZpY2llbnQgY2FwcyB0byBw +cm9jZXNzIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsgcl9jYXBzIDB4JXggd3hfY2Fw +cyAweCV4IHJlcXVpcmVkIHJfY2FwcyAweCV4IHdfY2FwcyAweCV4CgAAAAAAAAAAAFZQRCByZWdp +b24gaXMgdG9vIHNtYWxsIChTRVJDRkdfU1JfUEZOVlBEU0laRSAweCV4KQoAAAAAAAAAAAAAAABj +ZjogZmFpbGVkIHRvIGFsbG9jYXRlZCBtZW1vcnkgZm9yIGNvbmZpZ3VyYXRpb24gZmlsZSwgcmV0 +ICVkCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -9231,23 +9232,31 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAACCAAABIAAAAAAAAACCAAABAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAGgIAAAAAAAAAAAAAAAACAAAAAAAAAAAACgAAAAAAAAAAAAAIAAwAAAAABYAgAAAAAAwAA -AAAAAAAAAAAAAwAAAAAAAAAAAAAAAgAAAAAAAAAAACAAAAAAAAAAAAAAAAEAA4AAAAAAAAAAAAAA -AgAAAAAAAAAAACADgAAAAAAAAAAAABACgACAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA -AAAAAoAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAoAAAAAAAAAAAAEAAwAAAAAAAAAAAAACgwAAAAAA -AAAAABACgAAAAAAAAAAAADAAAwAAAAAAAAgAADAAAwAAAAAAAAAAADAFgwAAAAAAAAgAADAFgwAA -AAAAAAAAADAEgwAAAAAAAAgAADAEgwAAAAAAAAAAADADAwAAAAAAAAgAADADAwAAAAAAAAAAADgD -AwAAAAAAAAAAADgFgwAAAAAAAAAAADgEgwAAAAAAAAAAADgAAwAAAAAAAAAAADQGggAAAAAAAAAA -ADwDggAAAAAAAAAAADwAAwAAAAAAAAgAADwAAwAAAAAAAAAAADwEgwAAAAAAAAAAADwFAwAAAAAA -AAAAAD0EAwAAAAAAAAAAADwDgwAAAAAAAAAAACwAAgAAAAAAAAAAACwFggAAAAAAAAAAACwFAgAA -AAAAAAAAABAGgAAAAAAAAAAAABAGgsAAAAAAAAAAABAGgoAAAAAAAAAAAAAOggAAAAAAAAAAABAH -goAAAAAgAAAAAAAHggAAAAAgAAAAABAHAoAAAAAAAAAAABAHAoAAAAAAAAAAABAHAoAAAAAAAAAA -AAAHAgAAAAAgAAAAABAXgwAAAAAAAAgAABAXgwAAAAAAAAgAABAAAAAAAAAAAAAAABAGA4AAAAAA -AAAAAAAOAwAAAAAAAAAAABAGA0AAAAAAAAAAABAGAwAAAAAAAAAAABAGAAAAAAAAAAAAAAAGA4AA -AAAAAAAAAAAGAwAAAAAAAAAAAAAOAgAAAAAAAAAAAAAOAgAAAAAAAAAAABAGAgAAAAAAAAAAABAG -AgAAAAAAAAAAABAGAoAAAAAAAAAAABAGAoAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAgAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAQAwAAAAAAAAgAAAAAAAAAAAAAAAAAAP////////// +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAIIAAAEgAAAAAAAAAIIAAAEAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAaAgAAAAAAAAAAAAAAAAIAAAAAAAAAAAAKAAAAAAAAAAAAAAgADAAAAAAFgCAAAAAADAAAA +AAAAAAAAAAADAAAAAAAAAAAAAAACAAAAAAAAAAAAIAAAAAAAAAAAAAAAAQADgAAAAAAAAAAAAAAC +AAAAAAAAAAAAIAOAAAAAAAAAAAAAEAKAAIAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAA +AAACgAAAAAAAAAAAAAACAAAAAAAAAAAAAAACgAAAAAAAAAAAAQADAAAAAAAAAAAAAAKDAAAAAAAA +AAAAEAKAAAAAAAAAAAAAMAADAAAAAAAACAAAMAADAAAAAAAAAAAAMAWDAAAAAAAACAAAMAWDAAAA +AAAAAAAAMASDAAAAAAAACAAAMASDAAAAAAAAAAAAMAMDAAAAAAAACAAAMAMDAAAAAAAAAAAAOAMD +AAAAAAAAAAAAOAWDAAAAAAAAAAAAOASDAAAAAAAAAAAAOAADAAAAAAAAAAAANAaCAAAAAAAAAAAA +PAOCAAAAAAAAAAAAPAADAAAAAAAACAAAPAADAAAAAAAAAAAAPASDAAAAAAAAAAAAPAUDAAAAAAAA +AAAAPQQDAAAAAAAAAAAAPAODAAAAAAAAAAAALAACAAAAAAAAAAAALAWCAAAAAAAAAAAALAUCAAAA +AAAAAAAAEAaAAAAAAAAAAAAAEAaCwAAAAAAAAAAAEAaCgAAAAAAAAAAAAA6CAAAAAAAAAAAAEAeC +gAAAACAAAAAAAAeCAAAAACAAAAAAEAcCgAAAAAAAAAAAEAcCgAAAAAAAAAAAEAcCgAAAAAAAAAAA +AAcCAAAAACAAAAAAEBeDAAAAAAAACAAAEBeDAAAAAAAACAAAEAAAAAAAAAAAAAAAEAYDgAAAAAAA +AAAAAA4DAAAAAAAAAAAAEAYDQAAAAAAAAAAAEAYDAAAAAAAAAAAAEAYAAAAAAAAAAAAAAAYDgAAA +AAAAAAAAAAYDAAAAAAAAAAAAAA4CAAAAAAAAAAAAAA4CAAAAAAAAAAAAEAYCAAAAAAAAAAAAEAYC +AAAAAAAAAAAAEAYCgAAAAAAAAAAAEAYCgAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAACAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAABADAAAAAAAACAAAAAAAAAAAAAAAAAAA//////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// @@ -9257,24 +9266,24 @@ AAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAQAwAAAAAAAAgAAAAAAAAAAAAAAAAAAP////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////wAA -ACAAAAAAwAAAAAAAACAAAAAA4AAAAAAAAAACAAAAAAAAAEAAAAAAAAAAAAAAAAAAASEAAAAAAAAA -AAABASAAAAAAAAAAAAAAAgAAAAQABAAAAAAFAAAABAAAAAAAAAAAAKAAAAAAgAAAAACAAEAAAAAA -AAIAAACAACAAAAAAAAIAAAEAQAAAAAAAAAAAAAEAQgAAAAAAAAAAAAAAIAAAAAAAAAAAAAIQIAAA -AAAAAAAAAAIMAgAAAAAAAAAAAACFAgAAAAQAAAAAAACAQgAAAAAAAAAAAAIAIgAAAAAAAAAAAACA -QQAAAAAAAAAAAACAQYAAAAAAAAAAAAIAIQAAAAAAAAAAAAAQIIAAAAAAAAAAAAIlAIAAAAAAAAAA -AAAFAAAAAAAAAAAAAAiIBIAAAAAAAAAAAAiIBIAAAAAAAAAAAAiiAIAAAAAAAAAAAAiiAIAAAAAA -AAAAAAijAIAAAAAAAAAAAAijAIAAAAAAAAAAAAikgIAAAAAAAAAAAAikgIAAAAAAAAAAAASkgMAA -AAAAAAAAAASiAMAAAAAAAAAAAASjAMAAAAAAAAAAAASIBMAAAAAAAAAAAAAJAYAAAAAAAAAAAAIM -AIAAAAAAAAAAAACIBMAAAAAAAAAAAACIBIAAAAAAAAAAAAILAIAAAAAAAAAAAACKgIAAAAAAAAAA -AAALgIAAAAAAAAAAAACMAIAAAAAAAAAAAAIgEIAAAAAAAAAAAAIKAIAAAAAAAAAAAAIKgIAAAAAA -AAAAAAAJAoAAAAAAAAAAAAABAQAAAAAAAAAAAAABAUAAAAAAAAAAAAABAIAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAIAAAAAAAAAAAAAAgRAAAAAAAAAAAAAAgQgAAAAAAAAAAAAAgQQAAAAAAAAAAAAA -gYAAAAAAAAAAAACAAMAAAAAAAAAAAACAAKAAAAAAAAAAAAAACAAAAAAAAAAAAACBgAAAAAAAAAAA -AACBgIAAAAAAAAAAAACJgIAAAAAAAAAAAACJgMAAAAAAAAAAAAABggAAAAAAAAAAAAIBgAAAAAAA -AAAAAAIBgIAAAAAAAAAAAABBgYAAAAAAAAAAAAIBgYAAAAAAAAAAAABJgYAAAAAAAAAAAAIJgYAA -AAAAAAAAAAIBgQAAAAAAAAAAAABBgQAAAAAAAAAAACAAAAAAAAAAAAAAABAAAAIBAAAAAAAAABAA -AAIAAAAAAAAAABAAAAAAAAAAAAAAAACAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////// +////////////////////////////////////////////////////////////////////////AAAA +IAAAAADAAAAAAAAAIAAAAADgAAAAAAAAAAIAAAAAAAAAQAAAAAAAAAAAAAAAAAABIQAAAAAAAAAA +AAEBIAAAAAAAAAAAAAACAAAABAAEAAAAAAUAAAAEAAAAAAAAAAAAoAAAAACAAAAAAIAAQAAAAAAA +AgAAAIAAIAAAAAAAAgAAAQBAAAAAAAAAAAAAAQBCAAAAAAAAAAAAAAAgAAAAAAAAAAAAAhAgAAAA +AAAAAAAAAgwCAAAAAAAAAAAAAIUCAAAABAAAAAAAAIBCAAAAAAAAAAAAAgAiAAAAAAAAAAAAAIBB +AAAAAAAAAAAAAIBBgAAAAAAAAAAAAgAhAAAAAAAAAAAAABAggAAAAAAAAAAAAiUAgAAAAAAAAAAA +AAUAAAAAAAAAAAAACIgEgAAAAAAAAAAACIgEgAAAAAAAAAAACKIAgAAAAAAAAAAACKIAgAAAAAAA +AAAACKMAgAAAAAAAAAAACKMAgAAAAAAAAAAACKSAgAAAAAAAAAAACKSAgAAAAAAAAAAABKSAwAAA +AAAAAAAABKIAwAAAAAAAAAAABKMAwAAAAAAAAAAABIgEwAAAAAAAAAAAAAkBgAAAAAAAAAAAAgwA +gAAAAAAAAAAAAIgEwAAAAAAAAAAAAIgEgAAAAAAAAAAAAgsAgAAAAAAAAAAAAIqAgAAAAAAAAAAA +AAuAgAAAAAAAAAAAAIwAgAAAAAAAAAAAAiAQgAAAAAAAAAAAAgoAgAAAAAAAAAAAAgqAgAAAAAAA +AAAAAAkCgAAAAAAAAAAAAAEBAAAAAAAAAAAAAAEBQAAAAAAAAAAAAAEAgAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAgAAAAAAAAAAAAACBEAAAAAAAAAAAAACBCAAAAAAAAAAAAACBBAAAAAAAAAAAAACB +gAAAAAAAAAAAAIAAwAAAAAAAAAAAAIAAoAAAAAAAAAAAAAAIAAAAAAAAAAAAAIGAAAAAAAAAAAAA +AIGAgAAAAAAAAAAAAImAgAAAAAAAAAAAAImAwAAAAAAAAAAAAAGCAAAAAAAAAAAAAgGAAAAAAAAA +AAAAAgGAgAAAAAAAAAAAAEGBgAAAAAAAAAAAAgGBgAAAAAAAAAAAAEmBgAAAAAAAAAAAAgmBgAAA +AAAAAAAAAgGBAAAAAAAAAAAAAEGBAAAAAAAAAAAAIAAAAAAAAAAAAAAAEAAAAgEAAAAAAAAAEAAA +AgAAAAAAAAAAEAAAAAAAAAAAAAAAAIAAwAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// @@ -9284,36 +9293,36 @@ AAIAAAAAAAAAABAAAAAAAAAAAAAAAACAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////wAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAACACSAAAAAAAAAANmACAAQAAAAAAIAJIAAAAAAAAAA3IBJQRAAAAA -AAAAAAAAAAAAAAADlgAgAEAAAAAACAAAAAIAiAOHAABWACAAQAAAAAAAAAAAAAAAAAAAA5YAIABA -AAAAAAAAAAAAAAAAAAADlgAgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAAA5YA -IABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAAAAAA -A5YAIABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAAAAAA -AAAAA5YAIABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAAAAAA -AAAAAAIAA5YAJgRAAAAAAAhHIAEEAAACsgAC0gUgJEAAAAAAAAAAAAAAAAAAAAOWACAAQAAAAAAA -RyABBgyhgrBAAZIEICRAAAAAAABHIAEEDKBCs4ACEgUgJEAAAAAACAAAAAIAiAOFAACWASAAQAAA -AAAIAAAAAgCIA4UAAJYBIABAAAAAAAgAAAACAIgDhQAAlgEgAEAAAAAAAAAAAAAAAAAAAAOWACAA -QAAAAAANxRK6ArCA0xRUi+JKRiRAAAAAAAXFEroCt4DTFFSLYkmmJEAAAAAABcUSogawgNMUVIvi -SkYkQAAAAAANxRKiBreA0xRUi2JJpiRAAAAAAAXFEqIGsIDTFFSL4kpGJEAAAAAADcUSoga3gNMU -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 @@ -9330,29 +9339,29 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAgAMAAEAAAAAgAAAgAmJEAAAAAAAEcwAAYDIAK3AAgCAcAkQAAAAAAIAwAA -AgagCrUACAIAxiRAAAAAAAAAAAAAAAAAAgAAAgAmJEAAAAAAACBQAAQAAAACAAACACYkQAAAAAAI -YCAAhAAAAAAAAAYAIABAAAAAAAhgIACEAAAAAgEwAgAmJUAAAAAACGAAAAQAhAGABAQCAcYkwAAA -AAABwAAAAkOAAwIMiAIBpiRAAAAAAAgAYAAEAAAAAgAAAgAmJEAAAAAACABgAAQAAAAAAAAEASAA -QAAAAAAAAAAAAAAAAAAAAAQBIABAAAAAAAQIFIAGCgAABwFMAiCmJkAAAAAACIAAAAYAhAGABAgC -AaYmQAAAAAAAQAAAAgCgAAJACAIBpiRAAAAAAAAAAAAAAAAAAgAAAgAmJEAAAAAABAAAAAKEAAMC -iggCBKYkQAAAAAAAAAAAAAAAAAIAAAYBIEhAAAAAAAAgUAAEAAAAAgAAAgAmJEAAAAAACGAgAIQA -AAACAAAGACYEQAAAAAAIYCAAhAAAAAIAAAIBJiVAAAAAAAhgAAAEAIQBgAQEAgHGJMAAAAAACABg -AAQAAAAAAAAEASAAQAAAAAAAAAAAAAAAAAAAAAIAJkxwAAAAAAAAAAAAAAAAAAAABgEgAAAAAAAA +AAAAAAAAAAAAAAAACAAwAAQAAAACAAACACYkQAAAAAAARzAABgMgArcACAIBwCRAAAAAAAgDAAAC +BqAKtQAIAgDGJEAAAAAAAAAAAAAAAAACAAACACYkQAAAAAAAIFAABAAAAAIAAAIAJiRAAAAAAAhg +IACEAAAAAAAABgAgAEAAAAAACGAgAIQAAAACATACACYlQAAAAAAIYAAABACEAYAEBAIBxiTAAAAA +AAHAAAACQ4ADAgyIAgGmJEAAAAAACABgAAQAAAACAAACACYkQAAAAAAIAGAABAAAAAAAAAQBIABA +AAAAAAAAAAAAAAAAAAAABAEgAEAAAAAABAgUgAYKAAAHAUwCIKYmQAAAAAAIgAAABgCEAYAECAIB +piZAAAAAAABAAAACAKAAAkAIAgGmJEAAAAAAAAAAAAAAAAACAAACACYkQAAAAAAEAAAAAoQAAwKK +CAIEpiRAAAAAAAAAAAAAAAAAAgAABgEgSEAAAAAAACBQAAQAAAACAAACACYkQAAAAAAIYCAAhAAA +AAIAAAYAJgRAAAAAAAhgIACEAAAAAgAAAgEmJUAAAAAACGAAAAQAhAGABAQCAcYkwAAAAAAIAGAA +BAAAAAAAAAQBIABAAAAAAAAAAAAAAAAAAAAAAgAmTHAAAAAAAAAAAAAAAAAAAAAGASAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAACLSQBAkWBAIExiRAAAAAAAHAAAAItJAECRYE -AgTGJEAAAAAABAh0gEwJAABQAFwCYeYkQAAAAAAMCHSARAAAAFIAQAJhJiRAAAAAAAgCEKAEAAAA -AAEAAgAmJEAAAAAACAIQoAQAAAAAAQACACYkQAAAAAAECHQAQgEAAAcAiAJgxiRAAAAAAA3IFAAC -CQAABECcAmDmJEAAAAAACcgQgAa0kAQClIgCZcYkQAAAAAANyHQASLSQAwCUiAJgpiTAAAAAAA3I -dABItJADAJSIAmCmJMAAAAAACEcAAAQAAAAAAAACASAkQAAAAAAIRwAABAAAAAIAAAIFICRAAAAA -AABHIAEMByHCtwAIAgHAJEAAAAAAAEcgAQwHIcK3AAgCAcAkQAAAAAAARyABDAchwrcACAIBwCRA -AAAAAAAAIAEIAIQABUCIAgHGJMAAAAAAAAAgAQgAhAAFQIgCAcYkwAAAAAAAACABCACEAAVAiAIB -xiTAAAAAAAAAIAGGggABAsCIAgPGJMAAAAAAAAAgAYKCAAACwIgCA8YkwAAAAAAJwCABgqSAAQVA -iAIBxiTAAAAAAAgAAAAMAIQABUCIAgHGJMAAAAAAAAAgAYaCAAECwIgCA8YkwAAAAAAAACABgoIA -AADAiAICpiTAAAAAAAnAIAGCpIABBUCIAgHGJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAItJAECRYEAgTGJEAAAAAAAcAAAAi0kAQJFgQC +BMYkQAAAAAAECHSATAkAAFAAXAJh5iRAAAAAAAwIdIBEAAAAUgBAAmEmJEAAAAAACAIQoAQAAAAA +AQACACYkQAAAAAAIAhCgBAAAAAABAAIAJiRAAAAAAAQIdABCAQAABwCIAmDGJEAAAAAADcgUAAIJ +AAAEQJwCYOYkQAAAAAAJyBCABrSQBAKUiAJlxiRAAAAAAA3IdABItJADAJSIAmCmJMAAAAAADch0 +AEi0kAMAlIgCYKYkwAAAAAAIRwAABAAAAAAAAAIBICRAAAAAAAhHAAAEAAAAAgAAAgUgJEAAAAAA +AEcgAQwHIcK3AAgCAcAkQAAAAAAARyABDAchwrcACAIBwCRAAAAAAABHIAEMByHCtwAIAgHAJEAA +AAAAAAAgAQgAhAAFQIgCAcYkwAAAAAAAACABCACEAAVAiAIBxiTAAAAAAAAAIAEIAIQABUCIAgHG +JMAAAAAAAAAgAYaCAAECwIgCA8YkwAAAAAAAACABgoIAAALAiAIDxiTAAAAAAAnAIAGCpIABBUCI +AgHGJMAAAAAACAAAAAwAhAAFQIgCAcYkwAAAAAAAACABhoIAAQLAiAIDxiTAAAAAAAAAIAGCggAA +AMCIAgKmJMAAAAAACcAgAYKkgAEFQIgCAcYkwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAIAAAABAAEJBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAgAAAAEAAQkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -9365,63 +9374,63 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFtnbG9iYWxdCnJzc19n -bGJfY29uZmlnX21vZGU9YmFzaWN2aXJ0dWFsCnJzc19nbGJfY29uZmlnX29wdGlvbnM9dG5sbWFw -ZW4saGFzaHRvZXBsaXR6LHRubGFsbGxrcApyZWdbMHgxMDA4XT0weDQwODEwLzB4MjFjNzAKcmVn -WzB4MTAwY109MHgyMjIyMjIyMgpyZWdbMHgxMGEwXT0weDAxMDQwODEwCnJlZ1sweDEwNDRdPTQw -OTYKcmVnWzB4MTA0OF09NjU1MzYKcmVnWzB4MTA0Y109MTUzNgpyZWdbMHgxMDUwXT05MDI0CnJl -Z1sweDEwNTRdPTkyMTYKcmVnWzB4MTA1OF09MjA0OApyZWdbMHgxMDVjXT0xMjgKcmVnWzB4MTA2 -MF09ODE5MgpyZWdbMHgxMDY0XT0xNjM4NApyZWdbMHgxMGE0XT0weGEwMDBhMDAwLzB4ZjAwMGYw -MDAKcmVnWzB4MTBhOF09MHgyMDAwLzB4MjAwMApzZ2VfdGltZXJfdmFsdWU9NSwxMCwyMCw1MCwx -MDAsMjAwCnJlZ1sweDdkMDRdPTB4MDAwMTAwMDAvMHgwMDAxMDAwMApyZWdbMHg3ZGMwXT0weDBl -MmY4ODQ5CmZpbHRlck1vZGU9ZnJhZ21lbnRhdGlvbixtcHNoaXR0eXBlLHByb3RvY29sLHZsYW4s -cG9ydCxmY29lCmZpbHRlck1hc2s9cHJvdG9jb2wsZmNvZQp0cF9wbXJ4PTM0CnRwX3BtcnhfcGFn -ZXNpemU9NjRLCnRwX25yeGNoPTAKdHBfcG10eD0zMgp0cF9wbXR4X3BhZ2VzaXplPTY0Swp0cF9u -dHhjaD0wCnRwX210dXM9ODgsMjU2LDUxMiw1NzYsODA4LDEwMjQsMTI4MCwxNDg4LDE1MDAsMjAw -MiwyMDQ4LDQwOTYsNDM1Miw4MTkyLDkwMDAsOTYwMApyZWdbMHgxOTE2OF09MHgwNDAyMDEwMApb -ZnVuY3Rpb24iMCJdCm52Zj0xNgp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT0xCm5pcWZsaW50 -PTgKbmV0aGN0cmw9OApuZXE9MTYKbmV4YWN0Zj04CmNtYXNrPWFsbApwbWFzaz0weDEKW2Z1bmN0 -aW9uIjEiXQpudmY9MTYKd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9MQpuaXFmbGludD04Cm5l -dGhjdHJsPTgKbmVxPTE2Cm5leGFjdGY9OApjbWFzaz1hbGwKcG1hc2s9MHgyCltmdW5jdGlvbiIy -Il0KbnZmPTE2Cnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRoY3Ry -bD04Cm5lcT0xNgpuZXhhY3RmPTgKY21hc2s9YWxsCnBtYXNrPTB4NApbZnVuY3Rpb24iMyJdCm52 -Zj0xNgp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT0xCm5pcWZsaW50PTgKbmV0aGN0cmw9OApu -ZXE9MTYKbmV4YWN0Zj04CmNtYXNrPWFsbApwbWFzaz0weDgKW2Z1bmN0aW9uIjQiXQp3eF9jYXBz -PWFsbApyX2NhcHM9YWxsCm52aT0yOApuaXFmbGludD0xNzAKbmV0aGN0cmw9MTAwCm5lcT0yNTYK -bmV4YWN0Zj00MApjbWFzaz1hbGwKcG1hc2s9YWxsCm5ldGhvZmxkPTEwMjQKbnJvdXRlPTMyCm5j -bGlwPTMyCm5maWx0ZXI9NDk2Cm5zZXJ2ZXI9NDk2Cm5oYXNoPTEyMjg4CnByb3RvY29sPW5pY192 -bSxvZmxkLHJkZHAscmRtYWMsaXNjc2lfaW5pdGlhdG9yX3BkdSxpc2NzaV90YXJnZXRfcGR1CnRw -X2wydD0zMDcyCnRwX2RkcD0zCnRwX2RkcF9pc2NzaT0yCnRwX3N0YWc9Mwp0cF9wYmw9MTAKdHBf -cnE9MTMKW2Z1bmN0aW9uIjUiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT00Cm5pcWZsaW50 -PTM0Cm5ldGhjdHJsPTMyCm5lcT02NApuZXhhY3RmPTQKY21hc2s9YWxsCnBtYXNrPWFsbApuc2Vy -dmVyPTE2Cm5oYXNoPTIwNDgKdHBfbDJ0PTEwMjAKcHJvdG9jb2w9aXNjc2lfaW5pdGlhdG9yX2Zv -ZmxkCnRwX2RkcF9pc2NzaT0yCmlzY3NpX250YXNrPTIwNDgKaXNjc2lfbnNlc3M9MjA0OAppc2Nz -aV9uY29ubl9wZXJfc2Vzc2lvbj0xCmlzY3NpX25pbml0aWF0b3JfaW5zdGFuY2U9NjQKW2Z1bmN0 -aW9uIjYiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT00Cm5pcWZsaW50PTM0Cm5ldGhjdHJs -PTMyCm5lcT02NgpuZXhhY3RmPTMyCmNtYXNrPWFsbApwbWFzaz1hbGwKbmhhc2g9MjA0OAp0cF9s -MnQ9NApwcm90b2NvbD1mY29lX2luaXRpYXRvcgp0cF9kZHA9MQpmY29lX25mY2Y9MTYKZmNvZV9u -dm5wPTMyCmZjb2VfbnNzbj0xMDI0CltmdW5jdGlvbiIxMDIzIl0Kd3hfY2Fwcz1hbGwKcl9jYXBz -PWFsbApudmk9NApjbWFzaz1hbGwKcG1hc2s9YWxsCm5leGFjdGY9OApuZmlsdGVyPTE2CltmdW5j -dGlvbiIwLyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NApuZXRo -Y3RybD0yCm5lcT00Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgxCltmdW5jdGlvbiIxLyoi -XQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NApuZXRoY3RybD0yCm5l -cT00Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgyCltmdW5jdGlvbiIyLyoiXQp3eF9jYXBz -PTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NApuZXRoY3RybD0yCm5lcT00Cm5leGFj -dGY9NApjbWFzaz1hbGwKcG1hc2s9MHg0CltmdW5jdGlvbiIzLyoiXQp3eF9jYXBzPTB4ODIKcl9j -YXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NApuZXRoY3RybD0yCm5lcT00Cm5leGFjdGY9NApjbWFz -az1hbGwKcG1hc2s9MHg4Cltwb3J0IjAiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVt -PTI1Cmh3bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUs -MwpkY2JfYXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxz -b2NrZXRudW0sNQpbcG9ydCIxIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpo -d209MzAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNi -X2FwcF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0 -bnVtLDUKW3BvcnQiMiJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMw -Cmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBf -dGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1 -Cltwb3J0IjMiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209 -MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3Rsdlsx -XT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbZmlu -aV0KdmVyc2lvbj0weDE0MjUwMDFjCmNoZWNrc3VtPTB4NjNhNjUyYjMKAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW2dsb2JhbF0KcnNzX2ds +Yl9jb25maWdfbW9kZT1iYXNpY3ZpcnR1YWwKcnNzX2dsYl9jb25maWdfb3B0aW9ucz10bmxtYXBl +bixoYXNodG9lcGxpdHosdG5sYWxsbGtwCnJlZ1sweDEwMDhdPTB4NDA4MTAvMHgyMWM3MApyZWdb +MHgxMDBjXT0weDIyMjIyMjIyCnJlZ1sweDEwYTBdPTB4MDEwNDA4MTAKcmVnWzB4MTA0NF09NDA5 +NgpyZWdbMHgxMDQ4XT02NTUzNgpyZWdbMHgxMDRjXT0xNTM2CnJlZ1sweDEwNTBdPTkwMjQKcmVn +WzB4MTA1NF09OTIxNgpyZWdbMHgxMDU4XT0yMDQ4CnJlZ1sweDEwNWNdPTEyOApyZWdbMHgxMDYw +XT04MTkyCnJlZ1sweDEwNjRdPTE2Mzg0CnJlZ1sweDEwYTRdPTB4YTAwMGEwMDAvMHhmMDAwZjAw +MApyZWdbMHgxMGE4XT0weDIwMDAvMHgyMDAwCnNnZV90aW1lcl92YWx1ZT01LDEwLDIwLDUwLDEw +MCwyMDAKcmVnWzB4N2QwNF09MHgwMDAxMDAwMC8weDAwMDEwMDAwCnJlZ1sweDdkYzBdPTB4MGUy +Zjg4NDkKZmlsdGVyTW9kZT1mcmFnbWVudGF0aW9uLG1wc2hpdHR5cGUscHJvdG9jb2wsdmxhbixw +b3J0LGZjb2UKZmlsdGVyTWFzaz1wcm90b2NvbCxmY29lCnRwX3Btcng9MzQKdHBfcG1yeF9wYWdl +c2l6ZT02NEsKdHBfbnJ4Y2g9MAp0cF9wbXR4PTMyCnRwX3BtdHhfcGFnZXNpemU9NjRLCnRwX250 +eGNoPTAKdHBfbXR1cz04OCwyNTYsNTEyLDU3Niw4MDgsMTAyNCwxMjgwLDE0ODgsMTUwMCwyMDAy +LDIwNDgsNDA5Niw0MzUyLDgxOTIsOTAwMCw5NjAwCnJlZ1sweDE5MTY4XT0weDA0MDIwMTAwCltm +dW5jdGlvbiIwIl0KbnZmPTE2Cnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTEKbmlxZmxpbnQ9 +OApuZXRoY3RybD04Cm5lcT0xNgpuZXhhY3RmPTgKY21hc2s9YWxsCnBtYXNrPTB4MQpbZnVuY3Rp +b24iMSJdCm52Zj0xNgp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT0xCm5pcWZsaW50PTgKbmV0 +aGN0cmw9OApuZXE9MTYKbmV4YWN0Zj04CmNtYXNrPWFsbApwbWFzaz0weDIKW2Z1bmN0aW9uIjIi +XQpudmY9MTYKd3hfY2Fwcz1hbGwKcl9jYXBzPWFsbApudmk9MQpuaXFmbGludD04Cm5ldGhjdHJs +PTgKbmVxPTE2Cm5leGFjdGY9OApjbWFzaz1hbGwKcG1hc2s9MHg0CltmdW5jdGlvbiIzIl0KbnZm +PTE2Cnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTEKbmlxZmxpbnQ9OApuZXRoY3RybD04Cm5l +cT0xNgpuZXhhY3RmPTgKY21hc2s9YWxsCnBtYXNrPTB4OApbZnVuY3Rpb24iNCJdCnd4X2NhcHM9 +YWxsCnJfY2Fwcz1hbGwKbnZpPTI4Cm5pcWZsaW50PTE3MApuZXRoY3RybD0xMDAKbmVxPTI1Ngpu +ZXhhY3RmPTQwCmNtYXNrPWFsbApwbWFzaz1hbGwKbmV0aG9mbGQ9MTAyNApucm91dGU9MzIKbmNs +aXA9MzIKbmZpbHRlcj00OTYKbnNlcnZlcj00OTYKbmhhc2g9MTIyODgKcHJvdG9jb2w9bmljX3Zt +LG9mbGQscmRkcCxyZG1hYyxpc2NzaV9pbml0aWF0b3JfcGR1LGlzY3NpX3RhcmdldF9wZHUKdHBf +bDJ0PTMwNzIKdHBfZGRwPTMKdHBfZGRwX2lzY3NpPTIKdHBfc3RhZz0zCnRwX3BibD0xMAp0cF9y +cT0xMwpbZnVuY3Rpb24iNSJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKbmlxZmxpbnQ9 +MzQKbmV0aGN0cmw9MzIKbmVxPTY0Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9YWxsCm5zZXJ2 +ZXI9MTYKbmhhc2g9MjA0OAp0cF9sMnQ9MTAyMApwcm90b2NvbD1pc2NzaV9pbml0aWF0b3JfZm9m +bGQKdHBfZGRwX2lzY3NpPTIKaXNjc2lfbnRhc2s9MjA0OAppc2NzaV9uc2Vzcz0yMDQ4CmlzY3Np +X25jb25uX3Blcl9zZXNzaW9uPTEKaXNjc2lfbmluaXRpYXRvcl9pbnN0YW5jZT02NApbZnVuY3Rp +b24iNiJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKbmlxZmxpbnQ9MzQKbmV0aGN0cmw9 +MzIKbmVxPTY2Cm5leGFjdGY9MzIKY21hc2s9YWxsCnBtYXNrPWFsbApuaGFzaD0yMDQ4CnRwX2wy +dD00CnByb3RvY29sPWZjb2VfaW5pdGlhdG9yCnRwX2RkcD0xCmZjb2VfbmZjZj0xNgpmY29lX252 +bnA9MzIKZmNvZV9uc3NuPTEwMjQKW2Z1bmN0aW9uIjEwMjMiXQp3eF9jYXBzPWFsbApyX2NhcHM9 +YWxsCm52aT00CmNtYXNrPWFsbApwbWFzaz1hbGwKbmV4YWN0Zj04Cm5maWx0ZXI9MTYKW2Z1bmN0 +aW9uIjAvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD00Cm5ldGhj +dHJsPTIKbmVxPTQKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDEKW2Z1bmN0aW9uIjEvKiJd +Cnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD00Cm5ldGhjdHJsPTIKbmVx +PTQKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDIKW2Z1bmN0aW9uIjIvKiJdCnd4X2NhcHM9 +MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD00Cm5ldGhjdHJsPTIKbmVxPTQKbmV4YWN0 +Zj00CmNtYXNrPWFsbApwbWFzaz0weDQKW2Z1bmN0aW9uIjMvKiJdCnd4X2NhcHM9MHg4MgpyX2Nh +cHM9MHg4Ngpudmk9MQpuaXFmbGludD00Cm5ldGhjdHJsPTIKbmVxPTQKbmV4YWN0Zj00CmNtYXNr +PWFsbApwbWFzaz0weDgKW3BvcnQiMCJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09 +MjUKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwz +CmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNv +Y2tldG51bSw1Cltwb3J0IjEiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3 +bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2Jf +YXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRu +dW0sNQpbcG9ydCIyIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0yNQpscGJrX21lbT0yNQpod209MzAK +bHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90 +bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUK +W3BvcnQiMyJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0x +NQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFd +PTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1CltmaW5p +XQp2ZXJzaW9uPTB4MTQyNTAwMWMKY2hlY2tzdW09MHg2M2E2NTJiMwoAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -9437,50 +9446,50 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbZ2xvYmFsXQpyc3NfZ2xiX2NvbmZp -Z19tb2RlPWJhc2ljdmlydHVhbApyc3NfZ2xiX2NvbmZpZ19vcHRpb25zPXRubG1hcGVuLGhhc2h0 -b2VwbGl0eix0bmxhbGxsa3AKcmVnWzB4MTAwOF09MHg0MDgxMC8weDIxYzcwCnJlZ1sweDEwMGNd -PTB4MjIyMjIyMjIKcmVnWzB4MTBhMF09MHgwMTA0MDgxMApyZWdbMHgxMDQ0XT00MDk2CnJlZ1sw -eDEwNDhdPTY1NTM2CnJlZ1sweDEwNGNdPTE1MzYKcmVnWzB4MTA1MF09OTAyNApyZWdbMHgxMDU0 -XT05MjE2CnJlZ1sweDEwNThdPTIwNDgKcmVnWzB4MTA1Y109MTI4CnJlZ1sweDEwNjBdPTgxOTIK -cmVnWzB4MTA2NF09MTYzODQKcmVnWzB4MTBhNF09MHhhMDAwYTAwMC8weGYwMDBmMDAwCnJlZ1sw -eDEwYThdPTB4MjAwMC8weDIwMDAKc2dlX3RpbWVyX3ZhbHVlPTUsMTAsMjAsNTAsMTAwLDIwMApy -ZWdbMHg3ZDA0XT0weDAwMDEwMDAwLzB4MDAwMTAwMDAKcmVnWzB4N2RjMF09MHgwZTJmODg0OQpm -aWx0ZXJNb2RlPWZyYWdtZW50YXRpb24sbXBzaGl0dHlwZSxwcm90b2NvbCx2bGFuLHBvcnQsZmNv -ZQpmaWx0ZXJNYXNrPXByb3RvY29sLGZjb2UKdHBfcG1yeD0zMAp0cF9wbXJ4X3BhZ2VzaXplPTY0 -Swp0cF9ucnhjaD0wCnRwX3BtdHg9NTAKdHBfcG10eF9wYWdlc2l6ZT02NEsKdHBfbnR4Y2g9MAp0 -cF9tdHVzPTg4LDI1Niw1MTIsNTc2LDgwOCwxMDI0LDEyODAsMTQ4OCwxNTAwLDIwMDIsMjA0OCw0 -MDk2LDQzNTIsODE5Miw5MDAwLDk2MDAKcmVnWzB4MTkxNjhdPTB4MDQwMjAxMDAKW2Z1bmN0aW9u -IjAiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT0yOApuaXFmbGludD0xNzAKbmV0aGN0cmw9 -OTYKbmVxPTI1MgpuZXhhY3RmPTQwCmNtYXNrPWFsbApwbWFzaz1hbGwKbmV0aG9mbGQ9MTAyNApu -cm91dGU9MzIKbmNsaXA9MzIKbmZpbHRlcj00OApuc2VydmVyPTMyCm5oYXNoPTAKcHJvdG9jb2w9 -bmljX3ZtLG9mbGQscmRkcCxyZG1hYyxpc2NzaV9pbml0aWF0b3JfcGR1LGlzY3NpX3RhcmdldF9w -ZHUKdHBfbDJ0PTMwNzIKdHBfZGRwPTIKdHBfZGRwX2lzY3NpPTIKdHBfc3RhZz0yCnRwX3BibD01 -CnRwX3JxPTcKW2Z1bmN0aW9uIjEiXQp3eF9jYXBzPWFsbApyX2NhcHM9YWxsCm52aT00Cm5pcWZs -aW50PTM0Cm5ldGhjdHJsPTMyCm5lcT02NgpuZXhhY3RmPTMyCmNtYXNrPWFsbApwbWFzaz1hbGwK -bmhhc2g9MApwcm90b2NvbD1mY29lX2luaXRpYXRvcgp0cF9kZHA9MgpmY29lX25mY2Y9MTYKZmNv -ZV9udm5wPTMyCmZjb2VfbnNzbj0xMDI0CltmdW5jdGlvbiIxMDIzIl0Kd3hfY2Fwcz1hbGwKcl9j -YXBzPWFsbApudmk9NApjbWFzaz1hbGwKcG1hc2s9YWxsCm5leGFjdGY9OApuZmlsdGVyPTE2Cltm -dW5jdGlvbiIwLyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NApu -ZXRoY3RybD0yCm5lcT00Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgxCltmdW5jdGlvbiIx -LyoiXQp3eF9jYXBzPTB4ODIKcl9jYXBzPTB4ODYKbnZpPTEKbmlxZmxpbnQ9NApuZXRoY3RybD0y -Cm5lcT00Cm5leGFjdGY9NApjbWFzaz1hbGwKcG1hc2s9MHgyCltwb3J0IjAiXQpkY2I9cHBwLGRj -YngKYmdfbWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2 -WzBdPTB4ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMK -ZGNiX2FwcF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbcG9ydCIxIl0KZGNiPXBwcCxkY2J4CmJn -X21lbT0yNQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0w -eDg5MDYsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9h -cHBfdGx2WzJdPTMyNjAsc29ja2V0bnVtLDUKW3BvcnQiMiJdCmRjYj1wcHAsZGNieApiZ19tZW09 -MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2 -LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3Rs -dlsyXT0zMjYwLHNvY2tldG51bSw1Cltwb3J0IjMiXQpkY2I9cHBwLGRjYngKYmdfbWVtPTI1Cmxw -YmtfbWVtPTI1Cmh3bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4ODkwNixldGhl -cnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMl09 -MzI2MCxzb2NrZXRudW0sNQpbZmluaV0KdmVyc2lvbj0weDE0MjUwMDFjCmNoZWNrc3VtPTB4Mjdk -ZmU4MDUKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFtnbG9iYWxdCnJzc19nbGJfY29uZmln +X21vZGU9YmFzaWN2aXJ0dWFsCnJzc19nbGJfY29uZmlnX29wdGlvbnM9dG5sbWFwZW4saGFzaHRv +ZXBsaXR6LHRubGFsbGxrcApyZWdbMHgxMDA4XT0weDQwODEwLzB4MjFjNzAKcmVnWzB4MTAwY109 +MHgyMjIyMjIyMgpyZWdbMHgxMGEwXT0weDAxMDQwODEwCnJlZ1sweDEwNDRdPTQwOTYKcmVnWzB4 +MTA0OF09NjU1MzYKcmVnWzB4MTA0Y109MTUzNgpyZWdbMHgxMDUwXT05MDI0CnJlZ1sweDEwNTRd +PTkyMTYKcmVnWzB4MTA1OF09MjA0OApyZWdbMHgxMDVjXT0xMjgKcmVnWzB4MTA2MF09ODE5Mgpy +ZWdbMHgxMDY0XT0xNjM4NApyZWdbMHgxMGE0XT0weGEwMDBhMDAwLzB4ZjAwMGYwMDAKcmVnWzB4 +MTBhOF09MHgyMDAwLzB4MjAwMApzZ2VfdGltZXJfdmFsdWU9NSwxMCwyMCw1MCwxMDAsMjAwCnJl +Z1sweDdkMDRdPTB4MDAwMTAwMDAvMHgwMDAxMDAwMApyZWdbMHg3ZGMwXT0weDBlMmY4ODQ5CmZp +bHRlck1vZGU9ZnJhZ21lbnRhdGlvbixtcHNoaXR0eXBlLHByb3RvY29sLHZsYW4scG9ydCxmY29l +CmZpbHRlck1hc2s9cHJvdG9jb2wsZmNvZQp0cF9wbXJ4PTMwCnRwX3BtcnhfcGFnZXNpemU9NjRL +CnRwX25yeGNoPTAKdHBfcG10eD01MAp0cF9wbXR4X3BhZ2VzaXplPTY0Swp0cF9udHhjaD0wCnRw +X210dXM9ODgsMjU2LDUxMiw1NzYsODA4LDEwMjQsMTI4MCwxNDg4LDE1MDAsMjAwMiwyMDQ4LDQw +OTYsNDM1Miw4MTkyLDkwMDAsOTYwMApyZWdbMHgxOTE2OF09MHgwNDAyMDEwMApbZnVuY3Rpb24i +MCJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTI4Cm5pcWZsaW50PTE3MApuZXRoY3RybD05 +NgpuZXE9MjUyCm5leGFjdGY9NDAKY21hc2s9YWxsCnBtYXNrPWFsbApuZXRob2ZsZD0xMDI0Cm5y +b3V0ZT0zMgpuY2xpcD0zMgpuZmlsdGVyPTQ4Cm5zZXJ2ZXI9MzIKbmhhc2g9MApwcm90b2NvbD1u +aWNfdm0sb2ZsZCxyZGRwLHJkbWFjLGlzY3NpX2luaXRpYXRvcl9wZHUsaXNjc2lfdGFyZ2V0X3Bk +dQp0cF9sMnQ9MzA3Mgp0cF9kZHA9Mgp0cF9kZHBfaXNjc2k9Mgp0cF9zdGFnPTIKdHBfcGJsPTUK +dHBfcnE9NwpbZnVuY3Rpb24iMSJdCnd4X2NhcHM9YWxsCnJfY2Fwcz1hbGwKbnZpPTQKbmlxZmxp +bnQ9MzQKbmV0aGN0cmw9MzIKbmVxPTY2Cm5leGFjdGY9MzIKY21hc2s9YWxsCnBtYXNrPWFsbApu +aGFzaD0wCnByb3RvY29sPWZjb2VfaW5pdGlhdG9yCnRwX2RkcD0yCmZjb2VfbmZjZj0xNgpmY29l +X252bnA9MzIKZmNvZV9uc3NuPTEwMjQKW2Z1bmN0aW9uIjEwMjMiXQp3eF9jYXBzPWFsbApyX2Nh +cHM9YWxsCm52aT00CmNtYXNrPWFsbApwbWFzaz1hbGwKbmV4YWN0Zj04Cm5maWx0ZXI9MTYKW2Z1 +bmN0aW9uIjAvKiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD00Cm5l +dGhjdHJsPTIKbmVxPTQKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDEKW2Z1bmN0aW9uIjEv +KiJdCnd4X2NhcHM9MHg4MgpyX2NhcHM9MHg4Ngpudmk9MQpuaXFmbGludD00Cm5ldGhjdHJsPTIK +bmVxPTQKbmV4YWN0Zj00CmNtYXNrPWFsbApwbWFzaz0weDIKW3BvcnQiMCJdCmRjYj1wcHAsZGNi +eApiZ19tZW09MjUKbHBia19tZW09MjUKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZb +MF09MHg4OTA2LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpk +Y2JfYXBwX3RsdlsyXT0zMjYwLHNvY2tldG51bSw1Cltwb3J0IjEiXQpkY2I9cHBwLGRjYngKYmdf +bWVtPTI1CmxwYmtfbWVtPTI1Cmh3bT0zMApsd209MTUKZHdtPTMwCmRjYl9hcHBfdGx2WzBdPTB4 +ODkwNixldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsxXT0weDg5MTQsZXRoZXJ0eXBlLDMKZGNiX2Fw +cF90bHZbMl09MzI2MCxzb2NrZXRudW0sNQpbcG9ydCIyIl0KZGNiPXBwcCxkY2J4CmJnX21lbT0y +NQpscGJrX21lbT0yNQpod209MzAKbHdtPTE1CmR3bT0zMApkY2JfYXBwX3RsdlswXT0weDg5MDYs +ZXRoZXJ0eXBlLDMKZGNiX2FwcF90bHZbMV09MHg4OTE0LGV0aGVydHlwZSwzCmRjYl9hcHBfdGx2 +WzJdPTMyNjAsc29ja2V0bnVtLDUKW3BvcnQiMyJdCmRjYj1wcHAsZGNieApiZ19tZW09MjUKbHBi +a19tZW09MjUKaHdtPTMwCmx3bT0xNQpkd209MzAKZGNiX2FwcF90bHZbMF09MHg4OTA2LGV0aGVy +dHlwZSwzCmRjYl9hcHBfdGx2WzFdPTB4ODkxNCxldGhlcnR5cGUsMwpkY2JfYXBwX3RsdlsyXT0z +MjYwLHNvY2tldG51bSw1CltmaW5pXQp2ZXJzaW9uPTB4MTQyNTAwMWMKY2hlY2tzdW09MHgyN2Rm +ZTgwNQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= ==== diff --git a/sys/dev/cxgbe/firmware/t4fw_interface.h b/sys/dev/cxgbe/firmware/t4fw_interface.h index bd436681641c..2ee58bab22f5 100644 --- a/sys/dev/cxgbe/firmware/t4fw_interface.h +++ b/sys/dev/cxgbe/firmware/t4fw_interface.h @@ -8198,12 +8198,12 @@ enum fw_hdr_chip { enum { T4FW_VERSION_MAJOR = 0x01, T4FW_VERSION_MINOR = 0x0e, - T4FW_VERSION_MICRO = 0x02, + T4FW_VERSION_MICRO = 0x04, T4FW_VERSION_BUILD = 0x00, T5FW_VERSION_MAJOR = 0x01, T5FW_VERSION_MINOR = 0x0e, - T5FW_VERSION_MICRO = 0x02, + T5FW_VERSION_MICRO = 0x04, T5FW_VERSION_BUILD = 0x00, }; diff --git a/sys/dev/cxgbe/firmware/t5fw-1.14.2.0.bin.uu b/sys/dev/cxgbe/firmware/t5fw-1.14.4.0.bin.uu similarity index 58% rename from sys/dev/cxgbe/firmware/t5fw-1.14.2.0.bin.uu rename to sys/dev/cxgbe/firmware/t5fw-1.14.4.0.bin.uu index ed9375b3f97e..dc35d5aa8ae7 100644 --- a/sys/dev/cxgbe/firmware/t5fw-1.14.2.0.bin.uu +++ b/sys/dev/cxgbe/firmware/t5fw-1.14.4.0.bin.uu @@ -24,15 +24,15 @@ * SUCH DAMAGE. */ begin-base64 644 t5fw -AAEEiAEOAgAAAQQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAEEiAEOBAAAAQQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAABGoEeQSBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IE1vbiBKdWwgMTMgMjE6 -Mjc6MzMgUERUIDIwMTUgb24gY2xlb3BhdHJhLmFzaWNkZXNpZ25lcnMuY29tOi9ob21lL2Zpcm13 -YXJlL2N2cy9mdy1yZWxlYXNlKSwgVmVyc2lvbiBUNXh4IDAxLjBlLjAyLjAwAAAAAAAAAOe+ZdRg +AAAAAAAAAAAAAENoZWxzaW8gRlcgUlVOTUVNIERFQlVHPTAgKEJ1aWx0IFRodSBKdWwgMjMgMDA6 +NDM6NDUgUERUIDIwMTUgb24gY2xlb3BhdHJhLmFzaWNkZXNpZ25lcnMuY29tOi9ob21lL2Zpcm13 +YXJlL2N2cy9mdy1yZWxlYXNlKSwgVmVyc2lvbiBUNXh4IDAxLjBlLjA0LjAwAAAAAAAAAEXtwlZg AMgAH/zhSOEAe/AAEAAA4QAwuHj///8f/OFAgAAAAeEAe3AAABAAH//87CAAAADhAZwE4QUAAAAC AEDhBQgAAAYAQAACAAwABgAM4QUABAAMAACAAAEC4QB7POEAe0ThAHvk4gAAAAABAADhAHuQIAAA AAAAgADhAHsAAABAAeEAe5wAAEAAREREQuAAAADjAARzREREQOMACAAgAAJcAAAAAB//k2AAAAAA @@ -67,8 +67,8 @@ nOMAffwgAAGcIAABpeMAfgAgAAG4IAABvOMAfgwgAAG8IAABxeMAfhAgAAHYIAAB2OMAfhwgAAHc IAAB4uMAfhwgAAH4IAAB+OMAfiQgAAH8IAAB/OMAfiQgAAIYIAACGOMAfiQgAAIcIAACHOMAfiQg AAI4IAACOOMAfiQgAAI8IAACPOMAfiQgAAJYIAACWOMAfiQgAAJcIAACYuMAfiQgAAJ4IAACeOMA fiwgAAJ8IAACguMAfiwgAAKYIAIB8uMAfjQgAwAAIAMXCOMCfZAgAxcIIAMXCOMClJggAxcIIAdS -bOMClJggB1JwIAdYIOMG0AAgCAAAIAgWEOMG1bAgCBYQIAk/UuMG68AgCT9gIAlA4OMIFRAgCwAA -IAsAAOMIFpAgCwAAIAsAAOMIFpAgCwAAIAu9L+MIFpAAAAAAAAAAAAAAAAAgADeuIAA3oCAAO5Ig +fOMClJggB1KAIAdYMOMG0BAgCAAAIAgWEOMG1cAgCBYQIAk/cuMG69AgCT+AIAlBAOMIFUAgCwAA +IAsAAOMIFsAgCwAAIAsAAOMIFsAgCwAAIAu9L+MIFsAAAAAAAAAAAAAAAAAgADeuIAA3oCAAO5Ig ADegIAA7DSAAN6AgADhVIAA6pSAAOiogADegIAA51SAAOYwgADkhIAA3jSAAOMwgADegIAA3oCAA N6AgADh0AAAAAAEQGAEABAAAAAAAAAAAAAD///////8P/P//8P///wD8IADH2yAAyRcgAMlIIADJ DyAAyNUgAMjOIADIlyAAyI8gAMiHIADIOiAAyUYgAMgyIADIDiAAyUggAMgHAAAAAAAAAAoAAAAK @@ -77,9 +77,9 @@ AQACAAMABAAFAAYABwAIAAkACgAOABEAFQAZAB4AIwAtADwAUABkAMgBLAGQAfQAAAAAAAAAAAAA AAAAAAAAAAAAAQABAAIAAgADAAMAAwADAAQABAAEAAQABAAFAAUABQAFAAUABQAGAAYABwAHAAAA AgAAAAYAAAAKAAAADgAAABQAAAAcAAAAKAAAADgAAABQAAAAcAAAAKAAAADgAAABQAAAAcAAAAKA AAADgAAABQEAAAcAAAAKAAAADgAAABQAAAAcAAAAKAAAADgAAABQAAAAcAAAAKAAAADgAAABQAAA -AcAAAAKAAAADgAD/AAECAgAAAAAAAAAAAAAAIAijQyAIo5AgCKLjIAiiriAIo5AgCKHPIAihzyAI -o5AgCKOQIAihzyAIo5AgCKOQIAihzCAIoc8gCKF9IAijkCAIo5AgCKOQIAijkCAIo5AgCKOQIAij -kCAIo5AgCKOQIAijkCAIo5AgCKOQIAijkCAIo5AgCKOQIAijkCAIoacgAwtYAAAAASADD9gAAAD/ +AcAAAAKAAAADgAD/AAECAgAAAAAAAAAAAAAAIAijUyAIo6AgCKLzIAiiviAIo6AgCKHfIAih3yAI +o6AgCKOgIAih3yAIo6AgCKOgIAih3CAIod8gCKGNIAijoCAIo6AgCKOgIAijoCAIo6AgCKOgIAij +oCAIo6AgCKOgIAijoCAIo6AgCKOgIAijoCAIo6AgCKOgIAijoCAIobcgAwtYAAAAASADD9gAAAD/ IAMJEAAAAP8AAAAAAAAAACADC0QAAAACIAMLSAAAAAMgAwtQAAAABwAAAAAAAAAAIAMLKAAAAAEg AwssAAAAAiADCzQAAAAEIAMP2AAAAP8gAwkQAAAA/wAAAAAAAAAAIAMJEAAAAAAgAw/YAAAAACAD CkAAAAABIAMKSAAAAAQgAwpQAAAACCADClwAAAAgIAMKbAAAAEAgAwp0AAAAgCADCnwAAAEAIAMK @@ -87,13 +87,13 @@ hAAAAgAgAwqYAAAEACADCqwAAAgAIAMKxAAAEAAgAwrYAAAgACADCugAAEAAIAMK9AAAgAAgAwsI AAEAACADCxgAAgAACAQCAAAAAAAAAAAAAAAAACADCiwAAAAQIAMKNAAAABEgAwoUAAAAACADChgA AAABIAMKHAAAAAIgAwokAAAAAwAAAAAAAP//AAAAAAAA//8gAwmUAAABACADCaAAAACAIAMJsAAA AEAgAwnAAAAAICADCdAAAAAQIAMJ4AAAAAggAwnsAAAABCADCfgAAAACIAMKBAAAAAEAAAAAAAAA -ACAJJvAgCSaqIAkm5iAJJuYgCSaqIAkmqiAJJvAgCSbwIAkmqiAJJvAgCSaqIAkm8CAJJuYgCSaq -IAkmqiAJJqogCSaqIAkmqiAJJvAgCSaqIAkmqiAJJqogCSaqIAkmqiAJJvAgCSbwIAkm8CAJJvAg -CSbwIAkm8CAJJvAgCSbwIAkmqiAJJqogCSaqIAkmqiAJJqogCSaqIAkmqiAJJqogCSaqIAkmqiAJ -JqogCSaqIAkmqiAJJqogCSaqIAkmqgACAgUFCAgLCw4OEREUFBcXGhodHSAgIyMmJikpLCwvLzIy +ACAJJxAgCSbKIAknBiAJJwYgCSbKIAkmyiAJJxAgCScQIAkmyiAJJxAgCSbKIAknECAJJwYgCSbK +IAkmyiAJJsogCSbKIAkmyiAJJxAgCSbKIAkmyiAJJsogCSbKIAkmyiAJJxAgCScQIAknECAJJxAg +CScQIAknECAJJxAgCScQIAkmyiAJJsogCSbKIAkmyiAJJsogCSbKIAkmyiAJJsogCSbKIAkmyiAJ +JsogCSbKIAkmyiAJJsogCSbKIAkmygACAgUFCAgLCw4OEREUFBcXGhodHSAgIyMmJikpLCwvLzIy NTU4ODs7AAAAAAAAAAEDEREICBAJAwEAAAAAAAAgBO9oIAG/JCAAXUAgAZ2UIAG77CABt4AgAX8c IAQBRB//6aAf/+YgIADKAB//2PwgAIiEIAB7IAAAAAAAAAAAIAGfMCAApyAAAAAAAAAAAB//0rQf -/8SIH//CHB//wDAgAHcoIABv4CAAbmQgAL+4H//g5CAHHPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +/8SIH//CHB//wDAgAHcoIABv4CAAbmQgAL+4H//g5CAHHQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAIAHF/CABr8ggANI8IADRYB//73gf/82IH//KMCAApPAgBWDQIAFA 6CABIhwgAQswIAD/ACAA8MAgAObwIADUWCAE8MAgBDOAIAE2KCAEV0wgAe9cIACIQAAAAAAgANKc IAXVaCAAx0AgAaZMIAASICAAudggAA1YIANalB//8qggANJYIAQ2GAAAAAAAAAAAIAN99CAATgAg @@ -112,13 +112,13 @@ AAAgAw+sAQAAACADFpAAAAAAAAAAANdqpHjox7dWJCBw28G9zu71fA+vR4fGKqgwRhP9RpUBaYCY 3s+p9rtLYL6/vHAom37G6qEn+tTvMIUEiB0F2dTQOebbmeUfonz4xKxWZfQpIkRDKv+Xq5Qjp/yT oDllW1nDjwzMkv/v9H2FhF3Rb6h+T/4s5uCjAUMUTggRofdTfoK9OvI1KtfSu+uG05EHDBEWBwwR FgcMERYHDBEWBQkOFAUJDhQFCQ4UBQkOFAQLEBcECxAXBAsQFwQLEBcGCg8VBgoPFQYKDxUGCg8V -H//AAAAEACAgB1ggIAdb4B/84gAf/6yEH/+s9B//sEADgAAAgQAAAB//sDAA//gAAQAAAAAQAACB +H//AAAAEACAgB1gwIAdb8B/84gAf/6yEH/+s9B//sEADgAAAgQAAAB//sDAA//gAAQAAAAAQAACB BAEAgQQAAAEEAAABBAEAAAf//4AAAAAqAAAAH/+E0AYAAAAf/80QIARv7AIAAACAEAAAgAAABUFA AABBQAEAgwAAAR//mPwEAAAIIAMNvAwAAACBgAAA//+//7////8f/5Ow//8AAP//AP/wAAAA/3// -/x/84uQAQAAAH/+o5AABAAAAAP//H/+xMB//lGAP///////QFB//Zswf/ODoIAdV/B//ZyQf/N4A +/x/84uQAQAAAH/+o5AABAAAAAP//H/+xMB//lGAP///////QFB//Zswf/ODoIAdWDB//ZyQf/N4A H/9mgP//wNAf/62kH/+fFAAACGjg//4A4QGSAB//mZAA////H/+dbB//rbQEQQAIBAEACMAAAADA BAAApQAAADAAAAAf/5vw4QP+AOEEbgAAAIWEAACFgCALc1AgC3QQIAtzkCALc9Af/64wAAAcYAAA -/4AgB1hwIAdT6CALdFDhAC4AH/+uJB//qUQf/68AH/+qcAAAFsAf/63w4AAAoOEAMLgAAIAA4QBg +/4AgB1iAIAdT+CALdFDhAC4AH/+uJB//qUQf/68AH/+qcAAAFsAf/63w4AAAoOEAMLgAAIAA4QBg EAAAQADhAwgA4QNIAOEDiADhA8gA4QAQCB/84UDhAHtwH/+0bB//tGQf/OAIH/+0aB//tIQf/7R8 H/+0gB//tJwf/7SUH/+0mB/84gAf/6yEH/+qWB//nWwgAdd8H/+u/AAA/4AAAB1AH/+TsB//sECB gAAABAAACIKAAACBAAAAIAMNsAwAAAAf/5mMH/+ZfB//nwz//7//v////wQBAAjDAAAAH/+xMB// @@ -139,7 +139,7 @@ ACBgAAAf/6wEH/+dfB//nXAgC4ugAAMHgCALjBAf/5tUACAAAABAAAAAAAkAAAAwAP/8+H+j/7sA o/+6AOADAACD/7YAD////w//+AD/AAAAD//+ASALjFAgCyxwIAssoCALjOAADwAAAAoAAP//AA8f /62IA//AAIP/wAAgC41gIAuN0B//rmAf/7HAH/+xoP9g8AAf/4BgH/+TcASAAAgARAAA/x///wDA AAABgMIAAACBAP+//////wAAAIAAAAAACWwf/OIMDwAAACALLOAf/638AAAIbB//rvQf/59oH/+Z -eB//gHAgB1RAAAAnEB//2DAgC5RQH/+uVB//nWTerb7vIAMIwDQAAAA/AAAAH/+uyACZAAAAAIkG +eB//gHAgB1RQAAAnEB//2DAgC5RQH/+uVB//nWTerb7vIAMIwDQAAAA/AAAAH/+uyACZAAAAAIkG EAAHAgHAgACZAAAAH/+xxACIAAiCgAABH/+xWB//r1AADwP/AxEAAAMVAAAgCzEAIAsxYCALMbAg CzIQIAsxMCAA+aAgCzOwIAsz4CALNDAgCzSQIAD/SCkAAAAgAQXoIAuUoCALlQAgC5VwH/+wZPDw 8PD/AP8AqqqqqszMzMwf/7PQAAAgIB//sdggARacIAuWACALlnAgBFyIH/+t4B//rkAACQAAAAAg @@ -147,19 +147,19 @@ AAAASACCAAAAIAE54CALlvAgC5dgIAAo7CALnDAgC5xgIAs6ECALOeAgCzogIAs6gCALOwAgCzpQ IAs6oCALOtAgCzygIAs88CALmnAgC5qQIAs9ICALPXAgC5swIAubUCALPNAgC5uAIAuawCALmvAg Cz2gIAueACALnpAgC50wIAudQCALnMAgC52gIAudACALnNAgC52AIAueECALndAgC55QAAAfQCAL QCAgC0BAIAtAYAAJAAgf/7DMMAAAAB//scwf/66gIAtCkCALQnD///f/IAtC8CAEYkQAAIP/IAda -KCAHWyAVoAAAH/+sEAAACAYAAA/+AACIzH8AAADwAAAAIAuh0AAMAAAf/7EYIAuh8CALoTAgC6GQ +OCAHWzAVoAAAH/+sEAAACAYAAA/+AACIzH8AAADwAAAAIAuh0AAMAAAf/7EYIAuh8CALoTAgC6GQ IAuiMCALoFAgC6DgAADgACALnsAgC59w//wAACALoLAf/5sIAAQD/woAAAAf/6/0MwAAAOEAAAAf /7IUA//gAH///wAAAP/+AD/2kB//sSAAAB9oA//wACALisAgC4qAIAuK4B//syAgC0NgH/+qtBoA -AAAgC0OwIAGTbB//sRwAD///H/+w0B//q9wf/66UIAuisB//rVQf/6ooH/+sHCAHU+Qf/6iwIAtG +AAAgC0OwIAGTbB//sRwAD///H/+w0B//q9wf/66UIAuisB//rVQf/6ooH/+sHCAHU/Qf/6iwIAtG sMAEAAAf/6woH/+xkB//sPggC6PAIAtG8B//q7DgAQAAH/+fECALpQAgC0cwIADEIB//nwggAMEo IAukgCALpNAf/5soIAtJEB//nxQgC1Ww4P/+ACALepAf/62YH/+VbCALYqAgC2MwH/+sDB//sNQg -B1hwIAtmUCALZqAgC2XgIAtmEEgAAAAgAdAwH/+rdCAB0jAf/6lEH/+Z7B//rDQf/6mcAAAXoAAA -FewgB1hcH/+qBOEAXgAf/6sUAE01oAAASLkf/5mQ4QAuAB//rEDhAwYA4QAOAOAFAAAD/wAAH/+p +B1iAIAtmUCALZqAgC2XgIAtmEEgAAAAgAdAwH/+rdCAB0jAf/6lEH/+Z7B//rDQf/6mcAAAXoAAA +FewgB1hsH/+qBOEAXgAf/6sUAE01oAAASLkf/5mQ4QAuAB//rEDhAwYA4QAOAOAFAAAD/wAAH/+p pCADDbwf/L//PAAAAAAH//+DAAAAH/+pTCAB9Bgf/65kIAt5sOAGAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAgYAAAAAAAAD/////////////////////H//8DB///Awf//vQH//70B//+9Af//vQH//0GB// -+Igf//awH//2sB//9rAgBx7gAAAAAAAAAAAAAAAAAAAAACAHIVAgByFQAAAAAAAAAAAAAAAAAAAA -ACAHHuAgBx7gH//5hB//+YQf//mEH//5hB//+YQf//mEAAAAACAB2JwAAAAAAAAAAAAAAAAAAAAA ++Igf//awH//2sB//9rAgBx7wAAAAAAAAAAAAAAAAAAAAACAHIWAgByFgAAAAAAAAAAAAAAAAAAAA +ACAHHvAgBx7wH//5hB//+YQf//mEH//5hB//+YQf//mEAAAAACAB2JwAAAAAAAAAAAAAAAAAAAAA AgEAAAAAAAAAAAAAAAAAAAQAAAAAAAAAgYAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -306,7 +306,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAACAKABHyZxPyZ9MPA+YxAQIAFvJlF/Jmd2sGkGC0Zndj+FQPCVXk -ZA8UAGP/+QAAAGwQCCggBSogBysxBfsWBCAUEEgw+gpBDgC8ShCLIhjyWPcKCSE7ALbgDKYRqGYs +aA8UAGP/+QAAAGwQCCggBSogBysxBfsWBCAUEEgw+gpBDgC8ShCLIhjyWPcKCSE7ALbgDKYRqGYs Yjr/AgAKALW/EBzyUitiOQysCizClwy7AfsWBSFcADbgLoJKGfJNZOEeKZJ/L4JJ+fsBDgCKz9Aq IBQKpIf6JBQqALmWoBvyRS4iFogVLCEpH/JEn4D5Ih4sACBzMP/MEQAGEFAw/IYDIAIQaDD9hgIp gAQ+YP3yOxgJAFZwmYGJFQALjfsSBCAgAkIwAAiKKDwQ/ZYGIEAQYDD8lgcgBBBgMPmcICoDAGbw @@ -549,15 +549,15 @@ WxDMEEgwCSkoqYgogOD4hwpiAAAgsMAg0Q8AAMDA1cAF5BYBAgDA0RrlUQErEaq6/aaBIMgQSDBt CBAuooIODkL44Qph/gJKcGSQhmP/6MAg9iCWYgAAGLD8poEgyBBIMG0IEC+igg8PQvTwCmH+Akpw ZJBlY//owCD2IKViAAAYsBnlPNMP/OU8GAAgTvAslosY5Toolov9poEgyBBIMG0IDyuiggsLQvix CWH+Akpwyp5j/+nAIPYgf2IAABiwwNItpoEsooEF5BZmMDLSMNEPAPP/em/7EBAw8/+bb/sQEDDz -/9Fv+xAQMPoKAiAIEFgw/OUjEgAAaTBZ1JNj/8bdQPzlIBACEFAw8w4GAAgQWDBZ1I3ApFh61tIw -0Q8AAAAA+goCIAgQWDD85RcSAABpMFnUhWP/jgAA+goCIAgQWDD85RISAABpMFnUf2P/dgAAbBAG +/9Fv+xAQMPoKAiAIEFgw/OUjEgAAaTBZ1Jdj/8bdQPzlIBACEFAw8w4GAAgQWDBZ1JHApFh61tIw +0Q8AAAAA+goCIAgQWDD85RcSAABpMFnUiWP/jgAA+goCIAgQWDD85RISAABpMFnUg2P/dgAAbBAG HeUOCysRrbMqMn8Z5QwX5N2IoMBA+XkIAAEQKDD0gDRoACBO8CwyeP8yeyYAWM8QZfEzLDZ8KzJ5 KzZ73UAN5BYBAgAkpgAN5BYsCgn/AgAGAFxkkC8ye8HA/eT5EG8AN+AiMnwqIQSOIPoLRgAeCBPw JDZ8JDZ7YAAEAAAuNnz9rwEB/gJC8Aj/Av8lBCAsAD7gIjJ8sMz/MnsgHgA0oMnGY/+/2iBYekhl oN8qIQT6CUYAEgDCsMiZ0Q8A2iBYejvRDwDaIFh5/tEPAPosAAAAEFgwWHq90Q8AAAD60ogh8AJw -sADhBPBbGg//EGAwDLsDC6oBKtaIWdatJDZ8JDZ7KjJ/Y/8zABbkzy9gXGTwilnJyFh5vChwwfXk +sADhBPBbGg//EGAwDLsDC6oBKtaIWdaxJDZ8JDZ7KjJ/Y/8zABbkzy9gXGTwilnJzFh5vChwwfXk yxBOAP4wKVB9/wIAAABIhmD/AgACAEiGYP8CAAQASYZgKVB9sZkpVH0rYFxkvwhYeajIqy1SILDd -/VYgIFgAN2BYeSNj/vAAAAAc5Ln+MnwgBRBQMPgyeiAEEFgw+BYAIfICaLBZ1BwqMn9j/qoAACky +/VYgIFgAN2BYeSNj/vAAAAAc5Ln+MnwgBRBQMPgyeiAEEFgw+BYAIfICaLBZ1CAqMn9j/qoAACky e/I2fC8mALZgIjZ70Q8b5K0rsq7/AgAB/7WG0CVkXGP/YABYeS0qViBj/6LAoFv/OWP/esChW/83 Y/9yAAAkVH1j/2oAAGwQBBTkn/nkmBuwBDyg+ORoFAAgIvAjQn+piPQwSWgAIELwijB4qQIqQnsc 5JArMQT6Rn8qAEBi8Po1BCIAAFDwWHnszq0pMQT5DUYAEADCcMjX0Q/aMFh54NEP2jBYeaPRDwAA @@ -576,7 +576,7 @@ ixAKDIYIDIYAS2sAS2nRD44RKE0B/RIAIQACQjAvhMcODoYMDoYATW8ATW3RDwAA+BIFIAEQWDD7 6wMAABBgMPz0xSrgAVwwK/TEC7sJ+LsKAAAQYDDz/w5qACA28AAAAgqGAAqGAEtjAEth0Q8AAGwQ BBjjdwIDRwwzEagzKzIgGeOEirEosAD5iAoKAAg4IAIKPiiCEAMCPv0KAiIAAGCwC4AAIjYg0Q8A AGwQBBjjaAIDRwwzEagzKzIgGeN1irEosAD5iAoKAAg4IAIKPiiCEAMCPv0KAiIAAGCwC4AAIjYg -0Q8AAGwQBFnOuRLjjBPjeQwCACkiggipjgOoCoiEC4AAY//rEuOuA+gwBO4wBbEwkyCUIZUiEuOq +0Q8AAGwQBFnOvRLjjBPjeQwCACkiggipjgOoCoiEC4AAY//rEuOuA+gwBO4wBbEwkyCUIZUiEuOq E+NbhCAEMwKTIBLjqMAwKDdAKDdEKDdIKDdMIz0BcjPtEuOjwDCTIMcvE+OiAyMDEuOhhCAENAGU IBLjoIQgBDQBlCAS456EIAQ0AZQgEuOdhCAENAGUIMcvwDEDIwMS45qEIAQ0AZQgY//8AAAAEuOX gyADExQPMxGTIBLjlMAwIyYAV//ZEOOTkQCSAZMClAMR45GCEAHqMKIRAfAxwEAE5BYAAgAR442C @@ -671,35 +671,35 @@ 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 @@ -713,18 +713,18 @@ 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 @@ -732,12 +732,12 @@ YjD50gIiAABQsPmGAiDAAlhw/dIAIAEQcDD9hgAgABBoMFv+7itdAi2wBRTao9MP+irgJAGoB2Au MrkPAgD85wpwDRBAMC9QJXjxJ/oSMCoAIFTw/AoAIAAQcDD5Cg8gEBBoMPosAAwFAFZwWUEMwCDR DwDA0P4KACIAAFCw+z0DICACEXD8LAABwAJa8FlBBAAEiwBCYQBCYQBCYQBCYQBCYcAg0Q8AAB3a hiMSMognidOM0YiO+9ICIEACUHCbopyhmaP82oAQAxBIMP3SACIAIETwKTa+LzK8LjK7KDK9/aYA -IAAQMDD9MrogMBBYMPgWACAFEFAwWcmiFdp1LT0DJhQ6JhQ5JhQ4JhQ3JhQ2JhQ1JhQ0JhQzJhQy +IAAQMDD9MrogMBBYMPgWACAFEFAwWcmmFdp1LT0DJhQ6JhQ5JhQ4JhQ3JhQ2JhQ1JhQ0JhQzJhQy +D0DIAIQUDD6FDEgARBIMPkUOyD/EFgwKxQw+xQ8IQACQjAvgHYugHcuFD8vFD4ogHX4FD0gYAJY cPmyAiCAAkBwmYKOsf+yAyHQAmtw/4YDIgAAULD+hgEiAABiMPuyACABEHAw+4YAIEACWHBY6eos Mr/7CmQiAABQsPzMASIAAGkw/Da/IgAAYXBZRdH6NsAgABAQMNEPAB3aQyMSMognidOM0YiO+9IC IEACUHCbopyhmaP82j0QAxBIMP3SACIAIETwKTa+LzK8LjK7KDK9naD9MrogMBBYMPgWACAFEFAw -WclgKz0D+toxEQACWvAtsHcssHYsFD4tFD+JoIihj6IrsHX7FD0g/gJwcPqiAyAiAnOwmOGf4vnm +WclkKz0D+toxEQACWvAtsHcssHYsFD4tFD+JoIihj6IrsHX7FD0g/gJwcPqiAyAiAnOwmOGf4vnm ACACEHgw/xQxIAEQSDD5FDsgABBAMCgUOigUOSgUOCgUNygUNigUNSgUNCgUM5rj+BQyIP8QcDAu FDz+FDAgYAJwcIji+eIBIIACeHAp9gEo9gIq4gAq9gAu4gP+9gMiAABQsFjMuioWKCwWKv0WKyD+ AmBw+xYpIEICazCP0YXQ/tICIGICWzCespWwn7ElPQP/WQoiAABQsP3SAyAiAmMw/bYDIAEQcDD/ @@ -751,35 +751,35 @@ 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 @@ -816,60 +816,60 @@ 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 @@ -877,24 +877,24 @@ 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 @@ -912,13 +912,13 @@ KyISLPp/DLsB+yYSIAAQEDDRDx7Q8S0iEg7dAi0mEmP/yADaIFhrqPzQhh4AADagYAAmiF4Z0OSx iPhWDigJAEowKEQzCIgUKEQyCIgUKEQxCIgUKEQwY/8/wCDRDwAA+2wYIgAAULD8CgEgBRBoMFhr 0sAg0Q8A+2wSIgAAULD8CgEgABBoMFhrzMAg0Q8AbBAOJBYRJzAPKDAOhSf5MA0gAhBgMPwUISAB EFgwKxQr+RQtIP8QMDAmFCD2FCwgABBwMC4UIi4UIy4UJC4UJS4UJi4UJy4UKC4UKS4UKoVeKBQu -JxQv91LeIEACaHCI04vS/NIBIGACSHCckZuSKJYD/dIAIgAAUTD9lgAiAAAw8Fm71lm7zBzQsY8y -jjGNMPgyAyIAACKw+xYSIAUQUDD4FgAgMBBYMFm/jfpcAAIAAFjw/AoAIAEQaDBZOGJloJJkcOpo -cFP7EhIiAABRMP3QUxAAEGAwWcALe3s9HNCcLlLaL1LbKlLc+hYAIgAAafD5Ut0gMBBYMPkWASAF -EFAwWb93G9BDKV0D8AsHAMACSnAASWEASWFgADgc0I4mXQMtUtouUtsvUtwrUt2bEIowmhGJMZkS -iDL4FgMg0AIxsPgyAyAwEFgw+BYEIAUQUDBZv2PNaMAgx+/6CgUgMBBYMPzQfRIAAGiwWb9d0Q8A +JxQv91LeIEACaHCI04vS/NIBIGACSHCckZuSKJYD/dIAIgAAUTD9lgAiAAAw8Fm72lm70BzQsY8y +jjGNMPgyAyIAACKw+xYSIAUQUDD4FgAgMBBYMFm/kfpcAAIAAFjw/AoAIAEQaDBZOGJloJJkcOpo +cFP7EhIiAABRMP3QUxAAEGAwWcAPe3s9HNCcLlLaL1LbKlLc+hYAIgAAafD5Ut0gMBBYMPkWASAF +EFAwWb97G9BDKV0D8AsHAMACSnAASWEASWFgADgc0I4mXQMtUtouUtsvUtwrUt2bEIowmhGJMZkS +iDL4FgMg0AIxsPgyAyAwEFgw+BYEIAUQUDBZv2fNaMAgx+/6CgUgMBBYMPzQfRIAAGiwWb9h0Q8A wKDyFhAiAABZsFjf59Og8qwAAA4ANqAuMRBj/8wAAAAAKhIQ+xIRIgAAabD+CgAgYAJgcFjfumU/ -3GP/qgAA/SIAIAUQUDD80GkQMBBYMFm/R2P/kAAAbBAELCIUKyIT/c/3EuABLDD8uwwCDgA44GSw +3GP/qgAA/SIAIAUQUDD80GkQMBBYMFm/S2P/kAAAbBAELCIUKyIT/c/3EuABLDD8uwwCDgA44GSw fiwgBwwMQQzKEf/P8RoAIGqwLaI6D88K//KXItYBO2AuojkY0BIZz/T/7QEOAC1/kC4hBw4OSv/Q UR/ABDug/M/wHgkAS7Ce0P4iACgJAELw+NYFIAgQSDCZ0/zWAiACEEgw+OwRDgkAe7D+1gQsCQBL MJzRKaY5KCIUq4goJhRpMg7AINEPjyLK8GgyNMAg0Q+KJ/sKASAAEGAw+qwgIAEQaDBYYtrSoNEP @@ -928,8 +928,8 @@ Gc/fmaCIIMCR8tAWGYAEOiDypgIoCQBKMPimASAAEBAw0Q8AAAAAAGwQBi8iGC/wdCgKjnjxdigg BfnQDBBwADYgGNAJJCISCEQBJCYSjTkrMQv+IhEoAEDqUCkiE6uZ+SYTIgBSZRBk4MSK7H2nPYjr +uwAAAAQWDD8CgAgAhBoMAuAACsiFCoiExnP+QuqDCutQPzP+BoAEF5Q+sMYcAAQSDD5JhEiAAAS cNEPwCDRDwAAAAAAAPosAAAAEFgw/AoAIAIQaDBb/3/AkPkmESIAABJw0Q8A/M/oEAIQUDD+IgAg -MBBYMFm+vSoiEC2gBS4KlX7RtsDy/yRkIAEQWDBY51bAINEPHM/djeD+4AUgBRBQMPQWACAwEFgw -Wb6wKCISKfq/CYgBKCYSY/9VANogWOSdY/9MbBAILiIYLeB0KAqOeNENKSAFGM/N9c/NEAkAtmDA +MBBYMFm+wSoiEC2gBS4KlX7RtsDy/yRkIAEQWDBY51bAINEPHM/djeD+4AUgBRBQMPQWACAwEFgw +Wb60KCISKfq/CYgBKCYSY/9VANogWOSdY/9MbBAILiIYLeB0KAqOeNENKSAFGM/N9c/NEAkAtmDA INEPACQiEvkiESQJAEEw9CYSIH4AtTCKLIk2JjAgLzEK+Pr8IIsQYDD2C0UAlARScCoiECugBSwK lXyxwcDS/SRkIAEQWDBY5y/AINEPAAAAAPSRvmBAAlDwiZeJnvmcMCAGEFgwwCBtuQUACoYASWHR DwAAAAAPD07//AMgMRA4MPj/AQYBPmdQ/6gIACUQYDD6IhAgIRBoMPgmDCQJACkw9CYSICoEavB8 @@ -949,13 +949,13 @@ gAQ7oA/uAv8wJy+ABDugCO4CCO4RD+4CZeHXKzBMLDBN/TBOK4AEPuAMuwL8ME8rgAQ+4A27Agi7 EfoiECoJAGbwZLyXLKIY/wIAC/5I3xArVhIuMEgvMEn4MEovgAQ7oA/uAv8wSy+ABDugCO4CCO4R D+4CLlYULTA0LjA1wID5MDYtgAQ/YP/O1hwJAHdw/jA3LYAEP2D4VhUsCQBPcPhWEy2ABD9g/1YL LAkAd3CdXWP95ygwOCkwOfowOimABDogCYgC+TA7KYAEOiAKiAIIiBEJiAL/zsQQAgJCMCgmFp9b -Y/21jxUczsD9UgAgBRBQMPQWACAwEFgwWb2NLSISxOAO3QItJhItMD4sMDwrMEAuMD0vMEH4uxEN +Y/21jxUczsD9UgAgBRBQMPQWACAwEFgwWb2RLSISxOAO3QItJhItMD4sMDwrMEAuMD0vMEH4uxEN gAQ7IP4wPywJAHMw/zBCKgkAfvD4uxENgAQ7IP0wQywJAGswD7sC+MwRC4AEPuD+zAIKCQBu8Ay5 DPoiECH9pqJgLaISfNEIDc8MZvACLKYSLKIT/wIAB/2Z3xAMuAxmiyj7phMgABAQMNEPAADz/Blv -/xAoMPzOlxIAAGuw/lIAIAIQUDD2FgAgMBBYMFm9YWP7KAAAKjA4KzA5/DA6K4AEOqALqgL7MDsr +/xAoMPzOlxIAAGuw/lIAIAIQUDD2FgAgMBBYMFm9ZWP7KAAAKjA4KzA5/DA6K4AEOqALqgL7MDsr gAQ6oAyqAgiqEQuqAvnOhxACAlKwKiYWmVtj/L3AsCsmEfP8tWIAACuwACoiEGP64wAAbBAGKiIH JCAHKKkUBQtH9aIOJCABIDDzogkilQA2IP8CAAIBUprg/M51EgAAeLD4IgAgARBIMP6iAiH8Amrw -+goFIDAQWDD4FgAsBQBucFm9OhzOa/0wACAFEFAw/iBQIDAQWDBZvTQdzegMTBH/zeccACBrMCrC ++goFIDAQWDD4FgAsBQBucFm9PhzOa/0wACAFEFAw/iBQIDAQWDBZvTgdzegMTBH/zeccACBrMCrC Og9PCv/ylyQBIEKgLsI5/+oBDgEa/5ApIEAtIAcUzen2zlsQAQ4GYP8CAAIBAAJg+woAJAD8BiAp IQcoIQgezen9L0AJQAFMMPr/EAnABD5g/Q1BCAkAfnDw3REICQB2cPmmACgJAGow/iIAKAkAMjD4 pgQgBBBoMPamBiAwEHgw/6YDIEACSrD0pgIgAhB4MPjuEQAAECAw9KYFLgkAa7D+pgEvgAQ64PSm @@ -976,7 +976,7 @@ BSBWAH4wKyISLjIqC4pE+qoPAAAQYDD+qgoAARBoMPqiACvwAVwwWF+QJCYSiCeLIPn6wCBAAnow 9CYMLgBAT/D0hRQggAJ78J+Jn4guUnP6MhUgABBgMP67DAABEGgwWF+BKjIWsKr6NhYgABAQMNEP AAAAAAAA8/6TYAAQMDArIEAIuxCbYGP+i4ieLYAEK4AF+oAGLYAEP2AL3QL4gActgAQ/YPPNMRwJ AFdwCN0RCN0CA90BI9xn80MUAIkQWDDz/mdgCAIY8AAAAAAAAPP+eGAAEEgwj2D9PAACAABQsP7N -SR74AXww/yRAIDACWzD+ZgAgARBgMFhoIMAg0Q8ALNxI+9xnIgAAcLD7SxQCAAB5sFm74C4gB4sQ +SR74AXww/yRAIDACWzD+ZgAgARBgMFhoIMAg0Q8ALNxI+9xnIgAAcLD7SxQCAAB5sFm75C4gB4sQ 8/47bCABcDAAAABsEASJJy0gByMhByiZFA0LQf6SCSNAARww9IFLY8AEPOD/zK0Y4AEsMPy8EQIA thpg+cyqHAAgezAqwjoJuQr5kpckAJbCoCjCOR/MsPmKAQ4Aj84Q+My1GAIBbDAKmRAJMwIIMwKT oIggw5D/pgIgBBAYMPmmAymABDog+c0WGAkAGjCYoS8gQfghCCAAECAw9KYFIAAQaDD0pgchCwC3 @@ -988,15 +988,15 @@ QCABEGAw/+YAIAQQaDBYZ7DAINEPKSBACJkQmeBj/owAAAAA8/71YIkQaDBsEASKKo6vGMzM+CYL IEACSLD55gAgcAJ6sP8mCCIAAFiw/iYJIAAQYDD5pg8vmBBAMPgkBSACEGgwWGfmwCDRDwAAAGwQ BBvMvSoxDNMPK7J/HMya+TAQIBYQIDD7ox9wABAoMHyhF/osAAIAAFlw/DwAAgAAaTBY43PAINEP AGiRQWiSIWiUCcBA8//ZYAAQKDB8odF7q87aMFjjoNWg8//EYAAQIDD8oQdwFhAgMHujAmAAAcBA -2jBY47fz/6dgABAoMNowWOPJ9awAACIANqD8zJsQBRBQMP0yASAwEFgwWbtd8/9/YAAQIDAAAADz +2jBY47fz/6dgABAoMNowWOPJ9awAACIANqD8zJsQBRBQMP0yASAwEFgwWbth8/9/YAAQIDAAAADz /3RgDBAgMGwQBCkwE/SQa2D4ECgwaJEDwCDRD4Qn0w8PAgCEThzMiy0wEShNBClNAy2U/P4wEiAF -EFAw/oTdIDAQWDBZu0j6TQQgMAJY8PwwESH6AlKwWOPX+k0FKgAgLPD8MBIhvAJSsFjj0/osAAIA -AFkwWOVTwCDRD4QnDwIAhE4czHUtMBEtRAL+MBIgBRBQMP5EAyAwEFgwWbsy+k0CIDACWPD8MBEh +EFAw/oTdIDAQWDBZu0z6TQQgMAJY8PwwESH6AlKwWOPX+k0FKgAgLPD8MBIhvAJSsFjj0/osAAIA +AFkwWOVTwCDRD4QnDwIAhE4czHUtMBEtRAL+MBIgBRBQMP5EAyAwEFgwWbs2+k0CIDACWPD8MBEh kAJSsFjjwfpNAyoAICzw/DASIVACUrBY473AINEPAABsEATzixQAQBBQMPUtAyAAEEgw81RXIAcQ QDArVFYqVFIpVFP4VFQgQxAgMCRUVdEPAAAAbBAEjzj8zFUQBRBQMP0wECAwEFgw/+9RAgAAc/BZ -uxIpMBD6zE8QSAA+YGiSWWmUEog2IqJ/CYgRqCIoIAUpCpV5gV7AINEPAAAA2jBY5ff5Cgcv8AA2 +uxYpMBD6zE8QSAA+YGiSWWmUEog2IqJ/CYgRqCIoIAUpCpV5gV7AINEPAAAA2jBY5ff5Cgcv8AA2 oIuni74sso4MnVb8flgOAA1uUMDTftAQ+70CIAAQYDBY5cLAINEPAABY5RDAINEPAIs2KqJ/CbsR -+woAKgAgWrBY5JTAINEPAAAAAMCl/MwvEDAQWDBZuu76LAAAAhBYMFjjisAg0Q8AbBAEiC4jLDhz ++woAKgAgWrBY5JTAINEPAAAAAMCl/MwvEDAQWDBZuvL6LAAAAhBYMFjjisAg0Q8AbBAEiC4jLDhz iQXAINEPAACLLoiz/EwAAgAAaXD7vOAiAABQsAuAAIwi/SAFL90AtyBk39WOLnPp1mP/zQAAAGwQ FiUWFysgBxrMFyMWGYg09zIFIgAASTD5FgwiAABw8P7hDyABEBgwkx/6oX4sCwFAMPwWGiogAVww KxYW+MUUCg8BdDArFhMKWgz7Ehkr4AFQMCoWFCoSFy2wHfyxPSP/EBgw/BYSJh8BPDD9FAAkCgFA @@ -1007,7 +1007,7 @@ txCUGgZFFPAASWACAilwKBISZIc8KRIZiZV9lqIrEhIsEhD9HAAAARBQMPoWESIAAFFwWOioZqdw CizClwy7Ad6w9rwAB6UANuAt8kpk13gdy78o8kkp0mOMHPmLAQ4DtU4QKiAUnhcKrIf6JBQsA8qS oC0SGigSFP8KAyAMADdg/wIACAPSQ9BkMH+JGg8CAA8CAMiRZDBg+2wAAgAAULD8CgMgGBBoMFjo q44e/xILJgUANOAdy1v7EhMgABBAMJiimKP4pgQtAAQ7oPimBSogBD7g/f0CCgkAZvD9pgAtsAQ4 -4PzLmxoJAGbwm6H6CgUgHBBYMFm6VCkSFf8CAAIDhZpgwCAlRjnRDyoSEWSgc/sSByIAAFCw/AoD +4PzLmxoJAGbwm6H6CgUgHBBYMFm6WCkSFf8CAAIDhZpgwCAlRjnRDyoSEWSgc/sSByIAAFCw/AoD IBgQaDBY6I0rEAAWy4kfy4qOGyZinBnLW/sfFA4JAHuw9rYLDsAEP+D5/wIARAB+8CwSECtt/y0S EiiyPyuxfZ6gn6Gdopyjm6SYpWAAFiwSEC0SEithBYhjnqCfoZuimKOdpJylJqwYLRITjB4C3RD9 FggtAAQ7IPwWCSVHALXgGsshiBsvCgD/FgUgAhB4MP8WBigJAFIwKBYN+2wAAgAAULD8CgMgGBBo @@ -1033,11 +1033,11 @@ IhIhY/6AACgSGiwSGBvKaGSAY/yZAg//EHAw9HAhaAkAXnCZoZSgnqKeo56k/qYFIAAQaDCdpp2n naidqWP+Ri4SGSIWIS3iEiziEyviGIjthu4v4hSC7y7iEZ6inaOcpJulmKaWp5+pmaGSqJSgIhIh Y/4RAAArEhvH3/uZAgAAEGAw9HAbaAkAHnCZoZSgnaKdo52knaWcppynnKicqWP945mhlKCOE/8S ASAAEEAwmKKYo5ikmKaYp5ion6WeqWP9wioSGRnKO9MPiqUjEiAlEh/0Eh4gDgBOsGRweBzKNosb -DLsCK5b6Y/nUgx/A0vP592IFAD9wAMCl/MovEBwQWDD+XhECAABpcFm43GP4nAAAAAAA+hIUIAAQ +DLsCK5b6Y/nUgx/A0vP592IFAD9wAMCl/MovEBwQWDD+XhECAABpcFm44GP4nAAAAAAA+hIUIAAQ cDCeEZ4SnhOeFFjl0CQWHiUWH/MWICw0ADag+hIUIAAQWDBY5cIkFh4lFh8jFiBj/BgvEhBl+Lxj +GQayfGIGwqIAiiW+mP5WwAAAFjlxcipG8oU0w8rsIBksF0qEhRY5bv5Eh0rzAC2oPoSFCABEFgw WOWuKRIdY/u2AAAAAAAAAPP4MWAwEDAw+xISIgAAUXD8EhAiAABocFjmpWP4eAAAKxIZjBz9Ehci -AABQsFhhhNKg0Q8AAAAA+sn7EUEQWDBZjab7GkEhABBgMPrJ9hwJAGKwWY2mY/+AAAAAAAAAAPos +AABQsFhhhNKg0Q8AAAAA+sn7EUEQWDBZjar7GkEhABBgMPrJ9hwJAGKwWY2qY/+AAAAAAAAAAPos AAAcEFgw/AoAIAEQaDBYZK5j/6kAAPP4W2AAEFgwAAArEhb6LAAAABBgMPu8GCIAAGlwWGSlY/+E 2iBb4iZj+GaKJ40cwMD6rCAiAABbcFhcT9KgJUY50Q8AAAAAAPP4X2AEEBgwbBAEFMm5giAkQn8T ydUEIgwDIgLRDwAAbBAMGMmpKYKAKoJ3KI3mKIDBCaoR/4cPeAAgVnAknQHwAAphAAIhMCSdAyRM @@ -1046,7 +1046,7 @@ gBnJjShBKf8CAAYAf04QGsk+8AoHAgAASHAASWEASWEASWEASWEYyZ4fyb6OIBvJvPsWAiAEEFAw /RYJKgkAZvD7FggiAEuE4IlHKJkU9ICAYEACYnCNmSvCAP76wCAoECgw9NBDbgBAczBtCDB9sTgv 0AD50AcgZAQr8C/BBf74CAnABD5g+IxALAAgT3D42w9yAABTcP2sAAAPADagY//ID9oMY//uAAD9 ugwAABBIMAqdOPbcAAA0ALdg+kwAAgAAWHD8CgQgAhBoMFhXiNEP8/+CYAAQaDAAACocOvwKBiB0 -AliwWa8wY/9bwnaOaPoKBSAwEFgw/Ml+EgAAabD/IDkuYAFwMFm4JIpoCo9Xd/FtikcuoRX7+sAg +AliwWa80Y/9bwnaOaPoKBSAwEFgw/Ml+EgAAabD/IDkuYAFwMFm4KIpoCo9Xd/FtikcuoRX7+sAg QAJSsAurAavr/WxAKAA23ZD/ogAgMAA3YH3xKCzQANMPDwIAdcEdKdAHDJkR+d0IAIACQvD42yRy AABTcP2sAA/YALag/fsMAAAQUDALrTj23AAPTAA3YGP/dgAADtoMY//ZAAAsIDkKDUN9yYiOIAju EQ4+Ap5r0Q8O3Qxj/5AAAAAAAGwQBBjJVCmCfyowBy2RAi6RBCyRBfuSACEbADdg/9z/If4Cc7D8 @@ -1054,26 +1054,26 @@ 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 @@ -1131,7 +1131,7 @@ EO4AdjArIAcLC0H9xF0TwAQ+4KQzKTI6Db0KhCD90pckuAE6YCwyOf3KAQ4AKO8Q20BY/bzAwf0K ACABEHAw+MUPEAAQSDD5FgEgABB4MPkWAiIAAFqw+BYAIgAAUTBYWm8lNjkqIHArCvsLqgH6JHAg ABAQMNEPwCDRDwD7vBgiAABQsPwKASAEEGgwWF+axyTRDwBsEAQrIAcYxDgUxPgLC0H9xDcTwAQ+ 4PRCfyIAIETwKDI6Db0KLdKX/oJMZAAgWTAsMjn9ygEOACDvENtA/AoAIAIQaDD+CgIgEBB4MFmx -csCx+MTnGYAEPSD4pgAoCQBecJmhjyCfosDi/jY5IAAQEDDRDwAAAAD7vBgiAABQsPwKASACEGgw +dsCx+MTnGYAEPSD4pgAoCQBecJmhjyCfosDi/jY5IAAQEDDRDwAAAAD7vBgiAABQsPwKASACEGgw WF92xyTRDwBsEBT+MBAgBxA4MP/EIBABEGAw+sQREAAQMDD9ChgiPAA3oP8CAAAEMYegaOIDwCDR DysgBwUJR/kWGCogAVww+xYZIjQCOmAuIAX/AgAIBavDoCggcv8CAAIFpnoQ2iBYXHz/AgACBASq oIsiZbf/KiEajDUtIhD/Igkp8AQ+oPsWBCoACmJQDwlCyJkKC0L/AgAABU4q4C4SGfnD7xAYEFAw @@ -1160,7 +1160,7 @@ AEfw8/8CAAEQYDDzEh0uCQB7sPzuEQAEEHgw/woALgkAe7D+FgIgABBwMFhY38DB/8OAEgAAWrD6 IgAkABBIMPkWACAAEGgw+RYCIAAQQDD4FgEgARBwMFhY0ywSEv0SECIAAFqw+iIAL/8QQDCYEC4h JP8hJS0AAWww/AxIDXAEP2ANzALw/xEAABBoMPwWAi4JAHuw/AoBL/8QeDD+FgEgGhBwMFhYwNug +iIAL/8QYDD8FgAgABBIMCkWASghIikhCcDQ8IgRABwQcDD4mQIP/xB4MPkWAiABEGAwWFiyKhYT -KiEoWbDR/cNOEgAAYrD6IgAv/xBwMC4WAC4SES3QLBvDTP7dAgH+AmMw8ukQDBAEP2D5zBEICQBu +KiEoWbDV/cNOEgAAYrD6IgAv/xBwMC4WAC4SES3QLBvDTP7dAgH+AmMw8ukQDBAEP2D5zBEICQBu cAyZAguZAikWASgiFRnDQ//6/yAeEHAw+GgUAAAQaDD7EhMoCQBKMPgWAiABEGAwWFiW/AoBIgAA WrD6IgAgABBAMPgWACAAEGgw+BYBIAAQcDD4FgIgARB4MFhYi4kw/wIAAgFLqlAZwtYqEhUuIQcf wyUnpjknkmiJIIggLSAHKvL7/CAMJgAgRfD7IA0nkAQ94PggFSoAIDqwKhYULqUHLaQHLKQMK6QN @@ -1174,7 +1174,7 @@ DwD6LAACAABY8PxMAAIAAGlwWFoZ0qDRDwAAAAULR/sWGCI0AjrgKyAFwcT/AgAGANhm0G64ci0g cn7fbNogWFppZaB0jiJl4G8oIBSkiCgkFI8wevZSKiAHGMHkCgpBDKcRqHcpcjr/AgAEAbNCYB3C oSxyOQ2tCi3Sr/3LAQ4BqW8QLyBxAzwC/grqIgAAULD/5jkCAABpMP8KASIAAHGwWFomwIQodjkp Ehj/AgACAYMaYMAg0Q8A+iwAAgAAWPD8TAACAABpcFhZ69Kg0Q8A/MKTEAQQUDD9IgAgKhBYMFmx -DR/Bzi4hGvP59WABEGAwAAAAAAAAAPw8AAIAAGkw/goAIgAAWrD/CgEiAABQsFhaCvP9TmAIAjnw +ER/Bzi4hGvP59WABEGAwAAAAAAAAAPw8AAIAAGkw/goAIgAAWrD/CgEiAABQsFhaCvP9TmAIAjnw KxIbHcKBLhIZH8J/LdCAAOEE8McaAAMQcDD+9IAu4AE8MP34M3IAAHNwx5/4wngYEQBP8PkSGSwA QE9wCJkKGMI9KJaXGcJxDX0CDQ1H/ZSAIWwAN6Bk0W/B8/8WBSABEHAw/hYRIAAQaDAtFhDz+p1g FRA4MAAAAAAAAADz/fVgBhBgMMSAmB9j/Z4AiR74IHEiAABg8PosAAIAAGkw/grqIAEQeDD45jkJ @@ -1193,11 +1193,11 @@ wP0pkn+OK/CRBAH+AkNw8IgaAAEQeDAA/xr//P8uACBDsA/uAp4q+6wfIAEQYDD9CgAiAABQsFhc PGP7iQAAbBAEGMFRiSArgmj4goAgEBBgMPwkBSgAIF5w+ZkRAAAQWDD7JBQoACBKMPuEFCIAAFCw W9wy0Q9sEAQZwVeKMimSfwmqEaqZLJAG+JICIAAQWDD9+v4gCxBwMP6UBSH+AmMw/JQGKABAajD4 lgIiAABScFvcIsAg0Q8AAGwQBogiLyAHhzCVEvQWAy4gAXww9YHuZuABPDD/FgEhJAA14Pt8ASIA -AFCwWayE9qG2YgAAIrD2PAAPjRAoMPIWACDUADXgB3IJ9zwQI8AEOKDwACFiACAYsAAAAGmBCIoQ +AFCwWayI9qG2YgAAIrD2PAAPjRAoMPIWACDUADXgB3IJ9zwQI8AEOKDwACFiACAYsAAAAGmBCIoQ i2VY+k7UoGZA3yZsMPd8MCYAUhWQKGAQyI5ogURpgukoYBFlj9RgAHMAKGARyIxogSBnT9R1QdFg AK4AAIoQ+2IFIgAAYfBY+ofz/+RiAAAisACKEItlWPp+8//UYgAAIrAoYBHIjGiBIGdPnHVBmWAA dgAAihD7YgUiAABh8Fj6efP/5GIAACKwAIoQi2VY+nDz/9RiAAAisAAAAIoQ+2IFIgAAYfBY+irz -/1liAAAisAAAAIoQ/Ar9IAAQWDBZrYr8EgIiAAAisPb6ACYAd66QiDAGiAGYMGAADQAAAAAAAPIW +/1liAAAisAAAAIoQ/Ar9IAAQWDBZrY78EgIiAAAisPb6ACYAd66QiDAGiAGYMGAADQAAAAAAAPIW ACAAECAwiREYwGkMlxH8wGkWACBF8CpyOoIQDJwK/MKXJACpQqArcjkMuwH1vAABTgA24C2CSv/A dREjADdgLoJJL/J/iRP/6wEOAIn/kCggFAiJh/gkFCwAnpIg+1wAAgAAYPD6LAAO4AEgMP0SAyAB EHgwWFijihL6CkcABBBYMPt2OSIyADqgiieNE8DA+qwgIgAAW3BYU1XSoNEPwCDRD8e08hYAL/+u @@ -1220,8 +1220,8 @@ TmEB+ouPSS8WFI5NLhYViEwoFhYvQgv/FhcgwAJwcABOYQBOYSsWISsWIisWIy0WLSkWLCwWUyhS SSpSSCoWHygWICv6/ysWI/sWIiBgAlBw+xYhIMACWHBY+aMvUXkPAgAPAgD2rAAIByR+kC9RhH+i DShRhQ+ICP8CAAwHGkKQWPne9vr0IAdnKqDaIFj5tiVRhKWl8xYnIAdyrWAev7kYv50v4mYsEiYu 4oDzQhguACB9cPdCGS+QBD/g/+4IAAEQaDAt5RovQSslxgEvFkEcwAwmQhorQhcpQhYuQhQpFkQr -FkP5FgIoAEBDsCgWRfgWAyIAAGlw+xYBKngBcDD6FkIgABBYMPoWAC58AXAw/hYqIAUQUDBZrnDA -pfy/+xAAEFgw+L/4HuABFDD/FkYiAABo8P8WACIAAHHw+BYBIgAAebBZrmXAkf4KACCAEGAw/HwB +FkP5FgIoAEBDsCgWRfgWAyIAAGlw+xYBKngBcDD6FkIgABBYMPoWAC58AXAw/hYqIAUQUDBZrnTA +pfy/+xAAEFgw+L/4HuABFDD/FkYiAABo8P8WACIAAHHw+BYBIgAAebBZrmnAkf4KACCAEGAw/HwB AgAAW7D8nDkKBQBecPwSKioJAGbw/woCIgU1AyApFjUiFiv9Cgoh+gJDMPjcOAAAEEAw+BY0IAAQ aDAtFjMZv2Dyv94QARBoMPk5AQAAEFAw+to5CAUAT3DwhAQICQBWcPc9GAAFHSpgA3pTKhY2/wIA AAS5pZAGWlD6FkcoFAEwMPgWSCIElDGQKCIxCIhB+BZJIASS0ZAGyUH5FkoiBJw1kCoiMQoqQfkK @@ -1263,7 +1263,7 @@ KuY1+eY2IAICe/D+hAZgARBIMMCQKBJQCJkRApkC+b3tGAkASjAu7EDyHGAoCQBKMPjmJyIAAEjw IADTwlAYvWIevcKdcImw/HYCIAgQUDCac/52BSACEFAw+FgCCYAEPmD4dgQoCQBWcJlx8AYXADAC SfAACYrzPAIgQAI58I9A0w8PAgD/AgAAANOr0CkgAQCZMoUhACQELkIZLUIY/EIaKuABSDAqFi8O 3Rj8BkkMIAFsMP0WLiAYADagL0IUGb0xD8hT+Iz+LgBAT/AI9Tj7sgAiAABR8P0KASwaAWAw/goE -IDAQeDBZqhcdvOQrEi78Ei8gBBBIMPANBwIAAGqwAE1hAE1hAE1hHr1CAL0R+L2jHAkAbbD4pgIs +IDAQeDBZqhsdvOQrEi78Ei8gBBBIMPANBwIAAGqwAE1hAE1hAE1hHr1CAL0R+L2jHAkAbbD4pgIs CQB3cP2mACAQAnkw8Q8WACACcrAADoqVpihCFAwNBv2kHSh8AUAw+KQcIAgCcPAvEicu9jn5JAAg ABAQMNEPAAAoIi4ImFAoFkjAkPkWRyH7cDGQBgpR+hZJI/tx0ZAoIjH4CkACAABLsPgYQAgFAFfw CYgC+BZKIftoNZDz9s5qLgEwMAAAAAAAAAD5CgEgABBAMPIWVCpgAWgw+qz/IAAQEDD6mDgAABBQ @@ -1283,15 +1283,15 @@ MP+82hAcEHAwWFIdwMH9CgAgHhBwMP+82BAAEEgw+RYBL/8QQDD5FgIiAABasPgWACIAAFFwWFIR 4AQ6IPgWAS//EHgwWFH/wMH9CgAgHBBwMP/6/yAAEEgw+RYBL/8QQDD5FgIiAABasPgWACIAAFFw WFH0wMH9CgAgHhBwMP/6/yAAEEgw+RYBL/8QQDD5FgIiAABasPgWACIAAFFwWFHp8/ksYgAASrCL SS1BFv5BFyDuADSgHLyiKUIRKkIOL0INKEISJhYJKBYDKxYIKhYH+RYBIAUQUDD/FgUgABBIMPkW -ACAAEHgw/xYEIAAQWDD7FgYgABBAMPgWAiAoEFgwWar08xYnIfi4raAiEib7ElMvnhBQMPokAS+e +ACAAEHgw/xYEIAAQWDD7FgYgABBAMPgWAiAoEFgwWar48xYnIfi4raAiEib7ElMvnhBQMPokAS+e EEgw8/r8YAAQGDAAAAAAAPPwGGAAEEgw+swAADACW3D8CgAgShBoMFhW9sck0Q8AAAAiEib8vHwQ -BRBQMPMWJyAYEFgwWarcKxJT9iQBL/QQSDDz+qxgABAYMCISJvy8cxAFEFAw8xYnIBgQWDBZqtIr -ElP2JAEv9BBIMPP6g2AAEBgwHLxriEyPTZYS+xYBIAUQUDD4FgAgKBBYMFmqxv8CAAH4XK2gIxYn +BRBQMPMWJyAYEFgwWargKxJT9iQBL/QQSDDz+qxgABAYMCISJvy8cxAFEFAw8xYnIBgQWDBZqtYr +ElP2JAEv9BBIMPP6g2AAEBgwHLxriEyPTZYS+xYBIAUQUDD4FgAgKBBYMFmqyv8CAAH4XK2gIxYn Y/9BAABsEAosIAcYu3QMDEEMxhH+u3MWACBBsChiOsDT/s4KABUQSDD+4pcqAWhOECtiOQ67Afq8 AALKADbgKzADF7wy/LvBEtQAtuAlQhQFiFP4FgcufAEsMPxVAQIAxIfgwFAtQSobu2j5u2kQAhBw MPi7xhAAi0NQjzGboI0gl6X5pgIuCQBH8P+mBC2ABD9g+btbHAkAd3D9pgEgCBBoMJ2j8AkXADAC SrDyGR4AQAJSsLJVjkD/AgAAAIwrkCkwAQCZMgAkBC1CGidCGf9CGCrgAUww+xYKLyABaDCeGAf/ -GPcyAS4gAXww/xYJIBUANuAoQhQIyVP8iAEB/AJKcAmHOIsg/axQAAQQcDD/CjAgARBoMFmofYkY +GPcyAS4gAXww/xYJIBUANuAoQhQIyVP8iAEB/AJKcAmHOIsg/axQAAQQcDD/CjAgARBoMFmogYkY jBodu0iLGRi7rfANBwIAAGqwAE1hAE1hAE1hALIR/7wJEgkAEnD/pgIiCQBAsPKmACAQAnEw8Q4W ACACarAADYqXpiJCFAwIBvikHSJ8ARAw8qQcIAgCeXD/ZjkgBBBwMP40ACAAEBAw0Q8AAAAAAP+7 aBH/k0dQKEIajTGboIcg+aYCLAkAf3CdpJilmKf4dxEAEBBAMPimAyYJAHXw96YBIAAQODD3pgYg @@ -1308,24 +1308,24 @@ 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 @@ -1452,7 +1452,7 @@ kIrgKO3+mBaZoZzhnOCLQiiCfvPyfyABEFAw97sMAAAQSDD7qTgJkAQ6IPkWByIAIETwiDKJN54V /UERIAAQEDD+kgwoAEAyMPg2AiBgAkJw9UUSIKcAN2AtmRSKmfjoDAGQAnOw9NCKYgUAQ7AqFghl IEiKGPWyyBA0ADagGbKqKKAAFbLFCYgKKIIQ/KAHIgAAWrD9CgMiAABQ8AuAAC1BFStBEfoWCCoA Lu7QzCuIGGWPu4wyYABWAAAAGbKaKCAACYgKKIIQ/CAHIgAAWLD6PAAABBBoMAuAACxBFStBEfy7 -jnIAABKwjDLOwWABIgAAAPP/dmAAEFAwLUEQLUURY/9TAACMMszEZSBLZaBIHrNAfOA42sBZoIPy +jnIAABKwjDLOwWABIgAAAPP/dmAAEFAwLUEQLUURY/9TAACMMszEZSBLZaBIHrNAfOA42sBZoIfy CgAiAABasPz6/yIAAFDwWEwlizKKE4gWiUL/EgUqCQBasJoyn5EnhoEphoCfQiJFEtEPfscgx90N zAGcMokTjxaIQf4SBSgJAGZwmTKegCT2gCj2gZ5BihfAwPxFESCjALagixSxu/sWBCQaALrgH7Ko jkJj/mYAjEB0yVWNF/MSACBQADdgjxGKEvAxBAABEGAw8MwaAyAQQDD5osAv/xBwMP6yIxwRAHMw @@ -1468,16 +1468,16 @@ IgAAWbD6EgUgAxBoMAuAANagzS9lb9SMEo0TixGMwC3Sr/y8AQABEEAw/Iw5CAAyatBgACkZsdgo IAAJiAooghD8IAciAABYsPoSBSAEEGgwC4AA8/+XYgAAErBj/4plwEaNQHTZXYgQiREvgsDHr/4S AygRAFZwCf8BL4bAL+KxLuKtx48I/wMP7gGPEp7y0Q+JE4gRKZKxwNH5iAEAABBYMAjbOHvAuGV/ tYsUsbv7FgQlXAC64Bmx+Y1A8/7AYAAQGDDRDwAAAAAA9LFqEAEQEDD6CgQgIBBYMPyyaxIAAGlw -WaCvjhAAYQT94sAv/xBAMPAvGgMgEGAw/FwoDhEAR/AP3QH95sAsACA7MC7CsSzCrcf//F0RDhEA +WaCzjhAAYQT94sAv/xBAMPAvGgMgEGAw/FwoDhEAR/AP3QH95sAsACA7MC7CsSzCrcf//F0RDhEA e7D+zAEMACAncJzS0Q8AbBAEE7JXLjJpLTJtou4J7hGu3RixTRyxXvwuEQMgEHgw/y8oDgAgQ7CI 4Kz8+sKwIF8ANiArwrFksEl6vFEpwq/LkxuySBqxSKuqqvptCB0oorAvoq/5GRQOACBH8PqsMC4B AMfw/6ajIA4ANmBj/9sAAAAAAAAA+MKtIAAQSDApxrGY4orXKqwQWEYu0Q8AgtciLBDaIFvPUmih -AtEPANogW89vErIwC6gR9KA5YgAgQLAM6jArIoWLsCKs//y7CAIAAFCwWaKgKjKV8CEEAAEQWDAA -uxoLqgIqNpVZotXRDwAAAAAAAPoKByABEFgwWEbXLCJ/LCaD0Q8AbBAEE7EVIzF+ojLRDwAAAAAA +AtEPANogW89vErIwC6gR9KA5YgAgQLAM6jArIoWLsCKs//y7CAIAAFCwWaKkKjKV8CEEAAEQWDAA +uxoLqgIqNpVZotnRDwAAAAAAAPoKByABEFgwWEbXLCJ/LCaD0Q8AbBAEE7EVIzF+ojLRDwAAAAAA AABsEATAINEPAGwQBPSyFBMgECgwBSIo+LEQFAAgILAkQpfBXwNVDPVFFnIAIECwAzQJDEQRpCIi LQsiIRjRDwAAErFy0Q8AAABsEAb8sgUQAhBoMPowAyAAEEgw9SwAD/8QWDD7JBYgABAQMPJVGyI/ ADag86QLAA8QeDD/FgAgDxBAMCowCBmx9/8CAAoAvMKQCakKiZAKkAAAAIYz9odCBuABMDD6fAAC -AABZsFmePByx7CdUDCZUDSihByhVB/ABRWACEGgwiTOZEGABOYszbrgH8AExb+oQEDAqUAcKCkFZ +AABZsFmeQByx7CdUDCZUDSihByhVB/ABRWACEGgwiTOZEGABOYszbrgH8AExb+oQEDAqUAcKCkFZ Svccsd8qVBbwARpgAhBoMIszK1QWYAENizP/AgAEAIQC4Gi2Lfi1MGAIEFAwaLco+LglYAkQcDD/ AgAOAHVy0C9QIMCE/VQFLgkAR/AvVCBgANItVAVgAMwpUCAKmQIpVCBgAMCLMytVG2AAuI4zLlUa YACwKsJ9jzMpwoDwkAQOACBX8PoIBgH+Anvw+MKCLgBAR/APDxkN/zf4/zYA/xBAMAj/Ni9UI2AA @@ -1508,11 +1508,11 @@ mQj5ZRQmACBiMPgWCyoBfTbQ+xYTICAANOADOQL7zAAAFQA1IG1JBQAJhgBLYYYdiBuGYKhmKBIT /wIABgGVRZCJHZaQi8DWwPsIRwIAAEswbYkHKJAIaIELuJnAcfP742ADECgwiJMHuwEIuwKbwCgg IQ2IAQWIAigkIWP/2sCbeaFEuGb/AgAGAGU9kCpgCGSgl2ihZGii6WijVmmp3oljbpPeaZPbiyf8 +sAgQAJS8PwKACoAQGKw/LUUIIACUrCauZq4Y/+6jB6OIo8njSApIBYv+RSZEPhiAyAFEFAw+BYB -IAAQWDBZnnSIYygkFmP/j4ljKSUIY/+HHLAwi2P6IAcsACBi8CzAgC0K+/2qAQ3gBDsg/KoCAPwQ -YDAMqgELqgIqJAdj/1gAi2MLikL6Fg8q4AFcMCsWEFmcbSyhBy0SEI4fLiQMLSQNLCUHY/8wABqv +IAAQWDBZnniIYygkFmP/j4ljKSUIY/+HHLAwi2P6IAcsACBi8CzAgC0K+/2qAQ3gBDsg/KoCAPwQ +YDAMqgELqgIqJAdj/1gAi2MLikL6Fg8q4AFcMCsWEFmccSyhBy0SEI4fLiQMLSQNLCUHY/8wABqv Dh+v0PP8gGAAEHAwAAD/AgAD/nJ/kIlgKAr8CNgB/voAKAkAQnD+CggoAEB2cPgkByDxEEAw/JkC CABAQvD5ZgAoCQByMCgkIWAAAYlg8/ymbOABSDAAACoSElvNPBuv/gusEay7+xYHIFQANqAM6jAr -soWLsLCq+hYGKgAgZvBZoG0cr/yNFirCf/DRBAABEFgwALsaC6oCKsZ/WaChY/uDKcKAi5GIkJiw +soWLsLCq+hYGKgAgZvBZoHEcr/yNFirCf/DRBAABEFgwALsaC6oCKsZ/WaClY/uDKcKAi5GIkJiw iJCbgZ6QnpEowoKwiCjGgmP6//oKByABEFgwWESdihcpon8ppoNj+1EAAPosAAAwAlrw/AoBIAMQ aDBYSjL6LAACAABY8PxMAAIAAGlwWEbz0qDRDyUhCB+u4fC2EQgCAWgw+ogQBAkANXD2rtUYCQB6 MJjAjyCWwhau2sKAmMP2VQIAAxBAMPb2Ag+ABD/gCP8Cn8GDK48pnsWVxJ/Ik8n4nxAABBAYMPbG @@ -1538,13 +1538,13 @@ ID4QUDD7IBYmAfrWUPwKPSYB9sZQ/gr/LgIS4lCIOfgJQQAEECgwCVUMBQVB9VwPL/gQSDAJVQH1 XH8oACAqMPVFFABoAkIw+BYEIDQEcvD83P4gARBQMPogQSwFAGKwWEigZKP3ixgZrZ0MuhH9rZ0a ACBKsCyiOv29CgAIAkFw/dKXKgHMxxAsojmYGf3EAQ4Bxm8QLCEilxArIEEpMgn6rjUQCBBAMPwW BSAEEHAw+7sJDiABTDD/7gwLwAQ+4P+unh4gAXAw/hYDKgAgWrD6on8gAxBgMPoWBigAIHZw+CRk -IHgCSnD5FgcgBxBAMPgkXCIAAFhw/66RHgkAe7D/JSovgAQ7oP4WACDKAlCwWZPDjRYnJTUnJGj4 +IHgCSnD5FgcgBxBAMPgkXCIAAFhw/66RHgkAe7D/JSovgAQ7oP4WACDKAlCwWZPHjRYnJTUnJGj4 IQcgLhBIMPkkVyBSEFAwKiQF+a12EEIQUDD6JHQpQAFAMPoSBSnABDog+a2PGAkASjD4RgAgRBBw MPrbFAzAAWgw/yIAK0AEPuD+RgMuSAFoMP19QA+ABDug9d0RDAkAczD+rnEaCQBu8Pj/EQoJAGbw /K5sHgkAfXCfQR+tW59C/xIHK0AEOqD4IEEqCQBisJpGJ0UK/kYHKQAEOiD3jhQICQBaMP9FCygJ AEow+EYEIJACaLDyDRYAQAJhMABMY/khKiAAEFgwK0QxK0Qy+0QzIAAQUDAqRDUqRDb6RDcgABBA MPhEMCAAEHgwL0Q0LkQuKUQtJ0QvCYkUKUQsLSBXLUQ7DY0ULUQ6DY0U/UQ5IAQQYDD9jRQAeAJR -MP1EOCC4AliwWZN294sUAMACQLDzCBYAgAJJMABJigAIiAAJiogTJ0RTK0RSHa0qC4sUK0RR+4sU +MP1EOCC4AliwWZN694sUAMACQLDzCBYAgAJJMABJigAIiAAJiogTJ0RTK0RSHa0qC4sUK0RR+4sU AEACSPD7RFAgsAJRMAYJiADKigQJiACKiv1GGiAQAlowK0Yb+SB0KgAgQTAppHQvIQcoMAeYMSgg BywhCPmtIBvABDlg/w9KCgIBRDD8/xEKoAQ+4Pv/AgQAIFEw+62CHgkAT/D/RgAoIAFAMPoiAC8A BDog90YFLAkAczD3RgcgMBBIMPlGAywJAFswnESbRv1GAiAEEFgw/az0G4AEOqD8EgkqCQBasPpG @@ -1561,11 +1561,11 @@ YPgKSSMwADTgLjAS+wpVIykAN6ApIAX8Cv8mAY9eUCsgFvgkBSAaBGLwAMWOWEdlZKNIwEEZrGLA 7PxoEQABEFAw+axgGAAgSjD9gjoiAAB5MPSvOQAEEDgw+WkKBgUAf7D5kpcqAXi/UCWCOQlVAfus bBLrADVg+FwAAgAAUXDwCwcAQAIxcG15AgBIYWRBsS0hBx+sVQ0NSgzdEf6tYxwJAH9wLVYAKiIA +a1dEGQQWDD8rFAQCBB4MPxWAiuABDqg+1YDKgkAerAqVgH5JSogBxBAMPgkXCIAAFhw/yRkIAMQ -YDD+FgAgygJQsFmShB6sXYoR/yEiIC4QYDD8JFcgQhBoMP0kdCBSEGAwLCQF/SBBIAAQYDAsJTUP +YDD+FgAgygJQsFmSiB6sXYoR/yEiIC4QYDD8JFcgQhBoMP0kdCBSEGAwLCQF/SBBIAAQYDAsJTUP 2BT8JGgvQAQ/4PoJRgpIAVQw9IgRCgcBUDD4uxENAAQ/YPuZAgtQBDqg+q04GAkAUjD8VQogVBBY MPmtMxgJAEow+1ULLAkAR3D6VgcsCQB3cP1WBC4JAE/w/1YGIJACSLDyCRYCAABBsABIY/shKiAA EHgwL1QxL1Qy/1QzIAAQcDAuVDUuVDb+VDcgABBoMC1ULvxULyAAEFAwKlQw+1QtIAAQSDApVDQL -ixQrVCwoIFcoVDsIiBQoVDoIiBT4VDkgeAJRcPiIFAAEEGAw+FQ4ILgCWLBZkkL2bQEgwAJAsPMI +ixQrVCwoIFcoVDsIiBQoVDoIiBT4VDkgeAJRcPiIFAAEEGAw+FQ4ILgCWLBZkkb2bQEgwAJAsPMI FgCAAklwAEmKAAiIAAmK+l0BIAAQWDD7VFMgABBYMPtUUiAAEFgw+1RRIAAQWDArVFD+IHQhAAIx sP5UcCEAAlKwHqxeLCEHLTAHnTEpIAcvIQj9q+8dQAFgMPzMEQoCAUww+QlBCqAEPuD7zAILAAQ+ YPgyAC4JAF/w+6vdHAkAazCcoIwg+6YCLgkAd/D/pgQgABBoMJ2lnqb9pgcgMBBwMPjMEQAEEGgw @@ -1592,8 +1592,8 @@ ioArEhX4FhYgBBBIMPDdEQogAVAw+pkMCgkAbvD6q8gaCQBm8Jt0+xIRKCABTDApFhooggD6dgcg ABBQMCp1CvkSFCgAIEow+XYGIHgCQjAodQvwCxYAQAJJ8ABJYSkxKvp0LyAAEGgwLXQz+XQtIAAQ eDD/dDAgABBYMPt0NCAAEGAw/HQyIAAQcDD+dDEgABBgMPx0NyAAEHAw/nQ2IAAQWDD7dC4gABB4 MC90NSsSEi8SGQmJFCl0LP4wVy4AIEfwLxYZLnQ7Do4ULnQ6Do4ULnQ5/o4UAHgCUfD+dDggBBBg -MFmQzPkSEyCAAlHwAgmIAEqKAAmIAAqKKzIcKhIXK3RTC4sUK3RSC4sUK3RRC4sU+3RQIHQIUXAs -Ehr9q4sQigJR8PscAABCEHAw/jR0LCABYDD9CggsCQBrMP00ZS2ABDsg/BYAIAMQYDBZkLItMTX2 +MFmQ0PkSEyCAAlHwAgmIAEqKAAmIAAqKKzIcKhIXK3RTC4sUK3RSC4sUK3RRC4sU+3RQIHQIUXAs +Ehr9q4sQigJR8PscAABCEHAw/jR0LCABYDD9CggsCQBrMP00ZS2ABDsg/BYAIAMQYDBZkLYtMTX2 KQsANhBwMC40V/qSAyACAmtwLTU1LRIWHKt4LHYWi9ArdheI0I4/LzIcKnYZiZL5dhguACBH8C82 HC8SGC3SALEi+EQMDgAgfjD/FhgsACB3cP02DyAYADyg8goAIDACMbAZqlUpdhopEhrA9Q9fL7iY KHYb+DB0KAAgPnD4lHQtzgC34CoSEAWqDLaq/wIAA/7fQqCOH40eLeY5KzAWLAr/fLEIKjBBLBIZ @@ -1611,9 +1611,9 @@ BD/g+LsRAAgQaDD8VgIqCQBu8PtWASzAATgw/2IBLAkAezD4IEEoCQBWcPTqEQgJAGZw+6qzEAQQ YDDwiBEGIAF8MPfHDAgJAEow+am+FiABPDD3/wgKCQBasPpWBiB4Anvw/xYGKAkASjCYVC9VCxiq pfhWByAAEEAw+FUKIJACcLDwDhYAQAJpcABNYf8hKiAAEFAwKlQ1KlQ2+lQ3IAAQSDApVC74VC8g ABBwMP5UMCAAEGgw/VQ0IAAQWDArVDErVDIvVC0rVDMPjxQvVCwrIFcrVDsLixQrVDoLixQrVDn7 -ixQAeAJRcPtUOCC4AliwWY+6KSxg8wkWAIACUXAASooACYgACootIhwcqoEtVFMNjRT9VFIgigJR +ixQAeAJRcPtUOCC4AliwWY++KSxg8wkWAIACUXAASooACYgACootIhwcqoEtVFMNjRT9VFIgigJR cP2NFAIAAFhw/VRRIEIQSDD9jRQIIAE4MP1UUCgJAGIw+SR0IAgQYDD8JGUpgAQ6IPgWACADEGAw -WY+hG6le+iE1IDYQYDAsJFePY4hh+WIAIAICUrAqJTUpVhYoVheNYS9WGY5iLlYYLSYcLGIBLCYP +WY+lG6le+iE1IDYQYDAsJFePY4hh+WIAIAICUrAqJTUpVhYoVheNYS9WGY5iLlYYLSYcLGIBLCYP +1YaIBACUfAqVhv4IHQoACA9cCiUdC8KCC9GOSsgFi4K/36xCCogQSwSBlhEDPwSAiIAAFCw/RIB IgAAWPBb/LXRD8DY+RIEIEcQUDAqJAWZN44iiBP4NgkgABB4MP82CC/fALeg2iD7EgUgARBgMFhE htEPACsgQSu8EpsV8//DYAAQaDBsEAYoIAT/AgAGAHYOIPs8AAQAciIgBQhH/QoAIgB7giAqsAMs @@ -1682,8 +1682,8 @@ QAQ/IPCdEQTAAUQw+IpCBgcBQDD7JQsgABBIMPklCidQBDmg/NgUC4AEOqD8psIZQAQ6IPpVAgYJ AEGw8/8CBAkANXD/JgYsCQAvcPwmBywJAHdw/SYEIJACUfDyChYAQAJAsABIY/hxKiAAECgw9SQx IAAQGDDzJDIgABB4MP8kMyAAEHAw/iQ0IAAQaDD9JDUgABBgMPwkNiAAEFgw+yQ3IAAQUDAqJC4p JC/4JC0gABAwMCYkMAiIFCgkLCZwVyYkOwaGFCYkOgaGFPYkOSB4AlCw9oYUALgCWfD2JDggBBBg -MFmLyih8YPMIFgCAAkiwAEmKAAiIAAmKKHIcKCRTCIgUKCRS+IgUAKgCULD4JFEgDBBgMPiIFAD+ -Alhw+CRQICICWvBZi7krcHQrJGQqEiobpWYMqhGrqiSmOStwFikK/3mxCvpwQSBIEGAwWEAzxMX8 +MFmLzih8YPMIFgCAAkiwAEmKAAiIAAmKKHIcKCRTCIgUKCRS+IgUAKgCULD4JFEgDBBgMPiIFAD+ +Alhw+CRQICICWvBZi70rcHQrJGQqEiobpWYMqhGrqiSmOStwFikK/3mxCvpwQSBIEGAwWEAzxMX8 dAUgABAQMNEPLKEFLaEE/6IAIAICYzD8DE8B/gIjcPylBSYAju8QDEQR9PwID8AEOyAOzAwEDIvA 0A3dZPAMhA+QALtgLqEFGqZsJXUTLKLn+qLmL5AEO6D1dRQsACB3cP11EiugBD9g/cwICgAgWrD8 dhYi8wA2oBulPwwvEav/LxYpL/I68hYoJgFLQ+AuEikUpfwu4jkELwov8q//5AEOAUD/kB6l0wpb @@ -1700,15 +1700,15 @@ I4AEPOD+xgciCQBU8PPGASACEBAwbSoFCgmGAEhrjHfA0Pn6wCBAAmMw+rY5KABATzD9xQQggAJK cJnB+cYAIFIQQDD4dAUgABAQMNEPxdItdAVj+52OcmXpIStwQfp8AAABEGAw+7wSIAAQaDBYP/bA INEPwEDAwPwWJyfgAWgwGqWy+2wAAAAQYDD6oqEgARBoMFg3JxilrSoSJyiCovZsASACAlKwCGYu /wIAAf7uhqAqFidj/8cAAADz+NdgABBQMIlyyJrydAUgABAQMNEPAAD6fAAAARBgMPuMGCIAAGnw -WD/Y8nQFIAAQEDDRDwAAAGwQCAUGR/TVGgAFEFAw/KWWEDAQWDBZk7z3IhAiAkYZoBak7SViiypS +WD/Y8nQFIAAQEDDRDwAAAGwQCAUGR/TVGgAFEFAw/KWWEDAQWDBZk8D3IhAiAkYZoBak7SViiypS FSihAmSEj1gyzhyk3y1SFizCbitihf3cASwAIFMw/VYWLZAEOyD6IAcqACBm8CmwB/wK+yoCAVAw /qoRCABAZnD+IAwoCQBWcCm0B/ogBy+YEGgw/rQMIPwQYDD9tAUoAEBmcPK2CiAAEGAw/LYIKiAB UDD8tgkoCQBWcCm0B/W8AAQcADbgirf8oggvwAQ9IPuhFS/AEHAw+aILIEACarD2qRQuAEBzcP4W BSoAIHbw+7xAJgH5ZlCvZvalFCoAIGPw/wIACgH8VtDJOPnMAAAWADUgbUkFAAOGAElhKtIADwIA D6oI/wIABgIPXpCa0NPAiVD6pK4dgAQ6YPsxCCwJAGEwnDErVQgqonMKmQz5aBQAkAIhcPkNRQwB zZIgKnBwtqoAoQQAiBoI2AIoVg4kVhMkVhIvMCH0PCAuwAF8MP9UUCABV4fg/wIAAgFTg+C4SlmS -cBylOy1AAP5AASAwEFgw/1BQIgAAMrD2FgAgBRBQMFmTWi0xCBylM/5RCCAFEFAw/1IMIDAQWDBZ -k1SIIvogByLBALYgGKQFCgpBDKkRCJkIK5I6+hYEJAFKxuAcpAArkjkMrAoswpf8swEOAUDm0Csi +dBylOy1AAP5AASAwEFgw/1BQIgAAMrD2FgAgBRBQMFmTXi0xCBylM/5RCCAFEFAw/1IMIDAQWDBZ +k1iIIvogByLBALYgGKQFCgpBDKkRCJkIK5I6+hYEJAFKxuAcpAArkjkMrAoswpf8swEOAUDm0Csi Ei4iCRykQf0iCioIAVwwKxYGDLsKK7KADt0M+xYHIGACWvD/AgAKASJfUCsgFiwK/3yxEvogByAA EGAwWD7r+KPqEwgANqAsIQcdo/IMDEr+pBIdwAQ7IPqj8BwJAGswnDCJIP2kQxAFEHgw+jYCIEAQ WDD7NgMngAQ6YPsSBiYJAHmwljEsIhL77TgMSgFgMPq7EQ1gBDsg+qQ3GgkAZvD8IRoqCQBu8P0S @@ -1718,22 +1718,22 @@ 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 @@ -1743,18 +1743,18 @@ YwAEhgBJYS8iFh6iVC80Pw+PFC80Pg+PFC80PQ+PFC80PP9SDiAAEEgw+TQkIAAQYDAsNCL8NCYg ABBoMC00Iy00J/80MyAAEFAwKjQlD48ULzQyD48ULzQxD48ULzQw8A4XAJACUPDyGh4ABRBIMCxy ESw0OwyNFC00Og2NFC00OQ2NFC00OCsgB/xWDyogAVwwDLsRqLsptjkrIBYqCv96sQr6IAcgMBBg MFg898lTiFjIj49ZwOCeW5jwiVifkZ5YLlYJHKNJjSAvchQuchEochOYEPZSDiAFEFAw9hYBIDAQ -WDBZkWAp+pn5VAUgABAQMNEPAAAA+RYHIgAAUnBZkGf7XAAP/xBoMPz6/yIAAHKw/1BQIgAAULBZ -kHCJF2StYcHW2iD7XAACAABg8Fg8isAg0Q/aIFg9Ifih/x3lADagYAAUixT6LAAAARBgMPu8GCAF +WDBZkWQp+pn5VAUgABAQMNEPAAAA+RYHIgAAUnBZkGv7XAAP/xBoMPz6/yIAAHKw/1BQIgAAULBZ +kHSJF2StYcHW2iD7XAACAABg8Fg8isAg0Q/aIFg9Ifih/x3lADagYAAUixT6LAAAARBgMPu8GCAF EGgwWD1WjFhlz9GPLxijI/hWCyBAAmlw/fYAIHACcLCeWJ9Z/SYPIAAQEDDRD4g3KYkU9TwAAKwA NmCDiSQ8MPP87GBwAkjwAAAA8/wPYAAQWDDz/3lgjhBoMMCwm6vz/GxiAAAacAAAAADz/KZv/xBA MPy6DAA3ADTgCksU/rwIIgAAQPD+TjYCAABLMNMPbekFBgiGAElniRWqOPtPDACAAkpwbfkFCAiG AElpixUKbgyuuyu8QJvQY/wPjxUv/ECf0GP8BYsU+iwAAAEQYDD7vBIgABBoMFg9IWP/JgAAAADz /1ZgABAYMGwQBvwKAiBCEDAw9QoDIAEQWDD4otEQABA4MPcWACAuEEgw+CUqJABogSAqMBX5JFcg -iAA1IP8CAAAAbwUg/wIAAgBhASBuRTgKaxR7UAUsMBQsJGAqLGX9otcSAABYcP0WACADEGAwWYfz +iAA1IP8CAAAAbwUg/wIAAgBhASBuRTgKaxR7UAUsMBQsJGAqLGX9otcSAABYcP0WACADEGAwWYf3 JyRoJyRpJyU1JyYcJiR0HqIELiU30Q9uQ8P/orcSAABhcPskZCAjEEAw+CRcIMoCULD/FgAiAABY -cFmH5CckaCckaSclNScmHCYkdNEPACkwMMGi/wIABgBE1lD7JGQgugJQsPwKAyAiEFgw+yRcIDoC -WPBZh9YqLGH8CgMgMgJY8FmH0iowFWP/UgAAHaItLSUqLDQwY/8mwPb/JFwgCBBwMC4kZGP/NAAA -AAD6LF0gOgJY8PwkXCAgEEAw+CRkIgAAYXBZh8EpMBjTD3+XtCosYfwKAyAyAljwWYe8Y/+jGqH1 +cFmH6CckaCckaSclNScmHCYkdNEPACkwMMGi/wIABgBE1lD7JGQgugJQsPwKAyAiEFgw+yRcIDoC +WPBZh9oqLGH8CgMgMgJY8FmH1iowFWP/UgAAHaItLSUqLDQwY/8mwPb/JFwgCBBwMC4kZGP/NAAA +AAD6LF0gOgJY8PwkXCAgEEAw+CRkIgAAYXBZh8UpMBjTD3+XtCosYfwKAyAyAljwWYfAY/+jGqH1 LDEcKqJ/CcwRrKosoTYsNRyKoComHmP/XmwQCCciEPUIRwBCEFgw+nwAAgH/GiAoMDD2od0YAgLC 0CViiypSFSyhAmTEUlgvvRihzilSFiiCbi9ihfmcASgAIFIw+VYWJZAEPiD+IAckACAv8C1QB/8K +y4CAXAw/u4RDABAf3D5IAwsCQB3cC1UB/4gBy+YEEAw+VQMIPwQeDD4VAUsAEB/cPJWCiAAEHgw @@ -1774,9 +1774,9 @@ MBBgMFg7Z8lSiFjIjo1ZwMCcW5jQjlid4ZxYnFkvMDDI+yL6mfJUBSAAEBAw0Q8pchEqchSxmfl2 ESACAlKw+nYUL5kQQDD4VAUgABAQMNEPAAAAANogWDug+KB+HigANqBgAEHAwfxEIC+BEFgwK0Qh Y/8AAAAAAAD6LAACAABZcP0KjiIAAGDwWDr5wCDRDwCLFPosAAABEGAw+7wYIAUQaDBYO8qMWMjC wCDRD48vGKGY+FYLIEACaXD99gAgcAJwsJ5Yn1n9Jg8gABAQMNEPiDcpiRT1PAABJwA2YIOJY/0k -LjAx/KGLEAUQUDD/IgAgMBBYMPgNRQ7AAXAwWY+g+iwAAgAAWPD8TAACAABpcFv9Q8Ag0Q8AAByh -f40gLiIYhlCPoP7gdCAwEFgw9hYAIAUQUDBZj5LAINEPAAAAAPP8IWAAECgwwPCfq/P8fGIAABpw -AAAAAPP8pm//EEAwHKFvL3IRLjAwjSApchSZEChyE5gR9lIOIAUQUDD2FgIgMBBYMFmPfmP+7AAA +LjAx/KGLEAUQUDD/IgAgMBBYMPgNRQ7AAXAwWY+k+iwAAgAAWPD8TAACAABpcFv9Q8Ag0Q8AAByh +f40gLiIYhlCPoP7gdCAwEFgw9hYAIAUQUDBZj5bAINEPAAAAAPP8IWAAECgwwPCfq/P8fGIAABpw +AAAAAPP8pm//EEAwHKFvL3IRLjAwjSApchSZEChyE5gR9lIOIAUQUDD2FgIgMBBYMFmPgmP+7AAA AAAA/NoMADcANOAKTRT+3AgiAABA8P5ONgIAAEsw0w9t6QUGCIYASWeJFao4/U8MAIACSnBt+QUI CIYASWmNFQq+DK7dLdxAnWBj+++PFS/8QJ9gY/vlixT6LAAAARBgMPu8EiAAEGgwWDt1Y/6oAAAA APP8A2AAEBgwbBAIKCAE0w/0gBxq4AEsMPuHDGAYEEgw/wIABAHeCiB5gQTAINEPACciEC4KQvp8 @@ -1799,9 +1799,9 @@ ABAQMNEPKXIRKnIUsZn5dhEgAgJSsPp2FC+ZEEAw+FQFIAAQEDDRDwAAAADaIFg6RvifJB4oADag YABZwMH8RCAvgRBYMCtEIWP/AAAAAAAA+iwAAgAAWPD8TAACAABpcFj+FcAg0Q8A+iwAAgAAWXD9 Co4iAABg8Fg5mcAg0Q8AixT6LAAAARBgMPu8GCAFEGgwWDpqjFhlzACPLxigOfhWCyBAAmlw/fYA IHACcLCeWJ9Z/SYPIAAQEDDRD4g3KYkU9TwAASoANmCDiWP9DwAAAC4wMfygKxAFEFAw/yIAIDAQ -WDD4DUUOwAFwMFmOQPosAAIAAFjw/EwAAgAAaXBb++PAINEPAAAcoB+NIC4iGIZQj6D+4HQgMBBY -MPYWACAFEFAwWY4ywCDRDwAAAADz/AlgABAoMMDwn6vz/GRiAAAacAAAAADz/I5v/xBAMBygDy9y -ES4wMI0gKXIUmRAochOYEfZSDiAFEFAw9hYCIDAQWDBZjh5j/uwAAAAAAPvaDAA3ADTgCk0U/twI +WDD4DUUOwAFwMFmORPosAAIAAFjw/EwAAgAAaXBb++PAINEPAAAcoB+NIC4iGIZQj6D+4HQgMBBY +MPYWACAFEFAwWY42wCDRDwAAAADz/AlgABAoMMDwn6vz/GRiAAAacAAAAADz/I5v/xBAMBygDy9y +ES4wMI0gKXIUmRAochOYEfZSDiAFEFAw9hYCIDAQWDBZjiJj/uwAAAAAAPvaDAA3ADTgCk0U/twI IgAAQPD+TjYCAABK8NMPbekFBgiGAElniRWqOP1PDACAAkpwbfkFCAiGAElpjRUKzgyu3S3cQJ1g Y/vXjxUv/ECfYGP7zYsU+iwAAAEQYDD7vBIgABBoMFg6FWP+qAAAAADz++tgABAYMGwQBhmf5fKS XSIAAHCw/UwAAgAAYPD/CgAqAIyQ0CWSXJUQK1EE9VIAIf4CIzDzIwwAARBAMPy7EQIAABMw8AAO @@ -1880,8 +1880,8 @@ ES7SFPsSGiACAmMw/NYRIAICc7D+1hQvmRBQMPq0BSAAEBAw0Q8AAAAAKhIbWDXEZK1cYABNiifb MPqsICIAAGEwWDEajCD6FhktgAQ7IPuhCCwJAGEwnKErJQhj9bYA8/WvYAAQGDD6EhsgMAJZ8P0S EyABEGAwWDXuLhIaLRISLeYTLxIaj/jI88Ag0Q8AKBIbKhIai48cm8T8pgsgQAISsPK2ACBwAkow maibqfKGDyAAEBAw0Q8AAAAAAAAA+hIbIDACWXD8CgEgBRBoMFg12GP/rcDQ8/cRYBYQSDApEhsc -m7IoEhqNkCmSGI/giID+kHQgBRBQMPgWACAwEFgwWYm5wCDRDy0SGxybqS7iEf3SACAFEFAw9BYA -IDAQWDBZibFj/rz6EhsgJAJZcPwKASAAEGgwWDW+Y/9FAADz/qRgjRBoMPP272//EEgwwNDz9pdg +m7IoEhqNkCmSGI/giID+kHQgBRBQMPgWACAwEFgwWYm9wCDRDy0SGxybqS7iEf3SACAFEFAw9BYA +IDAQWDBZibVj/rz6EhsgJAJZcPwKASAAEGgwWDW+Y/9FAADz/qRgjRBoMPP272//EEgwwNDz9pdg AhBIMAAAbBA6KCAEIhZkIxZR9RZQJnQANiDyChgmAswOIP8CAAQCyCIgjDAvEmQjFk8vFlT98Acs 4AFgMPwWTCDWAmMwDEwU/BZNLCABbDD9FkskArsCICgSVA8CAA8CACiABcR+/wIABgKkPhDFkXmB KysKVHuBJSoSVCsST/wcFCAwAmhwW/vY/wIAAAlHKqAqEk8oElSJFZmnKIAFLBJPg8bzB0EABBAw @@ -1897,15 +1897,15 @@ nIieifqGBSBgAkIwKhJOKBJUwZv5pjkgVBAwMCaEBSsSVNMPDwIAK7AWLAr/fLEWLBJQKhJUAMyO KqBBWDSt/wIAAAfSKqAkEksemakMTRH+Ek0sACB3cC0WTi3SOv8CAAoHdvdQLxJOFppkL/I5BkYK JmKv9vQBDgdrN9AYmbXwCAcCAABBMG3pAgBIYSoSUSwSVPuarhAAEDAwJhZE+8UqIC4QaDD9xFcg BhBwMP7EXCAIEHgwL8RkKqAV+moUAAMQSDD/AgAIB6FSUCoSVByatisdAfwWRCAgAlrw+qxlIAMQ -YDBZf9IlElTAoCpUaCpUaSpVNSpWHPlRByBCEFAwKlR0GpmF+BJMKUABTDD7mdwZwAQ+YPtVNygJ +YDBZf9YlElTAoCpUaCpUaSpVNSpWHPlRByBCEFAwKlR0GpmF+BJMKUABTDD7mdwZwAQ+YPtVNygJ AFZwmUCHUPYSTSCYAkIwmEP4mX0XgAQ94PhGAiYJADmwlkEjUEEfmhEoUAUDNgn8ZhEAUBBoMPVR Ii4AIDfw//J/ICYEajDEvnuBCcXG/wIADgeIYhAYmYkamnf13RQJQAQ9YPaadRcABDzg/wtGDkgB eDDzEkwsBwF4MPZGBy1ABD9g9cwRD4AEO6D+CgAqCQB28P3MAgB4Ahjw80ULKgkAZvD7ElQmCQBd 8P5FCigJAFZw+UYGJgkARfD3RgQgkAIy8PAGFgBAAhEwAEJhLbEq/kQvIAAQEDDyRDcgABAwMPZE NiAAEDgw90Q1IAAQQDD4RDQgABBIMPlEMyAAEFAw+kQyIAAQYDD8RDEgABB4MC9EMP1ELSAAEHgw -L0QuDY0ULUQsLLBXLEQ70w8MjBQsRDoMjBT8RDkgeAJRMPyMFAC4Alrw/EQ4IAQQYDBZf3AoElT/ +L0QuDY0ULUQsLLBXLEQ70w8MjBQsRDoMjBT8RDkgeAJRMPyMFAC4Alrw/EQ4IAQQYDBZf3QoElT/ TEAgwAJCMAIIiABPigAIiAAPiiwSVCzCHCsSTyxEUwyMFCxEUgyMFCxEUQyMFPxEUCCoAlEw/BJM -IGACWvBZf18rElQvEkwPAgD+sHQuACB9MC70WC0STiwSTSzWOSuwFi0K/32xDSoSVPqgQSIAAGDw +IGACWvBZf2MrElQvEkwPAgD+sHQuACB9MC70WC0STiwSTSzWOSuwFi0K/32xDSoSVPqgQSIAAGDw WDPWKhJUKBJPxJUppAUogBJkgEUUmRiDpwSEKPpMAAAgAhjwW8GMLxJU/ZlbEgAAYTD+mjUSAABa sP/yACIAAFDwW8FBIhJUgiciLBDaIFu3FP8CAAAGfQagwCDRD8FpeGL2/wIACABllhBj/+sAAAAA /DwAACACWHD9MQgiAABT8P4KACIAAHlwWBnbLQqI/wIABga7bpCOFGTvvIjni4j1gRUvwBAwMPmC @@ -1963,29 +1963,29 @@ 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 @@ -2018,21 +2018,21 @@ EZkcKLIWKxIQmBoJiAqIgArdDCUSEfWARGACAlrwiBrKiipSF/5WFiAAEEAw+BYKIAICUrD6Vhcg MAJKcIoWKDwY9d9wYgUAVjBj/jAAwKH6VhYgARBAMJgaY//fAI0aCd0LiNPz0gIoACBCsPgWBSoA A1IQsTOT0ogV+NYDLLAAtyBj/frAoSpWFmP/GPosAAIAAFlw/QqOIgAAYPBYLV/AINEPAI0vHpQb /lYLIEACWXD71gAgcAJgsJxYnVn7Jg8gABAQMNEPixv6LAAAARBgMPu8GCAMEGgwWC4nY/2QiTcs -mRT1PAAAfAA3IIOZY/pgHJQJjSApIhiIUI/g/pB0IAUQUDD4FgAgMBBYMFmCB8Ag0Q/z+exiAAAp -MPP6LW//EEgwHJP+L3IULnIRjSApchOZEPhSDiAFEFAw+BYBIDAQWDBZgflj/0GLG/osAAABEGAw +mRT1PAAAfAA3IIOZY/pgHJQJjSApIhiIUI/g/pB0IAUQUDD4FgAgMBBYMFmCC8Ag0Q/z+exiAAAp +MPP6LW//EEgwHJP+L3IULnIRjSApchOZEPhSDiAFEFAw+BYBIDAQWDBZgf1j/0GLG/osAAABEGAw +7wSIAAQaDBYLgZj/Q0AAPP56mIAABkwbBAOKSAE10D8kq8QABAwMPwWECMWADZg+AoYJgGDjmD/ AgAEAX+iYCggB4Qw8xYOKCABQDD4Fgok4AEgMPQWDyDWAiEw9EQUBAR/gmApIAUtCk7/AgAGAWfu UC4KR/8CAAYFE3ZQKyAWLwr/f7EQAMWOKiBBWC2H/wIAAATxKqCIGhmSgwyFEalVKVI69BYJKgSf plAbk0EqUjkLiworsq/7pAEOBJXekBySkokZ8AwHAgAAQTBtmQIASGEfk432FgQgLhBAMPgkVyAG EEgw+SRcIAgQUDAqJGQvJSouMBX+bhQAAxBoMP8CAAgEyPNQKixl+5OWEAMQYDD7FgQgIAJYcFl4 -s4wejx8mJhwmJTUmJGn4IQcgQhBIMCkkdBmSZ/YkaClAAUAw+pK+GcAEOiD6JTcoCQBKMJhAjiD9 +t4wejx8mJhwmJTUmJGn4IQcgQhBIMCkkdBmSZ/YkaClAAUAw+pK+GcAEOiD6JTcoCQBKMJhAjiD9 EgkgmAJ78J9D/xIQL4AEO6D/RgIsCQB3cJ1BLMATZMfbIyBBKCAFGpLwAzsJ9yEiK8AEPuD7qggA UBBIMPqifyAmBEowxM58gQnF1v8CAA4EsGoQJkUK/JNXG0AEPeD33xQJAAQ84PoNRghIAVAw8xIP LgcBUDD6kmAfQAQ/4PXuEQmABDog9owUCgkAZvD4k0ocCQBHcP/uAgB4Ahjw80ULLAkAd3D7RgYo CQBucPhGBygJAFZw+UYEIJACQLDyCBYAQAJ5MABPY/shKiAAEEgw+UQ0IAAQUDAqRDAmRC/8RC4g ABBoMC1ENy1ENv1ENSAAEHAwLkQzLkQyK0QtLkQxC4sUK0QsKCBXKEQ7CIgUKEQ6CIgU+EQ5IAQQ -YDD4iBQAeAJRMPhEOCC4AliwWXhYhhn5TEAgwAJAsAIIiABJigAIiAAJiiwiHIseLERTDIwULERS -DIwULERRDIwU/ERQIKgCUTD8Eg8gYAJa8Fl4SI8f/iB0LgAgfTAu9FgmVjkrIBYtCv99sQr6IEEi +YDD4iBQAeAJRMPhEOCC4AliwWXhchhn5TEAgwAJAsAIIiABJigAIiAAJiiwiHIseLERTDIwULERS +DIwULERRDIwU/ERQIKgCUTD8Eg8gYAJa8Fl4TI8f/iB0LgAgfTAu9FgmVjkrIBYtCv99sQr6IEEi AABg8Fgsw4gexJYpJAUogBIPAgBkgEEUkgYjIgcEhCj6TAAAIAIY8Fu6ef2SSRIAAGEw/pMjEgAA WrD/IgAiAABQ8Fu6L4InIiwQ2iBbsANpoQVgB4R4kQPAINEPJCIQ9ZMYGOABLDD4TAACA1qaYCVS eipSFSuhAmS23lggNhiSRylSFhuTDyiCbiuydPmcASgAIFIw+VYWJZAEPiD5IAckACAu8ChQB/oK @@ -2065,11 +2065,11 @@ PS5SFyzMGPZWFiACAnOw/lYXIAAQGDAvEgsuEgYq/Bj8OgoOBQB2sP8WCyIAAHrw9Z9/bgABeDDz Y/gZAAAA+iwAAgAAWPD9MQgiAABh8FgKlGSh6YmnK5kUyrmLmSggBcPO+xYOJgDgZhDE4v8CAAYA 23YQw/3/AgAOAO56EPP22mIAABKw8//TYAAQWDDAoSpWFmP+z/osAAIAAFlw/QqOIgAAYPBYKr/A INEPAIsd+iwAAAEQYDD7vBggDBBoMFgrkGP9UowiZclQixr6LAAAARBgMP0SCSAwAlrwWCuJwCDR -D4k3LJkU9TwAARkANyCDmWP6DAAckWqPgC4iGI0ghlD+4HQgBRBQMPYWACAwEFgwWX9owCDRDwAA -AADz+ZNgABAoMPP50W//EEAwHJFeL0IULkIRjSAoQhOYEPZSDiAFEFAw9hYBIDAQWDBZf1lj/0GJ +D4k3LJkU9TwAARkANyCDmWP6DAAckWqPgC4iGI0ghlD+4HQgBRBQMPYWACAwEFgwWX9swCDRDwAA +AADz+ZNgABAoMPP50W//EEAwHJFeL0IULkIRjSAoQhOYEPZSDiAFEFAw9hYBIDAQWDBZf11j/0GJ ImWYwisgQfosAAABEGAw+7wSIAAQaDBYK2XAINEPLDAULCRgY/ZpAAD6LAACAABh8P4yCyIAAGlw -/zIHIgAAWPBYBx3AINEPANogW64/EpEAC6gR9KBhYgAgQLAM6jArIoWLsLCi/LsIAgAAULBZgXAc -kTAqwpzwIQQAARBYMAC7GguqAirGnFmBpcAg0Q/FwiwkBWP2m4sd+iwAAAEQYDD7vBIgABBoMFgr +/zIHIgAAWPBYBx3AINEPANogW64/EpEAC6gR9KBhYgAgQLAM6jArIoWLsLCi/LsIAgAAULBZgXQc +kTAqwpzwIQQAARBYMAC7GguqAirGnFmBqcAg0Q/FwiwkBWP2m4sd+iwAAAEQYDD7vBIgABBoMFgr QGP8FAAA8/j5YAAQGDD6CgcgARBYMFglnSwif/wmgyAAEBAw0Q/9CoQiAABh8P21CCIAAGlwWSJP wCDRDwD6LAACAABY8P0KiCIAAGHwWSNlwCDRDwD+CoUiAABh8P61CCIAAGlwWSJDwCDRDwBsEASL J4u++7wQIgAAUPBYfiKMJy7JFIvILcEV/u0BL8AQQDD0wgshQAJzsP/MICoATXdQ+OwADgBAR/D+ @@ -2081,17 +2081,17 @@ QDD7ogshQAJzsP+sICoAevcQCP8Br8z8zEAmAIIe0Cs9ASu8oP6lFCoAgV8Q/wIABgCF5tCbqBuQ uRyPiBqPoh6PoAAMi/wSCCIAAEjwAElhAElhAElhAElhAElhAElhAElhAElhAElhAElh/jYAIGYQ eDD4IgAgARBIMPo2AiBeEHAw+zYEIgAAWzD8mzkAChBQMPiIEQ4FAFvw/jYFKAkAUjD4NgEgWwA0 4Jc6/DYLIE4QUDD8ClYgiBBwMP41ECoFAFswmjn0DRYAYAJI8PAJpACgAnjw8gQWAIACQPDwCKIC -AABZsPAFFgAGEGAw8A+gAMACUPBZdY+PIsj2wCDRD8As0Q/6LAACAABY8PwKCiADEGgwW717wCDR +AABZsPAFFgAGEGAw8A+gAMACUPBZdZOPIsj2wCDRD8As0Q/6LAACAABY8PwKCiADEGgwW717wCDR DwDAMJOr8/8QYgAAGvADyAwI+AwojQEojOCYqGP++in8QJmoY/7yAAAAbBASHo9HHI9HhSeN4Sni AyVSDvviAiAgAlBwK6YCKaYD/aYBKaAEOOD+4gAkACBFcC1Suv9SvCADEEgwKVa+KFK9LqYA/lK7 -IDAQWDD4FgAgBRBQMFl+YvldAyAAEFAwKhQiKhQjKhQkKhQlKhQmKhQnKhQoKhQp+hQqIP8QcDAu +IDAQWDD4FgAgBRBQMFl+ZvldAyAAEFAwKhQiKhQjKhQkKhQlKhQmKhQnKhQoKhQp+hQqIP8QcDAu FCD+FCwgARB4MP8UKyACEEAw+BQhIQACSnAokHYvkHcvFC8oFC4pkHX5FC0gQAJwcPriASBgAkBw moGP44nimYKfg47g/oYAILcANSAZjxaLkoyR/ZIAIIACUHCdoJyhm6IpkgP5pgMiAABQsFiBvSoW FC0WFysWFSRdAywWFvhJCiCgAmBwi8H/wgMgARA4MPnCAiDAAjBw+WYCIAAQaDD/ZgMgAgJCMPh9 OAAAEHAw+2YBIgAAULD8wgAiAABZsPxmACCAAmBwW7M7LUkK0w9o0GovSQv7HGAiAABQsP4KASBg AmBw//wBIAAQaDD/7TgAABBwMFuzLyhJC2iARvscECIAAFCw/V0DIGACYHD93OggARBwMFiefSlS v/osAAIAAGjw/I7hEAICSnD5Vr8gZBBYMFj6ZSpWwNEPACpFCmP/jgAAKkULY/+yAABsEASDJ/My -DiAFEFAw/I/+EDAQWDBZff4oMsl9jwkpMs7MkyoyGsmoHI/5/TIaIAUQUDD+Ms4gMBBYMFl99ccv +DiAFEFAw/I/+EDAQWDBZfgIoMsl9jwkpMs7MkyoyGsmoHI/5/TIaIAUQUDD+Ms4gMBBYMFl9+ccv 0Q+MICsgPwyNR/C7EQ2ABD9g/AxHCgkAbvAMuwL7Nh0g+AJQ8FiMWvo0/CAAEGAwLDZg/DZhIAEQ WDD7NhoiAABQsFv+0fyOtxIAAFCw/QoAIGQQWDBY+jkuMskqNhz/CgggAhBoMP02Gi4JAHuw/jbJ IAAQEDDRDwAAAGwQBIcnH46gKnkUiHgpcRX6rQEvwBBoMPxyCyFAAlKw+3wgKgA9VlANuwGrmfmc @@ -2101,23 +2101,23 @@ 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 @@ -2125,23 +2125,23 @@ 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 @@ -2150,29 +2150,29 @@ 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 @@ -2180,19 +2180,19 @@ e6Hp+zwAAgAAULD8CgAiAABpcFvBumSv0ywgBXfBdvuLYBIAAFCwWLyRjWeKZrHb/btScAICcrCb Z55m0Q8AAAAAAAD6LAACAABY8PxMAAIAAGlwW8GpZK+S+DRAYCgQQDApYRcpnAEpZRcvIAX/AgAP /73D0CckBfsakCIAAFCwWLx60Q+bZ5pm0Q8qYROxqiplE9EPwrUrJAVj/4AsYRaxzCxlFtEPKyQF +wpkIgAAULBYvG7RDwAAAAD6LAAAKBBoMP0kBSGQEFgwWLxn0Q8AAABsEAqHNPaKahZwATwwB3gJ -DIgRqGYrYn/0MDMgOAA24BqKNC1tAi3QAC6idyqigA7dCAndEf2qCAABEGAwWU95KW0CKZyAKZB5 -/pcHcgAAMrB/nwPRDwAA+jwAAgAAWHBY+W7Ir8Ci/IsaEDIQWDBZePbRDwAA23D8MQoiAABRsFj5 +DIgRqGYrYn/0MDMgOAA24BqKNC1tAi3QAC6idyqigA7dCAndEf2qCAABEGAwWU99KW0CKZyAKZB5 +/pcHcgAAMrB/nwPRDwAA+jwAAgAAWHBY+W7Ir8Ci/IsaEDIQWDBZePrRDwAA23D8MQoiAABRsFj5 V/esAACjADag2nD8TAAAQAJY8Fj4PmWvuPYKKSAoEHAw/wonICUQaDD/AgAAJBBgMP8CAAAATIUg /wIAAgCDASD/AgACAJKFIGhEhWlFgipwBdMP/wIABgDY5pD/AgAGAONukHriB/8CAAgAz36Q/wIA D/+vspAqfGj8CgMgQAJYcFj4F2WvSSocGPwKCCBwAlnwWPgT/wIAAADmJqDaIFj4BdEPAAAAKzEK -+wtLAgAAUbBY+E73rAAPTwC2oMCi/IrkEDIQWDBZeL/RDwDacPscAAADEEAwbYoVLKBoJLAg/wIA ++wtLAgAAUbBY+E73rAAPTwC2oMCi/IrkEDIQWDBZeMPRDwDacPscAAADEEAwbYoVLKBoJLAg/wIA DgDo4RD6rAEgAgJa8CpwBcKUeaElfaExeuImf6Ij2nD7HAAACBBgMG3KDy2wGCygSLGq+7wBLgCx 41DaIFj35dEP/wIAD/9UMpD8PCYiAABR8PsKAiIAAGlwW/9D0Q8qcAV8oRf/AgAGAHjukP8CAA3/ PtGQ/wIADf86+pDaIFj31NEPAAAqcAV8oQh9oTp64i9/oizacPscAAADEGgwbdoVLKBoLbAg/wIA DgCrY1D6rAEgAgJa8NogWPfF0Q8AAAD/AgAP/xQykNpw+xwAAAMQcDBt6hUsoGgtsCD/AgAOAJjj UPqsASACAlrw2nD7HAAACBB4MG36FSygSC2wGP8CAA4Ab2NQ+qwBIAICWvD6fAAAAxBYMPwKACIA AGlwW/8S0Q8rfGj8CgMgQAJQcFj3s2Wtt9ogWPem0Q8AAAAAAPp8AAIAAFhwWPdVya6Jp4mewIEo -lH7RD/p8AAADEFgw/AoAIgAAaXBb/v/RD8Ci/IqAEDIQWDBZeFrRDwAAAAD6fAAAAxBYMPwKACIA +lH7RD/p8AAADEFgw/AoAIgAAaXBb/v/RD8Ci/IqAEDIQWDBZeF7RDwAAAAD6fAAAAxBYMPwKACIA AGlwW/710Q8AAAD9wwZ//xBQMMCh/wIAAf9JpqAqEQH/AgAB/0RykPw8JiIAAFHw+woCIgAAaXBb /ujRDwAAAAAAAPTDBn//EFAwwKFlrQ5j/ir9wwZ//xBQMMCh/wIAAf+QJqACKgJY93bRDwAAAAAA AP3DBn//EFAwwKFlrN5j/qX9wwZ//xBYMMCxZL7N+nwAAgAAaXD7CgQgTAJg8Fv+ztEPAAAAAAAA @@ -2216,9 +2216,9 @@ nUCMcPiIIxBEEFgw+ogBEAgQaDD6RgItgAQ7IPtGAywJAGswnEEpcEEDLAqOwC8SGfwWGiAEEGgw 8JkRDiABcDD+3QwOCQBP8P6JAR4JAEfwn0T/EhQsIAFsMC0WHYzA/kYHIAAQcDAuRQr9EhcsACBr MP1GBiB4AmMwLEUL8A8WAEACaTAATWEtcSr+RC8gABBIMClEM/1ELSAAEFAw+kQxIAAQWDD7RDAg ABB4MP9ENCAAEEAw+EQyIAAQeDD/RC4gABBAMPhENyAAEFgwK0Q1+xIcIAAQUDAqRDb9jRQN4AFg -MP1ELCoAIF8wKxYcKnBXKxIVKkQ7CooUKkQ6CooUKkQ5+ooUAAQQYDD6RDggeAJRMFluBPkSFiCA +MP1ELCoAIF8wKxYcKnBXKxIVKkQ7CooUKkQ6CooUKkQ5+ooUAAQQYDD6RDggeAJRMFluCPkSFiCA AlEwAgmIAEqKAAmIAAqKL3IcLhIeL0RTD48UL0RSD48UL0RRD48U/0RQIHQIcXAoEh35iRcSAABY -cPwKAyBCEFAw+nR0KCABQDD5CgkoCQBKMPl0ZSmABDog+BYAIIoCUTBZbeosEhspcTUDLQsqEhgq +cPwKAyBCEFAw+nR0KCABQDD5CgkoCQBKMPl0ZSmABDog+BYAIIoCUTBZbe4sEhspcTUDLQsqEhgq dFf+0gMgAgJKcCl1NSkSGhiIsChGFo+QL0YXi5CKfy5GGS3SAv1GGCwAIGLwLHYcKZIA+2YMAAIC ELD8FhsoACBWcPl2DyAYADyg8goAIDACGPAdh44tRhotEh3AtQtbL7jcLEYb/HB0LAAgJ3D81HQt 0gC24C4SHgXuDLHu/wIAA/7hQ6ApEhMoEhIoljkrcBYvCv9/sQgqcEEsEhxYIkItEhKOHCwSG5zr @@ -2240,7 +2240,7 @@ wMAswBJlzndj/oEtMF5l3qbz/qtgBBA4MAAmIRQjIRL0CgAvzAA1oPpSQiIAAFjw/AoAIAEQaDBY GS8oUkP0TAEgAgIY8AgzLnZJ22P/oABkzupgADIAAGTO4mAAKgAAZM7aYAAiAAD/AgAH/we+kP8C AAf/A96QY/95d6GB/wIAB/+/XpBj/2uKECwgByshCP6GlBBuAiGw9EQUDAIBZDD8DEEMoAQ/YPDM EQwJAHdw/aYAKgkAZvD8IgAgMAJpsP2mAyAAEHAwnqUdh+Qehn3+pgItgAQ7IP4SAiwJAGEw/KYB -KgkAbvCbpABOjZannaYCCo8sIAwAzBH2pgcqCQBm8PumBCIAAGGw+zxUIFACUrBZbK+OEPmGcx/A +KgkAbvCbpABOjZannaYCCo8sIAwAzBH2pgcqCQBm8PumBCIAAGGw+zxUIFACUrBZbLOOEPmGcx/A BD0g+4ZpHgAge7CeE/P+EmCJEFAwjSeFESzRFS3cIAvdAf3NCAXABD1g/dxAJAAgLPD4XAAKAMbp UJgSY/1EAAAAAPP9TGIAADIw8/10YAAQQDCPImTxUv8CAAf/PgEgiCcpiRQmUr30kTdgQAJSMIWJ JVAH+woAL8AQIDD8bAACAABpcFgZS4gniogpgRX7ggsgQAI6MAR9Af2ZCAIAAGHw+ZxAJgCR1tCL @@ -2258,17 +2258,17 @@ BSYBAkaQsKoMqhH6yggLwAQ+IAuqDAAKiweHYPAKgA+cALogKpEFGYYPFYcO+ZJsK5AEOqDyUkQo ACBSMPgWASngAUAw+BYCKAAgQnAJiBGoIo0nG4Wn/lpAL8AQQDD5LCAgQAJjcPfVFCwAQEMw/tUV IIACYzD81gkgkAJQsPzWCCCiAnGw8AsHAJwCYLAASWEASWEASWEASWEASWEASWErYAScE/liACQA xIbgK2IWJVJE/hYFLZAEOuD4YSIkACBlcC9QfI1Y+yYNIJwCWbCbEC3QBJku+CUiIBwQcDD/JEEm -AJd3UPwKBiDkAllwWWu3ihP8CgYg2AJZcFlrtIUQixX8CgMgwgJQsFlrsNtQ/AoDILoCULBZa62I +AJd3UPwKBiDkAllwWWu7ihP8CgYg2AJZcFlruIUQixX8CgMgwgJQsFlrtNtQ/AoDILoCULBZa7GI aRWG0fgmCy/AEFAw9yYMIAYANiCSjJJpjBQuYAwtYA0rYQcoYAcvYBYpYQkpJQkvJBYrJQcoJAcu JAz9JA0gBhBwMP4kBCBPEGgwLSQFKCIHLCUILFLPK4II/4EVIEACMjD5ggsgAgJjMPxWzyQAQFWw 9yYCLgAgL/D//EAmAHBeUCmJFAxHEft6CAgAID5w+YUUKgBq19DJNfm8AAATADUgbUkFAAOGAElh KmIAB6oI/wIABgB+fpCaYI4gCO0R/BIBLAkAbTCdsY0SLCUJHIae+90IIAUQUDD7JTYgMhBYMFl0 -b9EPAAAnlQXz/flgABBAMADVsFinoYoTixVYp59j/uDApfyGkRAyEFgwWXRkwCDRDwAYhigvYSku -YHyJYJktLyUi/iRBIOQCWbD4Jg4gBhBgMFlrXooT/AoGINgCWbBZa1uIa5gr9yYMIAYANiCSjJJr +c9EPAAAnlQXz/flgABBAMADVsFinoYoTixVYp59j/uDApfyGkRAyEFgwWXRowCDRDwAYhigvYSku +YHyJYJktLyUi/iRBIOQCWbD4Jg4gBhBgMFlrYooT/AoGINgCWbBZa1+Ia5gr9yYMIAYANiCSjJJr 8/6+b8AQUDCXi/P/V2IAAFpwAPv6DAA2ADTgCk4U/OwIIgAAQPD8TDYCAABK8NMPbckFAgiGAElj CjgI/k0MAIACSXBt2QUECIYASWUKfgyuXi7sQJ5gY/8KAC9cQJ9gY/8BbBAS9DIEIgAAeTACJgLy hZAUcAEgMARECQxEEQQiCCQif/4xCyC1ADUgGoYkGYVYKC0CKIAAKZJ3/hYUIgAAWTD6olwgARBg -MPYWEygAIEow9RYSKZAEOiD/FhEqACBCsFlKmC8wMyswMS4wNy0wNikwMPqgByIAAGKwJTA09jA1 +MPYWEygAIEow9RYSKZAEOiD/FhEqACBCsFlKnC8wMyswMS4wNy0wNikwMPqgByIAAGKwJTA09jA1 KYAEPmD43REKIAFQMPoWFyWABD1g9iKDJAkANXD+MQosCQB3cPuZAgBwAljw97wAAEYANaCKZ/qi DiCIAD5g+JJsYA4QcDD/AgACAFYGYGiUCf8CAAQBKgZg0Q9p8vpkb/crFhD8FgkgdAJo8C0WFmAB IwAAAAD5kcRgABBQMP8CAAABe4fg+xYQI54CO+CPNg8fUv4WGCSvADfg+swAAgAAYXBY+S/RDwAA @@ -2280,26 +2280,26 @@ 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 @@ -2311,30 +2311,30 @@ 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 @@ -2368,7 +2368,7 @@ NgUMR/8CAAIAlhsgiieLqP2hFS/AEBAw/6ILIEACcrAC4gH4qRQsACAXcP3cQCYAu1/QjxAM/xGv iPilFCoAIHrw/wIACgC1V1CIEMk4+bwAABYANiBtiQUAA4YASWEq4gAPAgAPqgj/AgAGAMZukJrg 0Q8lIQf58QgtgAQ/YPklCCAGAkLw+EgUAegCWvD7RgMoCQBDcJhJ99sCD+EQQDD7RgEtAAQ+oPhE GCtAASgw+H9kG8AEOqD+8h8qAgF0MP5GCyqgBD7g+39mGgkAWrAegOcl8h71RgosCQBucPxFDyAA -EEgwmUWYQh+A4PuqAgCoAljw+kYALAkAd3D9RgQuCQB/MP9GCCCAAlEwWWWQiicr+sD3ZjkgQAJK +EEgwmUWYQh+A4PuqAgCoAljw+kYALAkAd3D9RgQuCQB/MP9GCCCAAlEwWWWUiicr+sD3ZjkgQAJK sPsKACgAQF5w+6UUIIACSnCZqZmo0Q/RDwAA+6wYIgAAafD8CgEiAABQsFgakGP+so0n/vrAIEAC Y3D+CgAsAEBzMP7VFCCAAmMwnNmc2NEPwoJ4+dopcX99l9T7PAACAABhMPo6/yIAAGlw+iUIIgAA ULBY+0jRD8W1+yQFIgAAULBYDxnRD8DAnKvRDwAAAAAA+90MADYANOAoEgANSRQqnAj6PAAIAwBS @@ -2382,22 +2382,22 @@ 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 @@ -2411,35 +2411,35 @@ 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 @@ -2447,7 +2447,7 @@ VAYgARBYMFuWf8Ag0Q8AAAD6LAACAABY8PxMAAIAAGlwWQ8/wCDRDwDz/8JgABBYMGwQShl7qywg ByUWhocw9Uz/KOABKDD8DEECAAAxcPl3AQIAkQIgiSIYewj1kbdgBgJpcBl7HfzKEQYFADtw/XsD GgAgQrAqFof6ojogBgJZsCsWhQ3NCv3SlyoA5t6QKxKHK7I5DbsB+xaEIZwANuAugkpk4Xkpkn8v gkn5+wEOALhP0CogFAqkh/okFCwAyRKg+DwQICoAPSD6TP8iAABIcG2pBQAIhgBJYSIWgPodAiIA -AFhwWV/z2KD6Fogg/gA2oMCj+xwAAgAAYjBZaEXJfPsShCIAAFCw/WwAABACYPBYEOTwAAdiAABa +AFhwWV/32KD6Fogg/gA2oMCj+xwAAgAAYjBZaEnJfPsShCIAAFCw/WwAABACYPBYEOTwAAdiAABa sAAAAPhBF2IAAEBw+kz/IgAASvDTD22pBQAIhgBJYY0z/FwRAgAAULD8MgIqACBm8FgQmiwSh4on +xKFIgAAaTD7xjkgQAJSsPtMAAAAEGAwWA3S0qDRD4oni6j9oRUvwBB4MPmiCyBAAnKw/haDLgBA e7D+FoEsACB3cP3cQCYAYl5QKakUDEgRqJn5pRQqACBaMPgWgioAXldQyTzJStmwbUkFAAOGAElh @@ -2470,7 +2470,7 @@ aDD+CgEiAABasP8KAiIAAFCwWLNHJTZJLyAG/iICIBEQQDAoJAX//AEgARBAMP8kBi4JAEOwniLz /dJgERBQMAAA8/6LYgAAaTD6LAAAHBBYMPwKASALEGgwWBUeY/4DAABsEASJPxp7bYU+lZD7Mg4g cAIw8PR6ixAAEEAw8lcMAAAQEDD5tgEhkAIpcPg2DyIFADlw+DYOKgARnRAvon0ee2CW8Z4/LaJ9 nT4son/2pn0gAgJjMCymf9EPK6KAKa0ClrGZPyiigJg+JKKC9qaAIAICITAkpoLRDwAAbBAEiiLH -jfopUwAYAHqwCKgBmCLRDwDInlln4dug/CICIgAAULBZZSrRDwBsEASJJ/iSDCAjECgw9gokICUQ +jfopUwAYAHqwCKgBmCLRDwDInlln5dug/CICIgAAULBZZS7RDwBsEASJJ/iSDCAjECgw9gokICUQ ODDynDAgABBYMPKJDAGQAkIw+Ys5ACkQGDD0CisgPwA24GAAEIq+wLD6LAwBkAJSsAyrOcq1LLAA c8noLbAQ+rAfIcQII3B1oQV2oQJ3qdTaIFv/vPP/22IAAFqw0Q8AAGwQBPQiBy/AEEAwJUwg+FUB AAAQGDDzRRQggAIpcJVJlUjRD2wQBCggcNMPfIcUKiAH+yIAKgIBUDBZDjLIp9Kg0Q8AwCDRDysg @@ -2495,18 +2495,18 @@ AC4JAGuw/qYEIDAQSDD5pgMgAhBAMPumAiIAAEkw/aYGIAAQaDD9pgUtgAQ7IP2mBywJAHsw/KYB IEACWrBtigUGCYYAS2eGQiYmHIlB96xAIgDwBlAuCgD+Fg8gAPouYP4SDyADEFgw+iIHIAAQYDD8 PxEAAxBoMPX/CAAIAnOw/vY5IEACUrBYC1/SoNEPABl57i8WExh5/P0hFyAAEHAwnhGeE54UnhWe Fp4XKIKMnhj+FgkiAABQcPi4DAABEHgw/QxGCAkASjD4FhEuSAFoMP19QA+QBDug8N0RDAkAczD/ -FgAsCQBrMPwWAiBgAlhwWAZTZKDJwKX8edUQMhBYMFlnfcCl/HnTEDIQWDBZZ3qLImW8PvtsGCIA +FgAsCQBrMPwWAiBgAlhwWAZTZKDJwKX8edUQMhBYMFlngcCl/HnTEDIQWDBZZ36LImW8PvtsGCIA AFCw/AoBIAQQaDBYE4fAINEPneBj/Bwr4n0q4pcMzBSsuwm7EfuqCAIAAGkw+iYZIgAAYPDypggi AABYsFv3YMAg0Q8uIhOeHS0gUJ0cY/yUhTIlJhyJMZoe+6wAAgB5BlD2kQtgABAYMIon20D8CgAi AABpMPN2OSBAAlKwWAsb0qDRD8GwC8sC+zYEIAAQSDDz/cJgiBBYMAAA8/3RYAAQIDAAABx5ov0S -DCAFEFAw/hINIDIQWDBZZ0gqEhUsEhQvEhMtEhHz/CBgABBYMAAAAAD7bBgiAABQsP0SECABEGAw +DCAFEFAw/hINIDIQWDBZZ0wqEhUsEhQvEhMtEhHz/CBgABBYMAAAAAD7bBgiAABQsP0SECABEGAw WBNQwCDRDwD6LAAAHBBYMPwKASABEGgwWBNKwCDRDwDaIFuQy4oejDTz/S9gBBB4MNog+3wAAgAA YbBbkjOJQfoWDy3ABDqg954UZgAgZfD7fAACAABQsPwKACIAAGmwW5IDjR+trZ0fY/3z2iD7Eg4i AABhcFuSJIseiTHzrAANwAQ6oPee/WoAIGbw2iD8CgAiAABpcFuR9vP+6GIAIB6wAABsEAYZeXwq IAX4IAciAABw8PYKACIAAFlw/CIHIAMQKDD0oMdoIAFAMAsKR/3MMCIAfAKgGXe8/3lhF8AEPiCp dylyOg+PCv/9BCQBAC0w//ILKgCuLlAtcjn/2QEOAKj/UCggBxx3xAgrQAq7EAy7ApuQJiIA+3e4 F4AEOaD7lgImCQAxcPaWAS4AryFQLDAD/JYDICACSnD/AgACAMAaoP48ECAqAD0g+kz/IgAAQ7Bt -qQUACIYASWHAMPx5TxAFEFAw/SIAICgQWDBZZuEldjkuIAT/IAUgCQC3oMzxZDCH0jDRDwAAAAAA +qQUACIYASWHAMPx5TxAFEFAw/SIAICgQWDBZZuUldjkuIAT/IAUgCQC3oMzxZDCH0jDRDwAAAAAA APqS1y85ALcgZKHUKpLVjaGMoJzQj6Cd8ZahlqAsktewzCyW1y+t/40g/fY+IfACYrCcJyYkICYk IWP/AIfMwJD9fwwBkAI58A95OfcKKy75ADZgYAARj57AkP/WDAGQAnvwBvk5ZJ7fJpAAd2nnZJ7W bUkFAAOGAElhwCDRD4knGnhA+woAL/8QYDD8lgAgEAJCcPsmByoAkM6QHnkbKuLVEng4mKGSky/i @@ -2516,7 +2516,7 @@ NqD6LAACAABY8P0SACIAAGEwWA2w0qDRDxt3+C8hCP0KICwgAUAw/ZYDLQAEOyD8CgAuCQBn8JyV bUkFAAiGAElhFngIKKzI/wIACgBYRZAceOcowtsfeOOagZ+hLcLbnaApwt36xtsgAgJKcCnG3Ymw wDD7mgwBkAJKcPP+NGIFAFZw+iwAAAAQYDD7jBgiAABpcFgSgGP/LgAAHXjUItLYH3idmCGfky7S 2J6SLNLa+NbYIAICYzD81toiAAAQ8NEPACqS2I2hjKCc0I+gnfGWoJahLJLasMwsltpj/iebEFll -V9ug/CICIgAAULBYEPuLEIgRiiJj/sMAH3i8LPLeGXi9msGZoSjy3pigLfLg+vbeIAICa3At9uBj +W9ug/CICIgAAULBYEPuLEIgRiiJj/sMAH3i8LPLeGXi9msGZoSjy3pigLfLg+vbeIAICa3At9uBj /1AAAAAAAGwQBIooiacomRT7kgkgMgA2IPmiAiAAEGgwLSQE/SQFL/4QYDDyphkoAEBmcJmi/LAH IAMQaDBb/aXSoNEPAADz/85gABBYMGwQBi4gBNMP9woYJgEmB6D1DEcGATU/kPwWASIAcgMgKzAQ +AoBICsQaDD2Ci0mAdDu0PcKMiYB9LbQ/wIABgCgvtDChv8CAAYA38bQihEpIAfAwPkIQQIAhYKg @@ -2530,12 +2530,12 @@ e4Yr8NEEAf4CYnAAzBoAihr6rP8mACBhsApmApYqKCAgLiAFwJQJiAL4JCAj/zcboAgKQ/8CAAv/ MZqgiifAsPskICAgAlKwWAtswMAsJBQsJAVj/kSNEf8CAAP/H5tgjifI6NogW/v92iBb/PYpIAX4 CgggywA2YC8gIAj4AvgkICP/DBpgCAZD/wIAC/8GmaCKJ8Cw+yQgICACUrBYC1Zj/6YAAPosAAIA AFjw/EwAAgAAaXBb/1PcoPoiCCBnALcgjaJk0F3AINEPjzL8eAYQBRBQMP0iAC74AXww/xYCIDAQ -WDBZZZGIEsJm/wIABgBSthDCe/8CAAYAWb4Qwp3/AgAGAGDOEMOieom5+iwAAgAAWPD8TAACAABp +WDBZZZWIEsJm/wIABgBSthDCe/8CAAYAWb4Qwp3/AgAGAGDOEMOieom5+iwAAgAAWPD8TAACAABp cFkLYcAg0Q8AK6AH+wtBAAEQYDD7vBgiAABpMFgRkMAg0Q8cd+MswtdkwlQed+Ep4tWGkYuQm2CK kPamASAAEHgwn5CfkS3i17DdLebXJp3/jyD/Zj4h8AJycJ4n+CQgIAAQaDD9JCEgBxBgMCwkBWP9 CgAAAAAAAPosAAIAAFjw/EwAAgAAaXBZC77AINEPAPosAAIAAFjw/EwAAgAAaXBZC3nAINEPAPos AAIAAFjw/EwAAgAAaXBZC2HAINEPAAAAANog+4wYIAAQYDBYEWP6LAACAABY8PxMAAIAAGlwWAxf -iCJljsGJEGSevPosAAAAEFgwW5FdwCDRDwAAAAD8d7MQBRBQMP0iACAoEFgw/zAfIgAAcPBZZT0o +iCJljsGJEGSevPosAAAAEFgwW5FdwCDRDwAAAAD8d7MQBRBQMP0iACAoEFgw/zAfIgAAcPBZZUEo MB/Co/8CAAYAwlYQwrT/AgAGAL1eECwKJf8CAAYAt+YQ+iwAAAIQWDBYAKRj/DEAAAAAAPosAAAC EFgwWABxY/weAAAfdokWd5UuIQj8CiApAAQ+IPymAyAAEGAw/KYFLgkAS7D2pgYuCQB7sJ6k8/xp YEACSrAAAI4niuyPoYigmPCGoP9mASAAEHgw/6YAIGACc7D/pgEhsAJCsG1JBQIIhgBJYymsyP8C @@ -2591,33 +2591,33 @@ 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 @@ -2628,19 +2628,19 @@ sGQwSCS2OdEPAt0MDUoU0w9tqQUCAoYARmMKTwz4XEAuACBqMPrsECAiAD/gsP7TD23pBQQIhgBK ZS/JBA2SDKJSIiww8sYBL7sAt+DAIPLFBCCAAkFwmMCYwSS2OdEPCiIMkmlj/10iXECSwWP/kAAA AABsEAgrEhCSFfdythIAAEnw9hIFIgAAEbCbF5kU93GcFgAgObBgAAUAZFBvzSwqYoAKPAH8SfFx /gIpcI0UZNBN+tYAIAAQEDDRDwCPF2TwQgjqMBlw4SmSMcClCio3CpkoqYiYFgwCAIoXKXKC+HDa -GABAVnAIqY4IqAqIhAuAAAzqMIsWDLsMa7HZY/+ewCDRDwDaIFlY92P/kd4w/RIFIgAAeTD6FgAg -CBBYMPxyjRABEFAwWWAMxyvRD2wQBAXqMBZwxShiMcCVCSk3CYgoFHFv8AAVZAAgRXAGqAqIhAuA +GABAVnAIqY4IqAqIhAuAAAzqMIsWDLsMa7HZY/+ewCDRDwDaIFlY+2P/kd4w/RIFIgAAeTD6FgAg +CBBYMPxyjRABEFAwWWAQxyvRD2wQBAXqMBZwxShiMcCVCSk3CYgoFHFv8AAVZAAgRXAGqAqIhAuA AAnqMAlZDGqREwwCACpCggo6AQiqjmUv32mm3NEP0Q8AAAAAAABsEAQTcX32cU4QEAIosPpxexoA EBTQK2J9lbGaIylifZkiKGJ/9WZ9IAICQjAoZn/RDy9igC5tApXxniMtYoCdIixigvVmgCACAmMw LGaC0Q8AAABsEAQTcWj2ckYQcAIosPpyRRoAERTQK2J9lbGaLylifZkuKGJ/9WZ9IAICQjAoZn/R DwAAL2KALm0ClfGeLy1igJ0uLGKC9WaAIAICYzAsZoLRDwBsEAgack0YcIgpooYron0qoowogMEJ uxH6oCQoACBecPoWBSAeAH4wKp0BKqyAmhRgAAcrnQMrvICbFIwV/wIAAACmpyD0zAAAABAYMPZy -OxAAEBAw8AC6YAAQODAsUAcnVRvzVDkg/BBoMP3MAQ//EFgw+1QWLAkAYLD8VAciAABRcFkslYpX +OxAAEBAw8AC6YAAQODAsUAcnVRvzVDkg/BBoMP3MAQ//EFgw+1QWLAkAYLD8VAciAABRcFksmYpX iq4srQT7rQQv/xBIMPmm+iBAEGgwLaa2Kab7La0DKdULKdUKJ6a+KdUr+dUqIegCWvArpv4rpv35 -ppIhQAJjMCym6Cym6SemzhxyG41QL1ANLlAMkhKdEZMQ+GCAIDAQWDD4FgMgBRBQMFlfkStggAAw +ppIhQAJjMCym6Cym6SemzhxyG41QL1ANLlAMkhKdEZMQ+GCAIDAQWDD4FgMgBRBQMFlflStggAAw BAsLG3+/dowV8iwBIAICGPDzwX9wAgIhMI8UHnIIKfANKOJzL/AMLuKG+DUICAAgQTD5iBEFkAQ9 YP5VCA4AIEOwLlYQ/1QMJdwQUDAqVRopVA0pYIAAIAQJDRv/AgAD/4H/UG0ID7EiACAECQ8b/wIA -A/94f9Bj/+kAAAAA+goFIDAQWDD8cfESAABo8Flfa2P/ctEPbBAEiCcbcDX3+sAgBBBQMPWJFCIA +A/94f9Bj/+kAAAAA+goFIDAQWDD8cfESAABo8Flfb2P/ctEPbBAEiCcbcDX3+sAgBBBQMPWJFCIA ADCw8oIJIEACIjD5gRUkAEA5MPRMQCCAAilw9YUUIYACELDyhgkqAAQgkKKSkokAC4v9cD8SAAAo sNMPbaoCAEVhnSCMYPjMEQAEEGgw8yYCLAkAazCcIdEPAGwQBBlxEyggBB9xz/0iDiAAECAw/iIL JgB4AiD88ukgVhAoMPoiDCAAEBgw++wABgDYz1AJ2BH0oHNsACBDMJ6riytksAIqtgyKJ5Mr8yYM @@ -2649,11 +2649,11 @@ ADUgG3DwJSAHK7F+9OK7IgAAULD7KxQEIAEsMFiOMWShrNEPAI3Jctlp/sYJIgAAW7AuwAX4CkIg BgA24JO8/wIAD/++w5CJyWWfc4rLZa9u+8IAID8QQDAoxAUu8tL68uwgARBoMP67DAAAEGAwWAJd GnGVia6wmZmuY/9BACvyEoog/wIAC/+F2pDz/wNgARAgMI3L+MIKIBoIE3Cey4srY/+MAAD/AgAO AESSEJ7K8/99YgAAW7Ap4kIq4r0rIQn5nP8gABBgMPnmQiABEGgwWAJFiycqvCD+IgIqAEAysPO1 -FCCAAlKwmrn6tgggKQA3oPxxdRAFEFAw/SIAIDIQWDBZXuqKIlld5sfP+6wAAgAAULBYCYojJAUt -IQn+IgAgBRBQMPxxahAyEFgwWV7f0Q8tIAX/AgAP/3urUC0hNv4hNyAFEFAw/HFiEDIQWDBZXtfR +FCCAAlKwmrn6tgggKQA3oPxxdRAFEFAw/SIAIDIQWDBZXu6KIlld6sfP+6wAAgAAULBYCYojJAUt +IQn+IgAgBRBQMPxxahAyEFgwWV7j0Q8tIAX/AgAP/3urUC0hNv4hNyAFEFAw/HFiEDIQWDBZXtvR DwCILQmIEfWuVWwAIEMwicv/AgAOAHASUJ7LiyvIsJO8KsAFw7D/AgAP/yBakI3LZd42jsxl7jGI zWWOLPvCACArEEAwKMQFLvLT+vLtIAEQaDD+uwwAABBgMFgCDWP+CC0hNv4hNyAFEFAw/HFFEDIQ -WDBZXrnRD40nGXFCmUAs0RX4IgAgARA4MPvSCCBAAnNw+dILLgBAN7D/zAgJgAQ6IPzMQCgJADow +WDBZXr3RD40nGXFCmUAs0RX4IgAgARA4MPvSCCBAAnNw+dILLgBAN7D/zAgJgAQ6IPzMQCgJADow +EYBINQEWnAq2RQqrBD61RQgIAJS8HrDXMhJAASGAEthitgqrBD/AgAGAEbmkJrgiyJlvev7XBgi AABQsPwKASBAEGgwWAqt0Q+NzXLZCZ7N8/8dYgAAW7CIzP8CAA//iZIQnszz/wliAABbsACT22P/ vAAAAPvMDAAyADUgDE0UuNr6ejYCAABJMG2pBQIJhgBLY6xJ+vxAICQAP2ANewzTD225BQQJhgBK @@ -2688,7 +2688,7 @@ UrD65gEqABZakCzhBarKmuEebfGeoI0g+N0RAAEQcDD1pgIsCQB3cP2mASAAEBAw0Q8ebeieoI0g o0QkVd4jICKJK/xyeyABEFAw9DAcYf4CWPAAwQQAuxoAqhr6rP8oACBecAqZApkq0Q+NKZ0q0Q8A AABsEAQoIAb4jP8iAABQsPgkBiABEFgwW4j0wCDRDwAAAAAAAABsEAQUbyUBIhGiMqQigiDRDwAA AGwQBhhvUgEpEakz8AAJYgAgQPAAymzNeioigApLAftZ8nH+AjGwiRzyCgAgFAA2YGAACADacFlV -qmP/25qQ0Q/AINEP3TD+TAACAAB5cPoWACAIEFgw/G8+EAEQUDBZXL3HK9EPAAAAbBAEGG84AScR +rmP/25qQ0Q/AINEP3TD+TAACAAB5cPoWACAIEFgw/G8+EAEQUDBZXMHHK9EPAAAAbBAEGG84AScR pzeodyZygMePCEgDCGYBBlYCJnaADAIA0Q8AbBAEKSEEhyDzWBQJwAQ+YPl3CAngBDogCHcMJ3z8 9nIAKIABHDDwkQQAARBAMACIGvCQBAoAQDYw+wMZD/8QUDDwkQQIEQBSMPBIGgYAQEGwCGYC9nYA IBkANWAlIQLNQiohA7FbCwtP+yUCICgEWrDSMNEPsFz8JQIiAAAQ8NEPwND9JQUiAAAQ8NEPAAAA @@ -2742,14 +2742,14 @@ ipEmYn+MkJygi5CIMvq2ASAAEFgwm5H7lgAh/gJCMJgyhSf1XP8nkAQ94PUmByIAID2w+0UDIAgA NWDSMNEPJCAaDwIADwIAJkzo+yQbJuABMDD/ZhNv/xBIMBhseAhoCimGqymGsyQgGvI8AAIAAFLw CuQWAQIAHWtJLNKCAEEEAL4a8EEEAAEQeDAA/xoJ/wMPzAEOzAIs1oIK5BbRDwAAbBAEFmwhASUR pTWmVZRQDAIA0Q9sEAgYbE6SFPYSBCIAABGw8AAIZgAgQbDKXM0pKmKACjkB+Unycf4CKXDyCgAg -FgA14GAACgAA2iBZUqVj/9wAmnDRD8Ag0Q/eMP0SBCIAAHkw+hYAIAgQWDD8bDkQARBQMFlZuMcr -0Q8AAABsEAQaax4WbFDz+v4gABA4MCRirgACACmi0AOZASmm0BhrMyeGXFlVRFlb7xVsSB1qwAgs +FgA14GAACgAA2iBZUqlj/9wAmnDRD8Ag0Q/eMP0SBCIAAHkw+hYAIAgQWDD8bDkQARBQMFlZvMcr +0Q8AAABsEAQaax4WbFDz+v4gABA4MCRirgACACmi0AOZASmm0BhrMyeGXFlVSFlb8xVsSB1qwAgs EAxMAg3MAixmrhtsPSe2hCpSIhRqa/ZsJBAAEBAw92rLEEYANqATbD0rcnsqUtyrKwm7EauqLjKA -LWCAACAE/Q0bDgBAI7D+NoAgHAB/cCyiH8jDwLFZHnktUiKxIvM9QCv/4+yQxz4fbC4u8oID7gEu +LWCAACAE/Q0bDgBAI7D+NoAgHAB/cCyiH8jDwLFZHn0tUiKxIvM9QCv/4+yQxz4fbC4u8oID7gEu 9oJYhfzRDwAAAGwQBMBABOQWAQIAFmrwJWKCACEEADca8CEEAAEQQDDwiBoP/xBIMAmIAwhVAQdV AiVmggTkFtEPbBAEKyAHFmo7HGpC+wpBCgIBXDD4atQaoAQ+4PkhCCoJAGbwmzCHIPQ2CCsABDqg 9TYJKAkAVnD2NgIoCQBGcPg2BiAgEBAw8jYDIAMQQDD5NgQgABBIMPk2CieABD3g+TYLJgkARfD3 -NgEgYAIQ8NEPAABsEAQsIAf7IgAiAABQ8P0KASAEEHAw/CxAADAQeDBZV1cdaiMYaokea/XwDQcC +NgEgYAIQ8NEPAABsEAQsIAf7IgAiAABQ8P0KASAEEHAw/CxAADAQeDBZV1sdaiMYaokea/XwDQcC AABKsABJYQBJYQBJYSkgBy8hCAkJQfCZEQAAEFgw8qwwLgkAT/D+pgIuCQBH8P+mACAgAkqwAgSG AEljAASGAElhK6QW0Q8AAABsEAQoIAcaaggIKEAKiRAKmQKZMIcg9mn4F4AEPeAHVwKXMfAGFwAQ AjjwAAeK+yEIKcAEPWD6a1odAAQ6IP1p8hBgAhDw/TYEKgkAZvD8nOgqCQBW8Ps2BiGgAkpw/DYF @@ -2809,11 +2809,11 @@ mRTIqSsgBvqSCSAAuAbg+iwAAAQQWDBb/91loM+MMyshCQwMQ/S7EQ2wBDsg/AoQKgkAZvAMuwKb YGAAEAAAAC48EPAOFgIAAGmwAE1hLyAFbvhsKCByfo9m2iBb/19loJQpIAX7IgIosAE6YCogcn6v TfWwgGvABDngG2bZ/WbZGgAgWrAsojoNfQr90pckAKfDICyiOZoR/csBDgChbxD8bAAAAhBoMP4K ACIAABqw/woCIgAAULBb/x7A5C42OY8QaPJIiif7TAAAABBgMPqsICIAAGkwW/nR0qDRD/osAAAC -EFgwW/+pZK9SwCDRDwAAAAAAAPosAAIAAFjw/EwAAgAAaXBb/tnSoNEPAMAg0Q/aMFlU+fusAAP/ -ZcKg/wIAAgBIAqD/AgAF/12WoP8CAAP/Wcag2iBZVNnAINEPAIsxC8tTaLF8jDL8jFcANxBoMP8C +EFgwW/+pZK9SwCDRDwAAAAAAAPosAAIAAFjw/EwAAgAAaXBb/tnSoNEPAMAg0Q/aMFlU/fusAAP/ +ZcKg/wIAAgBIAqD/AgAF/12WoP8CAAP/Wcag2iBZVN3AINEPAIsxC8tTaLF8jDL8jFcANxBoMP8C AA//S+sQ+iwAAAgQWDBb/4plr4IuPBDyDhYCAABpsABNY2P+0mSukI+g/49XACoQQDD/AgAP/0HD -0BlnR4ii/wIAD/87ShCMIv68/y/+EGgw/iQGLABAazCcImP+Wooz/wIAAf8W7pDaIFlUx8Ag0Q/6 -LAACAABY8PxMAAIAAGlwWVR90qDRDwD6LAAAMAJZ8PwKASAEEGgwWAHaY/8BAABsEAgbaGqbEPgi +0BlnR4ii/wIAD/87ShCMIv68/y/+EGgw/iQGLABAazCcImP+Wooz/wIAAf8W7pDaIFlUy8Ag0Q/6 +LAACAABY8PxMAAIAAGlwWVSB0qDRDwD6LAAAMAJZ8PwKASAEEGgwWAHaY/8BAABsEAgbaGqbEPgi ACAAEEgwmRL5FgMiAABQsPMWBCACEGgw9BYFIAIQYDD1FgYpgAQ6IPYWBygJAGIw+BYBIgAAWHBb /2LRDwBsEATAINEPAGwQBpMQ/QoBIIACWfD6IDsiAABhcPYiByIAAEmw/BYCL8AQQDD5FgEqYAFQ MPVsICvABDqg+joIBABARXDwACdgUAJSsCggO7GIKCQ7LGEV/dwBLgAgLzD+rBAggAJ78PrsAAoA @@ -2823,7 +2823,7 @@ UDD5Zs4YAEBKMPMDSgqgBDqg9AVDCAkAUjD5ZjIYCQBKMPh2ACSABD1g+iIALgkAL/D/dgQqCQBm 8PR2BiLABDjg+3YCLgkAE7D+dgMgCAITcPsSAiuABDqg+3YFKgkAULCacQAJjfloCRBgAinwAAWK CdkCmX7RDwzqDGP/EQAAbBAE/WYXEBEQQDD7PBEKAASaEMGVc5toiyeJIo+zKLEDirKa8PqyAigO AUAw+IgJDAAgbzANiAr4jRQv/xBwMP+mASAAEGgw/bYDKhEAcTD9tgIoAEBWcJkiL4KyGWfssP// -hrIsACBLMCrCULCq+sZQIAEQeDD9tQMgFQA2oNEP2zD8IgIiAABQsFlRgtEPKs0BKaA+K5zoCwtH +hrIsACBLMCrCULCq+sZQIAEQeDD9tQMgFQA2oNEP2zD8IgIiAABQsFlRhtEPKs0BKaA+K5zoCwtH /7YTYgAAE7AcZ8QMvAouxqsuxrMpoD7e0A7kFgECABpmliiiggCRBADbGgCRBAD8GgLMAwyIAQuI Aiimgg7kFtEPAABsEAQsIAcdZdYMC0EMuhH/ZdUaACBqsCiiOg+/Cv/ylyQAUsIgLqI5DClACpkQ /+0BDgBKf5AoIQcfZkj+Zd4ZQAFAMPQxECnABDog+YgCCQAEPuD7ZdAYCQByMJjQ+SIAJAkASTD/ @@ -2879,7 +2879,7 @@ FvP/3GABECAwD04LhOOP4qSk9OYDKgADURCx/5/iY/yvY/3giTjKmYs5wKCaO5mwjDibwZo4+jYJ L5kQQDD4NAUgABAQMNEPAMCQ8/yCYgAAanAt+pn9NAUgABAQMNEPAMCBKDYWY/7vixz6LAAAARBg MPu8GCAeEGgwW/5SwCDRDxti+YoUCZkJ+6oICcAEPmCqmSmdCSmceCqR3iiR3SmR4QqIAfoKASv9 W8oQixz6LAAAARBgMPu8EiAAEGgwW/5BwCDRDwAAABxk1o0gLiIYiDCPoP7gdCAwEFgw+BYAIAUQ -UDBZUiSJOGSd1oI5mSCIOPKGASAAEHgwnzifOf82CyAAEBAw0Q/AINEPAAAAbBAEyDHRDwCIJ/aJ +UDBZUiiJOGSd1oI5mSCIOPKGASAAEHgwnzifOf82CyAAEBAw0Q/AINEPAAAAbBAEyDHRDwCIJ/aJ FC/AEDgw84IJIEACKjAHVQH1XEAgIAIxsPaFFCHgAhjw84YJKgAUqNAqgRX7YvMaACAasJqJm6CJ IPiZEQABEFgw9KYCKAkAXnCZodEPHGLqnDCLIPi7EQABEGAw9DYCKgkAZvCbMdEPAAAAbBAEZCB2 ZDBzZFBwKCICGmKs9AlHAD4CaPD9TRQAXwC2IAyYEfxipxgAIFIwKoI6DJwK/MKXKgAlbpArgjke @@ -2925,8 +2925,8 @@ BfvHIAX7uiAF+6cgBfuaIAX7hyAF+QsgBft0IAX7ZyAF+1QgBftHIAX7MyAF+vIgBfqyIAX68iAF +rIgBfkLIAX5CyAF+QsgBfkLIAX5CyAF+QsgBfqlIAX5KCAF+QsgBfkLIAX5CyAF+oggBfpvIAX6 ZSAF+lQgBfkLIAX6QSAF+icgBfoUIAX5+iAF+ecgBfnPIAX5vCAF+akgBflFAAAAAAAAAAAgBf8s IAX/NiAGALIgBgCMIAYAhSAGAH4gBgB3IAYAcCAGAGkgBgBiIAYAWyAGAFEgBgBHIAYAMSAGAAYg -Bf/aIAX/0SAF/7YgBf+sIAX/nSAF/40gBf+GIAX/cyAF/2wgBf8eIAX/QwAAAAAAAAAAIAag2CAG -njAgBpzEIAaacCAGmBggBpTgIAaV2CAGloggBpRUIAaY3AMPCBKDjpOSUlYAABAAAABjb25maWd1 +Bf/aIAX/0SAF/7YgBf+sIAX/nSAF/40gBf+GIAX/cyAF/2wgBf8eIAX/QwAAAAAAAAAAIAag6CAG +nkAgBpzUIAaagCAGmCggBpTwIAaV6CAGlpggBpRkIAaY7AMPCBKDjpOSUlYAABAAAABjb25maWd1 cmF0aW9uIGZpbGUgcGFyc2VyIGZvdW5kIGFkZGl0aW9uYWwgY29uZmlndXJhdGlvbiBhZnRlciBb ZmluaV0KAAAwAAAAZmNvZQAAAAB2bmljX2lkAHZsYW4AAAAAdG9zAGV0aGVydHlwZQAAAG1hY21h dGNoAAAAAG1wc2hpdHR5cGUAAGZyYWdtZW50YXRpb24AAABzcnZyc3JhbQAAAABmY29lbWFzawAA @@ -2940,13 +2940,13 @@ X2ZvZmxkAABmY29lX2luaXRpYXRvcgAAZmNvZV90YXJnZXQAcG9mY29lX2luaXRpYXRvcgAAAABw b2Zjb2VfdGFyZ2V0AAAAaXNjc2lfdDEwZGlmAAAAAHBwcABkY2J4AAAAAGIyYgBzb2NrZXRudW0A AABjZWUAaWVlZQAAAABhdXRvAAAAAGFuX2RpcwAAIAMWlAAEAAAAAAQAAAQAAP8CAAAAAAAAAAAA AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8CAAAAAAAAAAAAAAABAAL/AgAA -AAAAAAAAAAAAAAAC/wIAAAAAAAAAAAAAAAAAFgAAAAAgBpQYAAAAACAGk2ggBpD4IAaP6CAGbqgg +AAAAAAAAAAAAAAAC/wIAAAAAAAAAAAAAAAAAFgAAAAAgBpQoAAAAACAGk3ggBpEIIAaP+CAGbrgg BgdAIAXzACAF8eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBH0EIASJgCAEiYAgBImAIASaGCAE syAgBL+oIATHCCAEegwgBHeAIAQxhCAE5OwgBC80IAQsKCAF8bQgBfCEIAXp6CAEiYAgBekQIAXn -tCAF5uggByRgIAOc1CAD96wgBqusAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBFVA +tCAF5uggByRwIAOc1CAD96wgBqu8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBFVA IAQ/7CAETzAgBE2cIARMJAAAAAAgBEnIIARUfCADX8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -A///AAAD/wAAAD8AAAAPIAc0/CAG3cAgBzToIAbd0CAG3eQgBt0oIAbeaCAG3Pj/GDBgYAAAAAAB -AgMAAAAAIAahhCAEe2QgAIgIAAAAAAAAAIEAAAAAAAAAAAAAAAAgBCWYIAQkzCAEInAAAAAAIAQD +A///AAAD/wAAAD8AAAAPIAc1DCAG3dAgBzT4IAbd4CAG3fQgBt04IAbeeCAG3Qj/GDBgYAAAAAAB +AgMAAAAAIAahlCAEe2QgAIgIAAAAAAAAAIEAAAAAAAAAAAAAAAAgBCWYIAQkzCAEInAAAAAAIAQD hCAEA3wgBAN0AAAAACAD+nQgA/wAIAP7nCAD/BQgA/qQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAACAD+yQAAAAAAAAAAAAAAAAwMTIzNDU2Nzg5YWJjZGVmQUJDREVGAAAAAAAAAAAAAEFCQ0RF RkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5 @@ -2957,7 +2957,7 @@ AQBBAIEAIQCBACEAEBBhAQEAgQEBAIEDAgEAECBAAAAAAAAAAAAABAACAAEAAIAAQAAgABAACCBA gAAAAAAAAAAAAAAAAAAgAwkQAAAAACADD9gAAAAAIAMJFAAAAAEgAxCAAAAAAiADCRwAAAAEIAMJ JAAAAAggAwksAAAAECADEIgAAAAgIAMJMAAAAEAgAwk8AAAAgCADCUgAAAEAIAMJVAAAAgAgAwlk AAAgACADCXAAAEAAIAMJfAAAgAAAAAAAAAAAAAAAKhwAACo8AAAqXAAAKnwAAAIEAAAARAAAAAQA -AABAIAalICAGpNwgBqOsIAaiVCAGohAgBqHkIAaiPAAAAAAAAAIAAAAEAAAACABZZXMAMDEyMzQ1 +AABAIAalMCAGpOwgBqO8IAaiZCAGoiAgBqH0IAaiTAAAAAAAAAIAAAAEAAAACABZZXMAMDEyMzQ1 Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6AAAAAG5vbmUAAAAAYWxsACoAAABkaXNhYmxl ZAAAAABlbmFibGVkADB4AABOQQAAVjAAAFYxAABWMgAAVjMAAFY0AABWNQAAVjYAAFY3AABWOAAA VjkAAFZBAABWQgAAVkMAAFZEAABWRQAAVkYAAFZHAABWSAAAVkkAAFZKAABWSwAAVkwAAFZNAABW @@ -2989,8 +2989,8 @@ dGFsR3JvdXBUYWcAAAAAQXV0aE1ldGhvZAAAU2VuZFRhcmdldHM9QWxsAENIQVBfQQAAQ0hBUF9J AABDSEFQX0MAAENIQVBfTgAAQ0hBUF9SAABEaXNjb3ZlcnkAAABOb3JtYWwAAE5vbmUAAAAAQ1JD MzJDAABDUkMzMkMsTm9uZQBOb25lLENSQzMyQwBDSEFQAAAAAENIQVAsTm9uZQAAAE5vbmUsQ0hB UAAAAE5vdFVuZGVyc3Rvb2QAAABJcnJlbGV2YW50AABSZWplY3QAAE5vAAA1AAAAQ0hOZXQgMS4w -MAAAAAAADAAAAAABAAF8AAwBAAAAABAAAAAUIAdK0AAAAwUOQAAAAAAAEAAAACggB03YAAADGA5Q -AAAf/AAAH/wAAB//tLAf/7SwIAdYICAHW+AgCUDgIAlA4CAKAAAgCoAAIAqAACAK5oAgAwAA4QAu +MAAAAAAADAAAAAABAAF8AAwBAAAAABAAAAAUIAdK4AAAAwUOQAAAAAAAEAAAACggB03oAAADGA5Q +AAAf/AAAH/wAAB//tLAf/7SwIAdYMCAHW/AgCUEAIAlBACAKAAAgCoAAIAqAACAK5oAgAwAA4QAu AB//k7AAAGGo4QGOAAAAQA8AAZEMgAAAACALevAgC3sgAABAAAAAgAAAAAgAIAt8IP//8/8gC3xQ AACoLAAAqC8AAKgrAACoKgAAqOwAAIEAAACoNQAAqDcgCwEw4QBeACALAXAAAEAOAABAGiALAaAA ABAAAAD/6QAA/+AAAFAAAAD/+AAAqDv//8kkAABADQAA//cAAA//AAAPQgAA//UgCwIAAACABwAA @@ -3003,10 +3003,10 @@ SP/4XuD/3///4QL+ACADACAAAYafAACvAOEBDgAAAIj3ACAAAAE/AUAAD0JAFH01cBR9NW8f/6wU IAt+MCALfpAIAAAAH/zi5CADZ1wf/62cIAsGMCALB2AgCwZgDzwAACALBvAgA+S8IAPmkCALB8AP AAAAIAsIIB//hmAf/4dQH/+E0CALCHAgCwiwIAsI8CADDbAgAw0wIAuAICADDRAgC4BQIAt/ACAL f2AgC3/AH/+t8OAAAAAgAEXsH/+u9AD///8gC4BwIAsJgCALCeAgCwowIAsJsCADv2QACAAAIAPE -JCALC8AgB1RAAA/8AB//mXgf/5rMAAAwACALDAAgCwyQIAsNMFUAAAAOAAAAIAuBECADDigAAAgG +JCALC8AgB1RQAA/8AB//mXgf/5rMAAAwACALDAAgCwyQIAsNMFUAAAAOAAAAIAuBECADDigAAAgG IAsNYCALDkAAAA/+H/+trCALDtAgCw6gAADwACALgTAgCw7wIAsPUCALD4AgCw/gIAsQMCALEPAg C4FQIAsQkCADgNggA5iIIAsRUCALEZAgCxIAH/+toCALElAgC4IgIAOexCADpBQgC4HgIAsTACAL -EpAgCxNwIAsT0CALFEAgB1ugIAsUwCAHWHAgCxTw7////yALFVAgCxWgIAsYcP3///8gCxYAIAsW +EpAgCxNwIAsT0CALFEAgB1uwIAsUwCAHWIAgCxTw7////yALFVAgCxWgIAsYcP3///8gCxYAIAsW cCADpoQgCxbQIAsXMCALF5AgCxfgIAsYICALgnAgAw4gAABgACADDbQMAAAAH/+GwB//h8AgAw+w H/+GoD/////P////IAsY0B//h3wgCxkQIAsZUCALgpAgCxnQf///q///LlwAANGk///QTQAAnE4g CxpQIAsaECALGZAf/4a8IAMNuAAAaAAf/4a4AAAgAB//hyAgCxqQIAPfOCADx/AgCxtAH/+tlCAD @@ -3015,19 +3015,19 @@ YB//rlQgCx0AIAsdQB//reQgCx5QIAsdkABMS0AgA8d0IAsd4CALHpAEAQAIIAOo/CALHxAgCx7A IAsfcCALgNAgA9zUIAuAoCALIiAAAI4CIAsikCALIuAgCyMwIAsiUCALI4ADgAAAH/+wQCALI9Ag CyQw//f//yALJSAgCyXgIAPYgCALJqAf/6wgAADAACAD29wgA9aMIAPIDCALhRAgC4VQIAuE4CAL JuACAAAAIAsnICALKAAAABdwIAuF8CADC3QgC4ZAIAuGcCALhpAgC4YgIAP5JCALhcAgAwtUIAMK -5CADCuwgCygwH/+sQCALKFAgCyiAIAsooB//qxQgB1YUIAso0B//qkDhAH4AH/+sTAAA8/8EAAAA +5CADCuwgCygwH/+sQCALKFAgCyiAIAsooB//qxQgB1YkIAso0B//qkDhAH4AH/+sTAAA8/8EAAAA FAAAACoAAAAgBAH4IAspgB//rlAgC4dgIAuHMCAAHxgaAAAAIAsqECALiBAf/65AAB6EgCAEXIgf /7EkAA///yALKmAf/6/kH/+uBCALiKAf/62MOAAAAAAAH0AwAAB0AAAQNv//7/8f/7EIMAAAECAL ieAf/5nkiIiIiB//ragf/5VsAAAMvAAAiQYgCyqgH/+VWACcAADgAAkkH/+qiCALKsAgCyrgAAME -wOEDAgDg//4A4QCOAAAAloAAAJZAIAdYIAAAlqAAAJZg4QMALAADAAAf/N4A4QB6AAAB4ADhAZIA -AAHjAB//rbQgCysgIAsrUB//soQgCyugIAssAB//lRwgB1sgF5AAABSwAAAgB1pwgAAABCAHWyoA -AB9aIAMAeCAHW3AgAwCAFqAAAAhQAQAgoAAAP/AAACOgAAAD/wAfAMAABCAHH5ggBEVYIAcfXN6t -vv8f/7KIGsAAACAHWigAAP/qIAdbMAAACBQAAIgAABAAAB//rAwf/664IAQLzCADAJAgC4hQIAuI +wOEDAgDg//4A4QCOAAAAloAAAJZAIAdYMAAAlqAAAJZg4QMALAADAAAf/N4A4QB6AAAB4ADhAZIA +AAHjAB//rbQgCysgIAsrUB//soQgCyugIAssAB//lRwgB1swF5AAABSwAAAgB1qAgAAABCAHWzoA +AB9aIAMAeCAHW4AgAwCAFqAAAAhQAQAgoAAAP/AAACOgAAAD/wAfAMAABCAHH6ggBEVYIAcfbN6t +vv8f/7KIGsAAACAHWjgAAP/qIAdbQAAACBQAAIgAABAAAB//rAwf/664IAQLzCADAJAgC4hQIAuI cP8///8gAwDAIAssMDAAAAgwAAAMNAAACNAAAAAAAIkUOwAACDSQAAAFXUqAIARiRAAYAAD/B/// ADgAAAAwAAAgC4sgBgAAACAEb+z4AAAAAf//5wABwAAgAACABAAQAB//qlDhAZoA4QGaQOEBmjzh AZo44QGaNOEBmjAf/66gIAMK/CADCvSAAAADH/+tpP/8//9/////H/+VnCAEfQQgC45wIAuOsCAL juAgC48gIAuPUCALj5AgC4/AIAuQACALjkD//wAAD///8P/wAAAgC5CgH/+alCALkGAf/6mkIASJ -gCALkaAgC5HQIAuRQCALkOAf/5pEH/+bdAAA/4AAAC7gIAstICALLVD/+///AAQAAOEB4sAf/6xQ +gCALkaAgC5HQIAuRQCALkOAf/5pEH/+bgAAA/4AAAC7gIAstICALLVD/+///AAQAAOEB4sAf/6xQ kAAA8Pz/gMACAAAg/v+AwCALLaAgCy3gAAD4AAADAQgAAwEMj////yALLjAgCy6AIAsusCALLvDh AN4AAAMDCAADAgAf/6xE///wAOEA7gD//3//AAD8AB//rbwAAOAAAAAMAAADAwQAAREcAAERGAAQ CACAAAgAH/+ddAADAQT//8AAAAD//gAAJYAAAwMAH/+sPOD/4sAf/6roIAuSICALklAgC5JwIAuS @@ -3047,26 +3047,26 @@ EJkAAAA0AAAAIAufwCALQfAAGQAAIAtCQCADDkAAABIPIAtCsB//qlgf/7DMBQAAAIP/ABsDFQAA IAtDIP//QAAgC6JwIAtEACALRIAgC0TQAAGRrOEBkay/////IAtFAAsAAAAgBd84IAtFcCALReAg C0ZQIAtGgCALovAgC6NwIATJjCADCxQf/5yoAAE4gOAABgAAAicQIAukEH///w8f/60Y/AD//+EA lgDhAJoAAAAJ/+EAngAAALAAH/+uOCADArAgC0eA4QAOAAMAAAAAOP//4QASABMAAAARAAAAH/wA -AB//rXwgC0fAIAulMAABlI8AAZTPIAMC0B//nZAgAwdQIAtIACAHUnAgC0gwH/+ruCADCCAf/5Qk +AB//rXwgC0fAIAulMAABlI8AAZTPIAMC0B//nZAgAwdQIAtIACAHUoAgC0gwH/+ruCADCCAf/5Qk H/+cnB//mygf/5yU4QGeAP+///8AAZ80IAtJYCALSaAf/5UUIAtOgCALTtAgC08wH/+qzCALUKAf /6twAD///x//mzwAAP/9AAD/lwAA/9X//6uTwgAADgXcAQAD/wAAwAAAASALUQAgC1FAIAtRkCAL UdAgC1IgIAtSYB////Af/65kAgAAEB//nbAf/5WoAAL//wAAnEAgC4ogIAtUwCALVTAgC1XwIAuH kCALVoAgC1bAIAtXACALV0AbAAAAAAUAAiALrNAAAP4AIAYaHCALV5AgC1ewAAAhACALrZAgC60g -IAutYCAGKowgB1QYIAdUKCAHVFAgC1fg///I////8f///9/PIAtYEP//n/8AACAE///fOCALWEAf -/5VwIAdYUCAHWFggC1hwAAGQ+P/8+H8gC1iwIAtZICAHU+QgC1lQAAMAAh//nXAgC1nQIAtZgCAL +IAutYCAGKowgB1QoIAdUOCAHVGAgC1fg///I////8f///9/PIAtYEP//n/8AACAE///fOCALWEAf +/5VwIAdYYCAHWGggC1hwAAGQ+P/8+H8gC1iwIAtZICAHU/QgC1lQAAMAAh//nXAgC1nQIAtZgCAL WgAf/6rs4QMKAB//quQgC63w9////wEwGMAgC1pgIAtaQCALrjAgC1qAIAtbACALWsAgC1ugIAtb -4CALW0AgC1twIAuucAABhqAgBlhk4QMABAX14QAAJiWgAmJaACADCIjhAwAwAAQF7uEDAQThAeIA +4CALW0AgC1twIAuucAABhqAgBlh04QMABAX14QAAJiWgAmJaACADCIjhAwAwAAQF7uEDAQThAeIA H/+VYABgAAAf/5WEH/+quAAFAAQABBQAH/+dfB//nYAgCAAAIAgusCAIBmAgCG8AIAgFUCAIBEAg -CAMwIAgCICAIARAf/648H/+qDCAHVEQf/6iYH/+rUCAB2fzhAHYAIAuy4B//rUQgC2JAIAOeYCAH -W2ogC2TQIAda7BSQAABAAAAEIAtlQCALZXAgC2NAIAdbYCALY4AgC2PgAACP/iALZDAjKBUAIAtk -kCALs1AgC7PQIAdaqB//s6gf/7CwH/+zGP/oD/8AEIAAIAtmwCAGkhDhAFYAIAMIkOEAWgAByEAG -4QGZ4AAAflAAAH5AAAB+GCAGnjAf/6wQIAMP4CADD+QgAw/YIAMP6CADD/QgAw/8AFAgBuEBmgwA +CAMwIAgCICAIARAf/648H/+qDCAHVFQf/6iYH/+rUCAB2fzhAHYAIAuy4B//rUQgC2JAIAOeYCAH +W3ogC2TQIAda/BSQAABAAAAEIAtlQCALZXAgC2NAIAdbcCALY4AgC2PgAACP/iALZDAjKBUAIAtk +kCALs1AgC7PQIAdauB//s6gf/7CwH/+zGP/oD/8AEIAAIAtmwCAGkiDhAFYAIAMIkOEAWgAByEAG +4QGZ4AAAflAAAH5AAAB+GCAGnkAf/6wQIAMP4CADD+QgAw/YIAMP6CADD/QgAw/8AFAgBuEBmgwA cCAG/+AAAAACIAYgC2lwH/+csOEBmgThAZoIAAQgBiALaaAAAw0Q4QMeAP//7f8gAwi4IAtqACAL adAgC2owAAD+5SALamAgC2rQH/+sqAAEk+D/+2wg/+F7gAADDQQAAw0UAAMwAAAOAAAA4AAA/wD/ /+EDKgAAAIADAABjfCALrdD//7//AP8AAPv//84EAAAB/j4ADwAAIAz//98w4QMOAAAYAAMAALmT AAA/4OEDEgDz/+f/IAu0kCALtMAgAw9gIAu0UCALtPAAAwg0IAu1ICALtUAAAyI8IAu2UAADCAAA 5OHAIAu10B//rLAgC7YwIAu1cOEDIgD//0P///8//wADIgAgC7WgAAMiBCALtgAgC7ZwIAtrQOED -IjwgC7cAIAu20CALtyAAAw0AH/+ZDOAAAQDf//4AIAdY0OEB4kAABAAEAAQACCALa3AABACAAAP/ +IjwgC7cAIAu20CALtyAAAw0AH/+ZDOAAAQDf//4AIAdY4OEB4kAABAAEAAQACCALa3AABACAAAP/ ACALa6DAAAAGAB///wAAH/8AABAA4QAuAESAAFBsEAYa+7srMQAsoAiNoY6g/hYAKCYBNDD9FgEo RAFYMPwUCCoBAVww+7sJCAAgCjD6rBAoACBaMPiAACgAIFZwKZAA8IgyAAEQYDD5UgwAZgA+IGiD O3ZnNihABYNDJ0EDCDMMA3MK/ncRAZ4CGPAHMy3zwwwAYAJ6cAP/KK8i0Q8AKjADDaoR+iIMAZoA @@ -3074,32 +3074,32 @@ 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 @@ -3108,131 +3108,131 @@ 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 @@ -3247,32 +3247,32 @@ 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 @@ -3282,18 +3282,18 @@ EZkSiIOYE4sTihKJEfcSACAgAkBwl4CZgZqCm4MsQuglTQQlXKD/AgAP/xA4MP8CAAYAQOVQwDD/ 8C0QYAIwcPAACWAAEFgwAABvMkUp8gAt8gMu8gL48gEgQAJQcCimAS6mAi2mA/mmACAQEEgwbZoU /qAALAAgZvAt0Aixu/qsAS4AV+uQjMDTD/xZu3AAEFgwyTwDNgr88BwX4AQ5oPtsViIAAFCwW35t 9awAAA4AtqD3RvsgABAQMNEP3GDzpgogjAJZsPumCSCPEFAw+lUQICACSHDwCRYAYAJBcPkWGCBg -Alhw8AigAIACUXBY8zSMImXPu/osAAIAAFlw/AoKIAMQaDBbOyL3RvsgABAQMNEPLUK9LkK8L0K7 +Alhw8AigAIACUXBY8ziMImXPu/osAAIAAFlw/AoKIAMQaDBbOyL3RvsgABAQMNEPLUK9LkK8L0K7 KEK6mBCfEZ4SnRNj/tsAAAAAAAAA/eMGcgAAUfDAof0KBC9HADag/WQAIAAQWDArZAP7ZAEgABBY MPtkAiAQAlMw8goWAAgCSbDwCaIAAgIY8PP/FGAoAjGwAAAAbBAIGPAEiYGKgouDmxOaEpkRiICY -EIVC/PAAEgAAaLD1VQoABRBQMP5VEQAwEFgwWPwBiyspIDmMQf0hGyAcABLwwKTwAAZqCQBScNqQ +EIVC/PAAEgAAaLD1VQoABRBQMP5VEQAwEFgwWPwFiyspIDmMQf0hGyAcABLwwKTwAAZqCQBScNqQ +O/mECIABvAE1hHwAAhmCQBBsAAAwGAf7+2fM/4gDCAAEDgw+yANKOABVDD6790ZAAQ+YPc1Ai+A -BDug/DUDKgkAdvD879gYCQBecPqZAgAwEFgw+TYAIAUQUDBY++MoGhAIaAL4NgIgMxB4MC8UEC8U +BDug/DUDKgkAdvD879gYCQBecPqZAgAwEFgw+TYAIAUQUDBY++coGhAIaAL4NgIgMxB4MC8UEC8U ESgQDy0QDf4QDCIAAFCw+RAOICACYHD5FBQgIAJY8P4UEiAgAhkw/RQTIgAAcHD4FBUiAABo8Fs0 fSekLSekNSekMSekLyekKfekBiABEHgw/6QuIgAAErD/pAcvjxBwMP4kMCACEGgw/SQrIAUQYDD8 -JCogOhBYMCskKAeKFCokLIlCKiQ0+SQ3IEACWTD5iRQCAABhcPkkNiBwAlCwWPK6KFwQ+CQFIgAA +JCogOhBYMCskKAeKFCokLIlCKiQ0+SQ3IEACWTD5iRQCAABhcPkkNiBwAlCwWPK+KFwQ+CQFIgAA UPD4iBQAEAJhcPgkBCIAAFhwW34LKiQzCokU+SQyIAAQEDDRD2wQBIYnhm4kbQMlbQImbQT2YAAh AAI5sCMKAAAwBAYIG3+HOylBgrCZCQlP+UWCIDAAtmApcIDwMQQAARBQMPCqGg//EFgwC6oDCpkB -KXSAKFKD2zD8UoIiAABQsAuAAPVcDCACAhjw+TSvYBgCITArcIDJsRvvfvzvfxIAAFCwWPfrwCDR +KXSAKFKD2zD8UoIiAABQsAuAAPVcDCACAhjw+TSvYBgCITArcIDJsRvvfvzvfxIAAFCwWPfvwCDR DwCKJyqsEFuhOcAg0Q9sEAiIIiwgB4owGe98/AxBAgAAMTD1gVtrAAFQMC2SSvvveBGAADdgKJJJ K7J/C4gB+4wAAXcANiAY73IogID8xxEAbgJCMPhIFAYAIE3w/XI6KAAgIjCkjrPu/wIACgCW91Ad 72kpcjkNzQot0pcNngH+FgIuAItuUCggFC4gBKSI+AlHAgCvg6CaE/kkFCwAvhJgH+9eHu9eKSEH @@ -3308,64 +3308,64 @@ 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 @@ -3373,22 +3373,22 @@ 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 @@ -3396,10 +3396,10 @@ AhCwBycMDXUJK1AAZb8CY/8twEDGmgSUOGP+gyLQAC5AgPLhOnAAEGAw30Bk7w4u8IGxzPLp9HAC Anvwo87/AgAH/35XkPbO9GACAmtwassY8AAVYfQCYzAAAAAAAAAA/wIAB/9tVNCx3fy0ACACAjLw 8/6HYAEQEDAAAAAAAAD6zAACAABYsPUKACAAEHgw8/3pYAAQIDCJEg9IFCiUAPP/cGACAiEwixIP KhQPrBQstAAqtAHz/1pgBAIhMAAAbBAIIyIY0w/TDy8wBSQKcv4yACoAPnkQ+goFIDAQWDD86hES -AABo8Fj12S8wBSgKc/TxFHAAEBAw+Qp1JgB3R9D/AgAGAH5P0MCl/OoHEDAQWDD+MgAiAABo8Fj1 -zcosgzjTDyUyGBzp5CIwB/1QBCAFEFAw/lIAIDAQWDD/UAUiIAEQMFj1wihQBXhDPNEP/SIAIAUQ -UDD86fUQMBBYMFj1uy8wBfkKcCHIBCPwefHc+jIIIAAQWDD8CgAgAhBoMFuIZNEPAAAAAAAc6cyP -WC1QBI5Q//IAIAUQUDDyFgAgABBAMPgWASAwEFgwWPWo+jwAAAgQWDD9HBAiAABgsFujp/7pvxBR +AABo8Fj13S8wBSgKc/TxFHAAEBAw+Qp1JgB3R9D/AgAGAH5P0MCl/OoHEDAQWDD+MgAiAABo8Fj1 +0cosgzjTDyUyGBzp5CIwB/1QBCAFEFAw/lIAIDAQWDD/UAUiIAEQMFj1xihQBXhDPNEP/SIAIAUQ +UDD86fUQMBBYMFj1vy8wBfkKcCHIBCPwefHc+jIIIAAQWDD8CgAgAhBoMFuIZNEPAAAAAAAc6cyP +WC1QBI5Q//IAIAUQUDDyFgAgABBAMPgWASAwEFgwWPWs+jwAAAgQWDD9HBAiAABgsFujp/7pvxBR ADagjTDAwPymASwJAHdwnaAb6boMKRH4EgQoACBecJiQ0Q+COC8KdC80BS8kBS8wBfP/DGABEBAw iTgoCncoNAUolAUvMAXz/vZgARAQMADaMPzpqxAAEFgwW6Nx0Q8AbBAOKCAFKQqV9QoAJgCxzhAp MhL56lEAKACucPnLUQAAuAag/wIAAAC0BuCEJ4ROJk0CJWQRhzD3RocgARBIMClkEiwgbhfpsPZs @@ -3409,8 +3409,8 @@ LgkAe7CeES2QByuRKQ0NQQDdEQ27Agy7ApsUCuowlRcpTQKaFfcJFgBAAlBwAMqKBAmIAIqKAgmI AEqKAAmIAAqK+iwAAgAAWHD8CgQgAhBoMFuUm9EPKkKQ0w9krzQc6VmLNwyqKPoWECAgAlrwKxYR Wy6FLBIQHejfHul2jzD6EhEiAABasFsuPB/pQS4yEo03D+4C/jYSICACG3DaMFskDPMWEiH/dp6g 8AA5YgAAUPCKJyqsEFua34ssx871JTUqAEBm8JssY/6HAAAAAAAAAPo8AAAAEFgw/AoAIAIQaDBb -LnzRD1skGhPpWwuoEfSgNmIAIETwDOowKzKFi7Cwo/y7CAIAAFDwWPdLKnKY8DEEAAEQWDAAuxoL -qgIqdphY94Fj/msAAAD6CgcgARBYMFubgywyfyw2g2P+VGwQCpIY9RYJIAIzJSDyCgAgABAwMPAA +LnzRD1skGhPpWwuoEfSgNmIAIETwDOowKzKFi7Cwo/y7CAIAAFDwWPdPKnKY8DEEAAEQWDAAuxoL +qgIqdphY94Vj/msAAAD6CgcgARBYMFubgywyfyw2g2P+VGwQCpIY9RYJIAIzJSDyCgAgABAwMPAA SGA9EDgwAAAAAAAAAP8CAAYAlj7QwNAmbOr7+uogLAIhMPwKACAAEHAwjxkqEggLawz7OwgOACB8 sFswn6KiZiEd/wIAAACNJSCjbyvwAGS/uv8CAAYAc77QakG32/D9CgAkACB9MG0IGi6wAbHa/awA AAICYvD7zAAADwA3oHfhCnXKBGP/3gAAd+mJKMABwLD7xAAgAgJysPSDn2ACAmMw/wIACAGrp5DA @@ -3432,22 +3432,22 @@ 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 @@ -3456,38 +3456,38 @@ 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 @@ -3502,21 +3502,21 @@ gay7CbsR++QSGgAgWrApoSn84/oQ+gRacI5Hju4Y5A4f5Awt7QL15F0QoAJbcPAMBwIAAErwAElh AElhAElhAElhiUD/5pYgBBBgMPXmmimABD5g+OaUKAkAZnAp5pUooAcvoSkICEEAiBEI/wIF/wL/ 5pgg4AJLcAIDhgBJYwADhgBJYdnQ8pSGIAIQaDBbj17RDwAAKjESCgpL++RbEgALIqB6sg4iIhDN IPP/RWACEBAwAADz/ztgFhAQMCQmESxBGCtBGipADChAOS9BGy5AFi1ABylADSkkDS8lGy4kFi0k -ByokDPslGiB0AlCw/CUYIHQCWTD4JDkgBhBgMFjm8R7j4o1LDt0C/SYLID4AF3AY5EEvIRsI/wEv +ByokDPslGiB0AlCw/CUYIHQCWTD4JDkgBhBgMFjm9R7j4o1LDt0C/SYLID4AF3AY5EEvIRsI/wEv JRsoMRIICEsI/wIvJRtgAAUpMRIpJRuKJ4auJm0EK2AAJzqA9LAKYQACMbAqrBBblY3AkClkgChS -hyiCK3+PCPP+lGAAEBAwANogW47XhieGbipivmqiSihiwGiARMCl/OQoEDAQWDBY78yKJyxiwI2u +hyiCK3+PCPP+lGAAEBAwANogW47XhieGbipivmqiSihiwGiARMCl/OQoEDAQWDBY79CKJyxiwI2u 8MEEDAAgP3D80IAgARBYMPC7Gg//EEgwCbsDC8sBCwtH+9SAIAcANyBksK7H7y5mwCdtAyggOikg PCogOy0gPSwgPisgPysUDywUDv0UDSAAEHgwLxQHLxQGLxQFLxQELxQD/xQCIIAQcDAuFAEqFAn5 FAog/hBQMPoUDCACEEgw+hQAIP8QcDD+FAsoEQBKMCgUCI4QjRGMEosTK2a9LGa8LWa7/ma6IEAQ UDD6dQMgARBAMPhmvi//EEgw+WbDIAAQWDD5ZsIgARBgMP91AiIAAFCwW3EcY/7yKqwQW5VFY/9H -AAAAbBAWHOPq/TESIAUQUDD+IhAv/xBAMPgWBCAwEFgwWO+IKjES/ONYEgAAILD149sQBBAwMPoK +AAAAbBAWHOPq/TESIAUQUDD+IhAv/xBAMPgWBCAwEFgwWO+MKjES/ONYEgAAILD149sQBBAwMPoK SwAAEFgw9yqAIgAVoqAd49R60iApIhBklgcukRsODksK7gwOmzjUsMxJ1CDwACpgFhAQMAAvUoeC -Ry/yK/IiDiIAWv/QwKX848wQMBBYMFjvbvzjPxAmEBAwG+NRLUAMK7J3KlKBrbsJuxH5400aACBa +Ry/yK/IiDiIAWv/QwKX848wQMBBYMFjvcvzjPxAmEBAwG+NRLUAMK7J3KlKBrbsJuxH5400aACBa sCihKXmBeY1Hjd4Y45wu3QL/40gQoAJbsPAMBwIAAErwAElhAElhAElhAElhjEAZ40Io1pr/1pYt gAQ7IPnWlCwJADMwLNaVKaAHL6EpCQlBAJkRCf8CCP8C/9aYIOACS7ACA4YASWMAA4YASWH33ggA BBBgMPLkBiACEGgwW46b0Q8AKjww+zw4ICACYHBb/cf/EgQgKwA2oHSpAmjxIBzjm/6gOSAwEFgw -/UIAIAUQUDBY7zkc4wnz/ytgYxAQMC8i1sr9HOOSLSLKLiLLLyLMKSLNmRD4ItYgBRBQMPgWASAw -EFgwWO8sHOL88/73YBAQEDAf4wiLPYo8/AoBIAAQQDD7yDgAABBoMArNOPzjAx4A9sdQIhYgiD+C +/UIAIAUQUDBY7z0c4wnz/ytgYxAQMC8i1sr9HOOSLSLKLiLLLyLMKSLNmRD4ItYgBRBQMPgWASAw +EFgwWO8wHOL88/73YBAQEDAf4wiLPYo8/AoBIAAQQDD7yDgAABBoMArNOPzjAx4A9sdQIhYgiD+C Pv0KASAAEEgw+Nk4AAAQQDAC2DjyEiAuAOXOEIlHiZ4qkr7/AgAEAliCoBri8Y2ijqH4ogAgMAJY cJiwnrGdsoqjmrMe4t7+Fh8gMAJIcIqTjZL4kgEgUAJYcJixnbKaswAOi4mQ+bYAIHACSHAASWEA SWEASWEASWEY4tWcH58eLiLLKILsLhYRLSLKLRYQ/CLNIgAAUTD8FhMgcAJYcPkizCAFEGgw+RYS @@ -3540,113 +3540,113 @@ BgmGAEpnLSLJiz0rJsuKPComyok/KSbN+DIOL/8QeDAvJtP/JtIgARBwMPgmzCABEFgw/ibOIgAA UTD+xSIsCQA3cP0mySABEGAwW2+FwCDRDwAAAAAAAPP6AmIAACLwKSLNKiLMjj6IPwruDAmIDPjY OQ4FAHNwCO4CZe2yY/0bK5K9LpK8KJK7+pK6IDACaHCa0JjRntKb02P9xiuSvS6SvCiSu/qSuiAw AmhwmtCY0Z7Sm9Nj+08AKrwQW5OTLBIeY/8MAAAAACq8EFuTjykSHmP8pQAAbBAIHOI4/TESIAUQ -UDD+IhAgMBBYMFjt1CoxEvfh7BIAACCw/TIKK2ABUDD74iQSABUioHqyIikiEGSSkiyRGwwMS/rM +UDD+IhAgMBBYMFjt2CoxEvfh7BIAACCw/TIKK2ABUDD74iQSABUioHqyIikiEGSSkiyRGwwMS/rM DAAAECAwDJQ4zEjUIPAAYGAWEBAwhUcmctT5cucggBBQMPVSDiAgADdgKHIXCWYRqWZtiRCLZ4u+ -K7Kq/wIABgBnbtCqZiZSrdMP+1KrIQUANaAc4hQtUqouUqv/UrEgBRBQMPYWACAwEFgwWO2twSAb +K7Kq/wIABgBnbtCqZiZSrdMP+1KrIQUANaAc4hQtUqouUqv/UrEgBRBQMPYWACAwEFgwWO2xwSAb 4ZEsQAwrsncqcuesuwm7Ef3hjhoAIFqwLKEpfcF7jkcY4YyO7h/hihzhcy3tAvXh2RCgAltw8AwH AgAASvAASWEASWEASWEASWGJQP/mliAEEGAw9eaaKYAEPmD45pQoCQBmcCnmlSigBy+hKQgIQQCI EQj/AgX/Av/mmCDgAktwAgOGAEljAAOGAElh2dDylIYgAhBoMFuM29EPHOHmLmA5j2CdEfsWACAF -EFAw+wowIgAAa/BY7X5kbxf/AgAH/4olkI0g/mA5IAUQUDD84doQMBBYMFjtdvP/ImBjEBAwAIo6 +EFAw+wowIgAAa/BY7YJkbxf/AgAH/4olkI0g/mA5IAUQUDD84doQMBBYMFjtevP/ImBjEBAwAIo6 ZKEOijv8UrEgDgRS8CpWq4o8/lKqIA4EUzAqVrGNOg8CAA8CAP8CAAYAe/dQ+l0CIAEQMDD2VpAi AABI8PwJFgHgAlKwAEptCgmGAEprCAmGAEppBgmGAEpnBAmGAEpljDqKUCoWBvwWBSACEFgwK1aQ /OG5EDoQWDBbb3/7rAAAGgA2oJaojxX9EgYgABBwMJ6qn6kt0gJk0M2MR4zOJlaRK80EKrAAwI/7 vIAoAD1GkPkKACAEEGgwbdoKAJAECg4bf+cDsZnHn5kUCZgJAJEEAG0aDIgKL40D+I0CLAkAbrD9 tIAgZRBwMC71gy71gv/hmxAAEGgwLYaC/4aDIFgANqCOFP5WqSAAGa+gwCDRD8DwL1aqL1arL1ax -L1al8/33YAAQEDDHj5gUY//UAAAAAAAA8/16YAAQIDD6CgIgMBBYMPzhhxIAAGiwWO0f8/3HYAwQ -EDAb4Q/84Q8SAABRMFjpfGP/mooW/AoKIAMQaDBbLA5j/yFsEAgc4XotIgD+IAQgBRBQMP8wFSAw -EFgwWO0OHOD2F+D0FeFFKCA4G+Dw9ODwElAQMDD/KoAicBBoMPq88CYAToIgJgpkKCAMLrJ3KqKE +L1al8/33YAAQEDDHj5gUY//UAAAAAAAA8/16YAAQIDD6CgIgMBBYMPzhhxIAAGiwWO0j8/3HYAwQ +EDAb4Q/84Q8SAABRMFjpgGP/mooW/AoKIAMQaDBbLA5j/yFsEAgc4XotIgD+IAQgBRBQMP8wFSAw +EFgwWO0SHOD2F+D0FeFFKCA4G+Dw9ODwElAQMDD/KoAicBBoMPq88CYAToIgJgpkKCAMLrJ3KqKE qO4J7hGuqimhKf8CAAYAi6ZQjieO7hngzCvtAiu8UPAJBwIAAErwAElhAElhAElhAElhiCD15pog BBBIMPzmlCmABDog9+aWKAkASjAo5pUpoAcooSkJCUEAmREJiAIFiAL45pgoACBvsAIDhgBJYwAD hgBJYf/pCAAEEGAw9pQGIAIQaDBbjDTAINEPLjAV/wIAAABMh6D/AgAEAFSHoPgKCSYAXIeg/wIA -BgEFx5DAi/kKDSYAXUeQeeEv/OE5EAUQUDD9IgAgMBBYMFjszRrhNfzgtBJwEGgw9goWIoAQeDDz -/xBgIAJasAAA+iwAAgAAWPBb+4zWoMCl/OErEDAQWDD9IgAiAABxsFjsvhrhJRzgpP0qcCKAEHgw +BgEFx5DAi/kKDSYAXUeQeeEv/OE5EAUQUDD9IgAgMBBYMFjs0RrhNfzgtBJwEGgw9goWIoAQeDDz +/xBgIAJasAAA+iwAAgAAWPBb+4zWoMCl/OErEDAQWDD9IgAiAABxsFjswhrhJRzgpP0qcCKAEHgw 9W7WYCACWrDAINEPAAAAAPosAAIAAFjwW/7Z8/++YgAAMrAAAAAAAPosAAIAAFjwW/0d8/+mYgAA -MrAAAAAAAPosAAIAAFjwW/xy8/+OYgAAMrAc4Q/9MRIgBRBQMP4iECAwEFgwWOygKzES0w/7C0sA +MrAAAAAAAPosAAIAAFjwW/xy8/+OYgAAMrAc4Q/9MRIgBRBQMP4iECAwEFgwWOykKzES0w/7C0sA ABBoMPqyIWIAAFCwHODve8IWKSIQZJIVLpEbDg5L++4MAgAAU3AOmjhkoemMp4zOK8wQ+xYCIgAA SPAMCYYAS20KCYYAS2sICYYAS2kGCYYAS2cECYYAS2X/ogcgARBAMCjGGSggPi4gP4ugj/747hAJ AAQ6IPsJRwroAVww+LsRCAkAcjD9xhooCQBaMP79BCgJAEowKMYcK+AA/BYAIA8QQDD+7IAoALtG 0PkKACAEEGAwbcoKAJAECwgbf4cDsZnHn5oR8JEEAAEQQDAAiBr5FgMoCQBC8CjkgAmeCQ/uCvzt AyBlEEAwKMWDKMWCLu0CHODLLeaCLOaD/JwAATYANuCJEIoRLJYb/ODGEl4QWDBbboP7rAAA5AC2 -oPAA7GAMEHAwAAAc4MD9IgAgBRBQMP4xEyAwEFgwWOxOKSIQKjET+iUaIAcANmAqlRob4C4sIAwa +oPAA7GAMEHAwAAAc4MD9IgAgBRBQMP4xEyAwEFgwWOxSKSIQKjET+iUaIAcANmAqlRob4C4sIAwa 4LArsncqooSsuwm7EauqK6Ep/wIABgBFJtCNJ43eHOARptvwDAcCAABK8ABJYQBJYQBJYQBJYRzg IokgJdaaLNaU+JkRAAQQYDD31pYoCQBmcCnWlSigBy+hKQgIQfCIEQAAEHAw/N0CLgkAR/D1/wIC AABI8P/WmCDgAmMwAAmGAExhDgmGAExvL90D//yAIAQQYDD+9AYgAhBoMFuLdfP9cWAAEDAwiBGI gokS+aYIIDwANiDA4PP9WWIAADOw8//0YBYQcDCaEfP+4G//EGAwAAAAAAAA8/33YAAQUDAb4AIc -4AJY6HCME2P+v4oR/AoKIAMQaDBbKwFj/7cAAGwQBoQnhE4uQqn9IgAgxAgbsBzgcf5CkCAFEFAw -/0KRIDAQWDBY6/4rQpBkscH8380QAN8G4Brf3xXf3xbgMvff3xAAEBgw/d/eEAQQcDD/4FcSagA6 -4P8CAAIAdIbgI0aR80aQIgAAEPDRDwAAAAD6CgUgMBBYMPzgWRIAAHjwWOvnwCDRDwArQpH/AgAE +4AJY6HSME2P+v4oR/AoKIAMQaDBbKwFj/7cAAGwQBoQnhE4uQqn9IgAgxAgbsBzgcf5CkCAFEFAw +/0KRIDAQWDBY7AIrQpBkscH8380QAN8G4Brf3xXf3xbgMvff3xAAEBgw/d/eEAQQcDD/4FcSagA6 +4P8CAAIAdIbgI0aR80aQIgAAEPDRDwAAAAD6CgUgMBBYMPzgWRIAAHjwWOvrwCDRDwArQpH/AgAE AMES4IVA9kKGIgAAY/D7CjogAhBIMPlGkCIAAFFwW24H+6wAABUANqCWqfOmCiABEGAwnKiKUmSi cownLUKRjM6x3S1GkSvNBCqwAMDf+7yAKAEb7pD5CgAgBBBoMG3aCgCQBAoOG3/nA7GZx58f4CwJ nQnwkQQAARBwMADuGgzdCvbdAi4JAHKwLrSA/d0DIMkQQDAo1YMo1YLzZoIiAAAqcP9mgyHuADag +UapIAAQEDDRDy8gDCuidyqigK+7CbsRq6ovoSn/AgAGAEKv0I8nj/4l/QIrXFDwDAcCAABK8ABJ YQBJYQBJYQBJYYIgJvaa/faUI4AEOKD39pYiCQBwsCL2lSygByihKQwMQQDMEflccCgJAGIw8k0C KAkAMjD49pgh4AIQsAIChgBJYwAChgBJYfn9AyAEEGAw+ApiIQACSnD4lAYgAhBoMFuK5SNGkfNG -kCBiEBAw0Q8AAAD9IgAgBRBQMP5NAiAwEFgw/N/4EeACc7BY64XAINEPAAApTQMqQogrQocoQoaY +kCBiEBAw0Q8AAAD9IgAgBRBQMP5NAiAwEFgw/N/4EeACc7BY64nAINEPAAApTQMqQogrQocoQoaY EChGqitGq/pGsSEgAkpwKUal+kIAIgAAY/D6FgEgOhBYMFttovusAAAZADagjBH+EgAgARBoMJ2o nqqeqYzCZMDrG99VLCAMGt/WK7J3KqKErLsJuxGrqi+hKf8CAAYARy/QjSeN3hzfNyvdAiu8UPAM BwIAAErwAElhAElhAElhAElhGN9HgiAm1poo1pT4IhEABBBAMPfWliIJAECwItaVL6AHLqEpDw9B +d0CLwAEP+D5nHAuCQB7sPJNAi4JADOw/taYIeACELAGAoYASWcEAoYASWUp3QP5nIAgBBBgMPOU -BiACEGgwW4qaI0aR80aQIAAQEDDRD8ev+kapIAAQEDDRDxvfMfzfMRIAAFCwWOee9UapIAAQEDDR +BiACEGgwW4qaI0aR80aQIAAQEDDRD8ev+kapIAAQEDDRDxvfMfzfMRIAAFCwWOei9UapIAAQEDDR D9pQ/AoKIAMQaDBbKi5j/XyKEfwKCiADEGgwWyoqY/8DAAAAAGwQBoMngz4oMr4lCgH6gkJv/xAg -MCgywGiANyoKBfzfghAwEFgwWOsmiyctMsCMvgDRBCzNBCrAAABZGgSZAwmpAQkJR/nEACAHADag +MCgywGiANyoKBfzfghAwEFgwWOsqiyctMsCMvgDRBCzNBCrAAABZGgSZAwmpAQkJR/nEACAHADag ZJCRJDbALiA6LCA/KCA7KSA8KiA9KyA+KxQOKhQN+RQKIP8QaDAtFAv4FAkgAhB4MPwUDyCAEGAw /BQBLhEAe7AuFAj+PQMg/hAQMCIUDPIUACAAEBAwIhQHIhQGIhQFIhQEIhQDIhQCiBCJEYoSixMr Nr0qNrwpNrv4NrogQBB4MC/lAyU2viQ2wyQ2wiLlAtEPAAAqvBBbkKlj/2QAbBAIHN9lF97YKjAI iDApcm36FgUiAABosPdygChgAUAw+BYEKAAgSjD+0gApkAQ6IP/QBCYAIEXw9HILIgAAETCTEPIW -ASAwEFgw9RYCIAUQUDBY6uAc31H+cgAgBRBQMP9wBCAwEFgw9BYAIgAAafBY6tj530sSAABA8NMP -bSkFAAiGAElhHN9HGN9HLTAJ/jAKIAUQUDD1hhQgMBBYMFjqzCkwCY57+t7nEAkANmAK7gKee4sw -jBX43rIQABAQMPq2D3AGEFAw+ME6YBAQWDBowl906Rcu+o1+IQzaUPs8AAIAAGCwWOjWwCDRDwDd -QPoKBSAwEFgw/N8sEgAAeLBY6rRj/88vcDiMFPj2ZGAAEEgwKXQ4+OoCAgAAWPD6dgsiAABR8Fi3 -nI578/+kYgAAErCNcAjdEZ0zLHA4acaSc+aPjBQf3xr6dDgiAABR8P/uAQwJAFsw/nYLIgAAWPBY -t42Oe/P/amIAABKwAAAAAAAA/wIAA/+uD5CMFCp0OPP/kmwJAFswAAAAbBAGEt52KCJthTHyIoAo -YAEkMPzfBRgAIEow9YVHCZAEOiD1BQYCACBAsP4gOSAFEFAw/yA4IDAQWDD0FgAiAABpcFjqgche -2iD7PAACAABhMFi3btEPACggOLGIKCQ4Y//kAGwQBoMngz4c3vAtIgD+MhkgBRBQMP8yGiAwEFgw -WOpxKDIZ997bH/8QaDD1CgEgABAgMPkKDyGtADYgjieO7ivtBCqwAPZMAAAEEEAw+7yAKADFzpBt +ASAwEFgw9RYCIAUQUDBY6uQc31H+cgAgBRBQMP9wBCAwEFgw9BYAIgAAafBY6tz530sSAABA8NMP +bSkFAAiGAElhHN9HGN9HLTAJ/jAKIAUQUDD1hhQgMBBYMFjq0CkwCY57+t7nEAkANmAK7gKee4sw +jBX43rIQABAQMPq2D3AGEFAw+ME6YBAQWDBowl906Rcu+o1+IQzaUPs8AAIAAGCwWOjawCDRDwDd +QPoKBSAwEFgw/N8sEgAAeLBY6rhj/88vcDiMFPj2ZGAAEEgwKXQ4+OoCAgAAWPD6dgsiAABR8Fi3 +oI578/+kYgAAErCNcAjdEZ0zLHA4acaSc+aPjBQf3xr6dDgiAABR8P/uAQwJAFsw/nYLIgAAWPBY +t5GOe/P/amIAABKwAAAAAAAA/wIAA/+uD5CMFCp0OPP/kmwJAFswAAAAbBAGEt52KCJthTHyIoAo +YAEkMPzfBRgAIEow9YVHCZAEOiD1BQYCACBAsP4gOSAFEFAw/yA4IDAQWDD0FgAiAABpcFjqhche +2iD7PAACAABhMFi3ctEPACggOLGIKCQ4Y//kAGwQBoMngz4c3vAtIgD+MhkgBRBQMP8yGiAwEFgw +WOp1KDIZ997bH/8QaDD1CgEgABAgMPkKDyGtADYgjieO7ivtBCqwAPZMAAAEEEAw+7yAKADFzpBt igoAYAQKCRt/lwOxZsdvBmgJAGEEAFkaDogK/I0CKAkATrAptID4jQMgZRB4MC+Fgy+FgiTGgvfG gyRWADagKDIZJjYb0w/23jcSAKyCICgyGf8CAAQA2AIgKTIZ/wIABADxBmAqMhn7CgAoAfkCoC0y -Gv3cASBjEGAw/TYaKgAmaxD83rwQBRBQMP0iACAwEFgwWOo+Gt6mG94iH93WjickNhokNhkv8MEr +Gv3cASBjEGAw/TYaKgAmaxD83rwQBRBQMP0iACAwEFgwWOpCGt6mG94iH93WjickNhokNhkv8MEr sncqooT+4g4rkAQ+4P/3GnoAIFqwKq0B8AAVYQACUrCNImTT0cAg0Q8AACqtAyqsgC2hKXbR7R/e EvyiAC/hEEAwKOSo/+YmIBYQeDD43g0dgAQ7IPjmJCwJAHswLOYlKaAH/N4JGCABTDAAmREJ2QIM mQL55iggkBBYMAjqMP3tASAgAkjw+OYpISAQeDD/5VcgbhBAMPjkxiFgAmtwAgmGAE1jAAmGAE1h LTEajz4v5jSMPy3lbPzmNSoAIF+w+TIQIBYQYDD55jcgAhBoMFuJWcAg0Q8AAAAA8/61YgAAM3AZ -3nstNhuIKwmIAfgmCyAAEBAw0Q8AwKX83nYQMBBYMFjp98Cl/N5zEDAQWDD9IgAgIAIo8P8gOSIA -AHFwWOnw2iD83lsSXhBYMFtsGMCQ+6wAAAEQUDD7qTgABgA24JW4/QoBIAAQYDAJ3DhlznJj/s8A -AAAAAAD33mAQBRBQMPzeXxAwEFgw/SIAICACKPD/IDkiAABxcFjp2dog/HwAAl4QWDBbbAH7rAAO -lgA2oJWoY/4sHN5S/SIAIAUQUDD/IDkgIAJw8P4WASAwEFgwWOnLHN5M/SIAIAUQUDD+Mh8gMBBY -MFjpxiQ2GiwyIioyHykyGy0yIPsiByAIEHAwLjYZLTarj74AkQQqNqoo/QT8NrEhAAJCMC6AgPBZ +3nstNhuIKwmIAfgmCyAAEBAw0Q8AwKX83nYQMBBYMFjp+8Cl/N5zEDAQWDD9IgAgIAIo8P8gOSIA +AHFwWOn02iD83lsSXhBYMFtsGMCQ+6wAAAEQUDD7qTgABgA24JW4/QoBIAAQYDAJ3DhlznJj/s8A +AAAAAAD33mAQBRBQMPzeXxAwEFgw/SIAICACKPD/IDkiAABxcFjp3dog/HwAAl4QWDBbbAH7rAAO +lgA2oJWoY/4sHN5S/SIAIAUQUDD/IDkgIAJw8P4WASAwEFgwWOnPHN5M/SIAIAUQUDD+Mh8gMBBY +MFjpyiQ2GiwyIioyHykyGy0yIPsiByAIEHAwLjYZLTarj74AkQQqNqoo/QT8NrEhAAJCMC6AgPBZ Gg//EGgwDZkDCekBCQlH+YSAIAcAN6BkkhEa3hob3ZYtNhssMh8oMiIuMiAoNhAY3UaeP5w+KIDB K7J3KqKECbsR/4cPegAgWrAqrQHwAAphAAJSsCqtAyqsgC2hKf8CAAYATbdQGN2G/qIAL+EQYDAs 9Kj49iYgFhBAMPzdgR+ABDug/PYkLgkAQ7Au9iUsoAcMDEEAzBH93XscCQBjcPkSASwJAGsw/PYo IJAQWDAI6jAo9ikk9Mb9/QEhIBBwMC71V/YJFgFgAmtwAE1nBAmGAE1lKTEajD4s9jSIPyn1bPj2 NSoAIF/w/jIQIAIQaDD+9jcgFhBgMFuIzoYwHN3b/TKqIDoQWDD9FgAiAABRsFtrnvusAAARADag -laiPEJ+qn6mOYmThEy0yHWTc88Cl/N3uEDAQWDBY6WmNJ43eK90E/jIdIQACWvAqsID/CmQgDxBA +laiPEJ+qn6mOYmThEy0yHWTc88Cl/N3uEDAQWDBY6W2NJ43eK90E/jIdIQACWvAqsID/CmQgDxBA MP/uKAgAVkaQ9goAIAQQeDBt+goAYAQKCBt/hwOxZsdvBm8JAGEEAFgaDf8K+f0CKAkAQrAotID/ -/QMgAgJjsCz1gyz1giSWgveWgyBxADag9jYbIAAQEDDRDwAV3cr83c4QBRBQMP0yHSAwEFgwWOlH -2iD8XAACXhBYMFtrbvusAAxLADagKDwQmKhj+94b3TH83TESAABQsFjlnmP7nNog/AoKIAMQaDBb -KDDAINEPx5/5NhsgABAQMNEPABvdJfzdJRIAAFCwWOWS9jYbIAAQEDDRDyq8EFuO348nj/7z/eBv +/QMgAgJjsCz1gyz1giSWgveWgyBxADag9jYbIAAQEDDRDwAV3cr83c4QBRBQMP0yHSAwEFgwWOlL +2iD8XAACXhBYMFtrbvusAAxLADagKDwQmKhj+94b3TH83TESAABQsFjlomP7nNog/AoKIAMQaDBb +KDDAINEPx5/5NhsgABAQMNEPABvdJfzdJRIAAFCwWOWW9jYbIAAQEDDRDyq8EFuO348nj/7z/eBv /xBoMNpg/AoKIAMQaDBbKB5j/ttsEAaLK/RCACXcEEAwKBUA+SA5IBwAEvDApPAABmoJAFJw2pD9 IRsgJAAG8BjdBgTVEfAABmQJAEVwwFAc3WUuIA0vIAz5Kk4q4AFUMPC7EQAAEFAw+TUDL4AEP+D6 -NQIuCQB7sP67AgAFEFAw/N2NGgkAZvD7NgAgMBBYMFjpBfU2AiAgAlDw/CpOIAAQWDBY4A/Hfyc0 -ECc0Efc0EiAsAlDw9zQTIAYQYDD3NBQgdAIosPc0FSIAAFlwWN/6JzQxGtyYEtyW94sUAEQQeDD/ +NQIuCQB7sP67AgAFEFAw/N2NGgkAZvD7NgAgMBBYMFjpCfU2AiAgAlDw/CpOIAAQWDBY4BPHfyc0 +ECc0Efc0EiAsAlDw9zQTIAYQYDD3NBQgdAIosPc0FSIAAFlwWN/+JzQxGtyYEtyW94sUAEQQeDD/ NDMgABBwMP40MiBDEGgwLTQ1KzQw8jQlIkAQQDAoNCH6NB0gCBBIMPk0HCACEDAw9jQgIAAQYDD8 NDQgARAwMCY0OvY0OyAGEGAw/DQ8IEAQSDApNCQpNCb4MB4gAhBQMPo0NiAREBAwIjQnC4sUKzQv +4sUAGgCEPD7NC4grAJQ8PsqLChgAUAw+YgCAPAQSDD5CgUoAEBKMPs0NygJAEow+DQeIgAAWXBY -38r6PD4gBhAoMPwKBCDAAlkwWN/FG91GKj0B+qwmIAQQYDBY38EmJPf2JPggNRBoMP0k9iA3EHAw +3876PD4gBhAoMPwKBCDAAlkwWN/JG91GKj0B+qwmIAQQYDBY38UmJPf2JPggNRBoMP0k9iA3EHAw LiT5LEAXeMcIJST6YAAHAAAAwPUvJPomJPv1JP0gAxBIMCkk/ChAFyk9AfKcMiAcAGIwwaH6lDIg -ZgIScMHa/SQAIAIQKDD1JAMgHBBgMPwkASA5EFgw+yQCIAgCULD7HAACAABhcFjfohvcciuyqC6w -APoKACAZADeg2bBtCAwskAGxqvTAB2ACAkpwY//s+iQHIDwQaDD9JAYi4AFUMPw8AAAQAlCwWN+R +ZgIScMHa/SQAIAIQKDD1JAMgHBBgMPwkASA5EFgw+yQCIAgCULD7HAACAABhcFjfphvcciuyqC6w +APoKACAZADeg2bBtCAwskAGxqvTAB2ACAkpwY//s+iQHIDwQaDD9JAYi4AFUMPw8AAAQAlCwWN+V oj4n5Aj1RhUgABAQMNEPAABsEAaLK/RCACXcEEAw+BUAIAQQMDD5IDkgGAAS8PAABmoJADJw2pD9 IRsgJgAG8BjcaQTVEfAAB2QJAEVwAMBQHNzILiANLyAM+SpOKuABVDDwuxEAABBQMPk1Ay+ABD/g -+jUCLgkAe7D+uwIABRBQMPzc8BoJAGbw+zYAIDAQWDBY6Gj1NgIgIAJQ8PwqTiAAEFgwWN9yx18l -NBAlNBH1NBIgLAJQ8PU0EyAGEGAw9TQUIHQCELD1NBUiAABYsFjfXSU0MS0wHhjb+Rzb+vWPFABA ++jUCLgkAe7D+uwIABRBQMPzc8BoJAGbw+zYAIDAQWDBY6Gz1NgIgIAJQ8PwqTiAAEFgwWN92x18l +NBAlNBH1NBIgLAJQ8PU0EyAGEGAw9TQUIHQCELD1NBUiAABYsFjfYSU0MS0wHhjb+Rzb+vWPFABA EHAwLjQkLjQmLzQw/DQdIAgQWDD7NBwiQBBQMPo0ISACEEgwKTQg+DQlIAIQSDD5NDYgARBAMCg0 Ovg0OyIsEFAw+jQ3IAAQWDD7NDQgQxBgMP+PFAIAAFiw/DQ1IAYQYDD8NDwsYAFsMP80LywJAHdw /48UAPAQcDD+CgUsAEB3cP80LiAREHgw/zQnLAkAd3D9NB4gRBBwMP40MyAAEGgw/TQyIKwCUPBY -3y0qPD78CgQgwAJZMFjfKhvcqio9AfqsJiAEEGAwWN8l9wq4INACWTDyPQEgARBoMP0kKyA2EEgw -+SQtIDUQYDD8JCogAxBAMPYkLiAEEGAw+CQsIgAAULD6rC8hcAIQsFjfFSYkfPwKBCDYAlkw+j0B -IDIQcDD+JHsgagJSsFjfDQEbAvo9ASA5EHgw/ySBIAIQYDD8JIIgdgJSsFjfBhvb1iuyqCiwAPwK +3zEqPD78CgQgwAJZMFjfLhvcqio9AfqsJiAEEGAwWN8p9wq4INACWTDyPQEgARBoMP0kKyA2EEgw ++SQtIDUQYDD8JCogAxBAMPYkLiAEEGAw+CQsIgAAULD6rC8hcAIQsFjfGSYkfPwKBCDYAlkw+j0B +IDIQcDD+JHsgagJSsFjfEQEbAvo9ASA5EHgw/ySBIAIQYDD8JIIgdgJSsFjfChvb1iuyqCiwAPwK ACAZADYg2bBtCAwtkAGxzPTQB2ACAkpwY//s+j0BIAMQMDD8JIYgPBBwMP4khSLgAWAw/CwAAH4C -UrBY3vOjL6f/JfSH9kYVIAAQEDDRD2wQBiYgB4giGtvj9SIQJiABMDD1gkJrwAQ9oP3b4RoAIFbw +UrBY3vejL6f/JfSH9kYVIAAQEDDRD2wQBiYgB4giGtvj9SIQJiABMDD1gkJrwAQ9oP3b4RoAIFbw KLI6DW0K/dKXJAEbxiAssjkY3Ar9xAEOARTvECciEo8p/iIKJggBPDAnFgAIdwoncoD/7gwAYAJZ 8P8CAAoA+F+QKyAWKAr/eLEN+iAHIAAQYDBbk4Jkof8tIQce28sNDUr43E8dwAQ/YPvbxhwJAHdw nUCKIP7bZhAFEHgw+0YCIEAQYDD8RgMpgAQ+oPwSACgJAH5wmUEtIhL8jjgMSgFsMPrMEQ1gBD9g @@ -3658,73 +3658,73 @@ ihQqRDIKihQqRDEKihQqRDApUhEpRDsJiRQpRDoJiRQpRDkJiRQpRDgoIhYoRD8IiBQoRD4IiBQo RD0IiBQoRDzwBgcAgAJ5MABPYS4gBw4OQR/bZAzuEf/uCAAFEGgwLeY5KyAWLAr/fLEK+iAHIDAQ YDBbkumKJ/sKBCAAEGAw+qwgIAQQaDBbiyArIhIs+n8MuwH7JhIgABAQMNEP2iBbkyxkrgvAINEP AAAAAAAAAPtsGCIAAFCw/AoBIAUQaDBbk2DAINEPAPtsEiIAAFCw/AoBIAAQaDBbk1rAINEPAGwQ -DCciEBLbzSZwb4h3KyIVLCBQnBj4gg4mAQEwMPYWDSYAIBkw+BYFIgAAUbBY3j4c28OLHYoYHdtk -/bsRAD0QKDD6aggMACBi8PWkACoAIG7wK7LdLMCA/BYOIAICUrBY3jGOGI0ert323wgAABBwMC70 -AixwbysiF/wsQAAEAmtw/BYNJAAgaTD8IFgmACAZMPwWCSIAAFGwWN4jihkc26iLHapqJaQADLsL -LLCALBYO+7IhIAICUrBY3huPGY4e+yIZLgAge7D25ggAABB4MC9kAi1wb/wgYCAEAnOw/BYKJAAg -cTD9PUAGACAZMP0WDSIAAFGwWN4Lihoc25CLHapqJaQADLsLLLCAnB77siEgAgJSsFjeBI8ajh77 +DCciEBLbzSZwb4h3KyIVLCBQnBj4gg4mAQEwMPYWDSYAIBkw+BYFIgAAUbBY3kIc28OLHYoYHdtk +/bsRAD0QKDD6aggMACBi8PWkACoAIG7wK7LdLMCA/BYOIAICUrBY3jWOGI0ert323wgAABBwMC70 +AixwbysiF/wsQAAEAmtw/BYNJAAgaTD8IFgmACAZMPwWCSIAAFGwWN4nihkc26iLHapqJaQADLsL +LLCALBYO+7IhIAICUrBY3h+PGY4e+yIZLgAge7D25ggAABB4MC9kAi1wb/wgYCAEAnOw/BYKJAAg +cTD9PUAGACAZMP0WDSIAAFGwWN4Pihoc25CLHapqJaQADLsLLLCAnB77siEgAgJSsFjeCI8ajh77 IhsuACB7sPbmCAAAEHgwL2QCLXBvLCBo/BYLIAQCc7D9DUAEACBxMPNGCAAcAmtw/RYGIgAAUbBY -3fSKGxvbG4wW/dsYGgAgUbAlpAD7ywsN0AQ7IPuywSwAIGswLMCA/BYHIAICUrBY3eiNG4wX+yId -LAAgazD2IHAuACAzMPzMAiAAEGgw/eQCJAAgYTD8bAAKACAZMFjd3BLbYvjaqBQAIDEw+BYMJgAg +3fiKGxvbG4wW/dsYGgAgUbAlpAD7ywsN0AQ7IPuywSwAIGswLMCA/BYHIAICUrBY3eyNG4wX+yId +LAAgazD2IHAuACAzMPzMAiAAEGgw/eQCJAAgYTD8bAAKACAZMFjd4BLbYvjaqBQAIDEw+BYMJgAg GTAlZAD7cTQiAABgcPAIBwIAAHhw8A+gAAoQcDD/FgQv9hBoMMCQbQge2rAOuy0NvyivqqoqKqAA +sQAIgAAUzD0sAlgAgJjMGP/2AAA+aQBKgAW0FDbEG0IIC2wAC7N/yng//3k/yH+AlKw+bQAIAIC WvD6uwdx/gJjMGP/2C8QAPUKACAZADfg2RBtCAwokAGxVfSAB2ACAkpwY//ssWr7HAACAABhcFjd -rbFb+9sxFAAgWTAPAgAPAgAlsHijSrGq+7IfIgAAYXBY3aT/EgwgAgJZcPkSBSQAIFkw80YIAD0Q +sbFb+9sxFAAgWTAPAgAPAgAlsHijSrGq+7IfIgAAYXBY3aj/EgwgAgJZcPkSBSQAIFkw80YIAD0Q UDAqZAD5ko8iAABgcPIPBwIAAHBw8A6iAAoQaDD+FgQv9hBYMMDgbQge35ANmS0LmCio/68vL/AA /8QAIgAAUzD0kA1gAgJjMGP/2AAAAAAAAP6kASoAFtBQ2xBtCCAusAAvzf8t8P/+9P8h/gJSsP20 ACACAlrw+rsHcf4CYzBj/9goEAD1CgAgGQA2INkQbQgMKpABsVX0oAdgAgJKcGP/7LFq+xwAAgAA -YXBY3XOxW/va9xQAIFkwJbCgo0qxqvuyKSIAAGFwWN1ssVn/EgwkACBJMPNGCAA9EEAwKGQA+XIY +YXBY3XexW/va9xQAIFkwJbCgo0qxqvuyKSIAAGFwWN1wsVn/EgwkACBJMPNGCAA9EEAwKGQA+XIY IgAAYHD0DwcCAABwcPAOpAAKEGgw/hYEL/YQWDBtCB7akA2ZLQueKK6qqioqoAD6xAAiAABTMPSQ CGACAmMwY//aAMCA+KQBKgAW0FDbEG0IIC2wAC7N/yng//3k/yH+AlKw+bQAIAICWvD6uwdx/gJj -MGP/2C8QAPUKACAaADfg2RBtCAwokAGxVfSACGACAkpwY//sALFq+xwAAgAAYXBY3T2xW/vawRQA -IFkwJbCoo0qxqvuyKyIAAGFwWN02sVn/EgwkACBJMPNGCAA9EEAwKGQA+XIXIgAAYHD2DwcCAABw +MGP/2C8QAPUKACAaADfg2RBtCAwokAGxVfSACGACAkpwY//sALFq+xwAAgAAYXBY3UGxW/vawRQA +IFkwJbCoo0qxqvuyKyIAAGFwWN06sVn/EgwkACBJMPNGCAA9EEAwKGQA+XIXIgAAYHD2DwcCAABw cPAOpgAKEGgw/hYEL/YQWDDA4G0IHtqQDZktC58or6qqKiqgAPrEACIAAFMw9JAJYAICYzBj/9gA AP6kASoAFtBQ2xBtCCAtsAAuzf8p4P/95P8h/gJSsPm0ACACAlrw+rsHcf4CYzBj/9gvEAD1CgAg -GwA34NkQbQgMKJABsVX0gAlgAgJKcGP/7AAAsWr7HAACAABhcFjdBhvai7Fc9bCwJAAgYTCjSrGq -+7ItIgAAYXBY3P+xVv4SDCQAIDEw80YIAD0QeDAvZAD5chYiAABgcPgOBwIAAGhw8A2oAAoQeDD9 +GwA34NkQbQgMKJABsVX0gAlgAgJKcGP/7AAAsWr7HAACAABhcFjdChvai7Fc9bCwJAAgYTCjSrGq ++7ItIgAAYXBY3QOxVv4SDCQAIDEw80YIAD0QeDAvZAD5chYiAABgcPgOBwIAAGhw8A2oAAoQeDD9 FgQv9hBwMPoKACIAAFhwbQge2JAPmS0OnSitiKgoKIAA+MQAIgAAazD0kAlgAgJjMGP/0gAA+tQB KgAa6tD63AACAABYcNMPbQggL7AAKM3/LoD//4T/If4CUrD+tAAgAgJa8Pq7B3H+AmMwY//WKRAA -8goAIBkANmDZEG0IDCqQAbEi9KAHYAICSnBj/+yxavscAAIAAGCwWNzNpCKyItEPbBAOIhYRJCIQ -lB0S2lCHRyRAbyYgSCsiE/dyDiIAAFDw/GwABAYBIDBY3MAV2kb82ecb0AQ9INMP9xYFJAAgKvD0 -QIAqACAw8PUKPSoAIGbw9aQAIAICUrD7st0iAABhMFjcsisiFfZKCAAAEDgw9BINJgAgGrAnZAIm -IFD0QG8gBAJSsPoWByoAIBqwmh78bAAEBwEgMFjcpRvaKooeC0sLJLCApqr1pAAgAgJSsPuyISIA -AGEwWNydjR4qEhH8Eg0kACAxMPgSBywAIG0wJ9QCLMBuqESyRPqiEiMLADcg+yIXJgAgGTD8IFgu -PAFQMPwWDyAEAnOw/hYIIgAAUbBY3Iod2bKLGIof/bsLDdAEOuAd2a2qaiWkAPuywSwAIGswLMCA -/BYJIAICUrBY3H+IH48Z/hIRLgAgR/D7IhkmACAz8CdkAi7iEiwgYPwWECAEAnvw/u5RBAAgeTDz -RggABAJzsP4WCiIAAFGwWNxvKhIQG9mWLBIK/dmTGgAgUbAlpAALywsrssENzAsswID8FgsgAgJS -sFjcZC0SEIwbrcz2IGgsACA3MPsiGyAEAmMw99QCJAAgYTD8bAAKACAZMFjcWhLZ4PnZJRQAIDEw +8goAIBkANmDZEG0IDCqQAbEi9KAHYAICSnBj/+yxavscAAIAAGCwWNzRpCKyItEPbBAOIhYRJCIQ +lB0S2lCHRyRAbyYgSCsiE/dyDiIAAFDw/GwABAYBIDBY3MQV2kb82ecb0AQ9INMP9xYFJAAgKvD0 +QIAqACAw8PUKPSoAIGbw9aQAIAICUrD7st0iAABhMFjctisiFfZKCAAAEDgw9BINJgAgGrAnZAIm +IFD0QG8gBAJSsPoWByoAIBqwmh78bAAEBwEgMFjcqRvaKooeC0sLJLCApqr1pAAgAgJSsPuyISIA +AGEwWNyhjR4qEhH8Eg0kACAxMPgSBywAIG0wJ9QCLMBuqESyRPqiEiMLADcg+yIXJgAgGTD8IFgu +PAFQMPwWDyAEAnOw/hYIIgAAUbBY3I4d2bKLGIof/bsLDdAEOuAd2a2qaiWkAPuywSwAIGswLMCA +/BYJIAICUrBY3IOIH48Z/hIRLgAgR/D7IhkmACAz8CdkAi7iEiwgYPwWECAEAnvw/u5RBAAgeTDz +RggABAJzsP4WCiIAAFGwWNxzKhIQG9mWLBIK/dmTGgAgUbAlpAALywsrssENzAsswID8FgsgAgJS +sFjcaC0SEIwbrcz2IGgsACA3MPsiGyAEAmMw99QCJAAgYTD8bAAKACAZMFjcXhLZ4PnZJRQAIDEw +RYMJgAgGTAlZAAuIADwCQcCAABAcABIYZgU9xQBIAAQKDD+FAAgGQA3oNkQbQgMKpABsVX0oAdg -AgJKcGP/7LFq+xwAAgAAYXBY3ESxW/vZyxQAIFkwJbCwo0qxqvuyLSIAAGFwWNw9iRX/EgwgAgJR +AgJKcGP/7LFq+xwAAgAAYXBY3EixW/vZyxQAIFkwJbCwo0qxqvuyLSIAAGFwWNxBiRX/EgwgAgJR cPoKPSQAIFEw+Z0BJgAgGTAqZAACD4v5FgYiAABgcPmRlCIAAHBw8A6iAAoQaDD+FgQv9hBYMG0I Ht6QDZktC58or+6uLi7gAP7EACIAAFMw9JAMYAICYzBj/9oAAAAAAPekASoAFtBQ2xBtCCAtsAAu zf8p4P/95P8h/gJSsPm0ACACAlrw+rsHcf4CYzBj/9gvEAD1CgAgGwA34NkQbQgMKJABsVX0gAlg -AgJKcGP/7AAAsWr7HAACAABhcFjcChvZkrFcDwIA9bC4JAAgYTCjSiqsAfuyLyIAAGFwWNwC/xIM +AgJKcGP/7AAAsWr7HAACAABhcFjcDhvZkrFcDwIA9bC4JAAgYTCjSiqsAfuyLyIAAGFwWNwG/xIM IAICWXD5EgYkACBZMPNGCAA9EFAwKmQA+ZGVIgAAYHD0DwcCAABwcPAOpAAKEGgw/hYEL/YQWDBt CB7ekA2ZLQufKK/uri4u4AD+xAAiAABTMPSQB2ACAmMwY//a96QBKgAW0FDbEG0IIC2wAC7N/yng //3k/yH+AlKw+bQAIAICWvD6uwdx/gJjMGP/2C8QAPIKACAZADfg2RBtCAwokAGxIvSAB2ACAkpw -Y//ssWr7HAACAABgsFjb06QisiLRDxzZWhvZWigSEQyqAQuqASqGEmP84wAAAGwQIoY3hm4uYo4c -2VP6CgUgMBBYMP5+UQIAAGlwWOS/EtlP+FEPYAAQODDBiHhRQ9Jw0Q8AACUgLPMKPSIAAFEw+yIM -IgAAYXBY27gmINT7IjYqACApMCOkAPxsAAACAlKwWNuypWKkKPeEAiAEAhCw0Q8AFdiPiD0pUnEl -UoCpiAmIEfsiEiQAIEVwhVcsIEQsFjf1Ug4iAABRMFjboysSN/tOCAA9EBgwI+QALVACJRY4+tFD +Y//ssWr7HAACAABgsFjb16QisiLRDxzZWhvZWigSEQyqAQuqASqGEmP84wAAAGwQIoY3hm4uYo4c +2VP6CgUgMBBYMP5+UQIAAGlwWOTDEtlP+FEPYAAQODDBiHhRQ9Jw0Q8AACUgLPMKPSIAAFEw+yIM +IgAAYXBY27wmINT7IjYqACApMCOkAPxsAAACAlKwWNu2pWKkKPeEAiAEAhCw0Q8AFdiPiD0pUnEl +UoCpiAmIEfsiEiQAIEVwhVcsIEQsFjf1Ug4iAABRMFjbpysSN/tOCAA9EBgwI+QALVACJRY4+tFD YgAAY3ApXQL5nIAiAABTsG3ZEiyQSPykASACAkpw9MAUYAICUrAlFjgsUAJgABQAAAAAAAAA9RY4 LgAgb7An9AEsUAIa2FkobQMqFjTwCgcAQAJIcABJYfkWDCIAIFsw+4BYIQACSjApFjX7FDQigBAo MPiAeyBwAlBw+BYvIAQCELAPAgBbIBYqHDj8CgEgaAJYcFsfwioSOKWpK5Ao/AoAIBcANuBtCAwt kCmxzPTQB2ACAkpwY//sK60D+hw4IVACWvBbH7b7bQMgcAJQcPwSLyD4AlrwWx+x+hw4IEACWHBb -H2Ic2PEvECIuECEtECAoECOYECsQJJsRKhAlKhYCKRAmKRYD+BAnIDAQWDD4FgQgBRBQMFjkUxzY -5C8QKi4QKS0QKCkQK5kQKBAsmBErEC2bEioQLpoT+RAvIDAQWDD5FgQgBRBQMFjkRhvY1iywTCwW -LvuyFCoAICCwWNtFLBIuGdhz/CIIADAQeDD0KggAeBBwMPOkACACWAKgL6QBLqQC/RwgIgAAYrD4 +H2Ic2PEvECIuECEtECAoECOYECsQJJsRKhAlKhYCKRAmKRYD+BAnIDAQWDD4FgQgBRBQMFjkVxzY +5C8QKi4QKS0QKCkQK5kQKBAsmBErEC2bEioQLpoT+RAvIDAQWDD5FgQgBRBQMFjkShvY1iywTCwW +LvuyFCoAICCwWNtJLBIuGdhz/CIIADAQeDD0KggAeBBwMPOkACACWAKgL6QBLqQC/RwgIgAAYrD4 ChAgfhBYMA8CANMPbYo1/wIAAgI+RuAv0AAPDkP+nggOZAF8MP7ggC4AIH5w//CAIAQCYzD/xAEh -/AJa8P7EAiACAmtw96QjICMQQDAoFjYtEjb82LQQBRBQMPwWMyAwEFgwWOQcKRI2ZpRV+goFIDAQ -WDD82KwSAABqcFjkFiwSNitijsCj/MwBKxcBXDD8IggOAhbekPPYpRD+AlBw+qwRIAEQSDAI6jAM +/AJa8P7EAiACAmtw96QjICMQQDAoFjYtEjb82LQQBRBQMPwWMyAwEFgwWOQgKRI2ZpRV+goFIDAQ +WDD82KwSAABqcFjkGiwSNitijsCj/MwBKxcBXDD8IggOAhbekPPYpRD+AlBw+qwRIAEQSDAI6jAM 6jAIyDgc2KAd2J8Mjy0N+ygV2J772J8YACBaMAX/KAuIKKj/o/gPjzoI6jAO6jAI6DgMji0N7Sj1 7igIACBqMAuIKKjuo+gOjjoI6jAN6jAI2Dgd2IwMjC0FxSgNzCgMiAgLiCj+iBIEACBFcAjuA/+I EgoAIB1wBbU69Y0SDhEAR/D/SBIMEQAvcP5YEg4RAEfw+O4DDkABfDD9/xEOQAFwMP1fEg4JAHuw D90D/u4RDCABbDAO3QL9pAAh/gJKcPWfN2ACAlKwLRCQ+9hoEAEQcDD82EscAQB3cP4SNSzgAWww -LRSQJcYTLeTYLLA0LBYx+7IOKgAgILBY2tAsEjEf2FX6EjQgChBwMPkQkCIAIGCw9CwIAD0QWDD7 +LRSQJcYTLeTYLLA0LBYx+7IOKgAgILBY2tQsEjEf2FX6EjQgChBwMPkQkCIAIGCw9CwIAD0QWDD7 xAAg/gJocPIKBwBCAkNw8AiiAEICa3D4Fiwv9hBYMNiQDpktC5ooqoio+CiAAPjUACIAAFNw9Z/l YAICa3ArHH8rvCH3pAEqABXS0G0IIC+wACjd/y6A//+E/yH+AlKw/rQAIAICWvD6uwdx/gJrcGP/ 2CocfyqsISugAMCQ0w/5FjAgGwA24G0IDCugAbGZ9LAIYAICUrBj/+wAKRYw+swBIP4CWHD8EjAg -QgJa8FjamywSMBvYJtMPscz8sDwiACBgsPwWMioAICCw+7IQIAICUrBY2pIsEjL9EjQgAgJjMPlt +QgJa8FjanywSMBvYJtMPscz8sDwiACBgsPwWMioAICCw+7IQIAICUrBY2pYsEjL9EjQgAgJjMPlt AyIAIGCw9CoIAD0QWDArpADwDQcAtgJKcABJYQBJYQBJYQBJYQBJYQBJYQBJYQBJYfoWOSAAEEgw 8hYtIBAQaDBt2tIK6jAM6jAd2BEb2A8V2A0e2AwKyjgFqC0OjCj7iCgKACBisA2qKKqIo4wIyDoE 6jAK6jAEpDgFQi0OKij7IigEACBRMA1EKKQioyQCQjoM6jAP6jAIihIChBIM/DgFxS3+XigCEQAg @@ -3732,28 +3732,28 @@ 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 @@ -3766,7 +3766,7 @@ QWAHEHgwqkUrXCD7FgUiAABQsFv7ry1gbvysAAAAgIdgGNYTLoCAauEupar7giEiAABCsG3pEi+w AP+EICACAlrw9PAIYAICQjBgAAsA+AoAKAAgdrAolCAb1gb/1e8QPRBoMPwSCy4AIHMw/hYGJAAg L7D9VCAiAABAcPIMBwIAAFBw8AqiAAoQcDD6FgQv9hBgMNmwDrstDLooqpmp+SmQAPmEACIAAFIw 9b/lYAICQjDAsPukASoAFFBQARsCLbAALo3/LOD//eT/If4CUrD8tAAgAgJa8Pqz43H+AkIwLxAA -/AoAIBMAN+DYECmAAbHM9Z/3YAICQjCcHfscAABCAlFwWNg+iBaFHahVslUsMQrz/CxgBxB4MAAA +/AoAIBMAN+DYECmAAbHM9Z/3YAICQjCcHfscAABCAlFwWNhCiBaFHahVslUsMQrz/CxgBxB4MAAA APsSBSIAAFCwW/nr8//jYgAAKrCJImWeAosY+iwAAAAQYDD7vBggQhBoMFuNPMAg0Q+LGPosAAAA EGAw+7wSIAAQaDBbjTbAINEPAABsEAYrIhImIhD51cAQATuy0Ig0KiAH9QoAIAE3AiCJIv3VExC+ Ajlw90cUCiABUDD1klBtwAQ6oP/VEBwAIGswLsI6mhAPrwr/8pcqAWg/kC7COfzVOBoIAVww/+QB @@ -3781,12 +3781,12 @@ jxQIiBQoRDQvRDEPjxQvRDAuRCMOixQrRCLwCgcAgAJJMABJYSggBwgIQQyIEa2IJ4Y5KyAWLwr/ f7EK+iAHIGACYXBbjByKJ/sKBCAAEGAw+qwgIAQQaDBbhFMtIhIsYhH7YhQvfxBwMA7dAf0mEiAC AmMw/GYRIAICWvD7ZhQgABAQMNEPAAAA2iBbjFj91HweCAA2oMAg0Q8lkICxVQUIQQhfDLT/8/2F ZAUAR/AAABzUtf3UXhD/EHAwLkQ0LUQ1/EQ2L/8QWDArRDeKbrGqmm5bIAMqRDMKjBQb1RAsRDIM -jBQsRDEjsIArsiH8jBQAoAJRMPxEMCIAAGDwWNdpHdRfihP+CgAoACAZMP6EUCACAnjwL0QnD48U +jBQsRDEjsIArsiH8jBQAoAJRMPxEMCIAAGDwWNdtHdRfihP+CgAoACAZMP6EUCACAnjwL0QnD48U L0QmD48UL0QlD48UL0QkY/7hixD6LAAAARBgMPu8GCIAAGnwW4xowCDRD4sQ+iwAAAEQYDD7vBIg -ABBoMFuMYsAg0Q8AAGwQBCggBSkKkHmBSfzU7RAFEFAw/SIAIDAQWDBY4EWDJ4M++9ToEgAAULBb +ABBoMFuMYsAg0Q8AAGwQBCggBSkKkHmBSfzU7RAFEFAw/SIAIDAQWDBY4EmDJ4M++9ToEgAAULBb gNgpPQIY1OX4pgQgABBYMPumBSBAAmKwAgmGAExjAAmGAExhm6aJIsiaiicqrBBbhenAINEPiKL8 -CgQiAABasP0KAyIAAFCwC4AAY//bAABsEASJKsifipjIq8Cw/AoAIAIQaDBY4HPRDwAAbBAOHNTM -jSAuIAUvMgAoMAX0FgEgBRBQMPgWACAwEFgwWOAeH9QGHtQEHdRVG9TCjDf3GoAgkhAoMPoKkCBl +CgQiAABasP0KAyIAAFCwC4AAY//bAABsEASJKsifipjIq8Cw/AoAIAIQaDBY4HfRDwAAbBAOHNTM +jSAuIAUvMgAoMAX0FgEgBRBQMPgWACAwEFgwWOAiH9QGHtQEHdRVG9TCjDf3GoAgkhAoMPoKkCBl EDAw/MIOIKYAPSBvRCJuQh8kMAUPAgB6QWYtMG7+CpUgAIoHYP8CAAYA6nUQwCDRD2lE+C8wbmnx 8igwBXWJ7Iwo+jwAAAIQSDD5xGQgARBYMFgIocAg0Q8AJDAF/wIABgB2VRAtMG5p0cF1Sb6OKMCx ++RkIgAAUPBYCJfAINEPKrJ4iD0S048psn76socoACBSMCIgwQmZEfmrCAmQBDog/ycPegAgQrAp @@ -3802,14 +3802,14 @@ AExhiiLIpsAg0Q/ALNEP2iD8CgogAxBoMFsebMAg0Q8AAGwQBBTTCxXTxiRAwShSePJSgSIAAEiw +YgRAAEQWDD/RxVyACBAsCIiJ4IuIiIQ8AAPYf4CELAAIiKngi4iIhCwImQgViZSh4ZmAioLBqoL 8AAKb/8QYDAmLEh6YT3ybAAACQA2YChgJsqIZD/pLSAmwGD50eFgEBBwMG3qFKJn93AQKAAgGbAo gAD3iRFwAgIxsNEPiGR5idDRD8Ag0Q/4cwZyAAAzMNawZW+qY//pbBAUHNPuAHWOJCIJLSIALiAF -+CIbJuABKDDzIAcgBRBQMPgWACAwEFgw+CIcIgAAefD4FgEiIAEcMFjfNykiCicWGvMWGSIBil5Q ++CIbJuABKDDzIAcgBRBQMPgWACAwEFgw+CIcIgAAefD4FgEiIAEcMFjfOykiCicWGvMWGSIBil5Q LkIHLuIOIyISJyITK+Kr+3wBCgBAXPB8sQIj4rH54qsgMBBYMPzT1BABEEAw/woAIgAAaPD5egEI -AEBM8PqZDAIAAHHw+Y84AAUQUDBY3x/1CgAgJwA04Po8AAAAEFgwW/+p+hYbIgAASrD1rAADqgA2 -oC6REGAAAwAAx+/6CgUgMBBYMPzTvRIAAGlwWN8P01AX07r1CgAhAAC04CsiG/8CAAIBQMbg9SYb +AEBM8PqZDAIAAHHw+Y84AAUQUDBY3yP1CgAgJwA04Po8AAAAEFgwW/+p+hYbIgAASrD1rAADqgA2 +oC6REGAAAwAAx+/6CgUgMBBYMPzTvRIAAGlwWN8T01AX07r1CgAhAAC04CsiG/8CAAIBQMbg9SYb IgBiAaCKJ/xcAAABEFgw+qwgIAEQaDBbgsZgAKcY067+dQIoCQBD8JhwKCITmHIoIhKYcygiHCt1 A5p1+XYEKAkAYjD4dgcgABBAMCgWFxnSmCoxEZUYLjAonhn9Fg8gARBgMPwWECAGEFgwmx0b0qyV HCUWEfkWDiAUBFqwG9OXC6sCLUEYKhwg/QxGDkgBaDD57hEMBwFsMPDdEQwJAHMw+xYLLAkAazD8 -FgogoAJYcFt9rWSiHcCl/NOJEDAQWDBY3teNL8jb2iD7IhAgARBgMAvQAIwuyMn7IhAgABBQMAvA +FgogoAJYcFt9rWSiHcCl/NOJEDAQWDBY3tuNL8jb2iD7IhAgARBgMAvQAIwuyMn7IhAgABBQMAvA ANogWINawCDRD48q/BIZIgAAULD4GgAgQBBwMPj/AQAoEFgw/RwQKgUAf7BbjMj3rAACqwA2oI8q +9KnEQAQSDD/jFIAARBwMAyeOf8CAAgBF3bQwKDwAApgDRBoMAC4Gn6KCbGq8KEECf/6V1Ad02Qp QRovFhYpFhj90d8iNAA2YN+Q/ZM2cAAQWDAd01z7CgAgDhBIMPAAE2AEAmtwAAAAAAAAAPjzFHAO @@ -3817,24 +3817,24 @@ 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 @@ -3845,51 +3845,51 @@ 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 @@ -3899,59 +3899,59 @@ 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 @@ -3960,25 +3960,25 @@ Uhj6UgIoAEB+cClWEi6EdPwkBSBwADagfqdV8/35YgAAIXAA2kBb3oTRDwCKR/sKASAAEGAw+qwg IAEQaDBbemMpQGT/AgAAAEIGYP8CAAIAQgJg/wIAA/6kHmD6TAAAABBYMPwKACACEGgwWHw30Q96 0Afz/tRiAAAhcPP9n2IAACFw8/2XYgAAIXCIovwKBCIAAFqw/QoDIgAAULALgAAdysksQhIu+pL+ JAUsCQBrMCxGEtEPAAAAAADz/wJgABBYMPP9HGIAACFw2kBb4JfRDwAqQhhb+zzRD9owWwVxE8qx -C6gR9KA5YgAgRPAM6jArMoWLsLCj/LsIAgAAUPBY2KIcyyUqwn8AMQQAaxoLqgIqxn9Y2NiMLAbM +C6gR9KA5YgAgRPAM6jArMoWLsLCj/LsIAgAAUPBY2KYcyyUqwn8AMQQAaxoLqgIqxn9Y2NyMLAbM Apws0Q8AAPoKByABEFgwW3zZjSwuMn/+NoMsCQA3cJ0s0Q9sEASKLPkKlSACEGgw9QoAIAQQYDD8 rwICAHn2kIsnjr6fLC7tAi3kECggBf8CAAYAeM4QiSojkggrMhIo+o34lHQiAFi60BjLIYQn0w/6 ywgYAEBC8Pg2EiAgAiEwWw+OHMsDHcnp/ssDEgAAWrD/IgAiAABRMFsPRYQnJEwQ2kBbBRj2CgEg AHwGoIssiiooMhL0CoAqCQA28PsmDC+MEEgw+aR0IEoAYjCKN/sKBCAAEGAw+qwgIAQQaDBbefMr MhIs+n8MuwErNhL7yu4SAABQ8Ft2vyWkEi4yEo0y26D1pQguCQAjsP42EiCCADdg0Q8AijcqrBBb -e9McyigrMhIMuwErNhJj/zsA/SIAIAUQUDD8yvIQMBBYMFjWF9EPKrwQW3vIgyeDPvvKuBIAAFCw +e9McyigrMhIMuwErNhJj/zsA/SIAIAUQUDD8yvIQMBBYMFjWG9EPKrwQW3vIgyeDPvvKuBIAAFCw W3aoKT0ClaX4yrUSAABasPimBCBAAmKwAgmGAExjAAmGAExhlaaJImWfkoiiwMT9CgMiAABQsAuA ANEPiKLAxP0KAyIAAFDwC4AA0Q/aQFsE+BTKOAuoEfSgNWQAIEEwDOowK0KFi7CwpPy7CAIAAFEw -WNgpHMqsKsJ/AEEEAGsaC6oCKsZ/WNhfY/7LAAAAAPoKByABEFgwW3xhLEJ/LEaDY/6zbBAIF8rB +WNgtHMqsKsJ/AEEEAGsaC6oCKsZ/WNhjY/7LAAAAAPoKByABEFgwW3xhLEJ/LEaDY/6zbBAIF8rB Jj0BKDKOLHIUJmxA9XLqIgDJrhD6ctEgJgA3IC5y5P0KgCuQBDqg+zKTKgAgcrBtyQuMp4zOLsKq e+EJrarwAAxgABBQMC3CrbHdLcat1KAqUhEuoQL/UhIhRQA3oC/xAmTxOpQWW3TmGMmyKIJvJHLk qoj6FgQpkAQ6IPpSEiQAIEEwW3TfHMqhHcqfixYvQAf6yqAcACBusC6wB/tGCSD8EEAw8kYQLgBA R/D9FgUuIAFwMP/KlR4JAHuwn00uRAeOFJ5LKWI+mk/9RTUhABB4MPxGDiB0AC5wjkoqPQL9PQIu CQB7sP5GCiCQAmtw8g0WAJACYTDwDKIAsAJSsPAKFgCwAkkwAElhYAAOAAAAKWJCKUYSKGJDKEYT -gxQcyn0vYYItsAf+sDkgBRBQMP9FNCAwEFgw/ywADCABbDBY1ZccynUtUhGIFS5yFS3RApQQ+UIA -IgAAePD5FgEgBRBQMPgWAiAwEFgwWNWM9QoCIC0ANSAvIG7+CgEiAABRcA/qOfwKACAAWQag8/rq -IgB1gqDLMdpAWHoN0jDRD8As0Q8qPQIqrFhb94Mcylz7CjAiAAAisP1CACAFEFAwWNV3Y/6KAAAA -ABzKVv1CACAFEFAw/kIHIDAQWDBY1XAoIG6UKvlCCiDGADYgGspOCpoCmkqOLPxtAS4JACuw/iYM +gxQcyn0vYYItsAf+sDkgBRBQMP9FNCAwEFgw/ywADCABbDBY1ZscynUtUhGIFS5yFS3RApQQ+UIA +IgAAePD5FgEgBRBQMPgWAiAwEFgwWNWQ9QoCIC0ANSAvIG7+CgEiAABRcA/qOfwKACAAWQag8/rq +IgB1gqDLMdpAWHoN0jDRD8As0Q8qPQIqrFhb94Mcylz7CjAiAAAisP1CACAFEFAwWNV7Y/6KAAAA +ABzKVv1CACAFEFAw/kIHIDAQWDBY1XQoIG6UKvlCCiDGADYgGspOCpoCmkqOLPxtAS4JACuw/iYM L4gQaDAtRHQrwCkuwCr9wCsrgAQ+4A67AvzALCuABD7gDbsCCLsRDLsC+0YcIgAAUTBb94vSoNEP L3Lqi/8v/Dx/sUCIsY2wnYCJsJiRnLD8tgEgUQA24Ci9/4NAI4Y+jkovvPj/RgcuCQBTsJ5K8/8g YAAQGDAAAAApcuqLnSmcNHm5C/P/Cm/0EBgwAAAAAI2xj7Cf0I6wneGcsPy2AS+3ALbg8/7qYAAQ @@ -3988,39 +3988,39 @@ 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 @@ -4044,7 +4044,7 @@ oPKxQ3IAAEJw9LAzaOABTDD6zAggAgJKMP7WCwA7ADdgImUAIvLiAtILIyUBLPLiLVQADNwL9MYB IAEQEDDRDw2dOGP/ygAAI6UBlKH5VAAgABAQMNEPAMcv0Q9sEAQXxuXTDylyHShy4voaACnwBD5g +JgLDjAAvmAJqgxtqQ0rgQBysQv5nAEgEAJCMMcv0Q8jhQGUgflUACAAEBAw0Q8AAABsEAQaxb2M NCuievqigC1gAWAwrLsJuxGrqiigBPiLBmAAEBAw0Q/A0C2kWCswFC6iFRjGyP/FbxAQADbgLOEA -CMwBD8wCLOUAjKIrohQpohP9phMv/hBwMP2mFCwAQHMwnKL8CgAiAABScFjP2cAg0Q8AAGwQBCgh +CMwBD8wCLOUAjKIrohQpohP9phMv/hBwMP2mFCwAQHMwnKL8CgAiAABScFjP3cAg0Q8AAGwQBCgh BxnGtwgISgyIEQmIApgwhyD2xocXgAQ94PnFsxYJAD0wlzHwBhcAEAIQ8AACipU1+TYEIDACEPDR DwBsEASLM/oiByAAEGAw/CQnIgAAaTD7BksD8AFcMPtMAABAAlKwW3Vm+iAmIAEQODD4xZoQ4QA0 4AylEfvFmhQAIEVwLFI6C6sK+7KXIgBpxyApUjkfxpQcxmf7lAEOAGFeUC4hBw4OSgzuEQ/uAp5A @@ -4053,22 +4053,22 @@ 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 @@ -4076,49 +4076,49 @@ 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 @@ -4131,8 +4131,8 @@ JAXz9/5hkBBYMAAA2jD7HH8gCBBgMPu8QSACEGgwW2x3Y/vEAGwQBvYsAAFRADUgKixI+hYBIIAC YLD8FgIgoAJYsPsWACBwAjiw8sItH+8QcDD7wiwQABAoMPAASm/9EGAwAGiVaWmaMS0wBC8wBfgw Bi2ABD9gD90C/zAHLYAEP2AI3QII3RH/3QID6BB4MA/dLP1kNiIAQFiwLzABpfXz8woKAFkhUCkw AP8CAAAATIZgaJJsaZSptDnzCRYCAABB8ABIivAASWIAQHCwAAAoMAIpMAP6+t8gCgJY8PoiAQmA -BDog+hIAKAkASjD4ZRggAxBgMFjD8I0R+8ICEBACePDxDxYP/RBgMPIdHg/vEHAwKjABpaXzowoL -/8YlUGAAMooS/AoGL/sQWDD7PAIiAEBYsFjD4PvB8x/9EGAw8//Pb+8QcDAtMAMtZDTz/0liAEBg +BDog+hIAKAkASjD4ZRggAxBgMFjD9I0R+8ICEBACePDxDxYP/RBgMPIdHg/vEHAwKjABpaXzowoL +/8YlUGAAMooS/AoGL/sQWDD7PAIiAEBYsFjD5PvB8x/9EGAw8//Pb+8QcDAtMAMtZDTz/0liAEBg sMogGsF7i2AuonL6oowgABBgMP67DAABEGgwW3AbwrQrZAXRD9EPEsHhY//VAABsEAT6Cg4v/RBY MPskASAAEGAwKiQALCQCKTAAKSQDKDABKCQEJDACJCQF0Q8AAABsEDorIAXCZPQKJyYDtDbQwqX6 sShwABBoMMKG/wIABgODRtDzCigmA94m0PQKKSYD7h7QdLEG2iBYEALRD4kqg5pkNEYpFlYuHQH6 @@ -4140,29 +4140,29 @@ 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 @@ -4172,7 +4172,7 @@ gzllP+8mJAX6LAAAARBYMPwKACACEGgwWxNTZaixJCQF8/imYGQQWDDaMFhVOIM5ZT/BY//Ojjhj +TkAjztl/WbEg3jRKRq/4oswLqJy+qKMIAAQYDD+uwwAARBoMFtuGBy/PovO/jIIIf4CWvCbzic0 BWP9NgAA+iwAAgAAY3D7CgEgAhBoMFsTN2WoQSMkBfP4NmGQEFgwAAAAAAAAAPosAAIAAGNw+woD IAIQaDBbEy1lqBkkJAXz+A5hkBBYMAAA2jD7HH8gCBBgMPu8QSACEGgwW2oBY/vMAGwQHCgwIhW/ -wQiICQyIEahTJTJ/+iwAAEIANWASvwwtoAwuInsqIoSu3fndEQIAAFlw/aoIAAEQYDBYoRPCbfwa +wQiICQyIEahTJTJ/+iwAAEIANWASvwwtoAwuInsqIoSu3fndEQIAAFlw/aoIAAEQYDBYoRfCbfwa gCAmEDgw9EARYP0QaDBoQwn/AgAEAFmFINEPrDsusHl/5/UN7AEstHmKp/IagCAgAlKwW3BAoj4t 4HkiMoP4+v8g+xB4MPjkeiwAQH9w/eR5ICkAtKBj/78AAPo8AAABEFgwWFUjIzIJyDkpMAV2memD OWU/9IIpZC+dKiIVdan0KyAFd7HujSf00g4vwBBwMPckBSBAAmNw/goALABAczD+1RQggAJjMJzZ @@ -4181,21 +4181,21 @@ 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 @@ -4203,7 +4203,7 @@ AiEwY//rx8D/AgAP/3bfEAtLFPP+4mAIAiEwaHIt2iD8HBAgBBBYMFh8kGP/lQAAAPP+ymAAECAw ih/8HBAgAhBYMFh8E2P/egAAAIwe/RIPLeAEOyAAwQSMF4kY+goAIAQQWDDwuxoKBQBrMKuqKpav ixnAgPq2jCAAEFgw+ZKvIAgQUDBtqhfwgQQKIgFIMPCqGgAEAkIw+UkUCgkAVvCNGSvWi2P/dI8V L/0BLvGNwCTyEgYuCQATsC71jdEPAMAg0Q9sEAQYvNslgn0mgoD4gnskACAVcAlVEQVlCPVSBygA -IBIwCYgRCGYI9VIOIDsANSDdIP4wACAFEFAw/L4JECQQWDBYyObaYPwwACABEFgwWC9eKl0BKaGN +IBIwCYgRCGYI9VIOIDsANSDdIP4wACAFEFAw/L4JECQQWDBYyOraYPwwACABEFgwWC9eKl0BKaGN wLILmQL5pY0iAAAQ8NEPwCDRDwBsEAT3vf0RGBBQMAoqKKenJ3KXBHcoB3cK+DroJ/AEPeAIdywY vfYbvfYcvGsCKQvzmQkHwAQ44PyqCAnABD5g+HgCCAAgXnD4lgAmACBRsPdmwCCcECgwJWa/0Q8A AABsEAgWvKjZIPNifSIAABDwwLD1YoAgABA4MPhieyIAIEzw+TMRAAEQUDDzUwgADxB4MPMyBygA @@ -4222,25 +4222,25 @@ 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 @@ -4253,7 +4253,7 @@ Cok48/6oYAIQYDBsEASIMCowCf8KGi/qEGAw+AJDAABwJhD3ChYkAGgVIPgwCCAgAmjw+gtFAAIQ cDD6ekAAARAgMPgMQQhEAUAw9ME4YfoCSzD55DgBKAA2IPr3OAYAkBYgBIYMBgZHpr7/AgAKAIh1 0GRgaB+6K/hKACVAEHAw97txHgUAUjD+vgoJIAQ4oKju9+4IAgAAW3D/7wgCAABBsPm8AAAAgAYg C7oCAA+L8AuAACACc7DxChYB/AJCMPMKFgAgAnvw8lkeACACWvDyGR4PzgC2IA1rEQ29CgQOR8jp -+iwAAAEQWDBb/17wAAxgABBgMP27SxAsBHkw+lwAAgAAWPBYxDjAINEPAAAAAiwR/cwIAgAAWPD5 ++iwAAAEQWDBb/17wAAxgABBgMP27SxAsBHkw+lwAAgAAWPBYxDzAINEPAAAAAiwR/cwIAgAAWPD5 ChciAABDMG2aFCmCgPqCgSAQAkIw+bYDIBACWvCasPs8AAAcEEgwbZoVKcLQ+sLRIBACYzD5tjEg EAJa8Cq2Ltog/T0CIAEQWDD93JggAxBgMFv/PfP/iWAAEGAwAAAAAADz/3xv6hBgMPQKAC/0ADYg /4fsbgAgQvAK9zh+c+Hz/tViAAAyMAAAH7sgr+8o8oCYsC/ygZ+xY/8fAABsEAQXudkZuyIYuyL3 @@ -4263,7 +4263,7 @@ AieW0iaS0hW6+aU1JlKAlkElUoGVQC+W0i6S0tEPAAAAbBAEKzIALPrq+3pAAABkptD+ueMSAGDB IP+5qxCAEDgw9rrqFABWFSAkMQQEzUL00LlkgAEgMP8CAAAQEGAw/wIABgBUl2AoChH6yDkIACAn cP8CAAABEGAw/wIACgBHThD5CgAjABBAMPrJOAAgAmDw+briFgUATjD3SgsCAIdi0CkgDBu63AaZ EQmpCAuZCA+aCPvMAAAAqgdg3sAACovwDIAAIAJKcPEOFgH8Amtw8w4WACACUrDyWx4AIAJjMPIb -Hg/PALdg8AAJYAAQYDDAiXhBHfpcAAIAAFjwWMOswCDRDwAAAAAAAADz/+Zv6hBgMPi3OXAQAmDw +Hg/PALdg8AAJYAAQYDDAiXhBHfpcAAIAAFjwWMOwwCDRDwAAAAAAAADz/+Zv6hBgMPi3OXAQAmDw wKD5ur8QCBBYMG26Dy2SpQ0NUvTQumAQAlKwuJnAoC/if44gp6v/6gwAEBBoMFv/jWAAUAAqIAwb urMGqhGrqv+rCAAQEEgw/wIAAgAAazD/AgAAAEYGYN7AAguL8AyCACACUrD1DhYB/AJKcPcOFgAg Alrw8t0eACACYzDynR4PxwC2YPP/UWAAEGAwAAAA+woAIAgQeDDTD236DyiSpQgIUvSAHGAQAlrw @@ -4279,14 +4279,14 @@ AEfw+LAbL4AEP+D8qgIOCQBP8PmwWSuABDqg/PwBKgkAQrD4sBUqAAN7ELGqL7ARLLQfKrQbDIwU CooUKrQaLLQeCooUDIwULLQdKrQZDIwUCooUKrQYLLQcKrAQ/LAUIAICSnAptFkpsBL4zBELgAQ6 oP+wFioJAHqw+LAXLAkAQzD4qhENgAQ7IP+wEywJAHsw+aoCDYAEOyD4qhEMCQBDMP+qAgwAIGOw /ssGegAgU3Cxqiq0Eyy0FwyOFAqNFC20Ei60Fhy59A6OFA2NFC20ES60FQ2NFA6OFC60FC20EP0h -NiACEFAw/iE3IDIQWDBYxLCNN/4yCSACEFAw/LnnEDIQWDBYxKsvIAXEhf8CAA/+wcPQxZX5JAUg +NiACEFAw/iE3IDIQWDBYxLSNN/4yCSACEFAw/LnnEDIQWDBYxK8vIAXEhf8CAA/+wcPQxZX5JAUg ABAQMNEPAABsEAYmIAcYuDz0ua0WIAEwMAZjCQwzEQQ0CPpCfyIAIETwIz0fIzxw+jkIcAAQaDDA INEPiaGMoJyQi6AoqRCZsZ2g/aYBIDEANiCMp8rHH7nIi8EeuZwv8n8LixT+uwEB8AJysPscAAuQ BDrg/1wACgAgU/BbVjYsQn9zwbGNImXfrPtsGCIAAFCw/AoBIEAQaDBbcJLAINEPAABsEAYTubcC -JAkMRBGkMysyICQwfyYwfvUwfCEvADbgGrhaLTCELqJ3KqKADt0ICd0R/aoIAAEQYDBYmuUtoAf/ +JAkMRBGkMysyICQwfyYwfvUwfCEvADbgGrhaLTCELqJ3KqKADt0ICd0R/aoIAAEQYDBYmuktoAf/ CvsuAgEoMP7uEQwAQH9w/Ar8LAkAd3D1CUEMAEBncPakFiwJAE9wLaQH+jIpIgAAErAroAcMuwEL -mQIppActMH0GD0f8uZgSAABxMP0oQAAyEFgw+BYAIAQQUDBYxFUjMiRkMKQVuZDwAAllMAQ5IIM5 -ZDCUjTAoMRn+IAciAABhcP8gFiAEEFAw/zQWKWABQDD+NAcoCQBBMPg1GSAyEFgwWMREizrMtmP/ +mQIppActMH0GD0f8uZgSAABxMP0oQAAyEFgw+BYAIAQQUDBYxFkjMiRkMKQVuZDwAAllMAQ5IIM5 +ZDCUjTAoMRn+IAciAABhcP8gFiAEEFAw/zQWKWABQDD+NAcoCQBBMPg1GSAyEFgwWMRIizrMtmP/ w4u5ZL++KTAHLDAWLTEZirottSkstBb5tAcgDgC2oGP/3gAAiqhkr9cusAcvsBYosSmJqSilIi+k Fv6kBy/mADZgbQgWLaAWLKAHLqEiLpUiLZQWLJQHiZtkn8dj/+LRD2wQBvOKQgCAEEgw+TkBAgCg 4NAlrQElXID/AgAOAJ2RYPSRi2hIARgwLiAMKiANFrgD8wxGDgC9Q5AvIFErIFD0oRxqACB+8P1i @@ -4300,7 +4300,7 @@ d66ZCZkR8/9AbAAgT3AsUCYbuQcMzAkMzBGsuyqwfSwK/QyqAQOqAiq0fdEPJ2J3rnf5FgAnkAQ9 YQBJYR248x+49Re48xi3hfm4NRAAEHAw/nTBIgAAULD4gtgiAABZMPl1XCAEEGAw/3YtKYAEPaD8 PxEICQBNcP90wCgJAG5w+XYsIAUQaDALgAApci0JiUfIk9KQ0Q8AGbjgGLc1K3FcAz0JHrjcHLiw nhn83RELYAFcMPsWCiwAIGNwnBcrxn8qzQIlpAEmpAD64AEmACBKMPzgACYAIDNwLGQAKmQBKOAD -KeACKWQCKGQDLeAFLuAE/mQEIgAAULD9ZAUgARBgMFiZ+IsZHLi7KCEJLiAMLyAN9SEHIgAAGrAt +KeACKWQCKGQDLeAFLuAE/mQEIgAAULD9ZAUgARBgMFiZ/IsZHLi7KCEJLiAMLyAN9SEHIgAAGrAt MCYpIQgqIBQN3QkqNBQpNQgoNQkuNAwvNA0lNQf1EgotwAQ/YP4SCCAQEHgw/zQELAAgbzAt0H/w DgcCAABJMABJYQBJYQBJYQBJYRK3Ohm3QPwKBClABDtg/HYtIgkAEXDydiwoCQBKMCh1XC5gAS9g AC+0AC60ASpgAy1gAi20Aiq0AyhgBSlgBBa3LSm0BCi0BSZi2QM6Av0KBSIAAFkwC2AALXItDY1H @@ -4317,23 +4317,23 @@ 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 @@ -4351,7 +4351,7 @@ QGOwBe4CLvR9LdAmDd0JDN0Rrb0q0H3+Cv4qAEBisA6qASrUfdEPKHJ3r4gJiBGouJgSY/2zJXJ3 r1UJVRHz/opkACAu8AAAAAAAAADz/ulgABAQMMCAmBRj/gUAbBAKijAbtiIoIgL5tekaYAFQMAqq Cfe1zRvABDqg+pkIACoQYDD2kf8gbgA2ICkiBy2ZFPTTaGBAAlJwLZIJZNNdLtAA+NICIA4IY7B7 gUD7CgAgAhBgMFtr0x22DRu2DZegjCCTpSSkHJWmm6T9pgIv/xBIMPjMEQACEGgw+aQdLAkAazD8 -pgEiAABRcFi+88Ag0Q8AAAD5FgEggBBYMPtuAQIBdmGQBopCKa0BKZyA/wIADgFxkmCZGPTg6WhI +pgEiAABRcFi+98Ag0Q8AAAD5FgEggBBYMPtuAQIBdmGQBopCKa0BKZyA/wIADgFxkmCZGPTg6WhI ATAwKyAMLCAN9gdGDgBtwtAtIFEpIFCbF/TC5mgAIG5wG7SAsJiYEyqyePuygCMiADcgGLXViReo mSmQ3ayZqakJmRGpuSmcgJkViRWJkAqZDHlxHP8CAAoAR+3QihP/AgAKAELR0MvCG7TxKrJ8K7KE ZMKXGbXEiBepiCiA3ayIqKgJiBGouyu8gIiwCogMeHkJnhnwABZgABBYMMCB/XsMDAUAYjD+Fgkq @@ -4364,15 +4364,15 @@ qHcbtXAZtAHwCQcCAABK8ABJYQBJYQBJYQBJYRm1axiz/x60ntpw+ILbIAEQYDD85q0oCQBNsPnm rCAFEGgwC4AAHLSWLMKtiRD6tVoc6AFgMPTBFGD9EFgwJpAmBmYJDGYRpqYvYH33Cv4uAEBf8Af/ AS9kfYknjhEtmRT2tWQQABA4MPwiAiBAAlpw9+aDIJcAN2D6kgkhIgA3IGSgiiigAMKaeYkUHbVY jKL/AgAGAH/vEP8CAAf+qDcQ2rD8CgIgABBYMFtrFh61Uhi0/ZigjyCWopOlJKQc9aYGIAIQQDD3 -pB0vgAQ/4P6mBC4JAEfw/6YBIgAAUXBYvjbAINEPAAAAAAAA8/0laMABNDCaGGP9HQAAAPsKACAC +pB0vgAQ/4P6mBC4JAEfw/6YBIgAAUXBYvjrAINEPAAAAAAAA8/0laMABNDCaGGP9HQAAAPsKACAC EGAwW2caY/ysAABkwI/asPwKAiAAEFgwW2cVY/+OmRNj/UyZEmP+ThizxYkXKIJ3qYgJiBHz/W1q ACBG8Cnyd66ZCZkR8/5iagAgTvAtcCYN3QkM3RGtrSzQffvMAQABEHAwDswCLNR9Y/7QGLO0iRco -gnepiAmIEai4mBVj/OUp8neumQmZEam5mRRj/d0AAAAA/wIAD/+LMxBj/E3aUPs8AAAAEGAwWL3b -2iBYtVjAINEPAAAAAAAAAPP+JmAAEDgwwKCaEGP9LQBsEAYmMAgnMAn2CUEGRAEwMPgyACDNADWg +gnepiAmIEai4mBVj/OUp8neumQmZEam5mRRj/d0AAAAA/wIAD/+LMxBj/E3aUPs8AAAAEGAwWL3f +2iBYtVzAINEPAAAAAAAAAPP+JmAAEDgwwKCaEGP9LQBsEAYmMAgnMAn2CUEGRAEwMPgyACDNADWg +go4JgBilaD7CnggAGemEP8CAAQAWpUg+LTqEACjYdAas3qYEPAKBwIAAFIwAEphAEphAEphAEph -CZoJGbT2DKoRqpkikh9kIH4as4QtkIAuoncqooCu3fndEQIAAFiw/aoIAAEQYDBYlg4Ys2wbtOz9 +CZoJGbT2DKoRqpkikh9kIH4as4QtkIAuoncqooCu3fndEQIAAFiw/aoIAAEQYDBYlhIYs2wbtOz9 tOoYoAE8MPmc/y1ABDmg9LY/KAkAZnAptYD4gt4sCQBssP22PiIAAGEw+xIAIAUQaDALgAAYtN4o -gj/5PBAo6AFAMPyMAABxADYgCAwG8AAIbeABYDAAHLTW+lwAAgAAWPBYvZfAINEPe4bqLTIBcdbk +gj/5PBAo6AFAMPyMAABxADYgCAwG8AAIbeABYDAAHLTW+lwAAgAAWPBYvZvAINEPe4bqLTIBcdbk +bRJFcIAvSAoIARogUj/AgAEAF4CIGmFywcIRQhvCA3/Ef/8+CBAEHAwf+O3A4gL8AkXAAoANaBt aQIACIrz/6ZgABBgMBi0v21pBQAIiAAJimP/kgAABwhFqGsNuxErvPj/AgAL/7/ekAOIC/AJFw/N ADWgbWkCAAiKY/+/KCAEaIFw/wIABABQAiD/AgAF/6qeIAcIRahtDd0R/dz4IEAQYDD/AgAL/57v @@ -4381,21 +4381,21 @@ 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 @@ -4403,29 +4403,29 @@ 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 @@ -4433,47 +4433,47 @@ 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 @@ -4481,7 +4481,7 @@ INEPAIwiZMBSjiD4ryQQCRB4MJ8S+O4RAAEQeDD4FgAuCQB7sJ4Rjif9+sAgQAJTsP2tAQAAEHgw iCJlj5ErIHz6LAAAARBgMPu8EiAAEGgwW2WtY/94bBA6KCAF+q5oEC4QSDD7ygAuAm1KECoWY/sW ACAQAkBw8AoXABUQSDBtmgIACIr0rqIQQgJgcPwWWiALEEAw9BYCIJACULD6FmQj/xBIMP8iACB4 AlBw+hZbIAAQIDD0FBsgARAoMPUUIC+ABD/g+RUMLgkAR/AvFgMtIEkuIEguxAAtxAErIEorxAIk -FDkkFDr0FDsgAxBIMPkUOCCoAliwKxZcKBAALRAC/xABIEoCcHAv5AEt5AL45AAgEBBgMFiwbBOt +FDkkFDr0FDsgAxBIMPkUOCCoAliwKxZcKBAALRAC/xABIEoCcHAv5AEt5AL45AAgEBBgMFiwcBOt 3RauqhitOy8gQSkgQBuuo/sWZSCYAjhwJxZdKXQAL3QBLiBCLSBDLXQD/nQCIKgCaHAtFl8qIEUs IEQsdAQqdAUvIEcpIEYpdAYvdAcsIDkuIDgu1AAs1AEqIDopIDsp1AP61AIg+AJIcCkWYS8gPScg PCfUBC/UBSwgPy4gPi7UBizUBycgZSogZCqUACeUAS4gZy8gZi+UAi6UAy0gaCwgaSyUBf2UBCCA @@ -4489,12 +4489,12 @@ AmCwLBZeKiBqJyBrJ5QHKpQG966jEHACULD6FmAgyAJIsCkWYviC+CD/EHgw/xVCJBAQcDAuFUEu FSEkFFwkFGwlFUT0FIwgIBBoMC0UPC0UPY0nKBZmKSIA/dIOIAQQYDD2Nq0iAABQsP0WZygJAD5w +TasIAUQaDALgAAqMq0pEmcKikf9risTDgA2oC6QOi+QOwjuEQ/uArHuLpQ7Do4ULpQ6LxJj+doA IP4CQHD5FiwgcgJCMPAPFwAVEEgwbZoCAAiKKxJkHq5vLhYu/SIAIAMQYDD6HH8j/xB4MPQUyyAL -EHAw9RTQLYAEP2D/FWQsCQB3cP0WLyCkAlKwWLAAJBTpJBTqJBTr+AoDIP4CcHD4FO8gYhB4MP8U +EHAw9RTQLYAEP2D/FWQsCQB3cP0WLyCkAlKwWLAEJBTpJBTqJBTr+AoDIP4CcHD4FO8gYhB4MP8U 6CBiAkOwLYAC/4ABIKwCc7Av5AEt5AIogAAo5ACJICwiBysSZSgSZvzCDigJAD5w+TasIgAAULD8 FmggBRBoMPY2rSAEEGAwC4AAKjKtKRJoCopHZKKeK5A6LJA7CLsRDLsCsbsrlDsLixQrlDotEmMs qgD8FgAgEAJAcPANFwAVEEgwbZoCAAiKLBJaGK3nKBYCLyIA+xJkI/8QSDD0FBsgCxBAMPUUIC+A BD/g+RUMLgkAR/AvFgMtsAEusAAuxAAtxAErsAIrxAIkFDkkFDokFDsrElwoEAEuEAL5EAAgAxBQ -MCoUOPoSWyBKAnhwKfQALvQC+PQBIBAQYDBYr7kvEl4uEl0s8AEt8AAt5AAs5AEq8AMr8AIr5AIq +MCoUOPoSWyBKAnhwKfQALvQC+PQBIBAQYDBYr70vEl4uEl0s8AEt8AAt5AAs5AEq8AMr8AIr5AIq 5AMo8AUp8AQp5AQo5AUt8Acv8AYv5AYt5AcuEmAtEl8r4AEs4AAs1AAr1AEp4AMq4AIq1AIp1AMv 4AUo4AQo1AQv1AUs4Acu4AYu1AYs1ActEmIsEmEq0AEr0AArxAAqxAEo0AMp0AIpxAIoxAMu0AUv 0AQvxAQuxAUr0Act0AYtxAYrxAf1FUQkEBBQMCoVQSoVISQUXCQUbPQUjCD/EEAw+BVCICAQSDAp @@ -4502,26 +4502,26 @@ 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 @@ -4530,13 +4530,13 @@ IFP6LAAAARBgMPu8EiAAEGgwW2MfY/7sbBAKKCAFwpX/AgAOASRKEC0hGSsgFhesHSogUyYgB4Un IQcbquUKCkr2quMbwAQ6oPurMRoJAFqwKjYA+SIALUAEO2D2NgIgMBBAMPg2AyAEEFAw/dgUCYAE PmD9rD8YCQBWcPk2AS7AATgw+iBTIAAQMDD2NQouSAE8MPY2CC+ABD/g9jYJLgkAe7D2NgouBwE8 MPY2Cy9QBD/g9jYMKUAEOiD2Ng0uCQBH8PY2Di4JAHuw9jYPICAQSDD5NQssCQBrMPw2BisABDqg -/qoCAAYQYDD7qgIAgAJYsPo2BCBAAlDwWK25wHT6PCYgsAIwsPwKBiIAAFmwWK20+6wYEIkQSDD5 +/qoCAAYQYDD7qgIAgAJYsPo2BCBAAlDwWK29wHT6PCYgsAIwsPwKBiIAAFmwWK24+6wYEIkQSDD5 NCwgABB4MP80NCAQEEAw+DQuIAIQYDAsNDUsNDgsNDn7NC0gARBwMP40MyADEGgw/TQxIHQCUPD+ -qkIQABBoMP00MCIAAFmw/jQ3IIAQaDD9NDYgBhBgMFitm49TilKx+3+7AiqsAYxRjVCaUvtWAyAC +qkIQABBoMP00MCIAAFmw/jQ3IIAQaDD9NDYgBhBgMFitn49TilKx+3+7AiqsAYxRjVCaUvtWAyAC AmMw/FYBIEgCW3CbUIonwLD8CgAgABBoMPdGOSBAAlKwW1pMjyf4+sAgQAJz8PgKAC4AQEOw+PUU IIACc7Ce+Z74KyAWLQr/fbEK+iBTICAQYDBbYgMrIDewu/oK/ijgAVww+yQ3ILgEUnDAINEPjCJk wN6OIPir3RAIEHgwnxb47hEAARB4MPgWBC4JAHuwnhWOJ/36wCBAAlOw/a0BAAAQeDD/5RQggAJr -cP3mCSAgAlhw/eYIIAEQYDBbXZLAINEPHKvSLSAF/iAHIAUQUDD4IgAgMhBYMPgWACIAAHiwWLZY +cP3mCSAgAlhw/eYIIAEQYDBbXZLAINEPHKvSLSAF/iAHIAUQUDD4IgAgMhBYMPgWACIAAHiwWLZc iics+sDzog4gJhBoMP0kBSBAAlqw/AoAKgBAZvD8pRQggAJa8Jup+6YIICACUrBbW/4tMR2CKrHd /TUdL0oANKDwABpgLRAYMAAAAAAAAPosAAABEFgwWEDjgilkLycuIAVz6emCKWUv9GP/GQAA+iwA ADACWbD8CgEgBBBoMFtiSmP/Co8iZf8FKyBT+iwAAAEQYDD7vBIgABBoMFtiQ2P+7GwQBiggBSsg @@ -4550,19 +4550,19 @@ sAADitEPbBAE/atKEAIQWDArNAAqIBUeq0cYqaL4SREKQAQ6oPqaAgAFEFgw/6tDGgkAWrCaMfAI BwAgAiDwAERhAERhAERhAERhKCAHCAhB8FURCSAEOiAIVQKVNoUg/zYOIAAQIDD0NgggAxBYMP02 ECCgAiDw/jYPLbAEOWD8NgcgPAA1oC0gFcDh9zRZLEAEP2D+NFgsCQBucP40UCwJAHdwLTYVDOow CFoR/EUFKgkAWrD6RgMgwAIQ8NEP0kDRDwAAbBAE8yICL/EQIDAEMwGTItEPAABsEATaIPw8AAAB -EFgwWLMj0qDRD2wQCIdEAZQEiUaLSC9BC45H8kEKIgAAULAPTxT+kxQCAABg8PLoQAYsARAw++1Q +EFgwWLMn0qDRD2wQCIdEAZQEiUaLSC9BC45H8kEKIgAAULAPTxT+kxQCAABg8PLoQAYsARAw++1Q Ch8BXDD6uxEHcAQ5oPvdEQnABDog8DMRCAkAajD+nhgMDwEUMPmZVg1QBD9g8xYGIgMBFDD/MxEG CQBpsP4WBSwCARQw8g5BDAkAH3D+7hEGCQBZsPJCQQABEFgw+CIRDgEAX/D4ZgIILAE4MPKIEA/A BD/g/+4CD2ABPDD+3QIODwE4MPfnQA7gBD/g/4gCDvAEO6D3ZgIOCQATsPeqChgJAHIw+arfGAkA -SjCdF/dmAgIAAGhw9hYDKAkASjD4FgQgABBwMFix+dKg0Q8AAABsEATaIPw8AAAAEFgwWLLe0qDR +SjCdF/dmAgIAAGhw9hYDKAkASjD4FgQgABBwMFix/dKg0Q8AAABsEATaIPw8AAAAEFgwWLLi0qDR D2wQCAF0BIVFjkTzQgYiAABg8PJCByIAAFCw96EHLBMBdDDzdlgP4AEsMPV4UgpUASww/qlQBBMB LDDymRAP4AQ/4Pe7EAhABDog9hYFJ0ABPDDxdxEGNAFwMPIzGAgJAFow8xYGKhgBdDDykhQK0AQ+ 4PNmEQLgBDig92YCBhIBdDDxdxAOCQAX8P6SUAYJAE3w/mlQDAkAf3D+f1ACwAQ4oP0WByIAAGhw 8rsCBgkARfD+/xAAGBBAMP+ZEA4wAXAw8u4RCAkAfnD4dwIICQBecPlbEQVwBD1g9qqZFAkANXD3 -FgMqCQB28PuZAgAAEHAw+RYCJAkANXD1FgQgABBYMFixsdKg0Q8AAABsEAQUqo3TDypCgNsgW1iC +FgMqCQB28PuZAgAAEHAw+RYCJAkANXD1FgQgABBYMFixtdKg0Q8AAABsEAQUqo3TDypCgNsgW1iC +KEcYgAAGrD6Qn8iAABYsPwKACABEGgwW1hX0jDRDwD6Qn8gAgJYsPwKACAAEGgwW1hR+kKAIgAA WLD8CgAgARBoMFtYTWP/vgAAAGwQBPSqdxAAEEAwHqp2KObUHap1KNbUHKp1KMbUG6p0KLbUGap0 -KgoA+JbUIAwQSDBtmhmJKwSrCo07KbbA8zz8IfgCELD9ttQgAgJSsBiqRChGvcD1L0a8WI2Q8qwA +KgoA+JbUIAwQSDBtmhmJKwSrCo07KbbA8zz8IfgCELD9ttQgAgJSsBiqRChGvcD1L0a8WI2U8qwA ABkAtqAoQuXHL/iJQwAeAH4waJMHIkLo0Q/RDwDRDwAAbBAEE6pWKjJ/W1Pz1KD4IQxiAAAqsNKg 0Q8AAAAAKjJ/W1Pt+kkycgAAErBgAEwAAAAAAPoyfyIAAFlw/AoAIAEQaDBbWBn6Mn8iAAAosFtT 4vpBJnIAABKwsVh4KdT6MoAiAABZcPwKASAAEGgwW1gP0lDRDwAAAAAAAPoyfyIAAFlw/AoAIAEQ @@ -4581,7 +4581,7 @@ EAIFARww+jMRDgkAR/D/ZgEuCQAbsP5kCSAgAmmwBguGAE1nBAuGAE1li2B7tmQuwAGIYSsKgP5t QAgFAXQw+P9QAgDGAhAep93wDgcCAABysABOYQBOYcCAKMQBLiBQ9AoAIDAAN6CcEpYTE6mI8J4R DPAEP2D+qK4cCQB3cJ0RHagPYADNAAAAhhP8EgIgARAoMC/AAPj/DHABEBAwKMABeI8BwCDzEgAi AABTMFsSDB2ni/peFA6AAVQw8PEED+AEO6AO3Qwt3Rwp0n/wXBoP/xBwMP7MAwIAAFmw8CoaCABA -ZnD6mQIAABBgMPnWfyIAAFDwWLH7wCDRD6tmCqkCB2wCLNazKNK0JRIBDwIAA4gB+FUCAAAQYDD1 +ZnD6mQIAABBgMPnWfyIAAFDwWLH/wCDRD6tmCqkCB2wCLNazKNK0JRIBDwIAA4gB+FUCAAAQYDD1 1rQgEBBAMG2KHfUKACBcADfgJZEADlUC/cgKAAQCSnD1hrUgAgJjMCbWsykgULFE/wIAC/+cyRAp IA3KTiwgUcCB/EwICAUATjAJyQwsIAwIyBEImQILmQL5hkIBBgBicPP/fWbAAUgwAGP/qhapQGSf ySwgDCVig/ZieyAgADZgGKj0qMgogN2pialpCZkRqVkpnICJkAaZDGP/shmnlCmSd6yZCZkR8//p @@ -4590,37 +4590,37 @@ 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 @@ -4628,12 +4628,12 @@ BDug8JkRDgkAe7D4D0oIAwFQMP2IAg8QBD/g/+4CDgYBVDD6jUAO8AQ/4P+ZAg4JAVQw/d0QDsAE P+AP3QL6f0AKJAFQMP7/EAswBDqg/hIuKgkAcrD/3QIOLAFkMAL/Ef48QA5AAXAw+cwRD3AEO6D6 EjIuCQBTsPwSMy4JAGfw9MwQChAEOqD8EjQqCQBisPkKAiwJAE9wCYgC+BYnLFAEOyD8EjUqCQBi sP+lCxwJAH9wLRYi/Rx/LHAEOyD8pUYaCQBisP/uAgACAmtw/hYkIAAQcDD8qgINsAQ5oPwSLyoJ -AGKw+woAKgkAWrD6FiMiAABQsFit3R2mnPaqHGIAADKwLhI60w8PAgD/AgAH/PW/kIcsHKbCJiAN +AGKw+woAKgkAWrD6FiMiAABQsFit4R2mnPaqHGIAADKwLhI60w8PAgD/AgAH/PW/kIcsHKbCJiAN /zIMIgAAULD8wT8gARBAMPgSOiYFADIw/09TBtAEOaD2EjguCQA38P0cQCADEFgw/xYXIAAQcDD4 -dwgMACAzMFitw/apuWIAADKwizz9EjggABBwMA8CAP8yASgPAVgw+ypADAEBWDD7CVAGDAFYMP/P +dwgMACAzMFitx/apuWIAADKwizz9EjggABBwMA8CAP8yASgPAVgw+ypADAEBWDD7CVAGDAFYMP/P UAbgBDmg9/8QCQAEPmD+zBAK0AQ6oP+IEAoJAGKw/KacGAkASjD5MggqDQFcMP4WHyrQBD7g+/8C AAAQcDD8wT8qoAQ94PnJUQ4JADfw96YUCMAEPmD2/wIICQBecP8WHSACEFgw+iwACAkAVnD5iAIM -ACBrMPgWHiDAAmhwWK2X9qkJYgAAMrAuIA0oEjgZpoCLP488jD4sFjAvFikrFjEmkT/5kHwqCwF4 +ACBrMPgWHiDAAmhwWK2b9qkJYgAAMrAuIA0oEjgZpoCLP488jD4sFjAvFikrFjEmkT/5kHwqCwF4 MPkWNioKAXww+xYyKtAEOqD4MRomACBBsPgWKilQBD5g+pkCCgEBeDD/D0AGCQBJsPoWNChHAUQw +RYzKEQBQDD4FjUgDwA3oBqlIvpmAgABEHgwiTEoIQcsMQoBdAQqEjEtMRsrEjAKnhT+3REO4AQ7 oPq6GAwJAHdw/hI2KxcBXDArFiUqFib+XxQLwAQ/4P+lyhoJAH7wKhIp+clQDlAEO6DwmREOCQB7 @@ -4641,21 +4641,21 @@ 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 @@ -4668,13 +4668,13 @@ mR/5EhQrMAQ+4PHMEAggBDog+BIiLAkAQzD07hAIcAQ+YPnuAgjgAVQw/hItLAkAczD8mREMCQBr MP2kyxgJAGZw/xIcLXAEO+D+ThQI4AFAMP2IEQ4AQGuw/RIgLxAEP+D+WkIO4AFwMPXuEAgJAFIw +hIqKAkASjD5EiUs4AFsMPgWCy1ABD9g+BIhK5AEOqD9zAIM4AEkMPyZEA0gBD9g/aoCCGAEOiD9 HCAuCQBDsPgSKS4JAHuw/xImKgkAdvD+EicqCQBm8PwSKCkABDog+xYMIAAQWDD9/xAO4AQ7oP+Z -AgzwBDsg/pkCDAkAQzD8mQIAABBwMPqZAgIAAGGw+RYKIgAAULBYq57WoGZgIIowGaRc+asBDgAH -TpCKMf8CAAIAcYaQyLaJMQnbUmSwtNog/Ar9IAAQWDBYrMD3pEgfjRBgMPkiAiAOBGKwBqY4jCcP +AgzwBDsg/pkCDAkAQzD8mQIAABBwMPqZAgIAAGGw+RYKIgAAULBYq6LWoGZgIIowGaRc+asBDgAH +TpCKMf8CAAIAcYaQyLaJMQnbUmSwtNog/Ar9IAAQWDBYrMT3pEgfjRBgMPkiAiAOBGKwBqY4jCcP AgAtyRQrzCD6wgkgZgA3YGSQzP8KKiBeADagLqAAf+kLGKQ4LKICeMF6d8FA2rD8CgIgABBYMFtZ -+BmkNSwSGx2j352giyCXopOllaYmpB0spBz4uxEAAhBgMPmmBCoJAGbw+6YBIgAAUXBYrRjAINEP ++BmkNSwSGx2j352giyCXopOllaYmpB0spBz4uxEAAhBgMPmmBCoJAGbw+6YBIgAAUXBYrRzAINEP ZJBq2rD8CgIgABBYMFtWAWP/tIcsB5cMY/xrAAAAAAD/AgACAxkOUP8CAAH/n5JQYAY/d8mRY//C -AAAAAAAAAPwSEyIAAFCw+3wAAAEQaDBYebHHhPasAAYCfUaQZq8KHKQXizDz/vhqAEBm8ADaUPs8 -AAIAAGGwWKzQ2iBYpE3SoNEPAIotLaECZNYCW03Jhi/6FgQgEhBYMPpmCAYAtl3QwYP/AgAGALFF +AAAAAAAAAPwSEyIAAFCw+3wAAAEQaDBYebXHhPasAAYCfUaQZq8KHKQXizDz/vhqAEBm8ADaUPs8 +AAIAAGGwWKzU2iBYpFHSoNEPAIotLaECZNYCW03Jhi/6FgQgEhBYMPpmCAYAtl3QwYP/AgAGALFF 0MBg9xYTLrkAtaAsIA0dpDqLLIcUiTL3uwgCAABR8Py6OAgAQG5w+zYDKAkAVnCZMvP7zGAAEDAw KCBcDgRRAEAECAgb/wIAAAIifhAmJQkZotv6IA0gABBAMCgkFPgkFSABEHAw/hYhKgUAU7D+IgAo ACBNMCmQgPoWIiABEFAwKhYg+hIFKeAEPmD6JQgoCQBNMCkkB/P8vGABEFAwGKOKiS8qIFz4gkAk @@ -4683,38 +4683,38 @@ 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 @@ -4728,26 +4728,26 @@ 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 @@ -4843,8 +4843,8 @@ KrD/Dw9H/4QqIB8AN+DAIPLkJCAAEBAw0Q+KFSmhK7CZKaUrY/7kAAAt4Cb+mz8SAABbsALdEa7d Hpqkrt0s0oAemv8OzAH81oAgABBQMPq0JCAAEBAw0Q8AjRWPGv3QDCABEGAw+xIAIAAQcDD+9hEi AABT8P72Ei2ABD9g/bsCAIAQaDD+9FkqCQBu8FgCNmP+CMAg0Q8AbBAEFpqZiTCKKCZif/kISwZI AUww930BK5AEOqD4jwx2ACBRsPAAB2EAAjnwCQdGKCA20w/+jxx/6hAgMCkgWGSQVSUmE/MmFCIA -AFFwWKORwCDRD4kwwED6MgEgDgAucGagS3qW1YsxeLYP23D6LAACAABg8Fv+T2AADtpg+ywAAgAA -YPBb/ZrUoCwgNsDUDcwCLCQ2Y/+j2lD7PAACAABhMFijVMAg0Q8AAAAAAAD6bAACAABYsPx8AAAB +AFFwWKOVwCDRD4kwwED6MgEgDgAucGagS3qW1YsxeLYP23D6LAACAABg8Fv+T2AADtpg+ywAAgAA +YPBb/ZrUoCwgNsDUDcwCLCQ2Y/+j2lD7PAACAABhMFijWMAg0Q8AAAAAAAD6bAACAABYsPx8AAAB EGgwW/7+iTDz/5tiAAAisAAAAGwQBh+ZO5QRkxAUmT0WmMkGJgImRsUCXhH4CoAgABAoMP0KACH/ EBAw+goAIAEQYDD+FgIgCBAwMPtCxi4AIHuwbWojAFEEAMkaebAS8owAAAICUrAv4sIPAgB58AGx 3fVcASACAkIw/woAIAAQGDAE+worsscuEgL4PAAF4AQ/4PYKICA7ADbg9ZkZHgAgcXD1CgAuACAr @@ -4899,13 +4899,13 @@ B8wKLcL0DQ1PDbsCK8b00Q/7bAACAABQsFv1bWevwmP/ydEPBB4UB+4KLeL0H5fyD90BDV0CLeb0 0Q8EGBQHiAovgvQZl+wJ/wEPXwIvhvTRDylgIgKZEa6ZrZklloAlZRlj/kQAAAAA+kwAAgAAWbBb 9Vdj/p4AACpgIhuYEwKqEauqG5dzq6olpoAlZRlj/uUAAAAAAAAA+2wAAgAAUTBb9Utj/0QAAGwQ CooyjjD/IDYggBBoMPoEXwwuAVAw+qdBCWABdDD5FgcqLAFUMPqKQQAkAOJwDoZCJm0B8AAHYQAC -MbAOBkb4l/oQHgB78PmX+RoAFiYQdJsk/PrqIAAQIDAqIFlkoVZkQVMlJhPzJhQiAABRcFigZ8Ag +MbAOBkb4l/oQHgB78PmX+RoAFiYQdJsk/PrqIAAQIDAqIFlkoVZkQVMlJhPzJhQiAABRcFiga8Ag 0Q8AAPmWCBAEEEAw/woAKAkAQ/D4JDYgAJUrkJ0WnBWbFJoT/xYJJgCXTRDaYPwgJiIAAFkwW/84 KCBZ+UwSIAEQcDD5JRgg7AA2ICsgJhyWCQy6Ef4kWCoAIGKwLKI6/wIAAgHgRyAflgYtojkPvwov 8pf/1AEOAdZ/UCshBxyXAAsLSgy7EQy7AptAKSIAGJbQ+JkRAAMQWDD6FgIoCQBecClGAfAIFwAQ AkkwAAmKHZX1/UYEIBgQYDD8RgUiAABQsFrpaxiW7ysiES4iEvohGCIAAEqwjBf+RgsvfxB4MPoq FAgJAEZw/H1ACMABYDD13REMAEB7MPlGBisABDqg+RIJKgkAUvD6RgoowAQ6IPhGBywJAGsw+UYJ -LQAEOyCcSIkiwOEOmQKZIogSwPMvhjnwACBgARAgMAAAAAAAAMDA+lwAAgAAWPBYn+rAINEPAAAA +LQAEOyCcSIkiwOEOmQKZIogSwPMvhjnwACBgARAgMAAAAAAAAMDA+lwAAgAAWPBYn+7AINEPAAAA wECJFf8CAAIAz0Jg/ZeWEgB0EeCPFhiXjSkgJvkWCCABEFAw/hIIIgAAWfD5nQMtIAQ6YP0gDCwA IGsw8OEECgUAPrD+lWAeDAC5oMCg+BIJLgUAWjDAsQC7GvqPOQuABDtg8LsRCgkAcrD/bhpgARBw MCggDQYNRP+/AggJAFIw8AAPbgkAR/AK/wL9bIAuCQB+8BqVugDRBPDrGg//EEAw+JVEGhEARvAA @@ -4935,10 +4935,10 @@ EGgwW0PEIyRf0Q8p4HXAwfpCHiACAkpw+eR1IAEQaDBbQ70blj0qQCLTD6urK7DgZL+9W/P4IyRf ICYn8nuJKCbygP0kJyYAID7w/s1QB5AEPeD3ZggJkAQ+YPYWASYfAXQw/uZQAgBBC5AsIF8o8nv6 8oAgoARrMJMT8/J3LgAgTrD78gAoACBC8AmIEfO7DAoAIEKw8xIDIBwAD7CaEP0WAiFEADcgLvB1 0w8PAgCw7v0WAizgAXAw/vR1IRcANyAtJF/6LAACAABZMPx8AAIAAGmwW/8uwMD6XAACAABY8Fie -S8Ag0Q8iMQSOEfyV/RAYEFgw/uAoIgAAaLBYoCkflA8PAgAPAgD0lCcQjgR4sPQgZWEsEEAw+RIB +T8Ag0Q8iMQSOEfyV/RAYEFgw/uAoIgAAaLBYoC0flA8PAgAPAgD0lCcQjgR4sPQgZWEsEEAw+RIB KgAXlhApkCX6EgEg9AA2YCqhE3ojB4wRDysRK8UTjREt0h+N3GTQ6fP/kWAAEGAw8/+Jb+oQYDCL -ESuwKGSw5IwRsb0NDUf9xCggBBBQMPyV3xAYEFgwWKAMY//KAIsRK7AoZL/JjBEtvP8NDUf9xCgg -BBBQMPyV1hAYEFgwWKACjhEu4Chl756IEcCk/JXREAAQeDD/hCUgGBBYMFif+okRKZIfipxkoKuL +ESuwKGSw5IwRsb0NDUf9xCggBBBQMPyV3xAYEFgwWKAQY//KAIsRK7AoZL/JjBEtvP8NDUf9xCgg +BBBQMPyV1hAYEFgwWKAGjhEu4Chl756IEcCk/JXREAAQeDD/hCUgGBBYMFif/okRKZIfipxkoKuL nWSwpooRC7AAY/9wACqiHvwKACABEGgwW0M/jRJj/tku8HXAwfqiHiACAnOw/vR1IAEQaDBbQzeK EBuVtyqgIqurK7Dg/RICLrEANuBb83GNEmP+pIwRwNH9xCUr8AQ8oCvFE2P/C48RLvAiAu4RpO4u 4oIu9Gdj/wKPES/yH4/8yfOLEcDQ/bUTIAEQYDAstCUrsChj/vyPES7wIgLuEaTuLuKCLvRnY//X @@ -4947,10 +4947,10 @@ k1oQChAoMPuIEQAcEEgwCYgCKEbBG5NY/AoAIDIQaDD6k1QQARBwMPVGwyAAEHgwW0Xh1qDzk1IQ AFmuoByVgylCwiogL/zCACosAUww/BYAKgAgDvArsADA0vwK5yABEHAw/KoBC9AEPuD6JC8qCQBa sPokLyAUAG5wLSUgYAACLiUgLyAhDwIADwIA+/8RAAUQQDAI/wIvRsEbkzb8CgAgMhBoMPqTMhAB EHAw9UbDIAAQeDBbRb/2oEBiAAAqsMCA2YAaky8tQsIcky79q0AMCwFsMP3JOQgFAFqwCYgC+CUe -IgAAEXDRDwDApPsKFCIAAGDwWJ+A0mDRD9ww+goEIBQQWDBYn3zSUNEPAAAAbBAEwLDyAkcAHxBg -MP0KASIAAFCwWHO/ykj9MQAiAABQsPsKACATEGAwWHO6+iwAAAAQWDD8Ch8gABBoMFhztcAg0Q8U +IgAAEXDRDwDApPsKFCIAAGDwWJ+E0mDRD9ww+goEIBQQWDBYn4DSUNEPAAAAbBAEwLDyAkcAHxBg +MP0KASIAAFCwWHPDykj9MQAiAABQsPsKACATEGAwWHO++iwAAAAQWDD8Ch8gABBoMFhzucAg0Q8U kwX7KREAExBQMAqZAilGwRqTAhuTA/wKACAyEGgw/goBIAoQQDD4RsMgABB4MFtFjGagCStCwis1 -AGP/qgDApPyS+RAUEFgwWJ9WY/+ZAGwQBiogIfscAAAAEGAwW//X+ZUlEAASLqD4EQAgTgI84AmI +AGP/qgDApPyS+RAUEFgwWJ9aY/+ZAGwQBiogIfscAAAAEGAwW//X+ZUlEAASLqD4EQAgTgI84AmI ASgVACogIfscAAABEGAwW//O0qDRD9Kg0Q8AAAAAAAAA+hEAIg4AOOBpM9f+OxEKAEBKsAuqAioV AGP/xmwQBNQg/AooICYQWDD4PBZgJRBQMHoxLXsxW/8CAAYARuTQxirRDy0gQ/8CAAYATGdQ/wIA BgBVX1D/AgAGAG9XUMAg0Q8qICH9ks4QABBYMPwKACAAEHAwWALBwLD6ICEgFxBgMP0KCCAIEHAw @@ -4958,68 +4958,68 @@ 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 @@ -5039,15 +5039,15 @@ AQoAAVww+yIRC5AEPuD8qgIKCQAW8AuqAio0ASlgAfk0ByAAEBAw0Q9sEAQajnkpLQIrkBcson0q ooCrzAnMEayqKqIQ/o+zEAgQaDD5kBYgABAQMPSgQmCAEGAwhaEiogL2ogAgEwA2YGiRGMuRaJEC aJI/xirRD6zqqroqoMBoowJpp+ZoRkX/AgAGAFSFIPhIbW/qEBAw0Q/RDwAAAAAArOqquiqgwGij yGinxWiiAmmnv/8CAAYAWAEg/wIABgByBSDy+uooAF8BINEPZCBdLCAA/AxCABACUPD8zTkACgJY -sP00ByAIEGAwWJFnKjwQ/AoIIBoCWLBYkWTAINEPymouYAD+DkIAEAJQ8P7tOQAKAlmw/TQHIAgQ -YDBYkVsqPBD8CgggGgJZsFiRV8Ag0Q8AAGRf9i9QAP8PQgAQAlDw//05AAoCWXD9NAcgCBBgMFiR -Tio8EPwKCCAaAllwWJFKwCDRD8skKCAMuDr4jTkACAJYsP00ByAIEGAwWJFDwCDRD8lmKWAMuDr5 -nTkACAJZsP00ByAIEGAwWJE7wCDRD2Rf+CxQDLg6/M05AAgCWXD9NAcgCBBgMFiRM8Ag0Q8AbBAE +sP00ByAIEGAwWJFrKjwQ/AoIIBoCWLBYkWjAINEPymouYAD+DkIAEAJQ8P7tOQAKAlmw/TQHIAgQ +YDBYkV8qPBD8CgggGgJZsFiRW8Ag0Q8AAGRf9i9QAP8PQgAQAlDw//05AAoCWXD9NAcgCBBgMFiR +Uio8EPwKCCAaAllwWJFOwCDRD8skKCAMuDr4jTkACAJYsP00ByAIEGAwWJFHwCDRD8lmKWAMuDr5 +nTkACAJZsP00ByAIEGAwWJE/wCDRD2Rf+CxQDLg6/M05AAgCWXD9NAcgCBBgMFiRN8Ag0Q8AbBAE Go4SKS0CK5AXLKJ9KqKAq8wJzBGsqiqiEPKPTBCAEHgw+ZAWID0ANqCNoYyi/qIAIBQANmBokRnK mmiRAmiSOMYq0Q8AryqquiqgwGijAmmn5WhGNGhHOPhISW/qEBAw0Q/AINEPryqquiqgwGijz2in -zGiiAmmnxmhGPGhHWfhIRG/qEBAw0Q8AZcBawCDRD2Tf+LQ6/AoEIAICW3BYkQnAINEPZO/ktDr8 -CgQgAgJbsFiRBMAg0Q/JyIvA+zYBIAAQEDDRD8jqjOD8NgEgABAQMNEPwCDRD2Tf+I7Q/jYBIAAQ -EDDRD7HL/AoEIAgCUPBYkPTAINEPbBAEGY3vwrP3j9YZIAQ4oPmICAAiEFAw+Y/RHABkgWD2CmAg +zGiiAmmnxmhGPGhHWfhIRG/qEBAw0Q8AZcBawCDRD2Tf+LQ6/AoEIAICW3BYkQ3AINEPZO/ktDr8 +CgQgAgJbsFiRCMAg0Q/JyIvA+zYBIAAQEDDRD8jqjOD8NgEgABAQMNEPwCDRD2Tf+I7Q/jYBIAAQ +EDDRD7HL/AoEIAgCUPBYkPjAINEPbBAEGY3vwrP3j9YZIAQ4oPmICAAiEFAw+Y/RHABkgWD2CmAg QARRcPtRaH/qEBAwKoKFG4/MC6oBKoaF0Q8AAAAAAADyCgAgCBBgMNMPbcowACAEAw0bf9clAhVA 8gRABeAEPWDyLxQECQApMPL/EQWABDkgpP+n/47xBu4CnvGxIsAgI4KFFI+3BDMBI4aF0Q8AAPIK ACAIEDAw0w9tajIAIAQDCxt/tycCH0DyDkAP4AQ/4PItFA4JAHuw8t0RD4AEO6Cu3andLNKABswC @@ -5057,9 +5057,9 @@ Av2GhSAAEBAw0Q/7KUR/9xAwMPIKACAIEHgw0w9t+jIAIAQDBBt/RycCHEDyC0AN4AQ7IPIqFAoJ AGbw8qoRC4AEPuCrqqmqJaKABlUBJaaAsSItgoUejXAO3QL9hoUgABAQMNEPAGwQCCUgIhqNaCMk XyQkLS2ieyqigPyNIRwAIC9w+Y9oHZAEP2D/jlUSACBusCgxIP4xHSDAEDgw+40aEAAQMDD6MR4g QBAgMP/tAQgAQEow+DUgJgCEX1Bx5xBxpw3wABJiAEA7sAAAAAAAAPIKACYAhn9Q/2wADABAP7D9 -vzkADgBnsAz/ApIRHI9O+hYAIAgQWDD9XAAABRBQMFiZXfoKgCA2AGSwKTEgKDBwJzAtBJkCKTUg +vzkADgBnsAz/ApIRHI9O+hYAIAgQWDD9XAAABRBQMFiZYfoKgCA2AGSwKTEgKDBwJzAtBJkCKTUg 8AAGZgBARfDAcPgnIHAAEHgwKTEgKDBwLzAtCpkCKTUg8AAJbgBAR/AAAAAAAP8WBCIAACPw8jBf -IAQQUDD8jzUQGBBYMP1cAAIAABnw9xYAIgAAcLBYmUH0IFRvABB4MByNTQJbEay7KLKCD4gBCEgC +IAQQUDD8jzUQGBBYMP1cAAIAABnw9xYAIgAAcLBYmUX0IFRvABB4MByNTQJbEay7KLKCD4gBCEgC KLaCLrKED+4BDj4CLraEKrKAHI2tHY0h8tY5CgBAYrAGqgL6toAgABAQMNEPAAAAAAAAAPIKgC3/ fH6QY/8MhBT9CgEiAAAZ8AfTOfP/n2QFACNwD6gB/wIAD/942hDz/ulgQBAQMABsEAQejS78jTEf IAQ8oPuMvBAAEEgw+AoAL/8QaDDwAAlgARBQMLGZaJRJD5UKrlUlUsPyCgAv7wA1YAuWEW0IMAAh @@ -5068,9 +5068,9 @@ ACBAADVg9gqAIIcQSDBtCC0AIQQApxp3UBgLbwIvxrMuwrT9fwMPoAFwMP9VAQgBAHIwsWb2kwlw AgIQsMhRY//LIlruCII50Q8AAGwQDo0whDH7jgoQARBgMPYgIiAAEDgw9ARfADoAL3D5jtUQKRBA MPoKAyoAecEQCUkKiZAKkAAA3HD7jZIQAFMnUIQxBARf/wIAAgB6BSDAyPTDbHAnEFAwGY31bkZh KiAiK5J/KZKCq6oJqhH9MAgqACBScIqn+qIOJqkAN2D/AgAABAiHYP8CAAIEEINg/wIAAgQYh2D/ -AgAEBB4DYP8CAAQCVIdgwKT8jrMQGBBYMFiYwvAALG/qEGAwAAAAAAB6QS8cjq7+ICMiAABpsP8g -NiACEFAw9BYAIBgQWDBYmLfGyvpcAAIAAFjwWJbOwCDRDwAsIh8PAgAPAgCMycnB+iwAAgAAWPAL -wADz/9RiAABisPP/zG/aEGAwAAAcjpj+ICMiAABpsP8gNiACEFAw9BYAIBgQWDBYmKBj/6IuICv+ +AgAEBB4DYP8CAAQCVIdgwKT8jrMQGBBYMFiYxvAALG/qEGAwAAAAAAB6QS8cjq7+ICMiAABpsP8g +NiACEFAw9BYAIBgQWDBYmLvGyvpcAAIAAFjwWJbSwCDRDwAsIh8PAgAPAgCMycnB+iwAAgAAWPAL +wADz/9RiAABisPP/zG/aEGAwAAAcjpj+ICMiAABpsP8gNiACEFAw9BYAIBgQWDBYmKRj/6IuICv+ D0AAPAB/sH7nFn3nE3znEC0hIA0KRfAAD2qABDqgAAAA/SEgIAAQUDD5CgAgDwA34H7nB33nBHzn AcCRHo6B+HwADgcBbDD/IR4oBQB7sB6MLdZw/3dAAgAAIfD+jCkWBQA7sJ8e90wADgYBfDD/5DkO EAQ+YA+vAvhEAg4JADfw9CAkLgkAJ/ANaED4tzkEsAQ5IPYgIyQJACHw9CAhLgkAJ/D4ZhEFAAQ5 @@ -5078,7 +5078,7 @@ IAZEAvQgIC4JACfwLiAsC0QR9CEcLgkAI7AkNQb/IR0uCQB7sJ4yLzUHHo5cKCEZKDUI9yA0IAAQ MDCWNpc3JCA1JDQSLyAvLzQTKCAirogogOD2CoAgABA4MP4SDigBAUAw/jULJgUAQfAmNBRj/oQo IENljnz7TAACAABQsFhYJo0w8/3EYgAAYrAAKSIfhDIqIRz6FgYnAgA2YCvqAAurAvoWBiwDeibQ HI48iBYvIDYpIR0uICOUEpgQ+RYBKKABSDD4FgkoJgFIMJgX+YhACCkBTDCZFPgWCCAFEFAw+CEf -IBgQWDD4FgMiAABpsFiYN4oZBAtF+xYKIEgIWrCMFwRtQX3JF44YBI9Af+kPBJtBZLa2iBT/AgAG +IBgQWDD4FgMiAABpsFiYO4oZBAtF+xYKIEgIWrCMFwRtQX3JF44YBI9Af+kPBJtBZLa2iBT/AgAG A1jeEIoW+woBJgAQSDD7JC4uAR/WUASbQWSyNIwU/wIABgEX3xAsIh8swhT7FgwjuwA3INogC8AA ixzwA69iAABisCwiH4zJZMHt+iwAAgAAWPALwACNMPP802IAAGKwLCRt8/zIYgAAYfAqJG3z/L1i AABh8Ps8CCIAAFCwWE4ajTDz/KhiAABisPP8oGIAAGHwKiAhKLJ9KTAIJLKCqoj7jBIZkAQ6IP+X @@ -5104,29 +5104,29 @@ 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 @@ -5134,45 +5134,45 @@ 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 @@ -5198,7 +5198,7 @@ h/MDSggCAXww+pkQA8AEPOD5YQgiCQBM8P8PQQIJAETw87YALwAEP+D/h8EYCQB+cINg9bYGIAAQ QDD4tgUgMBBQMJqznLL1mQIDgAQ84Pm2BCIJAGzwk7Es4AcPzAL85gEgQAIa8AIOhgBDYwAOhgBD YYpnJbxA9RYXIEACUrAlEhf7EgwiAABhMFs40/0SESIAAGFw9KYBIgAAGrD6bAACAABY8FgvKYpn KqwQWzdM2mBbMkpj/iMAAMisjBSbFSvAOLG7K8Q4ixUsEhSdGfsWBSAPADcgLhITLeBcsd0t5Fwc -h5MvYTeOYI0g+BIJIAIQUDD4FgAgMhBYMFiRholnK5kU9LL1YEACUnCLmYyw/IxXADQQcDD8FhIm +h5MvYTeOYI0g+BIJIAIQUDD4FgAgMhBYMFiRiolnK5kU9LL1YEACUnCLmYyw/IxXADQQcDD8FhIm AcH3EMDw/xYQIAoQaDAqYQgrYBb4Cv8j/xBgMPyqDAAGEEgw+p04ADIEQvCMG50XKmBBAMyOWz0l /RIHJFwANqAYhWgMXxGo/y7yOv8CAAoAo++QGoduKfI5CloKKqKv+p4BDgCZ1lAbhTUuFhifH/AL BwIAAEuwnRcASWEASWEASWEASWEASWHwCaACAAArsPpsAAIAAFuwW/3aLGEILTr//wIABgC6bxAu @@ -5206,18 +5206,18 @@ EhLD9P8CAAYAsP+QiWcomRRkgkmLmR2HVhyE8CqwBy6wEomw/RIHLAUAc3D5iVcKCQBisPkWEiDA AmFw+rYBIgAAUbBYLtAvEhLDgvYWCiYApkfQw6X2FgomAKFX0IwajMeHFvv6wCBAAlMw+6sBAAAQ aDD9xRQggAJa8JvJm8j7PAACAABhMFs4YmP8hgAAAI0dZNKc/wIAAAFqB2D6EggiAABY8PxMAAAW EGgwWDVzLSAE8/vmYAAQODDcQP0KhCIAAFjwWDVtHIcqjjKPM4kgmRD4IAUgAhBQMPgWASAyEFgw -WJEawCDRDwCKYocW/RYHIr4ANqArYQgsOv//AgAGANFm0C0SEsPk/wIABgDH91CJZy+ZFPTx2mBA +WJEewCDRDwCKYocW/RYHIr4ANqArYQgsOv//AgAGANFm0C0SEsPk/wIABgDH91CJZy+ZFPTx2mBA AlJwi5klsAeMFfsKACIAAGlwWzTLimfbMPqsICIAAGEwWzg0jGCLZwjMEQxMAvymASBAAlLw+xIF IgAAYXBbOC1j+7OJZ2WcL2P6hy0SEGXenIcWiR+IFyiWOS4gFi8K//YWCif/bn+QKmBB+2AWIDwQ YDBbPHeWGmP+xAAAAIUaKlEUJVESwGD6FhYutAA2oPpywyIAAFlw/AoAIAEQaDBbNDEocsSxVQhV -LigSFrFmeGncY/6JyKiLFCmwQLGZKbRAKxIUyLktEhMs0GSxzCzUZI1i+hYIIBgAN2Da0FiP0dug +LigSFrFmeGncY/6JyKiLFCmwQLGZKbRAKxIUyLktEhMs0GSxzCzUZI1i+hYIIBgAN2Da0FiP1dug /Pr/IgAAUbBbO3WKGMTa/WQFIA4ANqCPFC7wQbHuLvRBLxIUZP0PKRITKJBlsYgolGVj/QHz/Q1g ABBYMPP7YWAAEFgwiWJkkXdk4K/7EgwiAABhMFs702P6uAAA8/20YAAQWDDIqIsUKrA6saoqtDor EhRkvL8tEhMs0F6xzCzUXmP8scTbLWQFY/ypxOouZAVj/KHz+zVgABBYMC8SEGX+boln+PrAIEAC UnD4qAEAABBYMPuVFCCAAkIw+JYJIgAAYTD4lggiAABY8Fs30GP6QAAAAAAtsAf8EgUgABBYMFs0 XvoWECA8ALag8/xxYAYQaDDz/ihgABBYMPn6wCAAEFgw+6UEKABATrD7EgwggAJKcJmh+aYAIgAA -YTBbN7xj+e7EqiokBfP8NGAKEGgwjzOOMvyGjxAFEFAw/SIAIDIQWDBYkIGLGMi4jRQs0DmxzCzU -OS0SFGTdPy8SEy7wXbHuLvRdY/0xAAAchoOOMo8ziiCaEIk3mRP4MgYgMhBYMPgWAiAFEFAwWJBw +YTBbN7xj+e7EqiokBfP8NGAKEGgwjzOOMvyGjxAFEFAw/SIAIDIQWDBYkIWLGMi4jRQs0DmxzCzU +OS0SFGTdPy8SEy7wXbHuLvRdY/0xAAAchoOOMo8ziiCaEIk3mRP4MgYgMhBYMPgWAiAFEFAwWJB0 ixjIuI0ULNBDscws1EMtEhRk3PkvEhMu8Gex7i70Z2P86ytcGPpsAAABEGAwWzx3Y/00nh76bAAA MAJZcP0SESABEGAwWzxximeOHvP+a2BAAlKwAADz+jBgABBIMIti9xIGLQQAtuArYEH6bAAAARBg MPu8EiAAEGgwWzxjY/zmAAAAAABsEAiTFPogByIAAEEw9TIAIgAAIXApIAQoFgL1BUcKIAFQMPoW @@ -5228,15 +5228,15 @@ QRiFMS0gBQmbCfy7EQBOEDAw+4gIAFAQcDD4gn8gKARzcPbRDHBWEFgw/wIADgFXW1AbhhkWhgz6 3hQMwAFAMPiPQgwHAUQw9KoRD0AEO6D2RgcgeAIxcPZFCykABDpg+YPwHVAEP2D4/xEMCQB3cP/M AgoJAFqw/cwCAAAQWDD6RgYoCQBiMPtFCigJAEow+EYEIJACeLDyDxYAQAJxMABOY/ohKiAAEGgw LUQxLUQy/UQzIAAQYDAsRDUsRDYsRDcrRC77RC8gABBIMClEMPpELSAAEEAwKEQ0CooUKkQsLyBX -L0Q7D48UL0Q6D48U/0Q5ILgCWLD/jxQABBBgMP9EOCB4AlEwWIbb9hYBIMACQLDzCBYAgAJJMABJ -igAIiAAJiiwiHIsULERTDIwULERSDIwU/ERRIKgCUTD8jBQAYAJa8PxEUCIAAGFwWIbK/iB0LgAg +L0Q7D48UL0Q6D48U/0Q5ILgCWLD/jxQABBBgMP9EOCB4AlEwWIbf9hYBIMACQLDzCBYAgAJJMABJ +igAIiAAJiiwiHIsULERTDIwULERSDIwU/ERRIKgCUTD8jBQAYAJa8PxEUCIAAGFwWIbO/iB0LgAg LTAu9FgnNjkrIBYtCv8PAgB9sQgqIEEsEgFbO0WIFCkKSCkkBSiAEg8CAGSOJBSDzyMiBwSEKPpM AAAgAhjwWsj7/YNWEgAAYTD+hL0SAABasP8iACIAAFDwWsixgicPAgAiLBDaIFq+hP8CAAH+8p6g YADMixP6LAAAARBgMPu8GCIAAGnwWzu1wCDRDwAAAAD6LAACAABYcP0xCCIAAGDw/goAIgAAeTBb IUktCoh9oV6KEPYSAi2aADagiqfbMPqsICIAAGGwWzbDjBCNwJoU+N0RAgAAGrD9bQICAABY8P2m ASIAAFCwWyB33qD6EgAgFwA3oNsw/GwAAgAAaTBYMrTAINEPAADz/P9iAAASsNog/BICIgAAWPBY M8nAINEPjyJl/SorIEH6LAAAARBgMPu8EiAAEGgwWzuIwCDRD9ogWr5tE4OtC6gR9KBBYgAgRPDA -IQzqMCsyhYuwI6z//LsIAgAAUPBYkZ0chCAqwn8AMQQAKxoLqgIqxn9YkdPAINEPxcIsJAVj/U0A +IQzqMCsyhYuwI6z//LsIAgAAUPBYkaEchCAqwn8AMQQAKxoLqgIqxn9YkdfAINEPxcIsJAVj/U0A AAAA+goHIAEQWDBbNdMtMn/9NoMgABAQMNEPbBAEHYM+KS0CLpAXL9J9LdKAr+4J7hGu3Y3X+goA IAEQKDD5MA0hMAIScP3SDiAGEEAw/zAOIYAQcDBtihStrK7MK8DdLMDXe8Mn/LNVcAICUrApMA1k kHppkUPK8Io0i6HJvMtom6AqIH8LQADAINEPAMqSaZEnyPQtMA9p0d2KNIyinKCLNCU0DSogf4uw @@ -5246,32 +5246,32 @@ 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 @@ -5289,26 +5289,26 @@ NfZREiIAABDw/C0CIAAQGDD9wBcgGQA2IClQSdMP0w/6CgEgCgA2YCtQXQujORqAji6ifStQIimi gPRQIS4AIGuw/yAAL5AEO6D4IAwoACB2cImXmBifGYmeLyABLiANKZ0C+ZBVITACYzD0VCAgnAA1 IJQTnxeeFisWBPkWAiBYAD0g/BYFIgCMASD/AgACAKoFIP8CAAQAuYEg/wIABADdhSD/AgAGAOwB IGhBM29FAm9CGWhFc2hGE4oT8qz/IAEQSDD6VCEiBQAScNEPwLHyCgAgARBgMPxUISIFABLw0Q+N -EnZ5AmQyHY4UZNHS/woBIFwAN6DyCgIgAxBAMPhUISIFABPw0Q8AwKX8go8QJBBYMFiMb8CR8goA +EnZ5AmQyHY4UZNHS/woBIFwAN6DyCgIgAxBAMPhUISIFABPw0Q8AwKX8go8QJBBYMFiMc8CR8goA IAEQUDD6VCEiBQAScNEPjxCOEcDR/+4MAAYQYDAO3DjyzP8gARBYMPxUISIFABLw0Q8AdnkCZD9k iBJkgXeJFGSRfXZ5AmQ/VIoSZK9PixRlv0qOF40WjBkO3TT/AgAP/59rEIkY+cgMAAUQEDAIJDjy -TP8gARB4MPRUISIFABPw0Q/ApfyCaxAkEFgwWIxKjiEbgJ8dgC38EgUgAgJzsJ4hLdJ9LMB/K7KB -rcwJzBGsu4u3i74rvQL7vIAgARBQMCq01mP+x8Cl/IJbECQQWDBYjDnAkJkhmSIpVRIoIAH4JAAg -ARB4MC9UI2P+oMCl/IJSECQQWDBYjC8bgIQvIAEuIA2MFR2AEf4WBi4BAPuwLiQALdJ9LMB/K7KB -rcwJzBGsu4u3i777vQIgARBQMP8WByEAAlrwKrTWY/5QwKX8gj8QJBBYMFiMG4sl+1USIAEQUDAq -VCOIJIkimRCYEWP+K8Cl/II3ECQQWDBYjBIdgGeOFR9/9YgkmCIv8n0u4H8t0oGv7gnuEa7djdeN +TP8gARB4MPRUISIFABPw0Q/ApfyCaxAkEFgwWIxOjiEbgJ8dgC38EgUgAgJzsJ4hLdJ9LMB/K7KB +rcwJzBGsu4u3i74rvQL7vIAgARBQMCq01mP+x8Cl/IJbECQQWDBYjD3AkJkhmSIpVRIoIAH4JAAg +ARB4MC9UI2P+oMCl/IJSECQQWDBYjDMbgIQvIAEuIA2MFR2AEf4WBi4BAPuwLiQALdJ9LMB/K7KB +rcwJzBGsu4u3i777vQIgARBQMP8WByEAAlrwKrTWY/5QwKX8gj8QJBBYMFiMH4sl+1USIAEQUDAq +VCOIJIkimRCYEWP+K8Cl/II3ECQQWDBYjBYdgGeOFR9/9YgkmCIv8n0u4H8t0oGv7gnuEa7djdeN 3i3dAv3cgCABEGAwLNTWY/3tAAAAAAD/AgAH/0Y10GP97AAAAAAA/wIAB/9GNdBj/dyLF4oWiRkL qjT/AgAH/zrWUPkKASAEEGAw/FQhIAMQEDD8FgMiBQAScNEPwOH9CgIiAAATsP1UISIFABOw0Q8A AGwQCichEiggNRV/z/kyASAAEDAw+RYJIBkANiAqIEnTD9MP+woBIAoANqAsIF0MtjksUn0rPQIt sBcpUoD6ICIsACBrMP4wAS2QBDsg/zAAKAAgZnCJlyQgISgwDImemBgsMA35nQIhMAJa8PmQVSIA ACkw9CQgIHAANSCfF54WnBWaE/kWAiBYAD0g+xYEIgBTgSD/AgACAHIFIP8CAAQAggEg/wIABACm BSD/AgAGALSBIPkSCSCYAD0gb0UCb0IyaEVcaEYs9SQhIDAAPWDAQNog9EwBIgAAWPBb/v3IoWpG -7cAg0Q/ApfyB0BAkEFgwWIuw8//PYAEQKDAAAAAAAAAA+hICIA4IOnBkYZz7EgMhRAA2oGSxSfP/ -qmADECgwjhCNEcDB/t0MAAYQKDANxThj/5EAwKX8gb0QJBBYMFiLnIsxGH/xGn9/+RIEIAICWvCb -MSqifSmQfyiCgaqZCZkRqYiIh4iOKI0C+IyAIAEQeDAvhNZj/zgAwKX8ga0QJBBYMFiLi8DgnjGe -Mi4lEi0wAf00ACABEGAwLCQjY/8QAMCl/IGkECQQWDBYi4EYf9YsMAErMA2JFBp/Y/sWBSoBAObw +7cAg0Q/ApfyB0BAkEFgwWIu08//PYAEQKDAAAAAAAAAA+hICIA4IOnBkYZz7EgMhRAA2oGSxSfP/ +qmADECgwjhCNEcDB/t0MAAYQKDANxThj/5EAwKX8gb0QJBBYMFiLoIsxGH/xGn9/+RIEIAICWvCb +MSqifSmQfyiCgaqZCZkRqYiIh4iOKI0C+IyAIAEQeDAvhNZj/zgAwKX8ga0QJBBYMFiLj8DgnjGe +Mi4lEi0wAf00ACABEGAwLCQjY/8QAMCl/IGkECQQWDBYi4UYf9YsMAErMA2JFBp/Y/sWBSoBAObw KzQAKqJ9KZB/KIKBqpkJmRGpiIiHiI74jQIgARB4MPwWBiEAAkIwL4TWY/6/wKX8gZEQJBBYMFiL -bYg1+CUSIAEQeDAvJCONNI4ynhCdEWP+msCl/IGJECQQWDBYi2Qaf7mLFBx/R400nTIswn0rsH8q +cYg1+CUSIAEQeDAvJCONNI4ynhCdEWP+msCl/IGJECQQWDBYi2gaf7mLFBx/R400nTIswn0rsH8q ooGsuwm7EauqiqeKriqtAvqsgCABEEgwKaTWY/5cjhn/AgAP/zW7kGAABI8Zd/kCZG5biBJkgEKJ E2SQSooZd6kCZG5JixJkvkSME2XOP48WjhWNFw/uNP8CAA//GfNQihjAhfrZDAIAACkwCYU4Y/4c APP+GGACECgwixn/AgAP/wc60GP/uY4WjRWMFw7dNH3BqPP992AEECgwAAAAbBAGH38bKi0CJ6AX @@ -5321,41 +5321,41 @@ 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 @@ -5365,7 +5365,7 @@ ACAAEEgwmRv5FgogBRBAMPUUNS+ABD/g/xYMLgkAR/CfGWP/lAAAbBAEGnxULCAMK6J3KqKArLsJ uxH5fFEaACBasCihKfx8ORD6BEowjieO7hh8TR98Sy3tAvV8nBCgAltw8AwHAgAASvAASWEASWEA SWEASWGJIP/mliAEEGAw9eaaKYAEPmD45pQoCQBmcCnmlSigBy+hKQgIQQCIEQj/AgX/Av/mmCDg AktwAgOGAEljAAOGAElh2dD0lIYgAhBoMFsnndEPAABsEAooUBhogQfAINEPAAAAACtcGvwKBiAg -AlBwWH9DuEv8ChAgMAJQcFh/QPwcGCIAAFCw/35sECACcHD9PAggAhBIMPkWACIAAFtwWwljwCDR +AlBwWH9HuEv8ChAgMAJQcFh/RPwcGCIAAFCw/35sECACcHD9PAggAhBIMPkWACIAAFtwWwljwCDR DwBsECAqIgeLOCcyAfWiDiABEDAw9Pr/IAgQQDDwsQQGAEBF8PiwIWIAAElwLV0ELNAAAGsaBLsD C8sBCwtH+9QAIAcANyBks5sskr79e/wUAS8DII7Sj9GI0JgQnxGeEo3TnROLExp76Y0SjhH/EgAg IAJgcJ/AnsGdwioWNJvD8AoHAEACSHAASWEASWEASWEASWEYe+IZe+0ae+uaGCkWCSiC7I4zLhYL @@ -5385,11 +5385,11 @@ GSigB/l7RBggAUAwAIgRCLgCCYgCKBYcD+owLxYd/PrwIDAQcDD+FT8mAEDlUCscf/u8ASAgAklw CAmGAEtpBgmGAEtnLApj/BSWICkANOAvMRMvFKCOK3HmBSghGygVUY4zLhYrjDIsFiqLNSsWLYk0 KRYsKxxg/AoHIAIQaDBbJpHz/gRgABBoMJY20Q8qrBBbLOuJJ4meY/xWACqsEFss5/P9r2AAEGgw H3scLxYg+yIAIAAQcDAuFiP+FiIgBRBgMP0UlSuABD7g+xYkKgkAZvArFiFj/2oAbBAIJiL9C+ow -F31W0w8PAgAoco//AgAKAKBG0B16uSt2jypyjv3SMSAAEGAwWIek/XswEAAQYDBYh6EnLQQnfPT7 +F31W0w8PAgAoco//AgAKAKBG0B16uSt2jypyjv3SMSAAEGAwWIeo/XswEAAQYDBYh6UnLQQnfPT7 FgcmAH+10Bh9R5IU+BYFIKACQjCYFmAAJAAogBj9mQwOACAb8C7gAACQBAgIGw4OG3jhXoYg/wIA BgBkNdDybAAAEgA1YC5iAvoSByAOADugeuNBhiTIQXRp2PY/FAAAEFAwbfkcoq390BguACAasC7g -AP8CAAACAlKw/wIADgBD65D2DUIIACAT8PkKCC+LALdg0Q8AwKX8EgUgMBBYMP8SByIAAGmwWIbr -jBaNZo5nj2j4YgkgBRBQMPgWACAwEFgwWIbkGn0XjCGGICqibpbAjSCLJYqk/NYBIAAQSDD5JgAg +AP8CAAACAlKw/wIADgBD65D2DUIIACAT8PkKCC+LALdg0Q8AwKX8EgUgMBBYMP8SByIAAGmwWIbv +jBaNZo5nj2j4YgkgBRBQMPgWACAwEFgwWIboGn0XjCGGICqibpbAjSCLJYqk/NYBIAAQSDD5JgAg ABBgMPkmASABEGgwWyonjBQrwvywu/vG/C//oDHQwCDRD/7TBn//EFAwwKFlryBj/2wsco6xzCx2 jmP+uABsEBCJJxp6qImei6Iokr6MoY2g+qIDJACugiCbEpwRnRCaEx56lYkSjxOKEfsSACAgAkBw m4CagZ+DmYLwDgcAQAJIcABJYQBJYQBJYQBJYRh6jhl6mRp6l5oYmRkoguyOM54bjTItFgr8MgUg @@ -5403,16 +5403,16 @@ lwD1NgYgABAQMNEPKrwQWywZlDz1NgYgABAQMNEPbBAELiL9CuowF3yVKHKQ/wIACgBoxpAvLQQv 4gRkQAJ02e79NRQAABBQMNMPbVkUrqv7sBgsACAasCzAAPvJWnACAlKw/QtCCgAgcXD7bAwPqgC2 4MziwCDRD4jhKnJvi+CbgIngiqSL5fiWASAAEHgw/+YAIAEQaDD/5gEiAABj8Fspgiwi/LDM/Cb8 IAAQEDDRDwAAAAAAAAD8swZ//xBQMMChZa9pY/+ZLXKPsd0tdo9j/ycAbBAG/nwAAgAAOPCXEQvq -MBN8Vigyj54QGnm7+zaPKgC6xtBoUCAtojH6Mo4gABBgMFiGpP16MBAAEGAwWIah+nmxFAAgXXBo -YB0rMo8tojH6Mo4gABBgMFiGmv16JhAAEGAwWIaYq2b6LAACAABZ8PxMAAABEGgwW/7i86wAACMA -NqD6CgUgMBBYMPx8OhIAAGjwWIYClTL2NgMiAAAQ8NEPwKX8fDUQMBBYMFiF+y4i/P8SACR8AT+g +MBN8Vigyj54QGnm7+zaPKgC6xtBoUCAtojH6Mo4gABBgMFiGqP16MBAAEGAwWIal+nmxFAAgXXBo +YB0rMo8tojH6Mo4gABBgMFiGnv16JhAAEGAwWIacq2b6LAACAABZ8PxMAAABEGgwW/7i86wAACMA +NqD6CgUgMBBYMPx8OhIAAGjwWIYGlTL2NgMiAAAQ8NEPwKX8fDUQMBBYMFiF/y4i/P8SACR8AT+g y/YpIv4afCqNkSqibouQm9COkIqki5X95gEgABBAMPiWACIAAGIw+JYBIAEQaDBbKTorIvywuysm /Cwi/G/FcxN8GyMyboo0LaECzNbwABZgABBQMFsk/Is4+qoKAgAAQrALqguYpfOsAABJADagKS0E laKWo5SkjHGcp4wQi3Cbpopzmjn9cgIh6AJKcP02CCAoADcgLiL9LSL8k+GeMJkx8yb9IAICa3D9 JvwiAAAQ8NEP0jDRDwAAKCL+LyL8k4CYMZkw8yb+IAICe/D/JvwiAAAQ8NEPAAApMo6xmSk2jmP+ gwBsEASEICgwBiUwByJCEAiIEQhTAvNFGiAOADSg8yUaIAAQEDDRD8Ag0Q8AAGwQFicwAgvqMBp6 -s9MPDwIAKKJ//wIACgJgRtAdeUcrpn8qon790jEgABBgMFiGMv15vhAAEGAwWIYv+hwAAgAAMvD7 -PBAgEBBgMFh8pSUwBykwBCgwCCswCSwwBSowCvC7EQiABDog+zAGKAkAWjD0MAsrgAQ6oPDMEQiA +s9MPDwIAKKJ//wIACgJgRtAdeUcrpn8qon790jEgABBgMFiGNv15vhAAEGAwWIYz+hwAAgAAMvD7 +PBAgEBBgMFh8qSUwBykwBCgwCCswCSwwBSowCvC7EQiABDog+zAGKAkAWjD0MAsrgAQ6oPDMEQiA BD5g/JkCC4AEPuD6RAIECQBdcPhEAgQJAE1w+TADIAkANWBoUAGlZSwQAPRACWD+EGgwaEABpGT6 Cv8mAIRvEP8CAAYAflcQeJcgZFEJ+iwAAgAAWHD8fAACAABpcP5MAAAAEHgwW/9UKTAD/wIAAABo ZlApIskPAgD+CgIiAGF2UC8is/8CAAAAW/vQLBAA/wIAAgBWclAoCv7/AgAGAGTHEPMtAyoATKVQ @@ -5433,71 +5433,71 @@ BwA2IGSQjcfPLDYUmj4nNSMkNhMlNhKdPi01IogZjxiOG549nzqYO40a/TYMIAEQWDD6IgAgARBg MFsGKsAg0Q8AAHurRCo2EvQ2EyAAEBAw0Q//AgAL/qOukMef/wIAC/6erlBj/90qkr0skrwvkrv4 krogYAJYcJiwn7GcspqzY/4cAAAAAAAAAPQ2EyAAEBAw0Q8qzBBbKj3A0fP/ZmAAEFAwAAAAAAAA +vr/IgAAS3D+kwhwARBoMMDR2tD+CgIs6AC2oGP8gwAson6xzCymfmP7OABsEAjJOvo8AAAAEFgw -W/t8ya7Apfx6rxAwEFgwWIRz0Q9kQGf6CgAiAABZMFv7dGWiERd4xCdyhypyASihAmSAV1sjg4t1 +W/t8ya7Apfx6rxAwEFgwWIR30Q9kQGf6CgAiAABZMFv7dGWiERd4xCdyhypyASihAmSAV1sjg4t1 HHhOCqkKC5kL+pUBIEYANmAtwnf7woAh+AI7MCdyhyzN5izAwYpyCd0R+RYFKgAgbvD/oQIgRgB/ -MC2yJ43ejd+dFGAAG8Ci/HqREDAQWDBYhFXRDwAAAAAusqeO7o7vnhRk/+1bI2mJdogUixUKpwv5 -dwsIACBCsPh1ECAAEEgwmXD5dgEvzAA14GQxfym0ACl0JpOyk3QqvBz8CgYiAABZcFh7RCZ1EZJ8 +MC2yJ43ejd+dFGAAG8Ci/HqREDAQWDBYhFnRDwAAAAAusqeO7o7vnhRk/+1bI2mJdogUixUKpwv5 +dwsIACBCsPh1ECAAEEgwmXD5dgEvzAA14GQxfym0ACl0JpOyk3QqvBz8CgYiAABZcFh7SCZ1EZJ8 LiA5LnQoLFAALVABLXQ9LHQ8KlACK1ADK3Q/KnQ+KFAEKVAFKXRB+HRAL4IQMDAmdCeKKyQgB/kg OSB4AjHw9ARBABwAErDApPAABmoJAFJw2pD8elUQMBBYMP8iAiIAAGiw/iIAJOABVDD1FgAgBRBQ -MFiEIRh4Gx94lRx6S/0iACPABD0g/vIWIgAgRPArMjoaelX+7AEsCQBjcP72FiIAdELgKTI5CkoK +MFiEJRh4Gx94lRx6S/0iACPABD0g/vIWIgAgRPArMjoaelX+7AEsCQBjcP72FiIAdELgKTI5CkoK KqKRG3fkDwIA+p4BDgBo1lDwCwcCAABLsABJYQBJYR94CyRxEClxEfp4ChiABDlg+Ho1FAkAQTCa 4C0iAPnlDCIAAFmw8nehEDQCU7D/5gIgEBB4MP/mAygJAEMw+N0RAgkAETDy5gUgAhAQMPjmBCwJ -ABdw/eYBIAYQYDBYevjyNjkvgBBYMCt0J/5xECIAAGnw/3ERIAUQUDD8eikQMBBYMFiD69EPwKX8 -eiYQMBBYMFiD59EPAMDxL7QA/3QmIgAAcTDyDhYAEAJq8ABNY/AEFgAgAmHwAExhY/5jiCLJhCoK -Bfx6ChAwEFgwWIPYY/+XAAAAAAD6LAAAMAJZMPwKACACEGgwWy/kiicrCgD6rCAgARBgMFsq/h14 -zJ2gjCAbefn7pgIgARBoMPjMEQAwEFgw96YDLAkAazD8pgEiAABp8Px58RAFEFAwWIPAY/83AGwQ +ABdw/eYBIAYQYDBYevzyNjkvgBBYMCt0J/5xECIAAGnw/3ERIAUQUDD8eikQMBBYMFiD79EPwKX8 +eiYQMBBYMFiD69EPAMDxL7QA/3QmIgAAcTDyDhYAEAJq8ABNY/AEFgAgAmHwAExhY/5jiCLJhCoK +Bfx6ChAwEFgwWIPcY/+XAAAAAAD6LAAAMAJZMPwKACACEGgwWy/kiicrCgD6rCAgARBgMFsq/h14 +zJ2gjCAbefn7pgIgARBoMPjMEQAwEFgw96YDLAkAazD8pgEiAABp8Px58RAFEFAwWIPEY/83AGwQ BPIi6CIAADCwKW0EKZygcpEv+vr/IAEQWDD2CgAgEBBgMNMPbcoUomf3cAgoACAZsCiAAPeJEnAC AjGwcpEC0Q8AwCDRDwAAAAD4cwZyAAAysNawZG/kgiDAYPKZw3AQEGAwY//bbBAEjSeN3izdBPvA ACABEDAw/goEIgAAULD4Cg8gABAQMPzMgCgAI0bQbeoKACAECw8bf/cDsSLHLwIuCQAhBABvGg3u -CvjtAi4JAH7wL8SA/u0DIAICSPAp5YIp5YMlhoL0hoMgCgA24NEPxy/RDxt3exx3e1h/6dEPAGwQ +CvjtAi4JAH7wL8SA/u0DIAICSPAp5YIp5YMlhoL0hoMgCgA24NEPxy/RDxt3exx3e1h/7dEPAGwQ BIwnis4AMQQqrQT4oAAgARBIMPCZGg//EFgwC5kDCYkB+QlHAAAQEDD5pAAgBgA2IMiR0Q8AKswQ WykqwCDRDwAAbBAEwEJtSlMoIr4sIrv7IrogABBQMPkKACA/ADYgjjCNMYczDrsM/cwMAAEQQDAM ijj7iTgAABAgMPqQG3AAEHgwJiK9iTIlIrwHZgwGhDgJVQwFjzh0+AYiLEDAINEPIi0DIizg0Q9s -EAgkIgf8eZcQBRBQMPRCDiAwEFgwWINVKDAV+TAUIACLniBlkQ8qMDj8Cv4kAISeoCswFi0wFyow +EAgkIgf8eZcQBRBQMPRCDiAwEFgwWINZKDAV+TAUIACLniBlkQ8qMDj8Cv4kAISeoCswFi0wFyow Ev4KwC4AfGLQDt0B/wIADgB2m2ArMBMIqhH7ChsqCQBasPWsDAoAa8ag/Mw2JgAgLPD+eX8aASri -0C1wBC9wBQjdEQ/dAv3PQgoADWuQHnbv//wDLWABbDDw8QQMCQB3cADdGitCtfpCtCAAEGAwWIR8 -wKX8eW8QChAoMAW1LPsKMCIAAGlwWIMqKHAaKXAbCIgRCYgCZYB0KUL6LUL5+jqAIAEQMDD3FgQg +0C1wBC9wBQjdEQ/dAv3PQgoADWuQHnbv//wDLWABbDDw8QQMCQB3cADdGitCtfpCtCAAEGAwWISA +wKX8eW8QChAoMAW1LPsKMCIAAGlwWIMuKHAaKXAbCIgRCYgCZYB0KUL6LUL5+jqAIAEQMDD3FgQg 2AA6YIsni74svQQswAAA0AQMDht/508N3gkL7gou7QMv4YIu4YMP7gx16z8pQvoAkAQMDxv/AgAA -AIJ/0AmdCQvdCi3dAy7Rgi3Rgw7dDGAA7MCl/HlNEDAQWDBYgwrAINEPwCDRD8fvdeO/jxSP8sB/ +AIJ/0AmdCQvdCi3dAy7Rgi3Rgw7dDGAA7MCl/HlNEDAQWDBYgw7AINEPwCDRD8fvdeO/jxSP8sB/ +/r/IFQAt+CIFIiDZYBIiRSJlGWQQYwUjMXPyhx2zY/DiMKJwZkRmBKfE/zCACIAAGhw/BYAIBAQ cDBt6hUuMCYv0AD/AgAOANLz0PM8ASACAmtwwCDRD4sU+7wIIgAAUTBb/y0sOoDzrAABPAA2oIqo hCf9Qg4gAEaCoC/dBP4yByEAAnvwK/CAAOAECwgbf4dNDukJDZkKKZ0DKJGCKZGDCJkMdZs9AKAE -Cwwb/wIAAABm/xAKrgkN7Qot3QMu0YIt0YMO3QxgALXH38Cl/HkTEDAQWDBYgs/AINEPAAAAx491 +Cwwb/wIAAABm/xAKrgkN7Qot3QMu0YIt0YMO3QxgALXH38Cl/HkTEDAQWDBYgtPAINEPAAAAx491 g8EAoQTwaRoP/xBwMA6ZAwm5AQkJR/n0gCAHADbgZJDPrNsqsID+OQwoAEO+kPkKACAEEHgwbfoK AJAECggbf4cDsZnHnxx4/QmYCQCRBABnGv2GCgYJAD6wJ7SAL20C9m0DIAICIXAkZYIkZYP+9oIi -AAAycPz2gyBbADagmTj1NgcgABAQMNEPwKX8eO0QMBBYMFiCp8Ag0Q/H38Cl/HjpEDAQWDBYgqLA -INEPAAAA9TYHL/8QSDD5NgggABAQMNEPAMCl/HjgEDAQWDBYgpjAINEPG3aJ/HaJEgAAULBYfvaW +AAAycPz2gyBbADagmTj1NgcgABAQMNEPwKX8eO0QMBBYMFiCq8Ag0Q/H38Cl/HjpEDAQWDBYgqbA +INEPAAAA9TYHL/8QSDD5NgggABAQMNEPAMCl/HjgEDAQWDBYgpzAINEPG3aJ/HaJEgAAULBYfvqW OPU2ByAAEBAw0Q8AACpMEFsoQo0njd7z/yJjgBBgMAAAAAAAAP7zB3IAAGrwBm0CZN31KUL6jyf9 8g4gTAA6YPCRBAgAIFNwLoCAAGkaC5kDCekBCQlH+YSAIAcAN6BkkJeq2yqwgHeqYvkKACAEEGAw bcoKAJAECg4bf+cDsZnHnxd4uQmcCQCRBABuGg3MCv/NAi4JAHKwLrSA/M0DIAICQXAoxYP4xYIi AAAacPf2gyAAEFgw+/aCICQANqApRvr1RvkiAAAS8NEPAPVG+S//EGgw/Ub6IAAQEDDRDxt2Tfx2 -TRIAAFCwWH66I0b69Ub5IAAQEDDRDyr8EFsoBo0njd7z/1pjgBBQMABsEAqEJ/x4lhAFEFAw9EIO -IDAQWDBYgkraEPwKECBMAljwWHlLKhwQ/AoQICwCWPBYeUcmEgMvEgL8EgEiAABRMPsSACACEEAw +TRIAAFCwWH6+I0b69Ub5IAAQEDDRDyr8EFsoBo0njd7z/1pjgBBQMABsEAqEJ/x4lhAFEFAw9EIO +IDAQWDBYgk7aEPwKECBMAljwWHlPKhwQ/AoQICwCWPBYeUsmEgMvEgL8EgEiAABRMPsSACACEEAw bYpLKaK+9AoBIAAQcDD9CgAgOgA2YCiiuimiuwuIDAyZDAlOOPhNOAAAEEgw+KK9LgAN91Auorz2 iAwAABBoMAhNOA/uDA5JOH2YBiqsQMAg0Q8p2iB5oQUror5otAPAINEPJDASKDATDwIACEQRCEQC /AqAIHACaTD/AgAKAEjvENog/HhlEIwCWTBbBEX2rAAPzAA2oC0Kgf2lECBsAmEw/KURIgAAWHAC -C4b7FgggUAJSsPAKogAgAkhw8AkWAHACQbD5FgkgBhBgMPAIoAAMAljw9GYSIJgCUbBYeQqlO/xM -AACkAlGwWHkHjiJl72z6LAACAABZsPwKCiADEGgwWsD1wCDRDwAAAAAAAP1MAAAFEFAw/HhCEDAQ -WDBYgfXAINEPAGwQCv5AECIAAFDw/0ARIgAAWTD4QCogARAwMPlALC+ABDug//r/LgkAe7D05QgC +C4b7FgggUAJSsPAKogAgAkhw8AkWAHACQbD5FgkgBhBgMPAIoAAMAljw9GYSIJgCUbBYeQ6lO/xM +AACkAlGwWHkLjiJl72z6LAACAABZsPwKCiADEGgwWsD1wCDRDwAAAAAAAP1MAAAFEFAw/HhCEDAQ +WDBYgfnAINEPAGwQCv5AECIAAFDw/0ARIgAAWTD4QCogARAwMPlALC+ABDug//r/LgkAe7D05QgC APOaIMCEbYoPLbAuLKBgsar7vAEuAPJjUIsg+7w6IgAAUTBtmQ8tsAAsoEaxqvu8AS4A2+NQjSD8 -eCUQBRBQMP7t/yAwEFgw/dIAIcwCc7BYgdQqPGz8CgQgdAJZMFh41PRNASDQAnjw9zx0IDQCITD2 +eCUQBRBQMP7t/yAwEFgw/dIAIcwCc7BYgdgqPGz8CgQgdAJZMFh42PRNASDQAnjw9zx0IDQCITD2 PGQqALkpEJ8TlhX3FgYg8AJA8PgWByDgAkjwmRgYeBApPQH4FgIhpAJKcPkWASBgAkIw+BYEIDMQ -ODDwAD9gERAwMAAAAAD/AgAANRBQMP8CAAYAUT7Q+rFPcDYQYDB8uQyKE/wKBCAEAlkwWHi0LUAB +ODDwAD9gERAwMAAAAAD/AgAANRBQMP8CAAYAUT7Q+rFPcDYQYDB8uQyKE/wKBCAEAlkwWHi4LUAB st2tRP8CAAoAfakQK0AA/wIAAABwBuD/AgACAGQG4P8CAAYAWALgdrmqKjAX/wIAAf/mYpBgAF+M -FC8yFY0gLkAC/hYJIAUQUDD90gAgMBBYMFiBmokZaJIVaZWfLjIV/wIAAgBPn6DA9S82FWP/jCgy -Ff8CAAIARhogwJQpNhVj/3mKFfwKBCAEAlkwWHiPY/9pAAAAAAArNNAuQAEuNNEsQAEtGgANzDb6 -EgEs4AFgMPwWACAEAlkwWHiE/BICIAUQUDD9EgAgMBBYMFiBe2P/KYoW/AoEIAQCWTBYeHtj/xmK -F/wKBCAEAlkwWHh3Y/8Jihj8CgQgBAJZMFh4c2P++dEPfcMB32Bl//Vj/kEAAAAAAPzTBnIAAFPw +FC8yFY0gLkAC/hYJIAUQUDD90gAgMBBYMFiBnokZaJIVaZWfLjIV/wIAAgBPn6DA9S82FWP/jCgy +Ff8CAAIARhogwJQpNhVj/3mKFfwKBCAEAlkwWHiTY/9pAAAAAAArNNAuQAEuNNEsQAEtGgANzDb6 +EgEs4AFgMPwWACAEAlkwWHiI/BICIAUQUDD9EgAgMBBYMFiBf2P/KYoW/AoEIAQCWTBYeH9j/xmK +F/wKBCAEAlkwWHh7Y/8Jihj8CgQgBAJZMFh4d2P++dEPfcMB32Bl//Vj/kEAAAAAAPzTBnIAAFPw 2mBlr+Bj/g9sEASKNPJ1SRhwAVQw/ZcHf/sQQDAImQEoIm0iIoCpiAmIEfmucXIAIECwhCeETihC -Gf8CAAAAdSYg/HekEAUQUDD9QhkgMBBYMFiBUygwRikwRxt3n/o9ASmABDog+YgCAPQQSDD6rLgs +Gf8CAAAAdSYg/HekEAUQUDD9QhkgMBBYMFiBVygwRikwRxt3n/o9ASmABDog+YgCAPQQSDD6rLgs AEBKECkKBG2aDyygfi2wgLG7/Nl4cAICUrDaQPtMECBAAmDwW/9OwCDRDwAAAPx3jxAFEFAw/TEK -IDAQWDD+IhAiAAB4sFiBOSoiEMDh/woAIAAQaDD5CgAgLAA2oCsxCiyhG/wMSwtgAVwwDLsMC6k4 +IDAQWDD+IhAiAAB4sFiBPSoiEMDh/woAIAAQaDD5CgAgLAA2oCsxCiyhG/wMSwtgAVwwDLsMC6k4 Ce84D+049d9FYgUASnDAINEPAADz/+hgABBIMP3DBn//EFAwwKFkr379IgAgBRBQMPx3chAwEFgw -WIEgwCDRDwAAAAD9IgAgBRBQMPx3bRAwEFgwWIEZwCDRDwBsEAQiIhD0IA9lYAEcMCQhGwQES3VJ +WIEkwCDRDwAAAAD9IgAgBRBQMPx3bRAwEFgwWIEdwCDRDwBsEAQiIhD0IA9lYAEcMCQhGwQES3VJ AdEPwCDRDwAAAGwQBIQqgkpkIEf++v8gARB4MP0KQiAAEFAw8AAQYAMQQDCCKMCg+AoDICgANKBt ihSiq/uwTiwAIBqwLMAg+qwBLgBvWxAsIAUPAgB9wdJlIFobdjoZdj0edmWNQBh0zYVHEnVs+IL4 IgAAUTD1Ug4sCQB3cP0mrCAEEGAw+SatIAUQaDALgAApIq0JiUdkkEoqUDorUDsIqhELqgKxqipU -OwqKFPpUOiAAEBAwKixO/AoDIEACWPBYd+UrTEj8CgMgogJQsFh34ooniq60O/qseCAGEGAwWHfe +OwqKFPpUOiAAEBAwKixO/AoDIEACWPBYd+krTEj8CgMgogJQsFh35ooniq60O/qseCAGEGAwWHfi 0Q8oIrYSdhAZdeQiIn8JiAEJiBH+dkMSACBAsIwsHXTmDswBDcwCnCwrUG4sUG8IuxEMuwKxuytU bwuLFCtUbmP/jwAAAPyzBnIAAFOw2vBlrvRj/xVsEAQoIGr6LAAAARBYMPwKACAkEEgw+SQFIAIC QjD4JGogAhBoMFsHXNEPAGwQBNMPbUoPJyAAJDAAsTP0eQhwAgIQsMAg0Q/0cwh//xAQMMAh0Q/R @@ -5509,63 +5509,63 @@ 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 @@ -5573,40 +5573,40 @@ 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 @@ -5616,12 +5616,12 @@ KJUa0Q/aQFgE4IRJZU/JY//RAAD6LAAAABBYMPwKACAAEGgwW/vtGm8eKqKMK6ECZL7VWxmNG25E HG5X+m8ZEgAAcrAZbuUswmsqooeNn67M8AsHDZAEOyD93AEqACBisP2WDyBAAmqwAE1hAE1hAE1h AE1hAE1hAE1hmhEoIBYsIQctIA3+IAwgARB4MC+kBC6kDC8gBy4gJi2kDSylBw7rCf1wrBvABD7g /qRTKgAgXfArsiArphUopBYvpAcupFOSqP2lFiARADTg2zD6FgEiAABhMFutKiwgJoMRG23jDMwJ -DMwR9G68GgAgZvD7vR8gsAJQ8Pu8WiAGEGAwWHFFikstoQJk0AxbGVeOTAKvEa/uLjYYKSAmCZkJ +DMwR9G68GgAgZvD7vR8gsAJQ8Pu8WiAGEGAwWHFJikstoQJk0AxbGVeOTAKvEa/uLjYYKSAmCZkJ DJkRqXkqkiRkoGuJqciZ+ZIJIgAAUnBln/STqfU1FyAAEFgwmzn7NgogJBBQMPo0BS26ADTgjDeM zo3F+sIEIAICW3D2NRkqAA5q0C3BGvvGBSACAnKw/sYEIAICa3AtxRrRDy/BGpvF+sYEIAICe/Av xRrRDwAjliRj/54AAGwQBhht3PhRCXAAEFAwwCHRDwDbMPxMAAIAAGlw+hYAIgAAcfD/HAACAABQ sFv8+GWv2ooQG28V+KDSYCYQYDAvslwJqhGq+o6nju4t4Rix3S3lGCmgBfyRHXAlEGgwLaQFLLF/ -/c8HcAAQEDDRDwBb/DbAINEPAP2iACAyEFgw/HBhEAUQUDBYeffAIdEPAGwQEi0gDC8gB4swKjAY +/c8HcAAQEDDRDwBb/DbAINEPAP2iACAyEFgw/HBhEAUQUDBYefvAIdEPAGwQEi0gDC8gB4swKjAY HG4q9DATIgAASTD5FgcgAxBwMP4WDiIAAEFw/sJnIgAAKPD4FgYmAgFQMPzCcCrgAVww/t0IDiAB fDD/FhEtkAQ/YPsWEiwAIGsw/BYQIzsANuD5CsAiAFv2kP8CAAQAV4EgKbxMmRAnnB8HRxQpIAQP AgBrlgf/AgAEAbOKYCsgFigK/3ixGYkWKiBB9MkaCOABTDCZHFslgf8CAAAFqiqgGW/PGm2a+G3C @@ -5630,12 +5630,12 @@ ZOZEKBIQj4ICKgL8EgcgARBIMP0SBi4JAE/w/4YCIgAAWPBbIojSoNEPmRBj/1QAAAAAAAAA8AoH AgAAQbDTD215AgBIYSwhBx1tpw8CAAwMSgzMEfoSACwJAGswLGYAKyIAHG2f+mYDIgAAULD8ZgIr gAQ+4Pt7AgIAAGEw+2YBIgAAWXBa6I0bbq8sIEEabc0dbXqDLSqicC4hIv4WFiOQBDzg/lAYIgAg VPCTGCMyCC3SdwzMCS8wDAzMEf4eQAoAIGbw/hYKLAAgf3D7sn8tkAQ/YPsWFyoAIGqw+hYJIAEQ -YDBYT/YpEheMNyggBS0SFvzCDiBQEFgw/BYNIBwEWjDE7n6BBMXyLyQF+iBBKkgBTDD5DkYOBwFM +YDBYT/opEheMNyggBS0SFvzCDiBQEFgw/BYNIBwEWjDE7n6BBMXyLyQF+iBBKkgBTDD5DkYOBwFM MP3YFA1ABDtg/W7YGUAEOiD5CgAvUAQ/4PllCiuABD7g+225HgkAW7D4/wIAsBBAMP/uAgsABDqg -+GULKgkAcrD9zAIKCQBasPxmBiCQAliw+mYEIEACUbD6FgsgBhBgMFhwXSwgQRts8gzMCQzMEay7 -+70fIEwCUbD7vFogBhBgMFhwVR9uuvts8xCAEGAwLGQ2+2Q3IBAQSDD5ZC4giRBAMChkLP9kLSAB -EGgw/WQzIAIQUDD6ZDEgABBQMCpkMC0wBMHs/wIABgQL91AqbDz8ChgguAJYsFhwPypsVPwSEiBg -AllwWHA8wOL+ZDUgABBwMC5kNChQMA8CAGiBLSgWFfsKJiAkEEgw/QrKIgQAAiD/AgAEAdUCIPgW ++GULKgkAcrD9zAIKCQBasPxmBiCQAliw+mYEIEACUbD6FgsgBhBgMFhwYSwgQRts8gzMCQzMEay7 ++70fIEwCUbD7vFogBhBgMFhwWR9uuvts8xCAEGAwLGQ2+2Q3IBAQSDD5ZC4giRBAMChkLP9kLSAB +EGgw/WQzIAIQUDD6ZDEgABBQMCpkMC0wBMHs/wIABgQL91AqbDz8ChgguAJYsFhwQypsVPwSEiBg +AllwWHBAwOL+ZDUgABBwMC5kNChQMA8CAGiBLSgWFfsKJiAkEEgw/QrKIgQAAiD/AgAEAdUCIPgW FSQEJQYgLwpR/wIABgHSfhCLHYyxirD6rQEgAgJjMPy2ASFoAlKwmrApEhP3ljkkAIKGIP8CAAQA jgEgKyAWLAr/0w98sQ0sEhL6IEEgeAJjMFskni4SEI3ix/4P3QH95gIgABAQMNEPAAAA8/zgYAgQ ODD/AgAF/pEBICwSEQzLEai7KxYTK7I6d7MTCc0KLBITLdKvLMI5/cYBCABn6xCOImXtIisSEfos @@ -5650,17 +5650,17 @@ BIgR9GyJHgkAJ/D+bpkYCQByMJ5n+GYGLgkAfPD4EhIuCQAn8PQSBCAAEHAwLmUK/2YEIHgCQjAo ZQsIBIYASWkoISr+ZC8gABB4MC9kMS9kMv9kMyAAECAwJGQ1JGQ2JGQ3KGQt+IgUAAAQIDD0ZDAg ABB4MC9kLvhkLCAAEHgwL2Q0LiBXLmQ7Do4ULmQ6Do4ULmQ5Do4ULmQ4KLABJLAAJKQAKKQBJBIY LrADL7AC/6QCIIACSbD+pAMgwAJAsAIIiABJigAIiAAJiigiHChkU/wSEiIAAFswCIgUKGRSCIgU -KGRRCIgU+GRQIKgCUbBYb2MrEhL6IHQqACBdsCq0WCkSE/eWOSICLoUgKFASDwIAZIVLFGxsgycE +KGRRCIgU+GRQIKgCUbBYb2crEhL6IHQqACBdsCq0WCkSE/eWOSICLoUgKFASDwIAZIVLFGxsgycE hCj6TAAAIAIY8Fqxmf1r9BIAAGEw/m1bEgAAWrD/IgAiAABQ8FqxT4MnDwIAIzwQ2jBapyL/AgAB /lYeoGAFiQAAAAAA8/nBYgAAEnCMHSrBILGqKsUgYAAMaITvjh0s4SKxzCzlIitkNf8SCiACEFAw KmTJKmTIih8pZDn7jBQACBBwMPxkNCoFAHuwKmQ4LjAEwfz4FhUv/hD7kIsYDWoI+7xsIAYQYDBY -by4oEhVj/AYAAAAAKxIR+iwAAAEQYDD7vBgiAABp8FskNWP5oR9sH59i/2xYEEQQcDCeY44tL/Jw +bzIoEhVj/AYAAAAAKxIR+iwAAAEQYDD7vBgiAABp8FskNWP5oR9sH59i/2xYEEQQcDCeY44tL/Jw Ce4R/BYBLgAgd/CP9y3Sf/0WAiBQEHAw/fIOIDIEcjDE7vwWASAeBHIw/BYBIFIQeDAvJAWIEo4T +A9GDEgBQDD4eEANgAQ7IP7cFA4JAGfw9YgRDUAEOyAMiAL4a/MeCQBH8A8/Agj/Ap9kH24NHG4A +FINL0AEO6D8ZgcuCQB7sJ5m/hIEIHgCQjD4ZQsgABBAMChlCi/gASzgACyUAC+UASjgAy/gAi+U AiiUAyzgBSjgBCiUBCyUBS/gByzgBiyUBi+UByjgCS/gCC+UCCiUCSzgCi7gCy6UCyyUCikhKilk -LQmJFClkLCggVy0WFChkOwiIFChkOgiIFChkOQiIFPhkOCAYEGAwWG7dIxIUixH8ChAgsAJRsFhu -2Rxr0/xmGiAIEGgwLWYbKyB0K2R0KhITG243J6Y5ii4pYhfAgPmcQCYAi16QHWwBLdJwCa4Rrt2N +LQmJFClkLCggVy0WFChkOwiIFChkOgiIFChkOQiIFPhkOCAYEGAwWG7hIxIUixH8ChAgsAJRsFhu +3Rxr0/xmGiAIEGgwLWYbKyB0K2R0KhITG243J6Y5ii4pYhfAgPmcQCYAi16QHWwBLdJwCa4Rrt2N 143eLNACKtAAJtAEK9ABJ9AF+GYRC4AEOqD70AYqCQBasPfQByYJADmw+KoRB4AEOaD70AMmCQBZ sPyqAgeABDmg+KoRBgkAObD7qgIGACAycPlrBnoAIFIwsaov0A0r0Akq1AMm1AcKjBQGjhQu1AYs 1AIm0A4q0AgMjBQOjhQu1AUs1AEOjhQu1AQu0AwMjBT81AArgAQ6oPzQCi+ABDug+6oCDgkAe7D/ @@ -5671,32 +5671,32 @@ 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 @@ -5708,43 +5708,43 @@ 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 @@ -5757,9 +5757,9 @@ gAQ5oAxmAghmEQpmArFmJpRjBoYUJpRiBoYUJpRhBoYUJpRgKVAF/wIADAGaSND/AgAMAZZaUCPi G9jg+VwAD/8QIDD4MxEACBBQMG2qDyuQNCqAZLGI+ZwBLgQSUtD4XAAACBBIMNMPbZoSKoA8KeBc se4PAgD4jAEuBApKkPMWASIAAEFw+goDIAgCSHDTD22qDyuQACqATrGI+ZwBLgQCUtAbZ0+4GPAL FwAVEEgwbZoCAAiKGmjl+hYCIKICWXD4IgAgAxBgMP86/yALEHAw/RQgIAMQSDD5FBstgAQ+IP8V -DCwJAHdw/RYDIEICUHBYaW8rXE78CgMgSgJQcFhpa/tncBAAEHgwLxQ7LxQ6/xQ5IAIQSDApFDgr +DCwJAHdw/RYDIEICUHBYaXMrXE78CgMgSgJQcFhpb/tncBAAEHgwLxQ7LxQ6/xQ5IAIQSDApFDgr slz+Ig0gAxBgMPkUOCCAAmhw/xYsIP4CUHD/FDsvkAQ7oP8UOioAIHbw/xQ5IHACQvDzCBYAkAJ4 -cPJfHgCAAnLw8Q4WAGICUrDyHR4AkAJa8FhpTy4SLPscCCIAAFCw/o4UAAsQYDD+FhQgAhBoMFv4 +cPJfHgCAAnLw8Q4WAGICUrDyHR4AkAJa8FhpUy4SLPscCCIAAFCw/o4UAAsQYDD+FhQgAhBoMFv4 TtEPL5BQJpBRDwIA/JBSL4AEP+AG/wL2kFMvgAQ/4Az/Agj/EQb/ArH/L5RTD48UL5RSD48UL5RR D48UL5RQKVAFKhYv+BYuJgEn3lD6Fi8gPxAwMPgWLiYC87ZQ+hYvIEQQWDD4Fi4mARfeUPsSLyIA AFFwWAMH+KwAAyQANqDaIPwSLiIAAFlw+A5HAAcQaDBb/s/7CooiAABRcFgCadEPLpBYL5BZCO4R @@ -5785,7 +5785,7 @@ ymsQHWYhLdF//wIAA/zDe1DaUFgBIdEP2iD7XAAAABBgMFv8mC5wfWXpZ/saciIAAFDwWAf70Q/a IPwSLyIAAFlwW/zOLxIvL/AC/wIAAgDSa9AoEi+Ig/8CAAH+Pu4Q2lBYAQ7RD9og/BIvIgAAWXBb /MLRD9og+1wAAAAQYDBb/IDRDwAAAAAAAPsSMSIAAFDwWAEujTcPAgCN3inQUCrQUfvQUimABD5g CpkC+tBTKYAEPmALmQIImREKmQL0Ei4gAgJKcCnUUwmJFCnUUvmJFAADEGAw+dRRIAoCITD5iRQC -AABZMPnUUCCcAlDwWGfg+hx/IgAAWTD6rDUgAxBgMFhn2ysSLRxnRhlmRAuLFCsWLYg8+YgBDAAI +AABZMPnUUCCcAlDwWGfk+hx/IgAAWTD6rDUgAxBgMFhn3ysSLRxnRhlmRAuLFCsWLYg8+YgBDAAI ZtAcZ0IMjAKcPGAACAAdZOINjQKdPNog+zwAAAMQcDD+NFQiAABh8Fv9ONowWApi0Q/aIPtcAAAA EGAwW/xKinhb/C3RDwAAANog+1wAAAAQYDBb/ET6fAAAARBYMFv7W9pwW/sZ+3IIIgAAUfBb+vnR DwAAAPsSLyADEHgw/1RUIgAAUXBYAZD4rAAAeQA2oNog/BIuIgAAWXD4DkcABxBoMFv9WPpcAAAA @@ -5793,45 +5793,45 @@ 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 @@ -5841,7 +5841,7 @@ MPkmrSAFEGgwC4AAKSKtCYlHyZ0qQDorQDsIqhELqgKxqipEOwqKFPpEOiAAEBAw0Q8AKCK2EmMl GWL5IiJ/CYgBCYgR/mNYEgAgQLCMLAMNRP3dEAwAQHMwDcwCnCwrQG4sQG8IuxEMuwKxuytEbwuL FCtEbtEPAAAAbBAE0w9tSg8nIAAkMACxM/R5DHACAhCwwCDRDwAAAAD0cwh//xAQMMAh0Q/RDwAA bBBAhDQSYub1YgYUcAEgMARECQxEEf5SZyIAICCwLS0CLdAAKlJwJCJ/Dt0I+d0RAAEQYDD9qggC -AABZMFhENy0wTC8wTf4xLiIAADKw9yKDLYAEP2D/3QIAARBYMP7PQABMAE+wZHSW9BZuIAAQEDCE +AABZMFhEOy0wTC8wTf4xLiIAADKw9yKDLYAEP2D/3QIAARBYMP7PQABMAE+wZHSW9BZuIAAQEDCE emVA8mUgaod5ZX/yYABfAAAAAAAAAPQWbiR0ADXgIgoAhHpkQEGMSs3HzyiESWVP9PwWBCA9ALSg YAAtziaMyGTP5orJZK/zbQgKKKE2fYEMiqtkr+Vj/+4AAAAAAPKsAA/cADagnBTMJod5ZX+xZCQb FGHPhS0kQnAJVRGlRIVIKTBUh0eMV/dyDiAAEFAw/MIOIABZBmBpklgtMS9u3woYY/7/AgAKAINq @@ -5852,87 +5852,87 @@ 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 @@ -5946,47 +5946,47 @@ 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 @@ -5994,12 +5994,12 @@ h4ZgaZK2YAUMZeRZKTBU/wIAAANThmBpkqLAxSxkVCswWPkKASgD94Lg/goBIAAQaDAJ7Thk0GEr MhkrZRkbWwwqMFqIbA8CAAp6QP6qEAgAQFowCogCKGYMKjBaG1lnCmpA+4gBCvAEOqD7W8oYCQBS MChmDCowWi9gBfuIAQoFAVAw8KoRAD0QWDD7ZAUoCQBSMChmDC9kMP0KASAAEGAwCdw4ZM8UKGAM GVkwFVmzJ2IWKZJ3JVKE82EZJ5AEPeD5WhcYACBKMPmIEQYAID1w+BwQJAAgRXDwCRcAEBBIMNMP -bZoCAAiKG1kiKlEp0w8PAgD/AgAH/2JekBxamI1g/mAFIAUQUDD/YFQgMhBYMFhlMRpZGPliACDh +bZoCAAiKG1kiKlEp0w8PAgD/AgAH/2JekBxamI1g/mAFIAUQUDD/YFQgMhBYMFhlNRpZGPliACDh EFgwKxQo+hYGIAgQIDD6WRMZgAQ+YPoWBCgJACZwmRUsYAcqUSn7WQ4cIAFgMADMEQyqAguqApoY D+ownxmZHR5aMv4WDCBAEEAwKBUXLWBULRRBLGAFLBRC+2AwIAEQaDAtFEArFEMqYhb6FhEgYAJQ cImliKSPo46i/KIBIKACWHCcsZ6yn7OYtJm1iqCasIlgKRYaKGBUKBRtL2AFLxRw/mAwIAAQYDD+ -FHEg8AJQcPwUbiBoAlmw/RRsIgAAYTBYXAL7bDwg/gJQcPqsASAIEGAwWFv9+3xyIP4CUHD6rAsg -BhBgMFhb+ftsTiD+AlBw+qwOIAMQYDBYW/T7bFwg/gJQcPqsFSAIEGAwWFvv/RFKKAYBGDDzqUAK +FHEg8AJQcPwUbiBoAlmw/RRsIgAAYTBYXAb7bDwg/gJQcPqsASAIEGAwWFwB+3xyIP4CUHD6rAsg +BhBgMFhb/ftsTiD+AlBw+qwOIAMQYDBYW/j7bFwg/gJQcPqsFSAIEGAwWFvz/RFKKAYBGDDzqUAK CwEYMP8RSyYJARww8x4UB7AEPeD/FTkuCQBw8PmqEQmgBD5g/2IMKAkAVnD+DkAEBQFsMPnuEQWw BD1g/z9UDgkAK7DzekAOCQB7sP4UdCwNAWgw+2BpLaAEOyD/YGgsDgFsMPndEQQFARww/1URDAkA azD/P0AMBgFcMPt+QAoFAVww/u4RDfAEP2D9/xEMCQB3cP/MAg4EARww9f8CDAkAazD8CjAqCQBm @@ -6015,19 +6015,19 @@ CooUKvQ+Y/sGK/A+LPA/CLsRDLsCsbsr9D8LixQr9D5j+uwAACzwPi3wPwjMEQ3MArHMLPQ/DIwU LPQ+Y/rQLfA+LvA/CN0RDt0Csd0t9D8NjRQt9D5j+rbaIFsE5tEPAC6gcLHuLqRwLjIbwcj47hEC AP8aYPo8AAIAAFmw9Pr/IAgQeDBt+g8vsDQtoGSxqvu8AS4BrGvQ+mwAAAgQQDDTD22KDy+gPC0w XLEz+qwBLgGl69D+FgAiAABRsP0cAAADEEgwbZoPL9AALqBOsar93AEuAahz0CtgBftkMCA9EFAw -KmQFY/olAAAA+zxFIP4CUHD6rCEgAxBgMFhbDygSLS8SKC6CGA+PFC8WKC2CGRxZdPsKLSAuEHgw +KmQFY/olAAAA+zxFIP4CUHD6rCEgAxBgMFhbEygSLS8SKC6CGA+PFC8WKC2CGRxZdPsKLSAuEHgw /eoIDAAgP3D9hhkhYQA3oBhXon2LbCkSKP8CAA387eZQY/nOK6BcLKBdCLsRDLsCsbsrpF0LixQr pFzaIPs8AAIAAGEw/VwAAgAAcbBb+Rtj+Z8ALKBcLaBdCMwRDcwCscwspF0MjBQspFzaIPs8AAIA AGEw/VwAAgAAcbBb/HBj+W8tMDgoMDkPAgD5MDotgAQ/YAjdAvgwOy2ABD9gCd0CCN0RCN0C/wIA -BgC+31D/AgAGALr/UC8SKP4WKyCoAljw+hYqLAArZ9DccFha1Nog+xIrIgAAYTD9XAACAABxsFv7 +BgC+31D/AgAGALr/UC8SKP4WKyCoAljw+hYqLAArZ9DccFha2Nog+xIrIgAAYTD9XAACAABxsFv7 KSkSLcCAKJYZY/kCK6BeLKBfCLsRDLsCsbsrpF8LixT7pF4j/KQCYPxgMCAGEGgwLWRULGQFY/nA -3HBYWsDRDy6gcbHuLqRxY/jDAC+gcrH/L6RyY/i3KKBysYgopHJj+KwAACmgcrGZKaRyY/ifLGRU +3HBYWsTRDy6gcbHuLqRxY/jDAC+gcrH/L6RyY/i3KKBysYgopHJj+KwAACmgcrGZKaRyY/ifLGRU +gpAIIYQWDD6ZAUiAABRsFv0o2P4hgAtEij/AgAN/EJnUC0wOCgwOfkwOi2ABD9gCN0C+DA7LYAE P2AJ3QII3REI3QL9FikgGARbcP8CAA/8JvtQGFoUKTEuLhYr+hYqL/94wlDaIPxMAACoAljw/VwA AgAAcbBb+u4cWP4tMDgoMDkqEir5MDotgAQ/YP4SKywJAEdw+DA7LYAEP2D53QIALRBYMPjdEQAu EHgw8/6gbAkAR3AAAAAA+xwQIgAAUbD8CgggAhBoMFsC0GP3zAAAAB9Z8isxLn+xeBhZ8i4WK/oW KiB4BELwKhItwJApphlj96cqMFr/AgAD/AdikP8CAAP8A2aQ/wIAAfv/apAKDEP8zP8gABBYMAy5 -OGP36AD8fAAAqAJY8FhaZx5Y0S0SKNMP/wIADfu091DaIPsSKyIAAGEw/VwAAgAAcbBb+rhj/5Qo +OGP36AD8fAAAqAJY8Fhaax5Y0S0SKNMP/wIADfu091DaIPsSKyIAAGEw/VwAAgAAcbBb+rhj/5Qo EiwvgHL//AEiAABRsP+EcifQEFgwWAEFZa94Y/coAAAAAAAA/fMGcgAAUTDAoWSsnmAADP3zBnIA AFEwwKFkrKssZFT6bAAAQBBAMPhkBSCGEFgwW/Q8Y/bsAAB/4wHAQWVP3GP8qABsEAYrIAeJJwsI QfSRLWBAAmJwKpkUZKEiipn+ChIhHQA2oI+gLaAwD49X/xYBJgFTd1ApoQgtOv/+CksmAV/uUCkg @@ -6038,8 +6038,8 @@ K5kUJVJ/9LH8YEACUnCImSaAB8Cw/FwAAgAAabBbBsCKJ9sw+qwgIgAAYTBbCimMIIsnCMwRDEwC /KYBIEACUvD7XAACAABhsFsKItEP0Q8AAAAAAADwDgcP/BBoMP5XrRAkBGnwiRAGaAJtmQIASGEr IAcLLUAK3RD8EgIsCQB3cJ1giSD/EgEgMBBAMPpW3xAwAmMw/GYDKYAEPmD6ZgIoCQBN8PlmASA8 BEPwiif7TAAAABBgMPqsICIAAGkwWwaXKyAH1aD7IQgsIAFYMP5ZRh0ABDsg/AoAKgkAZvCcZfwS -AioJAHbwm2QARY0CBo8uZgYsZgctIAzTD/psKC0ABD9g/GYHKgkAbvD7ZgQgqAJY8FhZwipcGfwK -AyB6AljwWFm+9Fd7EIICWPD8CgMgOgJRcFhZuRlW7i1QB44SLlULLCEHnVH/IAcvwAQ54PwMSg4A +AioJAHbwm2QARY0CBo8uZgYsZgctIAzTD/psKC0ABD9g/GYHKgkAbvD7ZgQgqAJY8FhZxipcGfwK +AyB6AljwWFnC9Fd7EIICWPD8CgMgOgJRcFhZvRlW7i1QB44SLlULLCEHnVH/IAcvwAQ54PwMSg4A IHGw+iEILcAEOyD/LUAOIAF8MPD7EQygBD9g/cwCCgkAWrD7VqQcCQAjMJzg/SIAKgkASrCa5Pvm AiAEEEAw+eYGIDAQWDD75gMgABBIMPnmBS2ABD9g+eYHLAkAR3D95gEgQAJjsAIFhgBMYwAFhgBM YRlWiwz4Ef8SACgAIEow/4Y5IgAAULBbAz3RDwAAABNXwSgiHiMyfwmIEfgzCAIAAFCwWwM22jBb @@ -6049,12 +6049,12 @@ AzXRDwDz/gZgABBAMPosAAIAAFjw/EwAAgAAaXBb/MfRDwAAAPosAAABEGAw/RIAIDACWjBbDohj oPlGAyYJAEGw9kYBIEACETACA4YAQmMAA4YAQmESVm4MfxGi/5Xw0Q8AbBAEKSITDwIA+FetHjYB TDD782dgAgJT8AoKQfiYAQqgBDqgCogC+CYTIGsANOAqIgcqrBBbB/P0Igcj6BBAMAgzKNMP+jwA ACACITBam4H9VdwSAABg8P5YtBIAAFqw/yIAIgAAUTBamzeCJyIsENogWpELaKEnwCDRDy0gVf4g -BSAFEFAw/FipEDIQWDBYYirAIdEP2iBb8a3AINEPANogWpEfElZfC6gR9KA5YgAgQLAM6jArIoWL -sLCi/LsIAgAAULBYZFAcVtMqwn/wIQQAARBYMAC7GguqAirGf1hkhcAg0Q8AAPoKByABEFgwWwiH -LCJ//CaDIAAQEDDRD2wQBhVXHYstKlJrCbsRq6qKqsmiK6xg/AoEIgAAUHBYWQqKEGAABQAaVfaa +BSAFEFAw/FipEDIQWDBYYi7AIdEP2iBb8a3AINEPANogWpEfElZfC6gR9KA5YgAgQLAM6jArIoWL +sLCi/LsIAgAAULBYZFQcVtMqwn/wIQQAARBYMAC7GguqAirGf1hkicAg0Q8AAPoKByABEFgwWwiH +LCJ//CaDIAAQEDDRD2wQBhVXHYstKlJrCbsRq6qKqsmiK6xg/AoEIgAAUHBYWQ6KEGAABQAaVfaa EB9V9I0nHlYX+vo4A+gQYDAMrCwDzCgOzCj8FgAgIAJTcFsHrYQQgyf6TAAAIAIY8FqbPf1VmBIA AGEw/lb/EgAAWrD/IgAiAABQ8Fqa84InIiwQ2iBakMdooQLRDwDaIFqQ5BJWJQuoEfSgNmIAIECw -DOowKyKFi7Cwovy7CAIAAFCwWGQVKlKT8CEEAAEQWDAAuxoLqgIqVpNYZEvRDwAAAAD6CgcgARBY +DOowKyKFi7Cwovy7CAIAAFCwWGQZKlKT8CEEAAEQWDAAuxoLqgIqVpNYZE/RDwAAAAD6CgcgARBY MFsITSwifywmg9EPAGwQEBtVuiwxJ/VX1RIAAGlwji4pIAcqUjr2MSYiAABBMPkJQQ+QBDug+8EP egAgcrAvITf/AgAOAi/j0CchNv8CAA4CKjmQjydk8PQr+RQpFhT08gkkUAA24JoemB/0FhAgIAJT 8FsHbi0gBf8SFCALEEAw/gpWI/8QSDD2CgcmAid3UC4hCBpVrfnpDAP/EGAw+YY5CcAEP+D2FhIk @@ -6064,9 +6064,9 @@ FgQiAABh8FsFU4on+qwgIgAAKfD8Eg8iAABY8FsIuowgix8IzBEMuwL7pgEjgAC1YNEPAP8CAAYC GoIgHVVTKRIS8A0HAgAAQTBtmQIASGEqIEEvIQccVpMKrQn3V3odwAQ/YPNVeBwAIGsw/MJ/L0AB fDD+ISIvwAQ/4PNVcR4JAB/w/I1CCsABZDD8fEANgAQ/YP7dFAoJAG7w9cwRDUAEP2D9CgAsCQBr MP0WBSsABDqg/0YAKgkAZvD7VVAaCQBasB9X3vwiACBYEEgwmUOXR/NGAiBIEEAw/UUKL0AEO6D4 -RQsgBxBoMPuqAgCQAliw+kYEIEACUTD4zBEOCQB7sP5GBiwJAGsw/EYBIAwQYDBYWFArLFz6VmoQ -iRBIMPlELCAAEDAw9kQ6IAAQeDD/RDkgABBwMP5EOCAYEGAw+kQtIC4QQDD4RDsgeAJRMFhYQB1X -u/5ASCAAEDAwJkRE9kUlIIoCUTD2RhQvhBB4MP9EPCACAnOw/kRIICgCWHD9FgUgAxBgMFhYMvtV +RQsgBxBoMPuqAgCQAliw+kYEIEACUTD4zBEOCQB7sP5GBiwJAGsw/EYBIAwQYDBYWFQrLFz6VmoQ +iRBIMPlELCAAEDAw9kQ6IAAQeDD/RDkgABBwMP5EOCAYEGAw+kQtIC4QQDD4RDsgeAJRMFhYRB1X +u/5ASCAAEDAwJkRE9kUlIIoCUTD2RhQvhBB4MP9EPCACAnOw/kRIICgCWHD9FgUgAxBgMFhYNvtV ExAAEEgwKURULCBoLERVLiE2LkUsLyE3+0UvIEIQUDAqRGQpRS4vRS0nIAXFhv8CAAYBYcXQxdAt JAUuIQgvOv//AgAGATh/kBtVGiYSEIkgHVXaF1VRLCEHLyAHKE0B+IyQLUABYDD/I0AOIAF8MPoz EAsABDvg/MwRDgkAU7DzzAIAMBBQMPfuAgAEEBgw/cwCDYAEPmD1YHViCQAfcBZXhfYWBiACEDAw @@ -6080,20 +6080,20 @@ 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 @@ -6108,43 +6108,43 @@ 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 @@ -6169,42 +6169,42 @@ D8DonhFj/usAAADz/EFgABB4MGwQDigxCBpQgyk6//8CAAYAdc4Q8AoXACACSHAACYoACYoACYoA CYoACYoACYoACYoACYobT48eT9+IIBpPjPoWBiAEEEgw/hYKKYAEOiD7FgQoCQBKMJgVLyAHLTEI Dw9BAP8RD90CDt0C/RYIIgAASPAM6jD8FgkgABBYMPsWCyBgAlBwAgmGAEpjAAmGAEphiyf8uRQt gAQ9YP6yCSwJAG0w/7EVIEACUvD9Fg0gOAA3IPTgMGCAAkMwePMM/AoEICACWHBbArPRDxxSDo0g -jzP+MgIgBBBQMPUWACAyEFgwWFt70Q/7HBAiAABQsPwKBCACEGgwWvrK0Q8AAABsEASFIBtSABNP +jzP+MgIgBBBQMPUWACAyEFgwWFt/0Q/7HBAiAABQsPwKBCACEGgwWvrK0Q8AAABsEASFIBtSABNP kSkiCiQhNfgydCAAEDAw/SIHKuABSDDzMoskACBZMPhVDAA9ADag9CA1b8AQWDAo3CD2Jgcv/xBg MPzWACgAQFow9tUUIIACQjAo1gn41gggAFqGoP8CAAIAZAKgKSYKd5cS+yxYIAAQUDBbYsBgAA8A AAAAAPoiEyAAEFgwW2K7liiWKZYqliuWLJYtJiYOJiYPJiYQJiYRJiYSJiYTJiYUJiYVJiYWJiYX -JiYYJiYZJiYaJiYbJiYcJiYdJiYeJiYf/FHPEAUQUDD9CmAgMBBYMFhbPP0KcCIAAFlw/SQFIAAQ +JiYYJiYZJiYaJiYbJiYcJiYdJiYeJiYf/FHPEAUQUDD9CmAgMBBYMFhbQP0KcCIAAFlw/SQFIAAQ YDD6MhEgARBoMFr+g/oyEiIAAFkw/AoAIAEQaDBa/n/RD48/+SIKIBACc3D+9gEgeAJA8JjTn9Ke P2P/O4s9+SIKIBACU3D6tgEgaAJg8JzTm9KaPWP/IAAAbBAGHFGxGE9cjyCNNfUgBSAFEFAw/jIE -IDAQWDD1FgAk4AFoMPkgBCNoAWww+RYBJPgBdDD1FgIiAABo8PQWAy4AQEOwWFsQFU8vKVJ0KFKF -o5MJMxH8UZ0SACAeMI0w/jAFIAUQUDD/MgogMBBYMFhbBcKz/AolJgDn3RD9CiQmAOPlEPZQ8hYA +IDAQWDD1FgAk4AFoMPkgBCNoAWww+RYBJPgBdDD1FgIiAABo8PQWAy4AQEOwWFsUFU8vKVJ0KFKF +o5MJMxH8UZ0SACAeMI0w/jAFIAUQUDD/MgogMBBYMFhbCcKz/AolJgDn3RD9CiQmAOPlEPZQ8hYA 3+0QaEEwaEIt+EMqYBUQcDB+QSLB9n9BHSgiGGSBtok4ZJG3KyAEZLG2jCdkwbmNOgbdAi02Co0/ yNvaMPsyECABEGAwC9AAiTr/AgACAJAiUIw+yMv7MhAgABBQMAvAAIk6GFF0JDE1IlKLK1J0hTDA YPhECArgAUgw+1UMAD8ANqD0MDdvwBBwMI03L/r/9jYHIEACY3D/1gAsAEBzMPbVFCCAAmMwLNYJ /NYIIABrhqD/AgACAHUCoCk2Cv8CAAAATl5Q+zxYIAAQUDBbYjWWOJY5ljqWO5Y8lj0mNg4mNg8m NhAmNhEmNhImNhMmNhQmNhUmNhYmNhcmNhgmNhkmNhomNhsmNhwmNh0mNh4mNh/8UUkQBRBQMP0K -YCAwEFgwWFq2+ApwIgAAWXD4NAUgABBgMPoiESABEGgwWv39+iISIgAAWTD8CgAgARBoMFr9+cAg +YCAwEFgwWFq6+ApwIgAAWXD4NAUgABBgMPoiESABEGgwWv39+iISIgAAWTD8CgAgARBoMFr9+cAg 0Q8AAAAAAAD6MhMgABBYMFtiD2P/ZAAA+jIIIAAQWDD8CgAgAhBoMFrtUMAg0Q8Aiy/5MgogEAJT cJqx+9YCIHgCYLCc05ovY/8Zjy35MgogEAJzcJ7x/9YCIGgCQLCY054tY/7+AAD9TAAABRBQMPxR -IBAwEFgwWFqLwCDRDwAjJhhj/kKSOGP+QsGYKSQEY/5AWvHZiyCboJonY/45AGwQBBtOlRpRE/lR +IBAwEFgwWFqPwCDRDwAjJhhj/kKSOGP+QsGYKSQEY/5AWvHZiyCboJonY/45AGwQBBtOlRpRE/lR ExAAEGAw/igRAAUQaDD6iggAARBwMPs0AggAIEow9IYAIAAQeDBbAKTSoNEPbBAEIyRy+iwAAAEQ WDBbAxXaIFsDotKg0Q8AAGwQBIoqGVEAHE5x+ApyIGQACrArIAUJqQH6CnAoAEBmcPkmCiA4BELw erEU+iIIIAAQWDD8CgAgAhBoMFrtDtEP0Q8AbBAIHFDxJCIYAGWOIyAHL0IILUAE/kIAIAUQUDD/ -8gAiIAEcMPMWACAwEFgw9hYBJOABLDBYWk76LAAAEBBYMP0cECIAAGDwWwhNZKCHHFDfiyDA0f2k +8gAiIAEcMPMWACAwEFgw9hYBJOABLDBYWlL6LAAAEBBYMP0cECIAAGDwWwhNZKCHHFDfiyDA0f2k CSoJAGbwm6AaTmEMORH4EgQoACBWcJiQ+yAiIgAAULBa/UWOSvsKciB0EHgw+kAFIAAQYDD8JCMg QAALsH+hGGhSN4onwLH6rCAgARBoMFr99sAg0Q8AAAD8CnAgPARasHyhFvpCCCAAEFgw/AoAIAIQ aDBa7NrAINEPwCDRD9og/FC+EgAAWbBbCAnAINEPAGwQBhxQuv0iACIAAHkw/iAEIAUQUDD1FgAg -MBBYMFhaGhxQsy0yBC4wFy8yBvgyByAFEFAw+BYAIDAQWDBYWhIpIATBqPsgIiCuBFJwyLjaIFr9 +MBBYMFhaHhxQsy0yBC4wFy8yBvgyByAFEFAw+BYAIDAQWDBYWhYpIATBqPsgIiCuBFJwyLjaIFr9 FMCwKyQjKjAF+wp2IHQQYDD9CncggARisPrSLnAAEBAw/gpyLAATWpD/CnAgPARysH+hFvoyCCAA EFgw/AoAIAIQaDBa7K3AINEP0Q8jIhhj/6YAACs0BfskBSAAEBAw0Q8AAABsEAQkIhgfTi6NNBxQ -jPoKBSAwEFgw/jAXLABAf3BYWewoMBfCmnmBF/sgIiIAAFCwWvzuwKD6JCMiAABRMFv/d8Ag0Q8A -AABsEAQkIhgfThwtMgQcUHv6CgUgMBBYMP4wFywAQH9wWFnaKjAX+QokICUQQDAPAgD7rAAGAFfG +jPoKBSAwEFgw/jAXLABAf3BYWfAoMBfCmnmBF/sgIiIAAFCwWvzuwKD6JCMiAABRMFv/d8Ag0Q8A +AABsEAQkIhgfThwtMgQcUHv6CgUgMBBYMP4wFywAQH9wWFneKjAX+QokICUQQDAPAgD7rAAGAFfG kPxNyhYAU86QiUomCiP+ChQgHxAoMPydAgAOAIZwLUYK+UAFJgBKdpDB/v8CAAADEGAw/wIABgBF fpD1oXJwIRBAMHihavahZ3//EGAwKgp0epERjU/I3PtCECIAAFEwC9AAKzAXdbFC/lBPEH4EMvAr IhiNSiuwdPwKjiwAQHdw/UYKICgIYvDAw/wkZCAAEBAw0Q8AAAAA+iwAAAAQWDD8CgAgAhBoMFv/ TcAg0Q8A8/+ZYAQQYDDz/5FgAhBgMGP/iQBsEAYiIhhkIHAcUD2IKI0gLyAFjoD4gAUgBRBQMPgW -ACAwEFgwWFmZLiAFKQpz+gp0IJgES7D7CnYg1ARTsPwKciBKCFuw/QpwIDoEY7B94RX6IgggABBY -MPwKACACEGgwWuw7LiAF/SIAIAUQUDD8UCUQMBBYMFhZhcAg0Q+NL48oLgp1LiQF/vQFIBEAN2Da +ACAwEFgwWFmdLiAFKQpz+gp0IJgES7D7CnYg1ARTsPwKciBKCFuw/QpwIDoEY7B94RX6IgggABBY +MPwKACACEGgwWuw7LiAF/SIAIAUQUDD8UCUQMBBYMFhZicAg0Q+NL48oLgp1LiQF/vQFIBEAN2Da IPsiECABEGAwC9AALiAFY//DAIkoKAp3KCQFKJQFLiAFY/+xAAAAAAAAAGwQBCggcsCUCYgC+CRy IgAAULBbAqLSoNEPAABsEAYrIA0mIAccTusdTU/6IAwm4AEsMPnCRCYgATAw/tJ4INkANuAfTqGv ry/w3av/r+4J7hEOmQgpnID5FgIiAGaB4IgiZYEKKpANZKBCGk7aKqCA+E5GG4AEOqAKBUcOVRGo @@ -6212,19 +6212,19 @@ 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 @@ -6233,8 +6233,8 @@ ACBN8C1yCiyyAyJyC/SAKmwAQE9wf8cFGEvBCN0Ce8cFKQqACd0CfMcExIAI3QJ9xwIF3QJ+xwIG 3QL4Ov8pMAFkMPiRDXAAEGAwfzsSYAARAAAAGUwJwMH53QIKAAN80MBwGE0KGU25w/ovhhAihhHD +y+GEC2GEYiA+D8RCABASjD/TWMYCQB6MAWIAg+PAgz4OR9M/ZjwH0zk+Uz7GABASjAPiAL4lgAg CAA14J16knuJsB9L4HmWPC/yei3i3aP/Cf8Rr92N2g0MWQDMEQTIAv2MOgAOAGNwBswCedcEwIgI -zAJ61wTAlAnMAnvXBMDSDcwCnLPAwFhWBcAg0Q8AAPP/82+5EGAwbBAEiTD6XAACAABY8PxOiRBQ -AKpweZYXj8CIwZizn7KNwo7DnrWdtIjFicSZtpi3wMBYVfTAINEPGUtwKZKucZYH8//sb7kQYDCJ +zAJ61wTAlAnMAnvXBMDSDcwCnLPAwFhWCcAg0Q8AAPP/82+5EGAwbBAEiTD6XAACAABY8PxOiRBQ +AKpweZYXj8CIwZizn7KNwo7DnrWdtIjFicSZtpi3wMBYVfjAINEPGUtwKZKucZYH8//sb7kQYDCJ MgnJU2+SLf8aDCBKAD5gibKNs53BmcCPtIi1mMOfwo22jreexZ3EibBj/50AAAAAjjN/6Nnz/65v 6hBgMGwQBBlM9xpNVxhOHPdLYBcgARAw+mYCAAAQEDD2lvsgChAoMNMPbVoNKpL7CKsB97EIcAIC ELDHINEPCq1J/TYALSABUDD8RgAgABAQMNEPbBAK/UuUEgAAeLAs8A31FgUiAAAQ8PvwDCHgAjNw @@ -6253,7 +6253,7 @@ cPh2ACBqADfgL/z2blJ0LBIIDKwIDAxJ+cwCAAoQQDD8RvsgABBgMG2KFSJC+w4mAf8CAAACAmMw /wIAB/+7bZD/AgAP8BBgMP8CAAf/s22QY/9xAAAA/woAIAgCOfD/dgAgABBIMPP/fmAUEHgwGUyF +AoAIAgCOfCYcPP/jGAUEHgwaVFogheIGBxMfgioCAgISfyIAgAAEFgw+Eb7IAoQYDBtyg0sQvsO yQH9kRBwAgJa8PAAG2/wEGAwAAAAAAyrSfsWACsgAWAw+hYBIAAQYDDyFgcgGAC3II4QjXAA8QQA -7hryFgcsCQB3cJ1wihWLF1hU6cAg0Q8AAAAA8/6ZYBQQeDAp0nermQmZEfP8mWgAIEzwAAAAAJ8S +7hryFgcsCQB3cJ1wihWLF1hU7cAg0Q8AAAAA8/6ZYBQQeDAp0nermQmZEfP8mWgAIEzwAAAAAJ8S nhT9FgMh/sqc4PenCAIAAFhw+nwAAAgCYHBb/vmDUABgBAMDGfMDSQIAAGKw8xYAIRkAtqAoOv94 MROJE/8CAAoAhMzQixT/AgAKAH+e0I0R/H4QDWAEP2AO3QINPQItRvtj/TWbJGP9XJ8S8/0rYAAQ YDAAAAAAAADyFgch/6qc4JYYkhdj/uAAAJ8SnhT9FgMiAABR8PwcBCIAAFhwW/7YjROLUI4UjxL7 @@ -6267,22 +6267,22 @@ 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 @@ -6301,13 +6301,13 @@ KsAWLQr//wIABgBrbpCaMcCg8/+IYgAAGrAAAAAAAAD/AgAMAIYZoPs8AAIAAFCw/EwAAgAAaXBb RyrEFmP/iQAAAAAAAAD+IA0gbAA1IPkhCCCSADegLiETDp4MnjFj/3QuIA1k4GHZsIsvKvJxqbkK mQr5kgAgWgA1IPmRCCBqADegLCETDJwMnDFj/0dlXwfz/0Nv/xBQMIksCbkMY/8HAAAAAADz/ypv /xBQMPP/EWD/EFAwKiETizEKvAwOyzirqiolCGP/DIksCbkMY/+XKiETizEKvAwOyzirqiqVCGP+ -8ZkxY/7smTFj/ufz/0Fg/xBQMMY6HEraLiANLSAM9BYAIgAAebD1FgEgAhBQMPMWAiASEFgwWFQZ -0jDRDy4gDRxK0C0gDPQWACACEFAw9RYBIgAAebD7FgIv6hBAMPgWAyASEFgwWFQN8/6Ib+oQUDAA +8ZkxY/7smTFj/ufz/0Fg/xBQMMY6HEraLiANLSAM9BYAIgAAebD1FgEgAhBQMPMWAiASEFgwWFQd +0jDRDy4gDRxK0C0gDPQWACACEFAw9RYBIgAAebD7FgIv6hBAMPgWAyASEFgwWFQR8/6Ib+oQUDAA AGwQBBZIRYIwF0rD9EApYgBAMLD5Gh0qAAUR0BhKv3KLHiQt8CRM+PZKvRoAB8kQBkYKhmAKYAAA yVXGKtEPAAAYR+OoKIiA+DYBIAAQEDDRD8cv0Q8AAABsEAQeR42LMP9KsBABEGgw/EqhEDIQQDD7 ClcCAAAwsPirD3AAEBAwGUqpCakKiZAKkADGKtEPZEOFK2AhKmAgCLsRC6oC+jYBIAAQEDDRD2RD yCpgdiwK//8CAAYCUeaQ2aD5NgEgABAQMNEPGkh/KWAN+63tI3MANSBkk+0kon+PYAT/DA9UFA5E -EQTkDCRNB/RCJSiAAXwwAJEE8NgaAgAAWLD8SWAUAEBBMPTUOQAFEFAw/fwAAgAAcTBYU8T0NgEg +EQTkDCRNB/RCJSiAAXwwAJEE8NgaAgAAWLD8SWAUAEBBMPTUOQAFEFAw/fwAAgAAcTBYU8j0NgEg ABAQMNEPAAAAAAAAAGRPXihgDWSDv/I2ASAAEBAw0Q9kT0spYA1kk8LyNgEgABAQMNEPZE84KmAN ZKM38jYBIAAQEDDRDwAAAAAAZE8gK2ANZLM58jYBIAAQEDDRD2RPDSxgDfliCyOUADcgsJ39NgEg ABAQMNEPZE7zLmANZOOK8jYBIAAQEDDRD2RO4C9gDflhEiODADfgsJj4NgEgABAQMNEPZE7GKWAN @@ -6320,34 +6320,34 @@ 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 @@ -6355,38 +6355,38 @@ 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 @@ -6396,14 +6396,14 @@ FgQoCQBA8JgQ/SIAKPgBQDAHiAoogsQP3Qz43RECAABRsP7dAgIAAFhwC4AAhREFhUcFBQb2URVi AABIcAAEiwBJYQBJYQBJYQBJYRhEUBlF3/5FaxACEGAwnBGZE/7ifygJAEDwmBD9IgAo+AFAMAeI CiiCxP7dDAIAAFGw+N0RAAUQcDD+3QICAABYcAuAAIURBYVHBQUG9lDLYgAASHAABIsASWEASWEA SWEASWEYRCoeRVMZRcaZEf7ifygJAEDwmBD9IgAo+AFAMAeICviCxCIAAFGw/t0MAgAAWHD43REA -BRBwMP7dAgABEGAwC4AAhREFhUcFBQZmUILSMNEPAI0g+goCIAAQWDD8RbESAABw8FhO0NIw0Q+N -IPoKAiAAEFgw/EWsEgAAcXBYTsrSUNEPjSD6CgIgABBYMPxFpxIAAHFwWE7E0lDRD40g+goCIAAQ -WDD8RaISAABxcFhOvdJQ0Q8AjSD6CgIgABBYMPxFnBIAAHFwWE630lDRD40g+goCIAAQWDD8RZcS -AABxcFhOsdJQ0Q8AAGwQBPQgXWPwARQw9AogICAANOACiFfKggLJU8qYAupR9KAwYf4CWTACtDvS +BRBwMP7dAgABEGAwC4AAhREFhUcFBQZmUILSMNEPAI0g+goCIAAQWDD8RbESAABw8FhO1NIw0Q+N +IPoKAiAAEFgw/EWsEgAAcXBYTs7SUNEPjSD6CgIgABBYMPxFpxIAAHFwWE7I0lDRD40g+goCIAAQ +WDD8RaISAABxcFhOwdJQ0Q8AjSD6CgIgABBYMPxFnBIAAHFwWE670lDRD40g+goCIAAQWDD8RZcS +AABxcFhOtdJQ0Q8AAGwQBPQgXWPwARQw9AogICAANOACiFfKggLJU8qYAupR9KAwYf4CWTACtDvS QNEPACIR8//dYBAQIDAAAAgiEfP/1WHwAiEwDCIR8//PYfgCITAAAA4tEfxM/SH8AhEwDcI70Q/A INEPbBAEEkIwIiLY0Q8AbBAEgieCLoMogiejIrAi0Q8AAABsEASCJ4IugifRDwBsEAQSQiUiItfR DwBsEAQl+sAFJQEkURWlRCRNAfMmASGAAiEwlCDRDwAAAGwQBIIngi6DJoIloyKwItEPAAAAbBAE -gieCLoIl0Q8AbBAEG0VbJDx/BDoUC6oB+qwQIBAQWDBYmWIjpQLzpQMiAAASsPR8FAAAEFgw+6UF +gieCLoIl0Q8AbBAEG0VbJDx/BDoUC6oB+qwQIBAQWDBYmWYjpQLzpQMiAAASsPR8FAAAEFgw+6UF JMABGDD8pQQgIAJisPymACAoADUg+kwAAAEQaDBa7WForhX6TAAAABBYMPwiACABEGgwWu1caa7p 0Q8AbBAEF0H19kVAFeAEPKCnV/N2BCQAIDVwJFZ/0Q8AAABsEAQZQ02JkBpD/PhDSxgAQFZw+SIC ABAQIDAEJAKUgBNFMxRD9/NDRBIJABiwBCIB8jYAIAAQEDDRDwBsEAQYRBEaQz0ZQicmgiEdQ+sp @@ -6420,36 +6420,36 @@ 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 @@ -6460,32 +6460,32 @@ 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 @@ -6496,41 +6496,41 @@ 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 @@ -6538,37 +6538,37 @@ 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 @@ -6582,7 +6582,7 @@ IiJL0Q8ADCIRooIiIkvRDyJwNnkhmGgpLHohAmkqj8AiAjIKCCIKIiJL0Q/AIgIyCggiCiIiS9EP wCECMgoIIgoiIkvRD8AhAjIKCCIKIiJL0Q8AAABsEAgaOcIpooIcOD3+CgsgCRBoMPuifSGMADZg orsJuxELmwgqsCMERQn5CgAiAJ0KoGahMiqwLNMPaKIaaKUX/wIABADGgqD/AgAAAMoGoP8CAAQA ygKgpZUMVQolUmvaIPtMAAIAAGDwW/+r9jpyGgEBJDD0CEAL4AQ+4PQnFAgJAFow8ncRCYAEOiD4 -dwgIIAEsMPZ2CAIAi4Dg+RYEIAB3rqDdIPUWACIAAHkw/Dt+EAUQUDD7ChgiAABw8FhEdhk6Xql5 +dwgIIAEsMPZ2CAIAi4Dg+RYEIAB3rqDdIPUWACIAAHkw/Dt+EAUQUDD7ChgiAABw8FhEehk6Xql5 j5saO3j1qEIKLQEsMPS7EQmABDog+4gCDgBAV/AI/wKfmy2SHB87cQV+QvfuEQwAQH9wDt0CLZYc KpInxsD1K0QKAEBisAuqAiqWJyhtBIiAHDtnihQbOP/8qhEIAEBiMAqIAvptBCgJAFowmKAukh8f OhgP7gIulh+MksDRDcwC/JYCItgAOOCMmMDRDcwCnJiKmMe+C6oBmpjRDwAAAAD/AgAH/2TukPuq @@ -6591,13 +6591,13 @@ Umtj/q/z/ulgABBIMNEPaDVKaDc/aDgFaDk5fjE28/6LYAAQSDAosDb/AgAP/zhqEGP+eADz/nRg ARBIMCqwNmip8f8CAA//M3KQ8/5eYAIQSDAAAPP+VGACEEgw8/5MYAEQSDBsEAbaIPtMAAIAAGDw W/8+wHH4OgUaAQEkMPQJQAvgBD7g9CUUCAkAXnDyVREJgAQ+YPlVCAIAADKw96ASZAAgRXAsUoAd Oc0NzAEsVoDRD90g/jwAAgAAeTArUoAcN6wMuwIrVoAoUoAaOxAZOKgKiAH8Ow0YCQBKMPhWgCAY -EFgw9hYAIAUQUDBYQ/8q+sApUoP2q1EP8xBgMP67EQgAQGZwC5kCKVaDL1KIxoD4/wEIlQEwMAj/ +EFgw9hYAIAUQUDBYRAMq+sApUoP2q1EP8xBgMP67EQgAQGZwC5kCKVaDL1KIxoD4/wEIlQEwMAj/ Ai9WiC5Sifb/RQ4AQFOwD+4CLlaJLVKK9p5FDABAV3AO3QItVoorUo3HyPy7AQxGATAwDLsCK1aN KVKM9ghFCABAVnAJiAIoVowvUoIH/wIvVoItUoLH7g7dAS1WgtEPbBAEGzrlGDnCGjrkHDdz8AAP YAAQMDAAsWb/AgAIAEOBoABgBAIEG39H7G8zC8g4wHLwABJgABAoMGg4Amk7ZPcKACABECgwBhRA 9g9ABeAEOSD2LhQOCQAn8PLuEQ+ABD/gr+4I7ggt4oAKXxH/fwIMAEBXcA/dAgvdAi3mgAnqMCXC MQlVCQnqMAlZDGqRhm0IDQnqMAlZDP8CAAH/vSZgY//r0Q8AbBAEhSeFXi5SJf88AAAEEFAw9CAi -IBgQWDD8OrcQAgJzsP5WJSAAECgw9SRuIgAAaTBYQ6XaQPsKACAAEGAwW/55KyIfi7dksAoCKgIL +IBgQWDD8OrcQAgJzsP5WJSAAECgw9SRuIgAAaTBYQ6naQPsKACAAEGAwW/55KyIfi7dksAoCKgIL sABgAAMAAMCgZqEDHzepAkoRr68u8oAYOi0I7gEu9oAL6jAcNy8pwjEtwjENmQoLmQkN6jANnQxq 0RBtCAgI6jAImAxqgQRj//AAAMDXGDeMqKouooAfN6UP7gIupoApwoMJi1Jotxv5CgYuFgFMMA/Z OSuigsfgDrsBC5kCKaaCKcKDCbhSaIcfHzluLgpw+wpgLgBAfnAP6zksooIt+g8NzAEMuwIrpoIc @@ -6614,17 +6614,17 @@ DABBBAA6GgBBBPDbGg//EGAwDLsDC5kBCpkCKebAKnJ7KWLcCaoRqpklkDf7CggiAABSMA+6OQpV AiWUN2P+/wAAZD9IwCBtCC0rkHwsYtwAIAQLCxv+cnsgKAB+8K4uCe4RrswtxG0txGYjYiKxIv8C AAv/jRiQY//LAAAA9awAC/+7lqAk4oQAoQQAORoAoQTw2hoP/xBYMAuqAwpEAQlEAiTmhGP/dGUu HmP+3gAAAGwQCvdcAAIAADCwC+owGDfFKIJ//wIACgE6RtAeOc4dNlkaN8Ai4gEt0jErpn/6on4g -ABBgMFhDQx02Uh85xy3QwfK1DAABEHAw/vQAIBQAc3AuMABo4yvH/v9vAQA4EEAwePEeyXvApfw5 -vBAIEFgw/zAAIgAAaTD1FgAiAABxsFhCpigKE/8CAAoAtKoQFzY/DwIAJna9GjmyGzY//QpkIAAQ +ABBgMFhDRx02Uh85xy3QwfK1DAABEHAw/vQAIBQAc3AuMABo4yvH/v9vAQA4EEAwePEeyXvApfw5 +vBAIEFgw/zAAIgAAaTD1FgAiAABxsFhCqigKE/8CAAoAtKoQFzY/DwIAJna9GjmyGzY//QpkIAAQ YDD+CgogAxBIMPl2viAAEHgwWujIHTea8qwAAdwANqD1FgYgABBIMPMWBSE1ADUg1ZD2FgQsAAEw MPwWByH+Alkw+xYIIAMQGDDwABJgARAwMAAAAAAAAPYKASBSADTgjRgPAgD+EgcqAAPtUCYKAPTg eWPwBDmgGzYf8na+IAAQYDD4OY8QZBBoMPo5jBAKEHAw+BYAIAAQeDBa4j3yrAAAnAA2oGYgxrFV -dFOpHTd0FDl/C+owKdJ//wIACgC7TtAeNgcu4jEr1n8q0n78CgAiAABrsFhC8ptB+kYAIO0ANOAY +dFOpHTd0FDl/C+owKdJ//wIACgC7TtAeNgcu4jEr1n8q0n78CgAiAABrsFhC9ptB+kYAIO0ANOAY OXTA8C+EANEPiBUPAgCliCiAACh2vRo5cPs1/RAAEGAw/woBIGQQaDD5OWweCQB8sP92viAKEHAw +RYAIAAQeDBa4hryrAAPegC2oCtyvv8CAAP/t4bQYAAuihX5cr0qACAqsCmkAGP/VwAA+zlcEBQQ UDAFqgxa4jxj/okUOVPz/0xgAxAYMAAi+rkcOVWPFY4UjRYv8ACWEvUWASAEEFAw/RYAIAgQWDDy -FgMiAABpMFhCOIgYeFNssDMK6jAbNc8psjErsjELmQoKmQoK6jAKmgxqoQgM6jAMnAxrwfbz/pBg -ABAoMMCh/Dk+EAgQWDBYQigeOTbA0P3kAC/7EBAw0Q8YNyYvgn6x/y+GfmP9gQAAKHK+/wIAA/8Q +FgMiAABpMFhCPIgYeFNssDMK6jAbNc8psjErsjELmQoKmQoK6jAKmgxqoQgM6jAMnAxrwfbz/pBg +ABAoMMCh/Dk+EAgQWDBYQiweOTbA0P3kAC/7EBAw0Q8YNyYvgn6x/y+GfmP9gQAAKHK+/wIAA/8Q hhDz/hlvuRAQMMCgKna9GjkrGzW4/QpkIAAQYDD+CgogARBIMPl2viAAEHgwWuhBY/9pLNJ+scws 1n5j/oIAbBAGFzWnKAr/8CEEBgCgxJDzOR4aACA4sPqg3CABEHgwAPsaLTCA/nDcKmABXDD7FAAg CRBYMPoKRAYAXOyQLHDdDg5E0w/8DEQGAIbfkChw3v8CAAYAl18QCAhE+XDfJgCb3hAJCUT/AgAG @@ -6639,7 +6639,7 @@ Aw2qAQqZAinmwGP+ryniwAtYDACBBADKGgCBBAD9GgTdAw2ZAQqZAinmwGP+swAAAAAAAADz/1Ji AABj8PP/XmIAAGPw0qDRD2wQBBo1Fg8CACigwSz65/0ahyAAEFgw/IducA4QSDDBlG2aDy6hcAzu Af3hCHAEAlKwsbvHuxk1IP+7J2ABEGAwL5KFALEEAMgaCP8BD885zvfBnPkkLCAAEBAw0Q8AAAAA AAD6ksEh4AJy8ADhBADNGg2qAQrKOWSv1i8gIvIKACA6ADfg0Q8AKCAjxPD5gY1wFBBwMC0gIv/d -AgAAEFgwbeoPKKFwDIgB+NGIcAQCUrCxu/P/fm/7EFgwwKT8OGMQGBBYMFhBS8Ag0Q8AAABsEA4q +AgAAEFgwbeoPKKFwDIgB+NGIcAQCUrCxu/P/fm/7EFgwwKT8OGMQGBBYMFhBT8Ag0Q8AAABsEA4q Ih3AMCMkLimhAyihAv8CAAYBRs4QHDg3HzUpHjUpFzV5lxaeEJ8SLyAiHThU/RYJLAkAY/CcGCkg K/kOQABEAH5wfpcafZcXfJcULSEgDQtF8AATaoAEPuAAAAAAAAAA/SEgIAAQWDD8CgAgDwA3oH6X B32XBHyXAcDBGTcb/WhABAcBaDD2NdgSAABo8PQhHiwFACZw+TTFEgAAcPAIbjn0eEACAAAw8PiW @@ -6652,3528 +6652,3528 @@ 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 -AAAABgAAAAMAAAApAAAAAQAAABwAAAAcAAAAUAAAAAEAAAACAAAAZAAAAHEADj3VAAAACQAAAAYA -AAADAAAAKgAAAB8AAAAfAAAAHwAAABAAAAAAAAAAAgAAAGYAAAByAA7VvgAAAAoAAAAJAAAABAAA -AGoAAAACAAAAHAAAABwAAAAQAAAAAgAAAAAAAABmAAAAdwAPQkAAAAAKAAAACQAAAAQAAAD9AAAA -AgAAAB0AAAAdAAAAUAAAAAIAAAACAAAAZgAAAHcAD7xSAAAACgAAAAkAAAAEAAAAKQAAAAEAAAAd -AAAAHQAAAFAAAAABAAAAAgAAAGsAAAB4ABBGBAAAAAoAAAAJAAAABAAAAGoAAAAfAAAAHgAAAB4A -AAAFAAAAAgAAAAIAAABrAAAAeQcAOwACADgABAM7AQAAAAABNgFsAZYA8AEgAVMA4QExAWEAvADk -AQsA9QEiAUkAxgDrAQ8AwgDqARMAnQC/AN4AywDtAQ0AqgDJAOQAowDEAOAAgQCiAL0ArwDMAOMA -lACwAMYAiwCoAL8AAACBAJ0AmgCzAMcAgQCbAK8AbgCPAKUAAAAAAAAAiQCfALEAbQCIAJsAAABh -AHIAAAAAAAAAegCPAJ8AAAByAIcAAAAAAAAAAAAAAAAAAAAAAAAAAAD7ASYBagDZAP8BNgDuAS4B -jACrANMBEwDWAPkBKgC5ANoBCgC3AOIBMACMAK0A4QC6ANkBBgCiAL4A5wCWALcA6gBlAIwAugCk -AL8A5gCOAKgAzQB6AJgAwwAAAAAAlACRAKoAzQB7AJUAtwAAAHoAowAAAAAAAACAAJgAuABkAIEA -owAAAAAAfQAAAAAAAABtAIYApQAAAGYAjgAAAAAAAAAAAAAAAAAAAAAAAAAAAQABKQFVAM4A8wEV -AMcA7gEWAKEAwwDgAM0A7QEMAKsAygDjAKIAwQDdAH0AngC3AK0AyQDfAJMArQDBAIYAogC5AAAA -AACLAJcArgDAAH0AlgCpAEwAgQCZAAAAAAAAAIUAmgCrAGIAfwCTAAAAAAAAAAAAAAAAAHYAiQCZ -AAAAVgB5AAAAAAAAAAAAAAAAAGYAegCJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3wEDATEA -vwDfARAAvADkASwAjwCvAOIAvQDcAQcApAC/AOcAlgC2AOYAVwCGALQApAC/AOQAjgCmAMoAdgCT -ALwAAAAAAAAAjwCnAMgAeACRALIAAABtAJkAAAAAAAAAfACUALIAWgB6AJgAAAAAAAAAAAAAAAAA -ZwCAAJ4AAAAAAIEAAAAAAAAAAAAAAAAAAABqAIoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADb -AQABGwC3ANcA8ACwAM8A6ACQAK4AxgCzAM4A5ACZALIAxgCNAKcAvAAAAAAAjQCZAK8AwACAAJcA -qQAAAHwAlAAAAAAAAACFAJkAqABaAHsAjwAAAAAAAAAAAAAAAAB0AIcAlQAAAAAAAAAAAAAAAAAA -AAAAAABhAHUAgwAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAMwA6wEYALIAzwD2AKkAzAEAAIIAoQDKAK0AyADtAJgAsQDVAIMAoADHAAAAAACWAJUArQDO -AIAAmAC5AAAAdQCdAAAAAAAAAH8AlgC0AFUAfQCfAAAAAAAAAAAAAAAAAGYAgACdAAAAAAB9AAAA -AAAAAAAAAAAAAAAAYgCGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAP/w//D/wA/w/4CdsP8A+lD+AJmQ/AAJkPgAAADwAAAA/8D/wP+AX8D/APtA/gBbQP -wAC0D4AAAA8AAAAMAAAAD8AAAA7AAAAPgAAADoAAAA8AAAAOAAAADAAAAAEAAAAAATiAAABoKgAA -TiAAAYagAAGGoAACCNUAAgjVAAAAKAAAADIAAQRqAABoKgAASmcAAYagAAGGoAACCNUAAgjVAAAA -KAAAADIAAVsBAABoKgAAUCAAAgjVAAGGoAACCNUAArZxAAAAJgAAADIAASluAABoKgAATSkAAgjV -AAGGoAACCNUAArZxAAAAJgAAADIAAQRBAABoKgAASmcAAgjVAAGGoAACCNUAArZxAAAAJgAAADIA -AXQGAABsgQAAVAEAAosKAAII1QACiwoAArZxAAAAHgAAAC0AAUWFAABsgQAAUWEAAosKAAII1QAC -iwoAArZxAAAAHgAAAC0AASFaAABsgQAATuoAAosKAAII1QACiwoAArZxAAAAHgAAAC0AAQRqAABs -gQAATJcAAosKAAII1QACiwoAArZxAAAAHgAAAC0AAYagAABvmwAAVs4AAosKAAII1QACiwoAAw1A -AAAAHgAAACgAAVs4AABvmwAAVHUAAosKAAII1QACiwoAAw1AAAAAHgAAACgAATiAAABvmwAAUjwA -AosKAAII1QACiwoAAw1AAAAAHgAAACgAARwYAABvnAAAUCEAAosKAAII1gACiwoAAw1AAAAAHgAA -ACgAAWx0AABy4wAAV2MAAw1AAAKLCgACiwoAAw1AAAAAGwAAACMAAUtSAABy4wAAVVgAAw1AAAKL -CgACiwoAAw1AAAAAGwAAACMAAS+2AABy4wAAU2UAAw1AAAKLCgACiwoAAw1AAAAAGwAAACMAARhZ -AABy4wAAUYgAAw1AAAKLCgACiwoAAw1AAAAAGwAAACMAAXq6AAB2XwAAWj4AAw1AAAKLCgACiwoA -Aw1AAAAAGQAAACMAAVsrAAB2XwAAWFYAAw1AAAKLCgACiwoAAw1AAAAAGQAAACMAAUFeAAB2XwAA -VoEAAw1AAAKLCgACiwoAAw1AAAAAGQAAACMAASmTAAB2YAAAVMEAAw1BAAKLCwACiwsAAw1BAAAA -GQAAACMAAREqAABvmwAAT90AAgjVAAII1QACiwoAAw1AAAAAHgAAACgAARcEAABsgQAATiAAAosK -AAKLCgACiwoAAw1AAAAAGwAAACMAAAAAK2gjgxhqDQYLKgAAAAAAAAAAADIAAAPoAAAAKAAATiAA -AAAAAAPQkACYloAAD0JAAJiWgAAAHCAAAABLAD0JAAAD0JAAmJaAAQEAAAMDAgIFBQQEBwcGBgAA -ADIAAAPoAAAAZAAAw1AAAAAAAAPQkAPQkAAATEtAA9CQAAAAHCAAAABLAD0JAAAPQkAjw0YAAwIB -AAcGBQQLCgkIDw4NDAAAADIAAAPoAAAACgAAAfQAAAAAAAAD6ACYloAAD0JAAJiWgAAAHCAAAABL -AD0JAAAD0JAAmJaAAwIBAAcGBQQJCQgICwsKCgAAAAAAAAAAAAEAEAARAB4ADQASAAcAHwAOAAsA -EwAVABsACAAXACAADwAdAAwABgAKABQAGgAWABwABQAJABkABAAYAAMAAgABAHsAdQD7APUARQBv -AH0AdwBfAGkAxQDvAKMAPwD9APcAuwA5AN8A6QDPAJ0ARwBxAA8AWQAlAL8AEwBjAH8AeQBtAF0A -PQC5AJsADQBhAGsACwAJAFEAHwAxAFMAxwDxACEAtQCPANkArQAzAKUAQQBVAJcAkwDjACkAyQD/ -APkA8wDDAO0A3QDnACMAvQA7ALcATwAdAI0A1wCRAOEA6wDbABsAiwCJAIcArwDRAJ8ANQAtALEA -0wAXAKcASQBzAEMAZwChADcAzQBXABEAWwCZAAcALwCzAKsAlQAnAMEA5QBNANUAGQCFACsAFQBl -AMsABQCpAEsAgwADAIEAAAD6APQAfAB2AMQA7gD8APYA3gDoAEYAcAAkAL4AfgB4ADwAuABgAGoA -UAAeAMYA8ACOANgApABAAJIA4gD+APgA7ADcALwAOgAcAIwA4ADqAIoAiADQAJ4AsADSAEgAcgCg -ADYAEABaAC4AsgAmAMAA1AAYABQAZACoAEoAgAB6AHQARABuAF4AaACiAD4AugA4AM4AnAAOAFgA -EgBiAGwAXACaAAwACgAIADAAUgAgALQArAAyAFQAlgAoAMgA8gDCAOYAIgC2AE4A1gCQANoAGgCG -AK4ANAAsABYApgBCAGYAzABWAJgABgCqAJQA5ABMAIQAKgDKAAQAggACAAEAAwACAAQAAAAAAAAA -AAABAAIAHAAbABYAFQAeAB0AGAAXAAwACwAQAA8AIAAfABoAGQAUABMACgAJAA4ADQASABEACAAH -AAYABQAEAAMAAQAAAAIABAAAAAAAAAAAAAAwBAAAMBAAAFncAABagAAAWoQAAFqIAABajAAAWpAA -AZQwAAAQJAAAEDAAABA8AAAQ3AAAEQwAAHssAAB7NAAB4owAAeaMAAHqjAAB7owAAfKMAAH2jAAB -+owAAf6MAACNzAAAjoAAAH50AACP3AABkVgAAZJwAACP/AAEExwABBMYAAQTEAAEkxwABJMYAAST -EAAAd+AAAHfkAAB39AAAeAQAAZw8AAEQdAABEIQAAJQIAACYXAAAlgwAAJYUAACWIAAAliwAAJbE -AADQKAAAkAgAAwjcAANI3AADiNwAA8jcAAMI5AADSOQAA4jkAAPI5AABkFQAAGAcAAGg2AABkJAA -AHfgAAB35AAAd/QAAHgEAAB42AAAeOAAAHj0AAUAeAAFCHgABRMIAAGUBAAB48AAAefAAAHrwAAB -78AAAfPAAAH3wAAB+8AAAf/AAAGUDAAAAAAAAAAAAAAAAAAAMAC///9AAAAwCL///0AAAZQQn/// -/wABlDQAAAAQAAGUCJ//4/8AAZQ4AAAAEAAAECjh////AAAQLOH///8AABA0Af///wAAEDgB//// -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 -ABoAAAD6xogAIAAA8AAAAB//rDzhAwYAIAdSxCAHU2wf/4HwIAthICALYPAgC2FQIAuukP//f/8A -ADIAH/+bXB//nXQgC66wAAD4AAA8PDwf/7EwH/+WGB//mdQf/62cChQoUCAIDwQf/6w4IAdUAB// -lZwgAw60H/+USP//x/8AAv/AH/+bBCALsHAgC7AQIAuyoB//m6wgC2HwIAuyQCALshAgC2GAIAuy -cCALr6Af/5uoH/+boB//qbgf/6m0H/+CcB//qpAf/6rkH/+b1B//m9Af/4KQH/+q6CADCTAgAws4 -IAdUUB//grAf/6pwH/+qZB//qmgf/6psH/+qoB//qpwf/6qYH/+qlB//qogf/6p8H/+qgB//qoQf -/4LgH/+p8B//mygAAEADH/+UtB//qaSH////H/+bjB//nGgAD//wIAtm4B//g3AgC2dAH/+DgB// -rlQgC2eAH/+chCALZ9Af/5xYIAtoACALaDAf/4OQH/+byAAAJYAgC2hgIAtooB//mXAf/4OwH/+b -cB//mgQf/5lsH/+DuP//AAAD5/wYIAto0B//g8Af/6sgIAMJhB//qxwP////IAMO4CALaTAgCBPk -///rICAIE5T//+twIAgSVCAIE4z//+ywIAgRdCAIEkz//+2QH/+b7AP//+AABHIMAARyFAAEchwA -BHAUAARwKAAEcCAABHAsAACFgD///+AABEAkAARATAAESiQABADgAAQABCALa9AgC2wAAAQCxAAE -AsAgC7eAIAu3sAAEcGQgC7fgAARBwAAEQcQABEHIAARAeAAEQNwABEFAAARBRCALbNAgC20QIAtt -QCALbDAgC2xwIAtsoAAEcFgAABAoAARBYCALbZAAAHd3AAAzMyALbtAgC23QIAtuUCALbpAgC24Q -IAttYAAAICgABHQYAARKwAAEQMAABEDEAARB8AAEQfQABHQUIAu3QCALb/AgC2+wIAtvcCALbzAg -C27wAAQCcAAACPAABAJ0AAQCfAAEApAAAL8oAARwXAAEdAAAAPAGAARL8AAEcigAAZsvAAFjHQAE -ATAABADsAAQBCAAEdgAABAEEAAR2BAAA//gABAEAAAQA5AAEdggAAP/BAARyAAAAVVUABHIEAAQA -+AAEANwABADYAARySAAEATgABAEYAARyTAAEAPQABHJQAAR0CAAEcggABEBIAARK3CALcDAgC3Bw -IAtwsAAEQSwABEE8AARA4CALcPAABEEAIAtxIAAEcEgABHBgAARyIAAEdgwABHgEgBAAACALuCAg -Aw9wgBIAAwAEAOiAEAADAAQAwAAATiAABADMAAQAxAAEAMgABAE0IAgG1CAICxQAAgAhAAQAgAAP -/ykABABEIAtxUAAEAkQABAJMAAQCSAYGAAAABAGAAAAeeAABMLAABADQAAQA1AAEAPAABAD8AAII -1QABBGoABAEMAAQBEAAAosIABAEUAAQBHAAEASQABAEoAAQBLAAEAUAABAFEAAQCUAAEASAABAJg -AAQCZAAEAlQAAQAhdzWUAAAEQfwABEv8AACAIAAACAgABHAwIAgDwAAEYMAABGDEAACIAAAEQdQA -BEvUAARB2AAES9gABEHcAARL3AAEcDgABHAAIAtxgAAEcAQAAMAAIAtxwAAEYMgAAIAkAARAHAAE -ShwAABcsIAtyACALcjA7msoAAARg5AAEYNAgC3JgAARAAAAEQAQABEAMAARACCADCtQABEoEAARw -NAAEcAgABFAAAARUAAAEYMwAAH8AAARB0AAES9AABHBQAARQaAAEUEAABFRoIAgH8AAEUFAABFRQ -AARSJAAAQEAABFIoAARSLAAEQBAABEgQAARAFAAESBQgCAgQAARB4AAES+AgCAg0AARB6AAES+gA -BEHkAARL5AAEQewABEvsAARAGAAEShgAAO7wAARQYAAEVGAAABEAAAARMAAAEDAgCAPoIAgDPCAI -BUggCAScIAgGqCAIBfwABBMEAAQTJAD///8AgQIg4QHiQOEAEgD/wAwAH/+URB//lbAgC3UgAf// -/wPf0kACFg7A4QNGAB//mngABFSwAADj7wAEULAABGDgAADB8x//rIgf/4QQ//x//wAAfuiAAAcA -gAAFAIAABgCAAAQAgAABAIAAAgAgCT9gIAt1cB//lIAgCUDgIAMIwCALdaAAD///IAdT+B//rTAf -/6wAH/+u4B//rwAf/5SzH/+sMABUAAAgDAAA4QT+AOEFBgAAJAAA4QHeAOEAWgD4AAP/3//+AAAA -gGAAAEAJAAAJxCALu0AgC7uQIAu7wCALvIAgC7xQIAu7EN6tvu8gCAxEIAgOVAAJiWggCA5EIAgM -BCAIDpQgAw+gIAu8sCALddAf/6uQIAoAAAAKAAAgC3YA4v/+AB//q9Af/63UH/+ZDCAKoAAgCuBA -bBAGwKT8/LoQFBBYMFvJXvz8uRAAEFAw+woeIAAQaDBbnaT8/LUQABBQMPsKHiBAEGgwW52g/Pyx -EAAQUDD9/LAQHhBYMFudm/z8rhAAEFAw/Rp8IB4QWDBbnZb8/KoQABBQMPsKHiBAEGgwW52R/Pym -EAAQUDD7CgEgABBoMFudjfz8ohAAEFAw/fyhEAEQWDBbnYj8/J8QABBQMPsKASAQEGgwW52D/Pyc -EAAQUDD7CgEgABBoMFudfvz8mBAAEFAw+woBIAkQaDBbnXr8/I4QABBQMPsKASAAEGgwW511/PyK -EAAQUDD9/I0QARBYMFudcPz8iBAAEFAw/fyKEAEQWDBbnWv8/IQQABBQMP38hhABEFgwW51n/PyA -EAAQUDD7CgEgCRBoMFudYvz8dhAAEFAw+woBIAQQaDBbnV38/HMQABBQMP38dhABEFgwW51Y/Pxw -EAAQUDD9/HQQARBYMFudVPz8bBAAEFAw/fxwEAEQWDBbnU/8/GgQABBQMPsKASAJEGgwW51K/Pxf -EAAQUDD7CgEgCBBoMFudRfz8WxAAEFAw/fxeEAEQWDBbnUH8/FgQABBQMP38XhABEFgwW508/PxU -EAAQUDD9/FoQARBYMFudN/z8URAAEFAw+woBIAkQaDBbnTL8/EcQABBQMPsKASAMEGgwW50u/PxD -EAAQUDD9/EYQARBYMFudKfz8QBAAEFAw+woBICEQaDBbnST8/D0QABBQMPsKASACEGgwW50f/Pw5 -EAAQUDD7CgEgCRBoMFudG/z8LhAAEFAw+woeIAAQaDBbnRbApPz8NxAUEFgwW8jI/PwoEAAQUDD7 -CgEgABBoMFudDvz8IhAAEFAw+woBIAAQaDBbnQn8/CMQABBQMPsKASA4EGgwW50EwHD3FQAiHwA0 -4Ad0Avb8JBAAECgwtBr7LAAABBBgMFu/tY0R/PwUEAAQUDD9j1cOgAQ7YP2NFAgAQDNw+IgRDABA -N3D47gIMCQB/cP7dAgABEFgw/RYBLfABbDBbnO38/AQQABBQMP0RAyABEFgwW5zoLhEA0w8PAgB/ -7xj8/AkQABBQMPsKASIAAGhwW5y5LxEAf/fm9EwBIAgCKXD/AgAACAIQsP8CAAv/tZ1Q+goELeAE -PSD8+/sQFBBYMFvIifz77hAAEFAw+woBIAAQaDBbnM/8++QQABBQMPsKASAAEGgwW5zL/PvgEAAQ -UDD9+98QARBYMFucxvz73RAAEFAw+woBIAAQaDBbnMH8+9oQABBQMPsKASAAEGgwW5y8/PvWEAAQ -UDD7CgEgCRBoMFucuPz7yxAAEFAw+woeIEAQaDBbnLP8+8YQABBQMPsKHiAAEGgwW5yuJxUEE/vT -FfvT9PvTEAAQEDCxIvz7vhAAEFAw+woBIBAQaDBbnKX8+7oQABBQMP37uRABEFgwW5yg/Pu5EAAQ -UDD7CgEgChBoMFucmygRBNMPf48Y/Pu9EAAQUDD9HAggARBYMFucbSkRBH+X5vz7qhAAEFAw/RwK -IAEQWDBbnGf8+6cQABBQMP0cDCABEFgwW5xiLREF0w8PAgD+EQYgagQbcHPhLXTRCnThB/8CAAn/ -sJVQ+goCIBQQWDD8+6gSAAB4sFvIMccr0Q8A8/6FYgAAIfD9LAAABBBQMPz7oRAUEFgwW8gp/PuG -EAAQUDD7Ch4gBBBoMFuccMAg0Q8AAGwQBvgxCG/qEBAw0Q8AABb7lShihBr7lBn7lQqIAQmIAvhm -hCAUEFAwW8D7K2KEHPuQ/LsCAAAQEDD7ZoQgZBAYMMGkW8D0sSJzKfUb+4oAShH7XAAKACBasFv+ -qvagp2IAABKwwKT8+4QQFBBYMFvIBxT7ghP7gvz7gxAAEHAw/hUAIAAQEDCxIgwsL83B/EwAAAQQ -UDD7ChQiAABosFvH+/oKACABEFgw/AoAIgAAaHBbnBrAqlvA2C4RAPz7cRGOCBuw/SwAAAQQUDD8 -+24QFBBYMFvH7Rz7bfsKHiAAEFAw+hUBIAQCaHBbnAwtEQEN7RRo0RLAovz7ZRAUEFgwW8fixyvR -D9EPwKT8+2IQFBBYMFvH3cAg0Q8AbBAELSAiGPtd+CU0IA0At2BawPVmoFAtICLApPz7WRAUEFgw -W8fSKSAiwDD0+1YQDgC2YMGkW8CxsTN0OfXaIFrAi2agIdogWsBhZqAZHPtO+iAhIAcQWDD+CgAh -ABBoMFsrXtKg0Q/SoNEPAAAAAGwQBvoKBSAIEFgw/PtEEgAAaLBbx7sZ+0LTDyiQGMqG8/tBEMwQ -IDAEJCj0+vsiACAk8PosAAIAAFjwW3UPdKECZa/u0qDRDyiQ5GWP0Rv7NiyySCuySsCs/AlCAAAQ -IDD7DUIB8gJycP6kOQYAjYdgwOP+RAIAARBQMGmXAmjXnhP7FQrLOPt1Uw//EDAwLzKzw4AISAIG -iAMI/wH/NrMgARBQMFvAeSkys8GgCpkC+TazIAEQUDBbwHQqMrIb+xsLqgIqNrIpCoApNq4vMq8Y -+xgI/wEvNq/9+xYQNBBwMA5eKPj7FRwAIHdwidmL2orXj9b2uxEIIAQ+YPuqEQgJAF5wCpkCCf8C -CP8CLzawHvsLLjaxKzKyjtWI2B/7CY3U84gRD4AEO6D8+wUeCQBDsP+7AQwJAHdwDbsCDLsC+zay -IAEQUDBbwFAoMrIZ+v/6+v0QEBBYMP0KeCAQEGAw+YgBABQQcDD4NrIiAAB4cFptksmowKL8+vYQ -CBBYMFvHX2P+mQAA8/7vYAAQUDDBpFvAPsKwKjKzC0wCBswDDKoBCkoCC6oC+jazIBQQUDBbwDZj -/mgAbBAEGfrm+ZLAIAgANKDAINEPG/rjK7B/HPrk8/riG/AEPuAMuwIJ6lH7NkkjwgI+oPf63hAB -ECgw9goCIBIQcDAudrAmdrMtCsgtdrEsGvQsdrLbUP0KZCABEGAw+vrUEAoQcDD1dpEgABB4MFpt -ZfaiX2IAACKwwO//CgcgBhBAMPoKBSAEEFgw+frKEAAQYDAd+sktdqDE0S12gMDYLXajK3a1xNot -drYodrcvdrgsdrkodroqdrsudrzB1S12vSh2vit2vyp2wMDaLXbBKnbCLyoAL3bDK3bEwYAodsUv -CmQvdsYrKpsrdscldsgqdskqdsooCgModssvChIvdswuds0b+psrskgqCk7+OgAqVAFcMP52zivQ -BD7gC6oMKna0LJYUJpYVKAoYKJYZGvqkG/qk//qhEAEQcDD/dpAgABB4MFptL/ahh2IAACKwGvqc -G/qc/AoAIAoQaDD++poQABB4MP52kCABEHAwWm0l9qFeYgAAIrAa+pEb+pL8CgAgChBoMP/6kRAB -EHAwDwIADwIA/3aQIAAQeDBabRn2oS9iAAAisBr6hhv6hvwKACAKEGgw+PqGEAEQcDD4dpAgABB4 -MFptD/ahBmIAACKwGvp7G/p8/AoAIAoQaDD5+n0QARBwMPl2kCAAEHgwWm0F9qDdYgAAIrD7+nIQ -ABBgMPr6dRAKEGgw+naQIAEQcDD6+msQABB4MFps+vagsmIAACKwG/pt+zZAIAEQUDBbv6gW+mse -+moc+mr8NkAgABAgMNXgLTJA/wIAAgBV61DAqlu/oLFE9knocf4CcXD+CgAv+xAYMPoKBSAIEFgw -/PpeEgAAaPBbxrP2MFRiAAAg8Pr6WhAHEFgw/QpkIAEQYDD/CgAgARBwMP52gSAKEHAwWmzY9qAp -YgAAIrD6+k8QBxBYMP0KZCADEGAw/goKIAIQeDD/doEgABB4MFpszdSgyUfApfz6RhAIEFgw/SwA -AgAAcTBbxpjSQNEP0kDRDwAAAAAAAPP/bGAAEBgwbBAEE/o89AoAIAAQUDD2CswggBAoMPU4CAAB -EDgwKIDA+TJRIBgANiD0TAEiACA08PlC6WgAICjw0qDRD2Sf6PBBBA/lADSgAHsaZL/a2kBbv2tm -r+Jj/88AAABsEAQT+iYCIgoDIgoiIpzRDwAAAGwQBBj6IQIjCggzCiIymyMymvICXwOABDzgAyIC -0Q8AbBAEG/oaFfoY+rKCL+AQYDD4sn0gPgJo8P+ygSwAQGdwDaoM9IASZABAYrAusn4P/jn/AgAK -AGVxEMBAwKD8+gwQBhBYMFvGXAIrCgW7CvS2mSD9ADUgHfoHHPoH0w/9TQgAARAQMPO2nCIAAHtw -KsJ20w8PAgB/pw0uwnAM7hD+3wwKAEprkP6nF3ACEBgwLsJx0w8M7hD/AgAKAEp7kA7/DH2nJi7C -cgzuEP8CAAoASHuQ/v8MADAA7rDAofz57xAAEFgwW8Y8xirRD3un6yjCgvyIEAAGEEgw/4PdcAYQ -cDAvtpsptprApfz55RAAEFgwW8YxwCDRDwAAAAAAAPS2gi//nGaQAisKBbsKJLaZY/9CAAAAAP22 -myAAEGAw/LaaIgAAe3Dz/71gABBwMCK2mi+2m/P/r2ABEHAwAAAjtpovtpvz/59gAhBwMAAA/PnN -EAEQUDD7CgAv9BBoMFvGFcck0Q8AbBAK2hBbdKr2odxiAAASsPv5xBIAAFBwWmTf9qHJYgAAErAX -+cAU+cEpcn/8+b8f/xAQMPgKBSAAEBgw83Z+KABAJnD5dn8iAABQ8NMPbYoY2yDA2X2jAdsw/s0E -IAgCUrD75gAgCAJjMBr5sVt0iRz5sfoKACAREHgwbfoU2yDCgXijAgM7AivGFPqsBCAIAmMwGvmp -W3R/HPmm+goAIAUQSDDTD22aE9sgwNl9owHbMCvGKPqsBCAIAmMwGvmfW3R0HPmc+goAIAwQcDBt -6hPbIMLxf6MB2zArxi36rAQgCAJjMBr5llt0ahz5kvoKACAFEEAwbYoT2yDAmXmjAdswK8Y5+qwE -IAgCYzAa+Y1bdGAc+Yj6CgAgDBBYMG26E9sgwtF9owHbMCvGPvqsBCAIAmMwGvmEW3RW2hBbdED7 -+YMSAABQcFpkk/agmWIAABKwFvl/KXKBFfl2H/lz83aAKABAJnApdoEu8oEY+TAI7gIu9oEmVlDz -VlEgCAJhcPPGUSAQAllw87ZRIBgCUXAjplEa+XBbdCMZ+WYmVmTzlmUgCAJ6cPP2ZSAQAnJw8+Zl -IBgCanAj1mUa+WdbdBkZ+VwmVmnzlmogCAJacPO2aiAQAlJw86ZqIBgCQnAjhmoa+V5bdA/RDwAA -bBAOE/kiiiArMjILqihbduYtMjKMIf3KKAIAACKwW3biLzIyjiL/6igCAAA6sFt23hj4/iYyMhP5 -T/hmKAH+AkkwAJAE9gQZAgAAKrD8+UoQBRBQMPCZEQH+Ailw/SIAKYAEOeD+IgEoCQBKMP8iAigJ -AEFw+DbkIAgQWDBbxXkc+T+NI44kjyWLJpsQiieaEfkiCCAIEFgw+RYCIAUQUDBbxXAc+TeNKY4q -jyuJLJkQ+CINIAUQUDD4FgEgCBBYMFvFaIsljiMa+NkAUAQGDRkOriwO3Sz+IgYqAAbakAq7LAtL -KGAABQurLAtLLP6rEnIAAGLwH/jND+8sD08oYAAKAAAf+MoO/ywPTyyOJ58U/xYFKgAIcpAf+MQP -7ywPTyhgAAgf+MEO/ywPTyyfFo4ohimFKp8X9GYoCgAIcpAf+LsP7ywPTyhgAAgf+LgO/ywPTyyO -KwRVKJ8Y/xYJKgAIcpAX+LIH5ywHRyhgAAgX+K8OdywHRyyOLH6rDR/4qw/vLA9PKGAACgAAH/io -Dv8sD08sJxYQnxqOLZ8bLBYR+xYSKgAL8pAa+KAK6iwKSijwABFiAAB58AAAGvic33AOqiwKSiwX -+I2aHB747voWDSgDADvwmB74Fg8qAF/vkBT41y027cCg+jblKgBlZRCMFPs25ioAbeUQjRaOFf42 -5yoAdm0QjxiIF/g26CoAfv0QiRn5NukqAIg1EPY26ioAka0Qih71NusqAJpV0Isa/wIACgCj3dCO -H40bjBwA7hEO3QL9NuwqAKhlEIwujx3/Nu4gABBIMAOdCvzW1CAIAliw+7IOIAICYnADzAr7xtQg -EAJQsPqiDiAEAlpwA7sK+rbUIBgCQLD4gg4gBgJScAOqCiim1MAg0Q/Ao/z4uhAIEFgwW8TvKxIS -LBIRHfi1Y/8rAADAo/74oRIAAGsw/PiyEAgQWDBbxOYb+J1j/x6NFPz4rxADEFAw/viZEAgQWDBb -xN8e+JaeFWP/C40W/PioEAMQUDD++JEQCBBYMFvE2B/4j58XY/76jRj8+KIQAxBQMP74ihAIEFgw -W8TRGPiHmBlj/undYPz4nBADEFAw/viDEAgQWDBbxMoW+IBj/tjdUPz4lhADEFAw/vh8EAgQWDBb -xMMV+Hlj/sWNHvz4kBADEFAw/vgkEAgQWDBbxLwZ+CKZH2P+ssCj/PiKEgAAavD++B0QCBBYMFvE -tRr4GpobY/6fjRz8+IQQAxBQMP74ZxAIEFgwW8SuG/hkmx1j/pYAAGwQEhv4fRL4WR74fI24LLAX -KrI7juD+FgAiAAAYcPuw4yAAECAwKSJx+Q5bCWABTDD00OxoACB2cB/4My/yQfCeEQl0AWgwDo4C -LiZyoc4u4AAPH0AO/xEP7gIuJnQuInYvCgT/7gIIACBOMP4mdiDEADagGPhjKIJB8JwRD3QBVDAM -/wIvJoItInSjvi7gAP/6jygBAUAw+ogRD8AEO6D/3QEOCQBDsA7dAi0mdCgidsHADIgCKCZ2JCZz -wKgqJnob+FD5Cg0gIAJQcPkmeyBgEGAwW7t5Gvgl+QoYICACQHAPAgDTD9MPbZoP+YIAIAgCUrD5 -pj8gCAJCMC0iux/4Qh74Qg/dAQ7dAi0muxz4QCwmgxv4QPsmhCAAEBAw0Q8kJnIoInbHywyIAfgm -di9EALagJCaCY/9+AABsEAoX+DYW+BAPAgAoffcogMEqcd37cd8gHxBgMPRx4SASAP4wiXlkkl8l -ceP+cdksACBW8KTdpd36D0QKAWTvkPXylmiAAVgw9YKOaIABJDBlkob/AgAIAUGrEChx+ArvDA3p -DCl15f913CvgAXgw+6wMA+AEOqD8dd4h7gA2IATLDCt14Am5DPl15CngAUwwBZsMK3XiL3He8maE -L+AEP+AvZocuceIOnRH9ZoUv4AQ7oC5mhixx4v1m/S3gBDsg/Gb8IAAQEDDzcnQgALCsoMs7+Dz/ -KgE4xOD/AgAIAUCaENowW8MfLGKKHvf98K0RDABAczD7cdgsCQBrMCxmiitm/iligRr3qAqZAilm -gcCoW5zSFvfzImKH+WKGIgAAIrD/YoItUAQ+oP0iDA/wEGAw+GKDIgBAYLD6LAAAEwA34AmYOXgj -CCJmh2AABAAAAMCg+awAANgANqD5FgghyAA2YPX34RAAEBAw+WZ3IAAQGDAqYnfAuNMP8qoIAAAQ -YDBbu+uxM/U56HIAIBEwwCBmIJhbcqH2oJJiAAASsBz3qg8CAA8CACvCgR330A27AivGgVv92vag -cmIAABKwK3HfJHHhJXHjLnHZL3H4I3J0JnHl+nHdICkAN+CUEJYRlRKTE/z3whIAAHrw/ewAAAYQ -WDD+rAAABBBQMFvD3NEPHPe8kxOWEpUR9BYAIgAAevD97AAABhBYMPhx6iIAAHKw+BYEIAQQUDBb -w9HRDypifStifvlieyAeAlKw9LCOagBAYrAsYnwMnAwMuzYuYnnI6qrcfLMGLGZ9YAACAMCg8/72 -YgAASrAL/QwE3QwtdeAF2AwJiAz4deQp4AFsMAWcDCx14mP+DC5yPGXtmS5x2fpx3SAAEHgw/3Z0 -ICAQWDD7dd8iABAoMP2tCCWgECAw9HXhIYACa3D1deMqACPvkAoIRGSNkmAADgAAAADz/3tiAABa -cAAAAJUQ/PeGEgAAeTD+vAACAABqsPoKAiAGEFgwW8Oe8/3Nb+oQEDAAAAAAAACUEZUSHPd8+xYA -IgAAerD6CgIgBhBYMFvDlPP9pW/0EBAw8pwAAAAQUDD893QQBhBYMFvDjSJmd/P+UG/0EBAwAAD9 -PAAAAhBQMPz3bRAGEFgwW8OFY/2xAAD9PAAAAhBQMPz3aBAGEFgwW8N/Y/2ZAABsEAgZ92QtKkAt -lqoukoUokoYc92ET92L7CgMgABBQMPzsAQ/8EGgw/YgBCgUAYvD2910YCQBSMPiWhiBYABew//dX -EAgQSDD5FgEgCBBQMPoWACAIEFgw+/R+IAgQeDCfEmAAJQAAAPj3TRABEHgw/xYCIAAQSDD5FgEg -AxBQMPoWACACEFgwK4R+Cr0K9fdGHAAgbnD5FgQsACBv8P2dCAAgEGAwDcwM/fc8EAAQIDD+d1IA -BBBAMP5CUgZABD3g/NR/IgMAQLDCqFvCSBj3M/iAfigDABawD5kQCXkCCYgCBogCKTLQBZkBCYgC -+DbQICACITDzPBAtngI9IPT3KBAAECgw9vcpEgAAGHDCqFvCNixC4B/3Ji0yAAKuNg/uEP/MAQwJ -AHdw/cwCADAQWDD1XBAsCQAzMPxG4CAIAhjw9EwQIZAIWXAqCihbwicY9xQpguzy9xcaAwAWsBz3 -Fhr3Fo8U/7sQCABAZnD7qgICCQAR8PoiAg4JAE/wAv8C/4bsIAAQEDDRDwBsEAQV9wz2IgAgIBAY -MG06BodQdnsFuFXCINEPlyAiUATRDwBsEAiVFfIWAiIAAGEw9vcBEgAAUPD5LAAAABAQMPwWBCAC -Ahpw+hYDIEACIbAnYn8PAgDacFubnvs8AAIAACqw+nwAAgAAYXBbvm70oBNgEAIxsPRp1nAQAhCw -wCDRDwAAAIwSsV2tzCrAAMXd/woAJgCIbpD1/AACAABwcPMKACAAEDAw9AoiIC8QODBtCBRkoHzJ -YXehL2hiTLHK3KAqoAB9oVBj/+R0qez2bAEgAgJTMPrmACAIAnOw8//gYgAAYrAAAAAAAP/EACAC -AjGw+swBIgAAGzD65gAgCAJzsPP/u2IAAGKwdKmvL8QA8/+pYgAAKzDKaWhhV2hiR8gxJzQAZF9U -9FQAIAAQEDDRD8gxJzQAZF9C9FQAIAAQEDDRDwCOE/bmACAHADTgJzQAZFBBGPa5H/ZRqP/0VAAi -ACB4sNEPAIsV+hIBIAAQYDBbme+LFPoSACAAEGAwW5nsiRP2lgAgBwA04Cc0AMhRJFQAZq7lG/ao -GvZBq6qqItEPHfalHPY+/RIDLAAgazD/1gAiACBgsNEPAAAAbBAEizAmsAAnCgD4aUliAABK8GRg -QQu5AvgaACAAEFAw/AoJICMQaDBtCChobBV8YRJ9YTb4jP8gAgJSsPYkACACAhCwsXereSaQAGhp -UGSAY2RgSmP/0MBA9CQAIAICQnD4NgAgABAQMNEPLJAA+MkpYAAQKDCre/awACIAADrwbQgU9GAY -YAICKXAmcAGxd/hpCWIAAEnwY//kq3urWcmCwND9JAAgAgJycP42ACIAABKw0Q/GKtEPAABsEAZb -/v32prZiAAASsBT2bhn2P/z2bBABEFgw/fZsEAAQcDAf9msvxqUtxqQuxqcY9mkoxqYf9mgvxqke -9mguxqgtxqsY9mYoxqotQoIf9mUe9mUPAgAP3QEO3QItRoIc9mMsRoYrRocoQqoPAgAIGEv/AgAG -A/FOEBf2XShyM/b2XRaUADYg8vZcH/4QSDDz9hwf/xAoMBv2WRr2WQ8CACq2AC8ywBj2Vwj/AS82 -wC0y0C7qwP7dAQEVEHAwDt0CLTbQHPZRLDbRKjLbG/ZPC6oCKjbbGPZOKCY1LjLdL/rfD+4BLjbd -KzLSHfZKHPZKDbsBDLsCKzbSKzLSGvXGKqDACbsB+zbSIjgBOqAsMtMe9kId9kMOzAENzAIsNtMl -NvQlNvXA9C4y3g/uAi423iwywR32PP3MAQCAEGgwDcwCLDbBKjLCG/Y4C6oCKjbCLyItGfY2GPY2 -+vY2HgBAT/D89jUeCQBH8P8mLSAFEFgwW5ciGvYv/PYwEAYQWDBblx4a9iz89iwQBxBYMFuXGxr2 -KPz2KRAIEFgwW5cXGvYl/PYlEAkQWDBblxQa9iH89iIQChBYMFuXEBr2Hvz2HhALEFgwW5cNGvYc -HPYeGPYc+CYOICAQWDAPAgBblwf69hcRQRBYMP0KACD/EGAwW5ko+vYSEUEQWDD9CgAg/xBgMFuZ -JBr2Dfz2DxDkEEgw+SYKICMQWDBblvga9gj89goQJBBYMFuW9Rr2BPz2BhAlEFgwW5bxG/YFmyyb -K5stKXBAmRAtMtwtFgEsMtgPAgAPAgAMTFP8FgIk8gA2YPkWACACjIZg+RYAIgLXgmD/AgACAueG -YMYq9PWIEAIhLKApCszyCoAgABBQMPJOCAAAECgwLuDA+0JRIpAAN6D1XAEkACBJMPlS6W4AIBEw -9qQMYgAAErAU9eYvQtQZ9eUY9eUJ/wH4/wIALhBQMP9G1CAHEFgwW3DAKmF9/wIAAAHz6pD7CgIg -rxBQMFtwq/oKKyABEFgwW3Co+gorICkQWDBbcLX6CjIgARBYMFtwo/oKMiApEFgwW3Cv+govIAEQ -WDBbcJ36Ci8gLBBYMFtwqvoKJiABEFgwW3CY+gomICkQWDBbcKT6CjogRxBYMFtwofsKASCpEFAw -W3CQ+wotIKkQUDBbcJz6CjYgAxBYMFtwivoKNiAuEFgwW3CW+go3IAEQWDBbcIX6CjcgPBBYMFtw -kfoKJSACEFgwW3B/+golIAMQWDBbcIv6CjsgAhBYMFtwevoKOyAGEFgwW3CG+woBILMQUDBbcHQr -YYEiChgPAgD/AgAIAYfYkPsKViCzEFAwW3B8+gpHIAEQWDBbcGosYYH/AgAIAX9gkPoKRyA6EFgw -W3B0+gpGIAEQWDBbcGItYYEPAgAPAgD/AgAIAXPokPoKRiA5EFgwW3Bq+gpAIEwQWDBbcGf6CjMg -TRBYMFtwZfoKOSBOEFgwW3Bi+gqyIGIQWDBbcF/6CkkgTxBYMFtwXPoKTSABEFgwW3BL+wphIE0Q -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 -VBnp4Q17OCtWJCxSJSpSJKyq+5bbIf4CUrAoUictUiYqltwIfTgtViYvUicsUiavzP2W1yH+AmMw -K1IpKFIoLJbYC3g4KFYoKlIpL1Ioqv/45vUh/gJ78CxSKC/m9i1SKStSKK27/JbfIf4CWvAqUisv -UiorluAKfzgvViooUistUiqo3f/m9yH+AmtwK1IqLeb4LFIrKlIqrKr7luMh/gJSsChSLS5SLCqW -5Ah+OC5WLC9SLS1SLK/d/pbhIf4Ca3AsUi8qUi4tluIMejgqVi4rUi8oUi6riPqW6SH+AkIwKJbq -LkLwH+obD+4CLkbwLULCLVY3LELYLFY4K0LZK1Y5KkLbKlY6KULwKVY7KELsKFY80Q/AICdGxidG -yCJGzSJGzidGyiJGyyJGzCJmGyJGxydGxSdmGCdmGSdmGmP+tQAAAAAAAPrpixFBEFgwW4p0AqwC -+umHEUEQWDBbinVj/OgnRsZj/SEf6Pku8MHAhAjuAi70wWP87cCh/On2EAYQWDBbtWjGKtEPwKH8 -6fMQBhBYMFu1ZMYq0Q/Aofzp8BAGEFgwW7Vg0Q9sEAQb6Q79CgEiAAB4sNMPKrJ2DwIAf6cSLLJw -/MwQAAAQcDD8LwwKAD4TEP6nEHACEHAwLLJxDMwQf8t4DP8MfacoLLJyDMwQf8t1/P8MAD4A7rD6 -CgEgABBYMPzo+RIAAGiwW7VFxirRDwB7p+QtsoIM3RD/09twBhBwMJ9A/jYAIAYQcDD9LAAABRBQ -MPzo7RAAEFgwW7U5wCDRDwAAAAAAAPJGACAAEHgwnzDz/9ViAAB4sJ0wn0Dz/8lgARBwMJ9AnjDz -/71gAhBwMAAAbBAEJlpA+gqAIgAAQTD9+sAgQAJYsPMmACBgAmCw/CYMIAAQSDD8Jg0iHwEkMPkl -FCoAQG7w9aU6AIACWvD7JgkgcAJQsPsmCCgFABmw+CUVIgAAWXBbZo4DZDn7XAACAABRMFt8/Qpu -FC4lAtEPAGwQBBrpnQMLBvKihiIAAGiwKKKBKaKFDSIM9IATYgBAEvAoooIJmDl4IwUipoZgAAHA -IM8hIqJ8LKJ9oyL5onoh/gIQsPTAM2IAQBLwK6J7C5sMC8s2LKJ4yMmtLHyzBSymfGAAAcAgyCDR -D8Cg/OjXEAYQWDBbtPHRDwDz/9ZiAABacGwQBhPpQCgyIxXpKPIKACBFADYgJlJ6JDLfDwIApiYJ -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 -8/5LYgAAWnAZ4Kgqku0rku7HwPmS6yAeAlKw9LCJagBAYrAc4KEswuwMnAwMuzYe4J4u4unI7are -frMJH+CbLvbtYAACAMCg9KwADqEAtqDAoPzfzRAGEFgwW6vnY/6MAAAb4JH7sgoiAABQ8Ftdax3g -jh/glPzgnhAyEFgw/dIKIgAAcrD+9oMgBRBQMFur2h/gjC/yg/769CAAEBAwD+I4yCvRDwAA8/+D -YgAAWnAAFd/pIlLb9VLcIgAAUPBbXVQY4ID6hkkiAABQ8FtdSxzgfcCQKcZNLcJJKsZKLcZLDasM -At0MC2sUm8cNbRT9xkwiAABQ8FtdSRzgcvrGBiAIALagxyTRDx7gbhzgev3iSSIAAHiw/uJKIAUQ -UDD1FgAgYBBAMPgWASAyEFgwW6uyH+BkHOBwLfJM/vJLIAUQUDD/8gcgMhBYMFurq8Ag+t+9EUAQ -WDBbgKYY4FoqhoL637gRQRBYMFuAotygHd+l+t+0EUEQWDD54GARABBwMPnWCCwJAHMwW4Ce+Ao/ -LAAQcDD8CgYgABBYMBrfQytG0ytG0itG1CtG2StG2CtG3itG4CtG5StG5CtG5itG6itG7CtG9ytG -9itG/CtG/i5G8S5G8/5G+SABEEgwKUbiLEbnLEb9KEbw+EbyL/8QeDD/RtUgAxBoMC1G3P9G2yAA -EGgw/Ub6IBsQaDD9RuggEBB4MC9G9Bje3pmtHOA6LEbr+EbaIBoQSDApRtYf39L+4DQQHhBQMCpG -0P5G4SAREFAwKkbuL0bf/98vE/8QSDD5RvggDxBAMChG/y/ywhvgKitG7dEPAAAAAIga+Iz/IAEQ -SDD4FgogAgIqMPWVOQH9zRog+goFIDIQWDD8EgkgABBoMFurWPP7f2AQEFAwbBAEFd8BKFIV8goA -IAsANiDRDwAAAAAA+t9jEUEQWDBbgEwT4AcpMUf0ChAgABAQMPuXE3IAAFqwHd9KGuAMHOAHLNYI -IqZ8+t9XEQAQYDD8vAIBQRBYMFuAQiQ29BzgBB3fnR/eoxvf/iI2+hjf/hnf/Sk26/g27SwAEFAw -KjbxKjbzKjb5+zbhL/8QEDAiNtXyNtsgPxBwMC428C428i822v023yAREHgw/zbuIA8QaDD9Nv8g -ABBwMC420y420i421C422S422C423i424C425S425C425i426i427C429y429i42/P42/iAGEBAw -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 +AAAAZAAAAHAADRzvAAAACQAAAAYAAAADAAAAKQAAAAEAAAAcAAAAHAAAAFAAAAABAAAAAgAAAGQA +AABxAA491QAAAAkAAAAGAAAAAwAAACoAAAAfAAAAHwAAAB8AAAAQAAAAAAAAAAIAAABmAAAAcgAO +1b4AAAAKAAAACQAAAAQAAABqAAAAAgAAABwAAAAcAAAAEAAAAAIAAAAAAAAAZgAAAHcAD0JAAAAA +CgAAAAkAAAAEAAAA/QAAAAIAAAAdAAAAHQAAAFAAAAACAAAAAgAAAGYAAAB3AA+8UgAAAAoAAAAJ +AAAABAAAACkAAAABAAAAHQAAAB0AAABQAAAAAQAAAAIAAABrAAAAeAAQRgQAAAAKAAAACQAAAAQA +AABqAAAAHwAAAB4AAAAeAAAABQAAAAIAAAACAAAAawAAAHkHADsAAgA4AAQDOwEAAAAAATYBbAGW +APABIAFTAOEBMQFhALwA5AELAPUBIgFJAMYA6wEPAMIA6gETAJ0AvwDeAMsA7QENAKoAyQDkAKMA +xADgAIEAogC9AK8AzADjAJQAsADGAIsAqAC/AAAAgQCdAJoAswDHAIEAmwCvAG4AjwClAAAAAAAA +AIkAnwCxAG0AiACbAAAAYQByAAAAAAAAAHoAjwCfAAAAcgCHAAAAAAAAAAAAAAAAAAAAAAAAAAAA ++wEmAWoA2QD/ATYA7gEuAYwAqwDTARMA1gD5ASoAuQDaAQoAtwDiATAAjACtAOEAugDZAQYAogC+ +AOcAlgC3AOoAZQCMALoApAC/AOYAjgCoAM0AegCYAMMAAAAAAJQAkQCqAM0AewCVALcAAAB6AKMA +AAAAAAAAgACYALgAZACBAKMAAAAAAH0AAAAAAAAAbQCGAKUAAABmAI4AAAAAAAAAAAAAAAAAAAAA +AAAAAAEAASkBVQDOAPMBFQDHAO4BFgChAMMA4ADNAO0BDACrAMoA4wCiAMEA3QB9AJ4AtwCtAMkA +3wCTAK0AwQCGAKIAuQAAAAAAiwCXAK4AwAB9AJYAqQBMAIEAmQAAAAAAAACFAJoAqwBiAH8AkwAA +AAAAAAAAAAAAAAB2AIkAmQAAAFYAeQAAAAAAAAAAAAAAAABmAHoAiQAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAN8BAwExAL8A3wEQALwA5AEsAI8ArwDiAL0A3AEHAKQAvwDnAJYAtgDmAFcAhgC0 +AKQAvwDkAI4ApgDKAHYAkwC8AAAAAAAAAI8ApwDIAHgAkQCyAAAAbQCZAAAAAAAAAHwAlACyAFoA +egCYAAAAAAAAAAAAAAAAAGcAgACeAAAAAACBAAAAAAAAAAAAAAAAAAAAagCKAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAA2wEAARsAtwDXAPAAsADPAOgAkACuAMYAswDOAOQAmQCyAMYAjQCnALwA +AAAAAI0AmQCvAMAAgACXAKkAAAB8AJQAAAAAAAAAhQCZAKgAWgB7AI8AAAAAAAAAAAAAAAAAdACH +AJUAAAAAAAAAAAAAAAAAAAAAAAAAYQB1AIMAAAAAAAAAAAAAAAAAAAAAAAAAAABgAHEAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAADMAOsBGACyAM8A9gCpAMwBAACCAKEAygCtAMgA7QCYALEA1QCD +AKAAxwAAAAAAlgCVAK0AzgCAAJgAuQAAAHUAnQAAAAAAAAB/AJYAtABVAH0AnwAAAAAAAAAAAAAA +AABmAIAAnQAAAAAAfQAAAAAAAAAAAAAAAAAAAGIAhgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXwAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8P/w/8AP8P+AnbD/APpQ/gCZkPwACZD4AAAA8AAAAP +/A/8D/gF/A/wD7QP4AW0D8AAtA+AAAAPAAAADAAAAA/AAAAOwAAAD4AAAA6AAAAPAAAADgAAAAwA +AAABAAAAAAE4gAAAaCoAAE4gAAGGoAABhqAAAgjVAAII1QAAACgAAAAyAAEEagAAaCoAAEpnAAGG +oAABhqAAAgjVAAII1QAAACgAAAAyAAFbAQAAaCoAAFAgAAII1QABhqAAAgjVAAK2cQAAACYAAAAy +AAEpbgAAaCoAAE0pAAII1QABhqAAAgjVAAK2cQAAACYAAAAyAAEEQQAAaCoAAEpnAAII1QABhqAA +AgjVAAK2cQAAACYAAAAyAAF0BgAAbIEAAFQBAAKLCgACCNUAAosKAAK2cQAAAB4AAAAtAAFFhQAA +bIEAAFFhAAKLCgACCNUAAosKAAK2cQAAAB4AAAAtAAEhWgAAbIEAAE7qAAKLCgACCNUAAosKAAK2 +cQAAAB4AAAAtAAEEagAAbIEAAEyXAAKLCgACCNUAAosKAAK2cQAAAB4AAAAtAAGGoAAAb5sAAFbO +AAKLCgACCNUAAosKAAMNQAAAAB4AAAAoAAFbOAAAb5sAAFR1AAKLCgACCNUAAosKAAMNQAAAAB4A +AAAoAAE4gAAAb5sAAFI8AAKLCgACCNUAAosKAAMNQAAAAB4AAAAoAAEcGAAAb5wAAFAhAAKLCgAC +CNYAAosKAAMNQAAAAB4AAAAoAAFsdAAAcuMAAFdjAAMNQAACiwoAAosKAAMNQAAAABsAAAAjAAFL +UgAAcuMAAFVYAAMNQAACiwoAAosKAAMNQAAAABsAAAAjAAEvtgAAcuMAAFNlAAMNQAACiwoAAosK +AAMNQAAAABsAAAAjAAEYWQAAcuMAAFGIAAMNQAACiwoAAosKAAMNQAAAABsAAAAjAAF6ugAAdl8A +AFo+AAMNQAACiwoAAosKAAMNQAAAABkAAAAjAAFbKwAAdl8AAFhWAAMNQAACiwoAAosKAAMNQAAA +ABkAAAAjAAFBXgAAdl8AAFaBAAMNQAACiwoAAosKAAMNQAAAABkAAAAjAAEpkwAAdmAAAFTBAAMN +QQACiwsAAosLAAMNQQAAABkAAAAjAAERKgAAb5sAAE/dAAII1QACCNUAAosKAAMNQAAAAB4AAAAo +AAEXBAAAbIEAAE4gAAKLCgACiwoAAosKAAMNQAAAABsAAAAjAAAAACtoI4MYag0GCyoAAAAAAAAA +AAAyAAAD6AAAACgAAE4gAAAAAAAD0JAAmJaAAA9CQACYloAAABwgAAAASwA9CQAAA9CQAJiWgAEB +AAADAwICBQUEBAcHBgYAAAAyAAAD6AAAAGQAAMNQAAAAAAAD0JAD0JAAAExLQAPQkAAAABwgAAAA +SwA9CQAAD0JAI8NGAAMCAQAHBgUECwoJCA8ODQwAAAAyAAAD6AAAAAoAAAH0AAAAAAAAA+gAmJaA +AA9CQACYloAAABwgAAAASwA9CQAAA9CQAJiWgAMCAQAHBgUECQkICAsLCgoAAAAAAAAAAAABABAA +EQAeAA0AEgAHAB8ADgALABMAFQAbAAgAFwAgAA8AHQAMAAYACgAUABoAFgAcAAUACQAZAAQAGAAD +AAIAAQB7AHUA+wD1AEUAbwB9AHcAXwBpAMUA7wCjAD8A/QD3ALsAOQDfAOkAzwCdAEcAcQAPAFkA +JQC/ABMAYwB/AHkAbQBdAD0AuQCbAA0AYQBrAAsACQBRAB8AMQBTAMcA8QAhALUAjwDZAK0AMwCl +AEEAVQCXAJMA4wApAMkA/wD5APMAwwDtAN0A5wAjAL0AOwC3AE8AHQCNANcAkQDhAOsA2wAbAIsA +iQCHAK8A0QCfADUALQCxANMAFwCnAEkAcwBDAGcAoQA3AM0AVwARAFsAmQAHAC8AswCrAJUAJwDB +AOUATQDVABkAhQArABUAZQDLAAUAqQBLAIMAAwCBAAAA+gD0AHwAdgDEAO4A/AD2AN4A6ABGAHAA +JAC+AH4AeAA8ALgAYABqAFAAHgDGAPAAjgDYAKQAQACSAOIA/gD4AOwA3AC8ADoAHACMAOAA6gCK +AIgA0ACeALAA0gBIAHIAoAA2ABAAWgAuALIAJgDAANQAGAAUAGQAqABKAIAAegB0AEQAbgBeAGgA +ogA+ALoAOADOAJwADgBYABIAYgBsAFwAmgAMAAoACAAwAFIAIAC0AKwAMgBUAJYAKADIAPIAwgDm +ACIAtgBOANYAkADaABoAhgCuADQALAAWAKYAQgBmAMwAVgCYAAYAqgCUAOQATACEACoAygAEAIIA +AgABAAMAAgAEAAAAAAAAAAAAAQACABwAGwAWABUAHgAdABgAFwAMAAsAEAAPACAAHwAaABkAFAAT +AAoACQAOAA0AEgARAAgABwAGAAUABAADAAEAAAACAAQAAAAAAAAAAAAAMAQAADAQAABZ3AAAWoAA +AFqEAABaiAAAWowAAFqQAAGUMAAAECQAABAwAAAQPAAAENwAABEMAAB7LAAAezQAAeKMAAHmjAAB +6owAAe6MAAHyjAAB9owAAfqMAAH+jAAAjcwAAI6AAAB+dAAAj9wAAZFYAAGScAAAj/wABBMcAAQT +GAAEExAABJMcAASTGAAEkxAAAHfgAAB35AAAd/QAAHgEAAGcPAABEHQAARCEAACUCAAAmFwAAJYM +AACWFAAAliAAAJYsAACWxAAA0CgAAJAIAAMI3AADSNwAA4jcAAPI3AADCOQAA0jkAAOI5AADyOQA +AZBUAABgHAABoNgAAZCQAAB34AAAd+QAAHf0AAB4BAAAeNgAAHjgAAB49AAFAHgABQh4AAUTCAAB +lAQAAePAAAHnwAAB68AAAe/AAAHzwAAB98AAAfvAAAH/wAABlAwAAAAAAAAAAAAAAAAAADAAv/// +QAAAMAi///9AAAGUEJ////8AAZQ0AAAAEAABlAif/+P/AAGUOAAAABAAABAo4f///wAAECzh//// +AAAQNAH///8AABA4Af///wAAEEAABAAAAAAREAD///8AABEUAP///wAAeygAff/iAAB7MD//7v8A +AHs4AAAAAQAAe0A//+7/AAB8JAB9/+IAAeKIAAgAAAAB5ogACAAAAAHqiAAIAAAAAe6IAAgAAAAB +8ogACAAAAAH2iAAIAAAAAfqIAAgAAAAB/ogACAAAAACNyP////AAAI3Q////8AAAjnwAAADwAACO +hAAAAPAAAH5wf7//fwAAfnh/v/9/AAB+AALAAAAAAZFUAf///wABkZwB////AACP2AN///8AAI/4 +/////wAEExQAAAAHAAQTDAAAAAsABJMUAAAABwAEkwwAAAALAAB33AAAAAMAAHf0/////wAAeAQA +AAADAAGcOAABwEAAAZz4AAHAQAAAkAQAAAA+AAEQeAD///8AARB8AP///wABEIgAAAAAAACUBAAA +//8AAJQQAAD//wAAmFQAAAH/AACYWAAAAf8AAJYIAAAAAAAAlhwA////AACWJAD///8AAJYoAP// +/wAAljAA////AADQIAAAAAcAANAkAAAABwADCNgAAAADAANI2AAAAAMAA4jYAAAAAwADyNgAAAAD +AAMI5AAAAAMAA0jkAAAAAwADiOQAAAADAAPI5AAAAAMAAZBQAAAA7wABoNQAAAGDAAGQjAA4AAAA +AZCYADgAAAAFAHQAAAAHAAUAcAAAAAUABQh0AAAABwAFCHAAAAAFAAUTBAAAAAEgAxCwIAjYHCAD +ELQgCOeIIAMQwCAI5pggAxDMIAjmSCADEOAgCOWcIAMQ+CAI5DAgAxEIIAjjGCADERAgCOLwIAMR +JCAI4sggAxE0IAjimCADEUAgCOF8IAMRSCAI4VQgAxFcIAjhICADEWggCN+8IAMRcCAI3xQgAxGA +IAjeECADEYwgCN0AIAMRnCAI2/ggAxGsIAjazCADEcQgCNecIAMR3CAI11AgAxHwIAjWvCADEgQg +CNaUIAMSGCAI1ZQgAxIcIAjUpCADEiggCNOkIAMSMCAI03wAAAAAAAAAACADEjwgCNM8IAMSQCAI +0sAgAxJIIAjSiCADElAgCNJQIAMSXCAI0hggAxJgIAjR4CADEmggCNGoIAMSdCAI0XAgAxJ4IAjS ++CADEoAgCNE4IAMSiCAI0QAgAxKQIAjOICADEpggCNCwIAMSpCAI0KggAxKsIAjQcCADErQgCNA4 +IAMSvCAI0AAgAxLEIAjPyCADEIggCMvgIAMSzCAIy6ggAxLUIAjLcCADEtwgCMs4IAMS7CAIywAg +AxL0IAjKyCADEvwgCMqQIAMTBCAIymggAxMQIAjKQCADExwgCMoQIAMTNCAIyeggAxNQIAjJwCAD +E2AgCMmYIAMTcCAIyXAgAxOAIAjJSCADE5AgCMkgIAMToCAIyPggAxOwIAjI0CADE7wgCMioIAMT +yCAIyIAgAxPUIAjIWAAAAAAAAAAAIAMT4CAIxyQgAxPkIAjFNCADE/AgCMRUIAMUBCAIxCAgAxQM +IAjD7CADFBggCMO4IAMUHCAIw4QgAxQgIAjDUCADFCQgCMMgIAMRLCAIwiAgAxQ0IAjB+CADFDwg +CMHQIAMQlCAI6oAgAxCcIAjptCADEIAgCOkEIAMQqCAI6GAgCwAAAABBjAAAQYgAAEGGAACAAAAA +QYEAAKgZAACoGgAAwwAAAKgbAACoHAAAqBcAAP//AAAQBAAA5Z8AAB8RAADuCQAA//4AAOr/IAsA +IAAA/wAAAKgYIAsAYAAAYA0AD0JAAADerSALAKAgCwDw4QBeAP7//v8BAAAAAQABACAwAAAgC3tA +IAt7YAAAIEAAAYagIAt7kAAAQA0gC3vAIAt78AAAMNQgCwFQAABhqAAA/+kgC0iAH/+cuB//nMgf +/5OwAIAAAP+fAAAgCAEAABAAAEAIAAACAAAA+MAAAAAAYCz/f///IAulgOEAcgAf/5xM4QQSAACL +FEDhA/4AAAQASOEEAgAABAAhhhAAAAAEAECAAAAAgBQAA4AWAAOAEgAjgBGyA4AQAAUAKvEvAAGG +nwAK8S8gC6XAAAQACCALSKAf/5uQIAdYgB//rfQgC6aA4AAAAOEAdgAgC6XwIAumMCALSNAf/56Q +H/+cmOEBmgA/////AAGeDOEBngAAAZ50AAGerAABntgAAZ7wAAGfHB//npgAAf//AAGfTAABn5wA +AZ+w4QB6ACALSfAgC0pAIAtKoAAAD/8gC0sAIAtLcCALS7AgC0vwIAtMMCALTHAgC0ywIAtM8CAL +TTAgC01wH/+ctCADDrDhBJIAIAMOUP8A//8ADAAAgAAAH4AAAD8f/5yw/8D//x//rgQAAAgAACYM +ACALTbAgC04QIAuoECALp6AgC6bAIAunACALp1DhAC4ABAAAAB//lZThAFYAAoBQAIAAAIAAAEAA +//EAgAHwAACOAeCAAAAfACAIAAAgCBP0AAAU8OEBkgDhAA4AAAEAAAACAAAAfwBAAAMAAACCAIAA +wQDA//8j/wAAyAAQIAEgH/+cBB//rjzhAH4A4QCOADwAAAD//7//UGjoR5IAAADwAPAA37//+yAA +AAR/9///gABCAP/3/38ABgAA/wAAAABJJJIAAH4YEAEQAQAAfkAgASABFRUVFYQhhCEQEBAQ4QGO +AAAA/n8EBAGAH/+qzB//lWzMzMzMiIiIiEREREThAM4A4QCOBOEAjgjhAI4M4P/+ACAIDaQAAAjA +gAHEEcQRxBEA/wD/AEAAQP//P/8gC6jAIAuo8P8P///MiEQAIAuogAgICAggC6kg///gAUREAADM +zIiI//D/AAACADMqKhUV/v///x//m3Qf/6u8H/+tsB//mVgf/51wH/+d0B//mzwf/640AAD//R// +qzTjAAIA4v//ACALUGAgCOhgIAuqECAAAAAAMAAAAGAAACBgAADQAAAAIAupUCALqeAAABAAIAMI +yB//sDAf/6w0H/+AsB//rLD///AAIAuq4CALUqAgC1MgIAtTkCALqpAgC6pQIAuqsB//rEwgC1Qg +AAQAAOEAMgAf/4DgH/+BIB//gWAf/5rM/4AP///+AB8AAHtgH/ziAAgAAAAf/5yoH/+VqB//qrgf +/5UU4QL+AOEDvgDhAz4A4QN+AOEB4gDhAQ4A4QCSAP//8P8f/6mwAAAJAOEBDgThAQ4I4QEODP/w +AAAAAoAG//v//yALXGAgC1zAH/+B4B//nCgf/5swH/+uOBAAAAD/8P//IAMMgB//mbAAAH5M4QCK +AAAA8AAgC10wIAtdkCALXfAf/64IH/+sKB//qiAgC14wIAtesCALsMAgC15gH/+dZCALXzAgC17w +H/+bsCALr0AgC1+gIAtf4CALsbAgC7EQ39AAACALsVAf/6xAH/+sBP+AAAD//+AAIAtgICALYFAg +C67wIAMMjCAHVFQf/634IAtgkB//rEQf/7LMH/+zAB//rIQEAAAIEgAAACALrGAf/7G8gQAAAAAA +MAAgC6yQIAMMiB//sRwf/7PYH/+usB//sxhJAAAAIAursCALq/AgC6sAIAurYC4ANgAADwP/AxEA +AAMVAAAgB1KAIAtg0B//q2Af/5pQH/+qDB//nYwf/57AIADEIB//7TAf/+x8H/+trB//7jQf/6tE +AgCCEAIAAhAAACAAAgAAEAAaAAAA+saIACAAAPAAAAAf/6w84QMGACAHUtQgB1N8H/+B8CALYSAg +C2DwIAthUCALrpD//3//AAAyAB//m1wf/510IAuusAAA+AAAPDw8H/+xMB//lhgf/5nUH/+tnAoU +KFAgCA8EH/+sOCAHVBAf/5WcIAMOtB//lEj//8f/AAL/wB//mwQgC7BwIAuwECALsqAf/5usIAth +8CALskAgC7IQIAthgCALsnAgC6+gH/+bqB//m6Af/6m4H/+ptB//gnAf/6qQH/+q5B//m+Af/5vc +H/+b1B//m9Af/4KQH/+q6CADCTAgAws4IAdUYB//grAf/6pwH/+qZB//qmgf/6psH/+qoB//qpwf +/6qYH/+qlB//qogf/6p8H/+qgB//qoQf/4LgH/+p8B//mygAAEADH/+UtB//qaSH////H/+cCB// +m4wf/5xoAA//8CALZuAf/4NwIAtnQB//g4Af/65UIAtngB//nIQgC2fQH/+cWCALaAAgC2gwH/+D +kB//m8gAACWAIAtoYCALaKAf/5lwH/+DsB//m3Af/5oEH/+ZbB//g7j//wAAA+f8GCALaNAf/4PA +H/+rICADCYQf/6scD////yADDuAgC2kwIAgT5P//6yAgCBOU///rcCAIElQgCBOM///ssCAIEXQg +CBJM///tkB//m+wD///gAARyDAAEchQABHIcAARwFAAEcCgABHAgAARwLAAAhYA////gAARAJAAE +QEwABEokAAQA4AAEAAQgC2vQIAtsAAAEAsQABALAIAu3gCALt7AABHBkIAu34AAEQcAABEHEAARB +yAAEQHgABEDcAARBQAAEQUQgC2zQIAttECALbUAgC2wwIAtscCALbKAABHBYAAAQKAAEQWAgC22Q +AAB3dwAAMzMgC27QIAtt0CALblAgC26QIAtuECALbWAAACAoAAR0GAAESsAABEDAAARAxAAEQfAA +BEH0AAR0FCALt0AgC2/wIAtvsCALb3AgC28wIAtu8AAEAnAAAAjwAAQCdAAEAnwABAKQAAC/KAAE +cFwABHQAAADwBgAES/AABHIoAAGbLwABYx0ABAEwAAQA7AAEAQgABHYAAAQBBAAEdgQAAP/4AAQB +AAAEAOQABHYIAAD/wQAEcgAAAFVVAARyBAAEAPgABADcAAQA2AAEckgABAE4AAQBGAAEckwABAD0 +AARyUAAEdAgABHIIAARASAAEStwgC3AwIAtwcCALcLAABEEsAARBPAAEQOAgC3DwAARBACALcSAA +BHBIAARwYAAEciAABHYMAAR4BIAQAAAgC7ggIAMPcIASAAMABADogBAAAwAEAMAAAE4gAAQAzAAE +AMQABADIAAQBNCAIBtQgCAsUAAIAIQAEAIAAD/8pAAQARCALcVAABAJEAAQCTAAEAkgGBgAAAAQB +gAAAHngAATCwAAQA0AAEANQABADwAAQA/AACCNUAAQRqAAQBDAAEARAAAKLCAAQBFAAEARwABAEk +AAQBKAAEASwABAFAAAQBRAAEAlAABAEgAAQCYAAEAmQABAJUAAEAIXc1lAAABEH8AARL/AAAgCAA +AAgIAARwMCAIA8AABGDAAARgxAAAiAAABEHUAARL1AAEQdgABEvYAARB3AAES9wABHA4AARwACAL +cYAABHAEAADAACALccAABGDIAACAJAAEQBwABEocAAAXLCALcgAgC3IwO5rKAAAEYOQABGDQIAty +YAAEQAAABEAEAARADAAEQAggAwrUAARKBAAEcDQABHAIAARQAAAEVAAABGDMAAB/AAAEQdAABEvQ +AARwUAAEUGgABFBAAARUaCAIB/AABFBQAARUUAAEUiQAAEBAAARSKAAEUiwABEAQAARIEAAEQBQA +BEgUIAgIEAAEQeAABEvgIAgINAAEQegABEvoAARB5AAES+QABEHsAARL7AAEQBgABEoYAADu8AAE +UGAABFRgAAARAAAAETAAABAwIAgD6CAIAzwgCAVIIAgEnCAIBqggCAX8AAQTBAAEEyQA////AIEC +IOEB4kDhABIA/8AMAB//lEQf/5WwIAt1IAH///8D39JAAhYOwOEDRgAf/5p4AARUsAAA4+8ABFCw +AARg4AAAwfMf/6yIH/+EEP/8f/8AAH7ogAAHAIAABQCAAAYAgAAEAIAAAQCAAAIAIAk/gCALdXAf +/5SAIAlBACADCMAgC3WgAA///yAHVAgf/60wH/+sAB//ruAf/68AH/+Usx//rDAAVAAAIAwAAOEE +/gDhBQYAACQAAOEB3gDhAFoA+AAD/9///gAAAIBgAABACQAACcQgC7tAIAu7kCALu8AgC7yAIAu8 +UCALuxDerb7vIAgMRCAIDlQACYloIAgORCAIDAQgCA6UIAMPoCALvLAgC3XQH/+rkCAKAAAACgAA +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 +NtEqMtsb9ksLqgIqNtsY9kooJjUuMt0v+t8P7gEuNt0rMtId9kYc9kYNuwEMuwIrNtIrMtIa9cIq +oMAJuwH7NtIiOAE6oCwy0x72Ph32Pw7MAQ3MAiw20yU29CU29cD0LjLeD+4CLjbeLDLBHfY4/cwB +AIAQaDANzAIsNsEqMsIb9jQLqgIqNsIvIi0Z9jIY9jL69jIeAEBP8Pz2MR4JAEfw/yYtIAUQWDBb +lyIa9iv89iwQBhBYMFuXHhr2KPz2KBAHEFgwW5cbGvYk/PYlEAgQWDBblxca9iH89iEQCRBYMFuX +FBr2Hfz2HhAKEFgwW5cQGvYa/PYaEAsQWDBblw0a9hgc9hoY9hj4Jg4gIBBYMA8CAFuXB/r2ExFB +EFgw/QoAIP8QYDBbmSj69g4RQRBYMP0KACD/EGAwW5kkGvYJ/PYLEOQQSDD5JgogIxBYMFuW+Br2 +BPz2BhAkEFgwW5b1GvYA/PYCECUQWDBblvEb9gGbLJsrmy0pcESZEC0y3C0WASwy2A8CAA8CAAxM +U/wWAiTyADZg+RYAIAKMhmD5FgAiAteCYP8CAAIC54Zgxir09YQQAiEsoCkKzPIKgCAAEFAw8k4I +AAAQKDAu4MD7QlEikAA3oPVcASQAIEkw+VLpbgAgETD2pAxiAAASsBT14i9C1Bn14Rj14Qn/Afj/ +AgAuEFAw/0bUIAcQWDBbcLwqYX3/AgAAAfPqkPsKAiCvEFAwW3Cn+gorIAEQWDBbcKT6CisgKRBY +MFtwsfoKMiABEFgwW3Cf+goyICkQWDBbcKv6Ci8gARBYMFtwmfoKLyAsEFgwW3Cm+gomIAEQWDBb +cJT6CiYgKRBYMFtwoPoKOiBHEFgwW3Cd+woBIKkQUDBbcIz7Ci0gqRBQMFtwmPoKNiADEFgwW3CG ++go2IC4QWDBbcJL6CjcgARBYMFtwgfoKNyA8EFgwW3CN+golIAIQWDBbcHv6CiUgAxBYMFtwh/oK +OyACEFgwW3B2+go7IAYQWDBbcIL7CgEgsxBQMFtwcCthgSIKGA8CAP8CAAgBh9iQ+wpWILMQUDBb +cHj6CkcgARBYMFtwZixhgf8CAAgBf2CQ+gpHIDoQWDBbcHD6CkYgARBYMFtwXi1hgQ8CAA8CAP8C +AAgBc+iQ+gpGIDkQWDBbcGb6CkAgTBBYMFtwY/oKMyBNEFgwW3Bh+go5IE4QWDBbcF76CrIgYhBY +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 +IAAQeDBaW/v2obFiAAASsCNmE8TwL2YhLVIlK1IkHupQGendDXs4K1YkLFIlKlIkrKr7ltsh/gJS +sChSJy1SJiqW3Ah9OC1WJi9SJyxSJq/M/ZbXIf4CYzArUikoUigsltgLeDgoVigqUikvUiiq//jm +9SH+AnvwLFIoL+b2LVIpK1Iorbv8lt8h/gJa8CpSKy9SKiuW4Ap/OC9WKihSKy1SKqjd/+b3If4C +a3ArUiot5vgsUisqUiqsqvuW4yH+AlKwKFItLlIsKpbkCH44LlYsL1ItLVIsr93+luEh/gJrcCxS +LypSLi2W4gx6OCpWLitSLyhSLquI+pbpIf4CQjAoluouQvAf6hcP7gIuRvAtQsItVjcsQtgsVjgr +QtkrVjkqQtsqVjopQvApVjsoQuwoVjzRD8AgJ0bGJ0bIIkbNIkbOJ0bKIkbLIkbMImYbIkbHJ0bF +J2YYJ2YZJ2YaY/61AAAAAAAA+umHEUEQWDBbinQCrAL66YMRQRBYMFuKdWP86CdGxmP9IR/o9S7w +wcCECO4CLvTBY/ztwKH86fIQBhBYMFu1aMYq0Q/Aofzp7xAGEFgwW7VkxirRD8Ch/OnsEAYQWDBb +tWDRD2wQBBvpCv0KASIAAHiw0w8qsnYPAgB/pxIssnD8zBAAABBwMPwvDAoAPhMQ/qcQcAIQcDAs +snEMzBB/y3gM/wx9pygssnIMzBB/y3X8/wwAPgDusPoKASAAEFgw/Oj1EgAAaLBbtUXGKtEPAHun +5C2yggzdEP/T23AGEHAwn0D+NgAgBhBwMP0sAAAFEFAw/OjpEAAQWDBbtTnAINEPAAAAAAAA8kYA +IAAQeDCfMPP/1WIAAHiwnTCfQPP/yWABEHAwn0CeMPP/vWACEHAwAABsEAQmWkD6CoAiAABBMP36 +wCBAAliw8yYAIGACYLD8JgwgABBIMPwmDSIfASQw+SUUKgBAbvD1pToAgAJa8PsmCSBwAlCw+yYI +KAUAGbD4JRUiAABZcFtmigNkOftcAAIAAFEwW3z9Cm4ULiUC0Q8AbBAEGumZAwsG8qKGIgAAaLAo +ooEpooUNIgz0gBNiAEAS8CiiggmYOXgjBSKmhmAAAcAgzyEionwson2jIvmieiH+AhCw9MAzYgBA +EvAronsLmwwLyzYsonjIya0sfLMFLKZ8YAABwCDIINEPwKD86NMQBhBYMFu08dEPAPP/1mIAAFpw +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 +8/ow9SgAIG+w+hYCKAAgfnD7FgEoACBmcPwWACgAIF5w/NlzGAAgVnD5FjIgBhBYMPkWAyAFEFAw +W6TXKhIyzKktEj3wADVgABB4MMCx+xY0IAgQWDBbpuIuMO0tEjL+3QgAABBgMFulVigSNPgIBg4B +AEbw/RI9LgBAR/AuQCn8MXwgCBBYMA+7DPvaKABAEEAw/MwQDgkAQ7D+RCkqAwBisBzZsSoWGf/Y +KA90AVAw/bwAAAYQWDD4Fj4pdAFAMPgWACAFEFAwW6SzKRIZ0w/+Ej4l4wA2YBrY9ik2Kvo2KSgA +IFZwLRI2/9krEAoAN6ApNi0uNi4r8nYq8ncLqgwqFjwNOxQrFjNaUu0uMOwpMXv8EjwgCBBoMArd +DPTlnGjABD5gLhIz0w8N7igJ7jYvQCkoCoAI/wIvRCnA8PoWASAAEEgw/hYYK3QBZDD82YcfdAFw +MPsWAiAFEFAw+RYAIAYQWDBbpIwpEhjInBzY0fk2KCwAIGHwLDYnLTInZNDhLTIpZNDbLRYdHNl8 +/jIqIAUQUDD+Fi8gBhBYMFukficyGStCiiww7ygyJCpCjv9CkiwAICswLMCALhIv+vkICAAgWjD3 +zCgIACBKMAjuDPwWEioCk2OQLhIdp+73CAYB/gJzsPw2Ki4AQEOw/jYpIgAAazAc2WL9MicoACBz +cC4yKC4WOy0WMChGifsKBigAIFow+EaNKAAgUjD4RpEuACB+MP82IyAFEFAwW6RaLzDu9zIaLgAg +L/Av8IAuEjsH/yj/AgAKAnH7kCgSMKeI9wkGAf4CQjD/NigoAEBKMCg2JyoyLdMPyKQrMi5b8/8v +QpD1EhEgGQA34K9V/wgGAf4CKXAIVQH1Ro8kACB9cChCiSVcP/SENGQAQDVwKEKNKUKMJUaL9IQz +ZAAgLnAvQpLI9CpCkWSkM4gzKzInLDJm9TYCJAAgLjAlNmX0sIVkACAvMCkyKWSQei8w7xrYsScy +GikyGS4yKi0yKCgw7gnuLAfdLKqI+ICALgAgV/Av8ICu16h39woYLgAgP/AH2CwH6Sz82MMYACB+ +cPmICAAGEFgwB/cs/jYbJgAgRfD9NhwnoAQ94PcWACAFEFAwW6QVJVw/9zYsJABANXD1NiskACA9 +cCky4igyJtMP9TbhKAAgLnD1+oAg/gJKcAWVAfU2JSQAIC4w2lBba7ovMilk+6snMhn/AgAL/ZOr +0BjYhCQw76hEJECAKjIqB00oJRYR9TYpKgHR6pD9NiooACA9cPcKBgH+Akpw/xYiKABAVnApNikY +2HclMO4H3iwvMhotMij82JMUACBFcCVQgA/dLP7fCAAFEFAw9f8IAAYQWDD0ChguACB9MATYLATp +LP42GygAIH5w9TIrKAAgSjAE9Cz9NhwkACBBMPVcPyWgBDkg9BYAJABANXBbo9olNiskNiwtEiL+ +MikgBBBQMPzY0BAGEFgwW6PT0Q8AwFD5VTYIAqYDYNtQ8/efYAAQaDAoMqdliArz+ElgABAQMCgy +p/kWFCh2ALYgHtgN/ZwAAgAAEnD82MASAAA6cPnuDAAFEFAw/hYXIAYQWDBbo70vQpDJ868n/wgG +Af4COfAIdwH3Ro8mACB98CgyJCoy4ikyZisyAyxCki1Cjv9CiiB+Ajnw/kKMJgBANfAnRon3MiYu +ACA/8P9Giy4AIHuw/kaNLAAgd3D/MOwsACBrMP1GkSoAIGbw/DYCKAAgXnD7NmUqACBKsPk24SgA +IFIw+fqAIP4CQjD6NiMoAEBKMCg2JfXwCmYAIEXwKDDtZIbOJxYVKzD1LTDwLjDxLzDyKDDz/DD0 +KgAga7D4FgAqACB6sPsWAioAIEKw/BYBKgAgYrD82B4aACBasPoWFiAGEFgw+hYDIAUQUDBbo4Ii +MO4nMhr7MOwiACAosCIggCsWGvciKATVALbg/woAJtAANKAiFjcoMO0oFilgBQ37FicgARBIMPkW +NC//EEgwKRYuW6WDLRIqLBIrW6P4LBI0+xIuLAEAYvAuEif/EikqAEBm8CsWLf0SLSIAAFuw/RYo +IgAAU/BbpXUtEiosEitbo+soEi4vEjQtEi0Pvzf4/wEMACBssPwSKCwAIG/wDX0MKTF79FN8aMAE +PmAqEjEK2igJqjbVoCsydGSzIS5AKSgKQAjuAi5EKScSMSgxfJITnBH8eygPdAFQMPzYRxAFEFAw +/3coCXQBPDD5FgQowAQ6IPtLWwYDAEXw+xYCKXQBPDD5FgAgBhBYMFujPmP1jBfXhBXXg2P1gym8 +PwaZASkmz2PzLBnXf2P6KMDg+e42CAG6A2Dz+mVgABBoMC9CiiVGifP7xmQAIC/wAAAoQo4lRo3z ++8dkACAuMAAAJUaR8/vFZAAgfXAALjYqGtgkLRIS+RIdIgAAYfD5NikgCAJasFtqxC9Cki0yKi4y +KSpCjitCimP6zAAAKhIwKjYnGtgY/jYoIgAAYfD7rAQiAABr8FtquGP7GQAa2BEvFiIlNin7rAQi +AABh8FtqshjXkSQw7ycyGf0yKiQAIEEwJECAY/xQACzydvrydyoBAG3wCzsUKxYkDKoMKhYfWlFM +KzD0LDDzLTDwKhYmLjDxLzDyKjD1+hYCKAAgb7D7FgEoACB+cPwWACgAIGZw/NeMGAAgXnD6mQgA +BhBYMPkWOCAFEFAw+RYDIMACOzBbou4vEjguMOwsEiYqMO36FikgCBBYMAy7DP28AAJhADag3bD4 +CgAoACBXsPgWISgAIH5w+RYgICUAt+D+FhogARBYMPsWNCAAEFAw+hYjL/8QWDArFi5gAD0AAAAr +Fhv+FhogARBoMP0WNC//EGgw/RYuIgAAU/BbpOItEiAsEiFbo1coEjQvEi4IuDf9EhsuAEBH8C8W +IyoSKSkSI/kWHCIAAFtwW6TWLRIgLBIhW6NMLxI0KBIu0w/5EiMuAQB+8PgSJi4AQEfw/hIaKAAg +SjD4+AgACBBoMAjdDCkxeysSHPThpWjABD5gLhIkDt4oCe42KDJ0ZIFvKUApxKAKmQIpRCkuFh4p +EiQoMXybEQ+aKPuXKAIAAGHw+xIfKMAEOiD4EiYqAwBCsCoWOfgWAyt0AVAw+hYAK3QBXDD7FgQr +dAE4MPoWAi90AXAw+goFIAYQWDBbopgpEjlkkQEe1t0pNionFjr+NikuACBycC0SOvkSHiAPADdg +LTYu/jYtLgAgc3BkmBQuNicpNihj+AsoMqdkjOMpQCkrCoALmQIpRClj/NQAABrXgi8WIvusBCIA +AGHwW2okLxIiLjIpY/Vv21Dz8l1gABBoMMDw8/yBYAAQYDDAUPlVNggBOwNg2lDz/INgABBoMBrX +cv42JyIAAGNw+AoAIgAAanD4NiggCAJasFtqEBzXDxrXaScyKC0yJ2PzpQAuNikb1179EhIgABBI +MPk2KiIAAGEwW2oGHNcEJDIZKjDvLTIqLjIp9zIoKgAgKrAqoIAqFiVj86YAAAAAAAAA8/cBYAAQ +aDAe1p0nFjpj/wUsMqdkzpQoQCkpCoAJiAIoRClj/oXAoCoWHPP+VWAAEHgwwOD57jYIAQODYPP+ +WmAAEGgwKhIaKxIXLRIVLBIULzDtLxYp/cwMAAEQQDD4FjQqACBm8FukUC8SKS4SGi0SFq/u/t0I +AAAQYDBbosIoEjT4CAYOAQBG8Aj/AfIWNyoA2xPQLRIV9w4GDAAgP3DyEjch/gJrcPI2KCwAQHdw +LTYnLzDvLhIp9zIZLgAgL/Av8IAvFiX3/ygAFQC3oPwKACEyADfg8ABYbAAgbLAALxYSLBIU+xIX +LAAgbLD9FhMiAABTsP3MDAABEGgw/RY0KgAgZvBbpCguEiktEhb+3QgAABBgMFuimy4SNC8SEv4O +BgwBAHLwDswB/RITKgBsexCn3vcIBgH+AnOw/zYqLgBAQ7D+NikiAABr8BzWpyow7gfZLCgyGv8S +JSQAIC6wJVCACCgs+TYbIgAgSjD4NhwiACAosP6cAAQAIHdw8goYLgAgF/ACiiwCmyz/uwgCAABq +MPuqCAB+AilwAvIs+iIIBABANXD6IhEABhBYMPIWACAFEFAwW6HpLBIUKxIX9TYrKgAgKLAKzAzy +NiwqACBm8Fvxl9egHdYnd9sKLkApwvAP7gIuRCkY1iTyCgAr+YQ6EMck0Q/aUPP6I2AAEGgwAACt +LRrW1C02Kfw2KiIAAGvw+6wEIgAAYfBbaXQnMhkpMO8tMiouMinyMigoACAucCmQgCkWJWP/DwAA +8/xoYAAQaDAqEhUqNica1sP8fAACAABosP82KCAIAlqwW2ljIjIoLTInKzDtKxYpY/5AAAAAAABs +EAbaIPscAAA9EGAwW3joGNa2iRAign8Kkjvyhn8iAAASsNEPAAAAbBAG2iD7HAAAPRBgMFt43hjW +rYkQIoJ/CpI78oZ/IgAAErDRDwAAAGwQCh7Wp4vjiOWJ5IziLeIBLRYBLBYCKRYEKBYF+xYDIgAA +ULD+4gAiAAApMP4WACA9EFgwW3ok86wAAD4ANqAvoAD61pgQgQA34CYcGPUWCCAAECAw0hCFIAVa +Alt6KPtcAAIAADqw+jwAAgAAYfBbnPjIp7gidindxirRD6N8K8AAwpz5sQpyAABTMGW/5GAAAbHK ++SIBL+EANqAroADToPW/sGQJACJwLAr/fEk0HtZ9jRgvCoCv7v7dCAAAEBAwItS80Q8AKQqA9RYI +KAAgSrD4UggAABAgMPQkvCAAEBAw0Q8Y1m+CGCkKgKmIqCL0JLwgABAQMNEPAAAAAABsEAbaIPsc +AAA9EGAwW3iU+NZmEAALLqDyEgAoACBBMPKE4CIAABKw0Q/SoNEPAABsEAbaIPscAAA9EGAwW3iI ++dZbEAAMrqAESAnyEgAoACBKMPKE3iIAABKw0Q/SoNEPAAAAbBAG2iD7HAAAPRBgMFt4e/nWThAA +DK6gBEgJ8hIAKAAgSjDyhN0iAAASsNEP0qDRDwAAAGwQBtog+xwAAD0QYDBbeG751kIQAAyuoARI +CfISACgAIEow8oTgIgAAErDRD9Kg0Q8AAABsEAbaIPscAAA9EGAwW3hh+dY2EAAMrqAESAnyEgAo +ACBKMPKE3SIAABKw0Q/SoNEPAAAAbBAG2iD7HAAAPRBgMFt4VPnWKhAADK6gBEgJ8hIAKAAgSjDy +hOAiAAASsNEP0qDRDwAAAGwQCh7WIYvjiOWJ5IzijeGdEZwSmRQoFgX7FgMiAABQsP7iACIAABkw +/hYAID0QWDBbeZj1rAAAjQA2oC+gAGTwhvMWCCAwAjhw8ABTYAAQIDC4InchbYMgDwIADwIA2jBb +eZr7PAACAAAysPpcAAIAAGGwW5xqZa/XpWwrwADCnPmxJ3IAAFMwZb/F+SIBIDUANqAroADVoPSw +F2QJACJw8/+yYgAAEHAAAADz/9xgAgJTMB3V9owYrcz0xOAgABAQMNEPxirRDx/V8P9PCAAAEHAw +/vTgIAAQEDDRDwAAbBAIJgoAJhYA9hYBIgAAULD2FgIgWxBYMFt5ZvOsAAHCADagwLD/HBAgXRBQ +MPgKCyIAACvwbYoco74t4AD60RxyAABi8PTQL2ACAlrw/fQAIAICe/D8CgsgFgJw8PocECACAhuw +9ckIAgAAWHD2lAAgABBgMFt39fo8AAA9EFgwW3lM86wAAVoANqCKEMDADwIA9aA1YCACaHAZ1Xv7 +1QcbkAQ5IAqZCCmdAvALBwDAAkpwAElhAElhAElhAElhAElhAElhAElhAElh+gosIAsQWDDTD226 +F6POK+AAerEX9LEBYAICYzD71AAgAgJrcPwKCyAWAnDw+hwQIAICG7D7HAQsACAvMPbUACAAEGAw +W3fOZqDUEtWm2iBbeTPcoPssAAIAAFDwW5wFzKfwAB9gABA4MAAS1Z/aIFt5K9yg+ywAAgAAUPBb +m/1loJLAcfo8AAAsEFgwW3kW/AoAIIIANqD+CgsgIAJIcNMPbeoVK6AA9LARYAICUrArlAD8zAEg +AgJKcMDLKhwQ+xwILgAgLzD29AAgABBgMFt3q/0SACAAJK6gGNWEixINSQv8EgEpwAQ+YPCxBAgA +IEowLYSDJ4SF/IVDIAEQSDDwmRoABBAQMCKEgPmEhCIAABKw0Q/GKtEPxqrSoNEP0qDRD2wQDB/V +cov0iPby8gkiAABQsPTyCCIAABkwhfeJ9YzzjfKO8Z4RnRKcE5kVlReUGJIZmBabFC/yAP8WACA9 +EFgwW3jg9qwAAEYANqAooADAkPvVMhCvADYgCZQC8xYMIFACEHDTEIUwDwIADwIABVoCW3ji+1wA +AgAAOrD6bAACAABh8FubssinuDNyOdfGKtEPpnwrwADC3P2xCnIAAFMwZb/kYAABscr5MgEv4QA2 +oC6gANag9e+qZAkAInAb1ReKHC8K//9BUnoAIFqwGdRuLK0B/MyAIAEQWDD0xLwgGgB9MC2Rfwvd +Ai2Vf35HJS6Rf8D0D+4C/pV/IAAQEDDRDwAAKQqAqbj4OAgAABAQMCKEvNEPwCDRDwAALK0B/MyA +IAAQWDD7xLwgABAQMNEPAAAAbBAG2iD7HAAAPRBgMFt3RhjVI4kQIoJ/CpI78oZ/IgAAErDRDwAA +AGwQBtog+xwAAD0QYDBbdzwY1RqJECKCfwqSO/KGfyIAABKw0Q8AAABsEAbaIPscAAA9EGAwW3cy +GNURiRAign8Kkjvyhn8iAAASsNEPAAAAbBAG2iD7HAAAPRBgMFt3KBjVCIkQIoJ/CpI78oZ/IgAA +ErDRDwAAAGwQBtog+xwAAD0QYDBbdx4Y1P+JECKCfwqSO/KGfyIAABKw0Q8AAABsEAbaIPscAAA9 +EGAwW3cUGNT2iRAign8Kkjvyhn8iAAASsNEPAAAAbBAG2iD7HAAAPRBgMFt3ChjU7YkQIoJ/CpI7 +8oZ/IgAAErDRDwAAAGwQBtog+xwAAD0QYDBbdwAY1OSJECKCfwqSO/KGfyIAABKw0Q8AAABsEAba +IPscAAA9EGAwW3b2GNTHiRAign8Kkjvyhn8iAAASsNEPAAAAbBAG2iD7HAAAPRBgMFt27BjU0YkQ +IoJ/CpI78oZ/IgAAErDRDwAAAGwQBtog+xwAAD0QYDBbduIY1MiJECKCfwqSO/KGfyIAABKw0Q8A +AABsEAbaIPscAAA9EGAwW3bY+NS+EAALLqCJECKCgAkiKPKGfiIAABKw0Q/SoNEPAABsEAbaIPsc +AAA9EGAwW3bMGNSziRAign8Kkjvyhn8iAAASsNEPAAAAbBAG2iD7HAAAPRBgMFt2whjUqokQIoJ/ +CpI78oZ/IgAAErDRDwAAAGwQBtog+xwAAD0QYDBbdrj2oB9iAAASsPo8AAIAAFkw/QpwIgAAYXD/ +EgAgARBwMFgc8dEPAAAAbBAG2iD7HAAAPRBgMFt2qvagH2IAABKw+jwAAgAAWTD9Cm8iAABhcP8S +ACABEHAwWBzj0Q8AAABsEAbaIPscAAA9EGAwW3ac9qAfYgAAErD6PAACAABZMP0KbiIAAGFw/xIA +IAEQcDBYHNXRDwAAAGwQBtog+xwAAD0QYDBbdo72oB9iAAASsPo8AAIAAFkw/QptIgAAYXD/EgAg +ARBwMFgcx9EPAAAAbBAG2iD7HAAAPRBgMFt2gPagH2IAABKw+jwAAgAAWTD9CmwiAABhcP8SACAB +EHAwWBy50Q8AAABsEAbaIPscAAA9EGAwW3Zy9qAfYgAAErD6PAACAABZMP0KciIAAGFw/xIAIAIQ +cDBYHKvRDwAAAGwQGBvUUPwKkCIAAFBwW5Y2+iwAAD0QWDBbd7vyrAACFgA2oCigACMWJiUWJfQW +JCCHADYg9QosIAAQSDD5Ficg/gIgcPAAW2AiAiEwuGb/AgAGAPGlkCdiAAd6Alt3uPt8AAIAABqw ++iwAAgAAYPBbmohlr9aiNy1wAPXRMXIAAHHwZd/G+WIBIawAN6AqEico4AD6mgICAAATsPoWJyAd +ADYg8/+vYgAAMHAAAAAA8//SYAICcfDAsCsWJyoSJiwSJfsSJCBYEGgw/xInIAQQcDBYHHUsEif6 +0zcQAhAQMA8CAP/HDXABEHAwLaHDAt0CLaXDLxIn/fcNcAgQKDAoocMFiAIopcMpEif8lw1wEBBo +MCuhww27AiulwywSJ/rHDXAgEBgwL6HDA/8CL6XDKBIn+YcNcEAQMDApocQOmQIppcQrEifTD9MP +eLcNLKHF0w8PAgAOzAIspcUvEifTD9MPd/cNKKHF0w8PAgACiAIopcUc0/QvEiQpEicrwn8oGoAI +mAEI+zn7xn8gHgBacCmhxtMPDpkCKaXGKxIn0w/TD3W3Cyyhxg8CAALMAiylxi4SJ37mCC+hxgb/ +Ai+lxigSJ3SHCCmhxg2ZAimlxisSJ3O3CCyhxgPMAiylxh7T2x/T2y7hfn/sTS8SJ3L3Ciihx8CV +CYgCKKXHKxInDwIAcbcKLKHHwOYOzAIspccvEidw9wgooccFiAIopccpEid/lhMroccNuwL7pccg +ABAQMNEPxirRD8Ag0Q8AAGwQCtog+xwAAD0QYDBbddT2oMxiAAASsBvSuA8CAA8CAPuwgCAgAmBw +/woBIAQQcDD9CgggAhAwMPsHQAACEEgw9xYIJgBATvD5EgAgAE3+0P8WBCAAXfrQ2vCfFPyvCgAC +AlKw9vYAIAgCe/D+tgEOAAf20CqsAf72ACAIAnvw/bwBDgAGbtD99gAgAgJSsGSgTP+XFHAAEHgw +ixiIFMDxC484YAADAAAAAH6XCvgKAiC+ADXgCP8CfZcFZGDIDv8CfJcFZMB3Df8C2jD7TAACAABh +cP0KXSABEHAwWBvi0Q8AAAAAAAD+twxwABBQMGP/ZwAAAAAA/rYBAFgAdvDfwPP/b2AAEFAwAAAA +AAAA/rYBAIgAdvDa8PP/V2AoAnhwAAAAAAAA/bwBAWgAcvAvHBDz/1FgABBQMAAAAAAA+QoDICAC +WHAKmS4LmQqJkPP/d24JAH5w/bwBAIgAcvDa8PP/ImAoAnhwAAAAAAAA+woBICACQHAKuy4IuwqL +sPP/NW4JAH7w/goCICACQHAK7i4I7gqO4PP/Jm4JAH+w8/7vYgAAU/BsEAbaIPscAAA9EGAwW3Vq +9qAfYgAAErD6PAACAABZMP0KaCIAAGFw/xIAIAQQcDBYG6PRDwAAAGwQBtog+xwAAD0QYDBbdVz2 +oB9iAAASsPo8AAIAAFkw/QpmIgAAYXD/EgAgAhBwMFgbldEPAAAAbBAG2iD7HAAAPRBgMFt1Tvag +H2IAABKw+jwAAgAAWTD9CmQiAABhcP8SACACEHAwWBuH0Q8AAABsEAbaIPscAAA9EGAwW3VA9qAf +YgAAErD6PAACAABZMP0KYiIAAGFw/xIAIAIQcDBYG3nRDwAAAGwQBMAg0Q8AbBAG2iD7HAAAPRBg +MFt1MPagN2IAABKw+jwAAgAAWTD9CmAiAABhcP8SACACEHAwWBtpiBAa0nT7CkAgDwA2ICmhfwuZ +Aimlf9EP0Q8AAABsEAbaIPscAAA9EGAwW3Uc9qAfYgAAErD6PAACAABZMPxcAABcEGgw/xIAIAEQ +cDBYG1XRDwAAAGwQBtog+xwAAD0QYDBbdQ72oB9iAAASsPo8AAIAAFkw/FwAAFQQaDD/EgAgAhBw +MFgbR9EPAAAAbBAG2iD7HAAAPRBgMFt1APagH2IAABKw+jwAAgAAWTD8XAAAUBBoMP8SACABEHAw +WBs50Q8AAABsEAbaIPscAAA9EGAwW3Ty9qAfYgAAErD6PAACAABZMPxcAABAEGgw/xIAIAQQcDBY +GyvRDwAAAGwQBtog+xwAAD0QYDBbdOT2oB9iAAASsPo8AAIAAFkw/FwAADgQaDD/EgAgBBBwMFgb +HdEPAAAAbBAG2iD7HAAAPRBgMFt01vagH2IAABKw+jwAAgAAWTD8XAAALBBoMP8SACAEEHAwWBsP +0Q8AAABsEAbaIPscAAA9EGAwW3TI9qAfYgAAErD6PAACAABZMPxcAAAkEGgw/xIAIAIQcDBYGwHR +DwAAAGwQBtog+xwAAD0QYDBbdLr2oB9iAAASsPo8AAIAAFkw/FwAACEQaDD/EgAgARBwMFga89EP +AAAAbBAG2iD7HAAAPRBgMFt0rPagH2IAABKw+jwAAgAAWTD8XAAAIBBoMP8SACABEHAwWBrl0Q8A +AABsEAbaIPscAAA9EGAwW3Se9qAfYgAAErD6PAACAABZMPxcAABeEGgw/xIAIAEQcDBYGtcZ0jAo +kH3AoQqIAiiUfdEPAGwQBmgxA8Yq0Q/aIPscAAA9EGAwW3SL+NJ4EAAPrqD5EgAoACBBMCiNASKA +PQkiNvKEPSIAABKw0Q/SoNEPAABsEAbaIPscAAA9EGAwW3R9GNJriRAign8Kkjvyhn8iAAASsNEP +AAAAbBAI+iwAAD0QWDBbdc7zrAAA7AA2oP4KLCAAECAw9RwAAgAAaHD8CgAgCxBAMG2KF6PKK6AA +frEX9LC3YAICYzD71AAgAgJrcPwKCyAWAlDw86wBICACWHD6HAAIACAvMPSUACAAEGAwW3Rc9qCK +YAAQSDD6HAAACxBYMNMPbboaKzAA+ZwBIgAAYnD0sA9gAgIY8PukACACAlKwLAoL2hD1zAgAKAJY +cPTEACAAEGAwW3RK+NI5EAAhLqAe0JyNFIkVIuJIL+JK85kQDFAEP2D53QICAEBAsPj/AQIJABNw +8uZILAkAf3D95koiAAASsNEPAMaq0qDRD9Kg0Q/RD2wQCPosAABbEFgwW3WO8qwAANcANqDzCgAi +AAAgcP8KXSIAAHBw+woAIAsQQDBtihyiui2gAP/RHHIAAGLw9NAvYAICWvD95AAgAgJzsPwKCyAW +AlCw8qwBICACWHD6HAAIACAnMPOUACAAEGAwW3Qb+iwAAD0QWDBbdXL5CgAgaQA2oPscAAALEGAw +0w9tyhotoAD5nAEiAABicPTQD2ACAlKw/bQAIAICWvAsCgvaEPTNCAAoAlhw89QAIAAQYDBbdAby +EgQgABCuoP/R9BDMEEAwCCIo/hIFLgAgF/D+9N8gABAQMNEPxirRDwAAAGwQCPosAABbEFgwW3VS +8qwAAOgANqDzCgAiAAAgcP8KXSIAAHBw+woAIAsQQDBtihyiui2gAP/RHHIAAGLw9NAvYAICWvD9 +5AAgAgJzsPwKCyAWAlCw8qwBICACWHD6HAAIACAnMPOUACAAEGAwW3Pf+iwAAD0QWDBbdTb5CgAg +egA2oPscAAALEGAw0w9tyhotoAD5nAEiAABicPTQD2ACAlKw/bQAIAICWvAsCgvaEPTNCAAoAlhw +89QAIAAQYDBbc8r+EgUgABkuoPIKACAGADeg0Q+CFP/RthDMEEAwCCIoov/4/QEgBxAQMCKEPfP2 +UiAAEBAw0Q/GKtEPAABsEAbaIPscAAA9EGAwW3O3GNGpiRAigIAKkjvyhIAiAAASsNEPAAAAbBAG +AioC+xwAAD0QYDBbc61moHod0ACLEC/QwS3SMvjQwxQAEEgw/w9AAAEQcDD73SgOBQB/sA+YOfjT +JnAAEFgw+AoKIAwQYDAPjDltCA+xzADBBADpGvnTCHACAlrwY//pAB3QWC/SrMCH8tA3GAMAQvAA +gQQA7Bry/wENAAQ7IA/MAvzWrCIAABKw0Q/SoNEPAGwQBtog+xwAAD0QYDBbc4j2oBhiAAASsBvP +2o0QK7IyDbooCkoUb6EGW3Nv0Q8AAB7Rc8CkC+4s/NFyEAEQWDBbnEkaz6tj/98AAABsEAYY0W3T +D9MPKYEAKRUAKIACKBQCW3NnCoNBbzNE2iD8Cj0gCAJYcFtzbvzQIhAAJi6gK8LxjRGhPv7gACPo +EHgwD90oDt0s+wtHDYAEP2ANuwL7xvEiAAASsNEPAAAAAAAA+goCIAEQWDD80VQSAABo8FucKccr +0Q8A0qDRD2wQDBzRT8ffnRSLwYjDicIpFgIoFgMrFgH8wgAiAABQsPwWACBbEFgwW3So8qwAAVIA +NqAqoAAuCmB662QvCnp6817TEPcKOiAgAihwhDDaQFt0rPtMAAIAADKw+iwAAgAAYbBbl3zKo7gz +dTne8goAIAAQGDD5CgEgABBQMPKaOAAAEEAwCpg4zYdgAPOibCvAAPrMAAYA8r7QZb/KYAHcAMAw +/AoAIF0QaDD7HCAgABAgMP4KCyIAACrw0w9t6heizirgAH2hF/SgL2ACAmMw+rQAIAICWvD8Cgsg +FgJwsPocICACAhOw9c8IAGACWHD09AAgABBgMFtzGvosAAA9EFgwW3Rx8qwAAHcANqAroAD9Ci8g +HAA24AqsAm0IDX2xYivAAfSwCGACAmMwY//rAIgUZIBQwMD6CgsgQAJIcG2qFSogAPSgEWACAhCw +KpQA/MwBIAICSnDAy6XL/AoAIEACUHD0tAAgaAJYcFty/Qr+UP0KASAAEGAwDtw4ZcCqxirRD5QU +wMD/CgsgQAJQcG36F6LOK+AAfbEX9LCbYAICYzD7pAAgAgJSsPwKCyAWAnCw+hwgIAICE7D1yAgA +aAJYcPSEACAAEGAwW3Ll+vZQAABkLqDAwPoKCyBAAkhwbaoVKiAA9KARYAICELAqlAD8zAEgAgJK +cMDLpcv8CgAgQAJQcPS0ACAgAlhwW3LV+woBIAAQYDAGvDj0z2FoHwFUMMDQCb04ZN9UyTNoO1XB +4X4xNMAg0Q8A8/+Qb+oQUDAYz7aCHKgiKCKAiRT/Eg0v/xBQMAqZAwmIAQj/Av8mgCAAEBAw0Q8A +Gs+ZixyMFI0dW3KywCDRD7HKgzHz/fJiAAASsBrPlIscjBSNHVtyq8Ag0Q8AAAAA+goBIAAQSDAG +qThln4Jj/tQAAABsEAr6LAAAPRBYMFt0BPOsAAEPADag9QoAIgAAMHD3CgAgIAIQcPQKLCAAEFAw ++AoLICACcHBtihyjrCvAAPSxHHIAAGqw9LBiYAICUrD75AAgAgJzsP0KCyAWAmDw+hwQIEACWHDy +2QgAAgIbMPeUACAAEGAwW3KPZqAv+hIIIAICKXD6ZAAgAgIxsPlSnmAAEFAwHNCAKxABLRAALcR8 ++8R9IAAQEDDRDwAA+TwAAAAQUDD+CgsgIAJYcNMPbeocLpAA3aD6rAEiAABicPTgFGACAkpw/rQA +IAICWvD9CgsgFgJg8PocECBAAlhw8t8IAAICGzD39AAgABBgMFtybWagIP8CAAH/ugVgsV380GIQ +BBBQMPsKASACEHAwW5szxirRD9Kg0Q8AAABsEAb6LAAAPRBYMFtzufOsAADyADag9dBWEAAQMDDy +HAAAABA4MPQKLCALEEAw+goAIgAAYHBtihyjrSvQAPSxHHIAAHKw9LCWYAICUrD7xAAgAgJjMP4K +CyAWAmjw+hwAAAICG3Dy6QgCAABZcPeUACAAEGAwW3JE96BOYAAQcDDZEP08AAALEFAw0w9tqhQq +0ADJpvqUACACAnOw/dwBIAICSnD+CgsgFgJo8PPcASIAAFBw8u0IAgAAWXD31AAgABBgMFtyMGag +HPVcBCACAjGw+AoLJf+rmaDSoNEPAPP/lW/qEFAwaGTv3WD80CEQAhBQMPsKASAEEHAwW5rwxirR +D8Ag0Q9sEAb6LAAAPRBYMFtzd/OsAAD6ADag9dAWEAAQMDDyHAAAABA4MPAAFmAsECAwAAD2bAEg +CxBAMPVcBCYAZkWQwKD+HAAACxBIMG2aHKOsK8AA9LEccgAAarD0sKJgAgJSsPvkACACAnOw/QoL +IBYCYPD6HAACAABZcPLdCAACAhsw99QAIAAQYDBbcf33r59gABBoMNkQ/DwAAAsQcDDTD23qFCrA +AMmm+pQAIAICa3D8zAEgAgJKcP0KCyAWAmDw+hwAAgAAWXDy3wgAAgIbMPf0ACAAEGAwW3HpZ69Q +wIt4YSPdYPzP4xACEFAw+woBIAsQcDBbmrDGKtEPAAAA8/+Jb+oQUDDSoNEPwCDRD2wQBvosAAA9 +EFgwW3Mz86wAAO4ANqD1zjYQABAwMPIcAAAAEDgw9AosIAsQQDD6CgAiAABgcG2KHKOtK9AA9LEc +cgAAcrD0sJZgAgJSsPvEACACAmMw/goLIBYCaPD6HAAAAgIbcPLpCAIAAFlw95QAIAAQYDBbcb73 +oE5gABBwMNkQ/TwAAAsQUDDTD22qFCrQAMmm+pQAIAICc7D93AEgAgJKcP4KCyAWAmjw89wBIgAA +UHDy7QgCAABZcPfUACAAEGAwW3GqZqAc9VwEIAICMbD4Cgsj/6udoNKg0Q8A8/+Vb+oQUDBoY+/d +YPzPnhACEFAw+woBIAMQcDBbmmrGKtEPbBAIH8+Zi/SI9vLyByIAAFCwifWM843yjvGeES0WAiwW +AykWBSIWBygWBisWBC/yAP8WACA9EFgwW3Lm9KwAADYANqDCfPIcAABAAihwgyAPAgAPAgADOgJb +cuz7PAACAAAysPpMAAIAAGGwW5W8yKe4InUp18Yq0Q+kbCvAAPexCnIAAFMwZb/mYAABscr4z3cf +4wA2oIkhwCAKkjnyhIAgABAQMNEPbBAM+iwAAD0QWDBbcsj0rAABCwA2oPMKACIAADBw989qEAAQ +EDDwAClgLBAoMACOHMWn/wIACgB28pD/AgAKAHL10P5lACACAhjw9mwCKgB3hODAoPsKCyBAAmhw +bbocpKwrwAD1sRxyAABysPSwMmACAlKw+9QAIAICa3D+CgsgFgJhMPscMCBAAlBw9MwBLAAgV7Dy +1AAgABBgMFtxSWevi/lMAAAAEFAw/goLIEACWHDTD23qHC2QAN6g+qwBIgAAYnD00BRgAgJKcP20 +ACACAlrw/goLIBYCYTD7HDAgQAJQcPTMAS4AIFew8vQAIAAQYDBbcTP2oGRgDxBAMP8CAAf/lcTQ +sT38zzAQBBBQMPsKASAQEHAwW5n4xirRDwAAAPoKBCABEFgw/M8pEgAAaPBbmfHGKtEPAAAAGs5Q ++BwAABAQSDBtmg/5gQAgBAJSsPmlrSAEAkIwwCDRD9Kg0Q9sEAbaIPscAAA9EGAwW3EU9qAXYgAA +ErCIEBvOFQgJR/i0fiQSAL5gaJMB0Q/GKtEPAAAAbBAG2iD7HAAAPRBgMFtxBxjPC4kQIoJ/CpI7 +8oZ/IgAAErDRDwAAAGwQCBnPBQ8CAA8CAIiRKBYB+ZIAIgAAULD5FgAgPRBYMFtyUvOsAADwADag +wFD3HAAAIAIQcPYKACAsECAw8AAPYAsQWDAAsVX7CgsiAFuRYPwcECAAEFAwbboco60r0AD0sRxy +AABysPSwj2ACAlKw+8QAIAICYzD+CgsgFgJo8PPcASAgAlBw91sKDAAgF7D21AAgABBgMFtw2vev +p2AAEHAwKRwQ/TwAAAsQeDDTD236FCrQAMmm+pQAIAICc7D93AEgAgJKcP4KCyAWAmjw91sKAAIC +G3Dy6AgAIAJQcPaEACAAEGAwW3DG969XYAIQKDDSoNEPAAAAAPP/nG/qEFAwG87GiRGMECy0gPm1 +RSIAABKw0Q/GKtEPbBAG2iD7HAAAPRBgMFtwtvagFGIAABKwiRAbzbcJCEf5tH8iDAC+INEPxirR +DwAAbBAG2iD7HAAAPRBgMFtwqhjOsYkQIoJ/CpI78oZ/IgAAErDRDwAAAGwQBtog+xwAAD0QYDBb +cKAYzqiJECKCfwqSO/KGfyIAABKw0Q8AAABsEAgZzqIPAgCIkZgR+ZIAIgAAULD5FgAgPRBYMFtx +7POsAADwADagwFD3HAAAIAIQcPYKACAsECAw8AAPYAsQWDAAsVX7CgsiAFuRYPwcECAAEFAwbboc o60r0AD0sRxyAABysPSwj2ACAlKw+8QAIAICYzD+CgsgFgJo8PPcASAgAlBw91sKDAAgF7D21AAg -ABBgMFtw3vevp2AAEHAwKRwQ/TwAAAsQeDDTD236FCrQAMmm+pQAIAICc7D93AEgAgJKcP4KCyAW -Amjw91sKAAICG3Dy6AgAIAJQcPaEACAAEGAwW3DK969XYAIQKDDSoNEPAAAAAPP/nG/qEFAwG87L -iRGMECy0gPm1RSIAABKw0Q/GKtEPbBAG2iD7HAAAPRBgMFtwuvagFGIAABKwiRAbzb8JCEf5tH8i -DAC+INEPxirRDwAAbBAG2iD7HAAAPRBgMFtwrhjOtokQIoJ/CpI78oZ/IgAAErDRDwAAAGwQBtog -+xwAAD0QYDBbcKQYzq2JECKCfwqSO/KGfyIAABKw0Q8AAABsEAgZzqcPAgCIkZgR+ZIAIgAAULD5 -FgAgPRBYMFtx8POsAADwADagwFD3HAAAIAIQcPYKACAsECAw8AAPYAsQWDAAsVX7CgsiAFuRYPwc -ECAAEFAwbboco60r0AD0sRxyAABysPSwj2ACAlKw+8QAIAICYzD+CgsgFgJo8PPcASAgAlBw91sK -DAAgF7D21AAgABBgMFtwePevp2AAEHAwKRwQ/TwAAAsQeDDTD236FCrQAMmm+pQAIAICc7D93AEg -AgJKcP4KCyAWAmjw91sKAAICG3Dy6AgAIAJQcPaEACAAEGAwW3Bk969XYAIQKDDSoNEPAAAAAPP/ -nG/qEFAwG81miRGMECy0ffm1RCIAABKw0Q/GKtEPbBAI+iwAAD0QWDBbca/zrAABWAA2oBfNFvbM -hRAAECAw9QosIAAQYDD8FgUgABBQMPAAO2ALEEgwGcx9BB8UB/8KLfKu+goAL/8QcDD+mAMAAgIh -MPjdAQALEEgw+BIFLAkAbvD99q4mAH+RIGWA990QbZoco64r4AD1sRxyAAB6sPSwumACAlKw+9QA -IAICa3D/CgsgFgJw8NoQ8+wBICACWHDx/ggAABBoMP3kACAAEGAwW3AqCqIC9yBaYgAAcPABGQL/ -CgAgCxBAMG2KFCvgAMm2+5QAIAICe/D+7AEgAgJKcP8KCyAWAnDwseP7HBAiAABQcPkKACwAIA/w -+dQAIAAQYDBbcBb2oFpiAAASsC4KAS4WBRrNS44UKqJ/DqsoLDroDLsse2Mb+c4YE/+E/RDz/wRr -AAQ+4AAAAADz/3Zv6hAQMB/OEvzOEhABEFgwCv8s/UwAAAQQUDBbmM4bzDNj/8QA0Q/RD2wQDhvO -CvocAABIEGAwW4/L+iwAAD0QWDBbcVDyrAAAfAA2oCigANMPZIBv9woAIJACMHDwAA1iAAAYcAAA -AAC4M3YxVoQw2kBbcVL7TAACAAAqsPosAAIAAGFwW5QiZa/dolwqwADC3P2hN3IAAFswZa/L+TIB -ICQANuAusADSsPXvr2YJAD5wLxoMf3AMEs3o9yZ/IAAQEDDRD8Yq0Q8AAAAA8//MYAICWzBsEAT6 -LAAAPRBYMFtxKfKsAAAbADagE83c2jBbcTPcoPs8AAIAAFCwW5QEyKLGKtEPGM3WGs3XIoJ/Gc0W -CiIBCSIC8oZ/IAAQEDDRDwAAAGwQFhvN0PwKeCIAAFBwW4+M+iwAAD0QWDBbcRH0rAAAgAA2oCig -AA8CAA8CAGSAqfkKACDwAjBw+RYhICwQODDwAA1iAAAQcAAAAAC4InYhToMg2jBbcRD7PAACAAAq -sPpMAAIAAGFwW5PgZa/dpFwqwAD3oVlyAABbMGWvzfkiASAeADbgLBIhKrAA/JwCAgAAIvD8FiEv -qAC2oGAAPwDGKmYgMhrNgS0SIC6hfn3sBi2lf9EPAAD+oX8gARBYMPzNohAEEFAwW5hZxirRDwDz -/6pgAgJbMNEPwPAvFiEiEiEiFiDz/7lgABAQMAAAAGwQFhvNlPwKeCIAAFBwW49Q+iwAAD0QWDBb -cNX0rAAAiQA2oCigAA8CAA8CAGSAl/kKACDwAjBw+RYgICwQODDwAA1iAAAQcAAAAAC4InYhV4Mg -2jBbcNT7PAACAAAqsPpMAAIAAGFwW5OkZa/dpFwqwAD3oUlyAABbMGWvzfkiASAnADbgLBIgKrAA -/JwCAgAAIvD8FiAvqAC2oB7NSPzlfiAAEBAw0Q8SzUQvIX7/JX4v6hAQMNEPAAAAAAAAAPP/umAC -AlswGc09wID4lX4gABAQMNEPAGwQBi0gAPs8AAIAAGEw+lwAAD0QeDD/0SlwABAwMMU7c9Ef3iBt -CBX00EhgAgIxsC3gAf/RDHACAnOwc9EEY//jAAAXzVCbEvwWASAAEBgw+hYAICACIfAlcn/bIPxs -AAIAAFFwW5NvyKy4d/R56HAQAhjwxirRD9pQW3CVdqnpGsuHGM1Bqjp4oeiLEiitFCiCOYwR/RIA -IgAAULALgADSoNEPbBAG3ED6IAAiAABpcPIWAyAAEDgw/jwAAD0QeDD/oS5yAAAYsMUrcqEk2zAP -AgDTD20IFfSgSGACAjnwKrAB/6EMcAICWvByoQRj/94AABbNJp4S/BYBIAAQEDD9FgAgoAIpsCRi -f9sw/HwAAgAAUTBbk0PIrLhm9WnocBACELDGKtEP2kBbcGl3qekay1sYzReqKnih6IsSKK0UKIIl -jBH9EgAiAABQ8AuAANKg0Q9sEAbcQPogACIAAGlw/wo9IgAAcPDyFgMiAAAYsP+hLHAAEBAwxUt0 -oSLbMA8CANMPbQgV9KCNYAICELAqsAH/oQpwAgJa8HShAmP/3hXM/Z0SnBGeEBbM+vAAD2AAEDgw -ALhm9WFdcBACOfAkYn/bMPwsAAIAAFEwW5MVZa/i2kBbcD5yqdoayzAYzO+qenihMosQabEUjBEt -Ov99yQwezAov4oAu4n+v7p4RixAorRMoghWMEf0SAiIAAFDwC4AA0qDRD8Yq0Q8AAABsEAbcQPog -ACIAAGlw/wo9IgAAcPDyFgMiAAAYsP+hKHAAEBAwxUt0oR4DOwJtCBX0oFpgAgIQsCqwAf+hCnAC -AlrwdKECY//jFczOnhKcEZ0QFszL8AAPYAAQODAAuGb1YSpwEAI58CRif9sw/CwAAgAAUTBbkuNl -r+LaQFtwDHKp2hrK/hjMwKp6eKkExirRDwCLEiitEiiCHYwR/RIAIgAAUPALgADSoNEPAAAAAGwQ -BBrK7xnMtSyiSPqiSiDMEGgwDS0o9MrtEDQQWDDyyjgIACBucPmQ3Sh3AVAwC4gc88y0FAAgQTD0 -QgAgygA2YP8CAAAAYQZg/wIAAgBdAmD/AgACAFkGYP8CAAQAVQJgE8yfCtlByJlokQppkg1gAAcA -AAMzFANDFANTFAMKSVt8uwoMX/vMlxIAAFCwWj1sG8uRA9oU0w8LqgJbfLQKDF/7zJESAABQsFo9 -ZQOqQlt8rwoMX/vMjRIAAFCwWj1g+8tDG/AEOSBbfWTcoPvMiBIAAFCwWj1aG8yG+iwAAAoQYDBa -PVYbzIT6LAAAChBgMFo9UxvMgfzMgRIAAFCwWj1PwCDRD2P/WQBsEAgXyqwTzH4ockgnckoUzHsV -zHzyhzgAABAwMPosAAIAAFkwWjo/CuhB+ilBAhoAuiBvkgVvogJusgHAYfosAAIAAFjwWjo3JE0C -8z0CIZoIKTD6TkIMQAFQMPrPQgxIAVQw/903DAEAczANzDf7zGYcACBhsPzMAyIAAFCwWj0t+8xi -EgAAULD8CgcgARBoMFo6Q/vKphIAAFCw/AoHIAEQaDD4HBAgChBwMPgWACABEHgwWjogyaDAovzM -VRAIEFgwW5bxxyvRDwD7zFASAABQsPwKByACEGgwWjow+8qUEgAAULD8CgcgAxBoMPkcECAKEHAw -+RYAIAEQeDBaOg7JpsCi/MxDEAgQWDBblt/HK9EPAAAAAAAAAPvL3hDMEHgwDy8o/QqAIAAQcDD/ -uwgMOwE4MPm9ASo9ATgw+pQ+ICEANyD4wUtgARB4MGjCTGnDFi6UPC6UPWAADQAAAAAAAP6UPiIA -AFOwLwr//bwID6AEOqD7wLwsAwB/sP3EviIAAFCw/MC9LOABbDBbfKXSoNEPL5Q8L5Q9Y//MLpQ8 -L5Q9Y//DbBAI+8wbEgAAULD8CgEgARBoMFo5+fvMFxIAAFCw/AoBIAAQaDD+CmQgIAJAcPgWACAU -EHgwWjnWyK/AovzMDhAIEFgwW5anxyvRD/vMCRIAAFCw/AoBIAAQaDBaOeb7zAUSAABQsPwKASAB -EGgw/gpkICACSHD5FgAgFBB4MFo5xMmmwKL8y/0QCBBYMFuWlccr0Q8AAAAAAAAA/MsdEgAAULD9 -ye4QIAJYcPsWACDIEHAw+8vzEAoQeDBaObTIr8Ci/MvwEAgQWDBblobHK9EPwCDRDwAAbBBa0yD7 -y9oSAABQsP0KACIAEGAwWjnCGMvpGsvmGcvmG8vjHMvWH8vm/xadIIACaHAtFp8sFpkrFpopFpwq -Fpv4Fo0gwAJQcPoWoCAFEEAw+BaSIAAQSDD5Fpgg/gJwcPvL2RBiAnOwLhah/MvWEEACcHAuFp4s -Fo8rFo4pHQH5FqIgoAJKcCkWkGABJwAAAAgiNcCl/MvNEAgQWDD9TAACAABwsFuWWd1A+goFIAgQ -WDD8y8cQDAIQsP4sAAIAAHiwW5ZSJBKN+jwAAgAAWTBaOXTyBUYACBBYMPoCRwWABD1g/Mu8EgkA -KLD6CgUiAABosFuWRdwg+jwAAgAAWTBaPGwiEpglEo4mEo/3EpAiAABQ8PsSnSAAEGAwWjxlKhKi -KRKhLBKeLhKfLxKgLRKcKxKbKBKdJE0CJm0CJV0C9RaOIAICELAiFpj2Fo8gIAI58CcWkCQWjSiN -Aiu9Av3dAiAgAnvw/xagIAgCc7AuFp/9FpwgCAJjMCwWnisWm/gWnSAgAkpw+RahICACUrAqFqIp -EpkqEpooEpIpnQIqrQL6Fpoh/gJCMCgWkvkWmSJYADYg+xKZIgAAUPBaOTkkEo4lEo8mEpAnEqIt -Ep4rHQIuEqAvEqEvFqj+FqchQAJi8PwWpSFgAlrwKxam+tYAIAAQEDD6PAACAABZcFo5KSoWpPtM -AAIAAFDwWjklLRKkKBKnLhKoDZ9G/4YALMEBbDD95gAoAQBr8P35Ng7JAVAw/nYAKsEBUDD66zcM -AwBTsPwSpigDAGZw+xKlKAEAWjAqZgAoxgAptgAcy14pFgMoFgQtFgD+FgEgCBBYMPoWAiIAAHCw -/RKYIAUQUDBbleL0TAggEAIpcPkSqCAIAjGw+BKnIAgCOfD/EqYgAgIQsP4SpSAIAkpw+RaoIAgC -QjD4FqcgCAJ78P8WpiAIAnOw/halJf+XmKD7EpoiAABQ8Fo489Kg+xKbIgAAUPBaOPD7EpwmyAEQ -MPYWcCTAARQw9RZxJMgBUDD0FnIiwAFQMPIWcyIAAFDwWjjl/WwAAgAAcXD/TAAABBA4MPIWACAI -EFgw/MstEsgBUDDyFgEgBRBQMFuVtSoSmPMWjCACEHAw+qz8IgAASfD66TgA/xAwMPcKACAAVyZg -IhaL9B0CIP8QMDDzHQIhQAIhMPSUCgAAEDgw9BapIUACKPD0PLAhgAIY8I9AjVCOMPISiywAIH9w -DR0U/tgMAAUQUDD4IggCAAB4sPzLDRLAARAw8hYAIAgQWDBblZQoEqn2JjYGAQA8sPM8BCAIAilw -+Fm1cAgCITAjEoz6Ep8kACAx8AQUFPRM+i/6EEAw9KYAKIABJDDynOAr/kwWYMAl8/yRYgEAknBj -/8/aMCoWjFgBF2akBCoSjBvK8xzK81o7pSoSjBvK3fwKASABEGgwWji8G8ra+hKMIAEQYDD4HQIg -ABBoMP4KZCGgAkIw+BYAIBQQeDBaOJhlo8MqEowbys78CgEgABBoMFo4rRvKzPoSjCABEGAw+R0C -IAEQaDD+CmQhoAJKcPkWACAUEHgwWjiKZaPGG8rEHMnoHci6KhKMKB0C/grIIaACQjD4FgAgChB4 -MFo4gGWjdBrKsBnKsB/Ky/jKwBAAEGgw/RaKIAAQYDAsFoQoFpUvFqP5FoUgQAJYcPsWlCD+AnBw -+haGIIACWHD7FpMgwAJQcPoWlyBiAnOwLhaJKR0BHsqvKRaI/haWIKACSnApFocjEockEoglEokm -EpcnEpYiEpWMYI1QKhKMDwIA/90RDXAEOyD9zAICAABYsFo7W4xAjTAqEoz/3RENcAQ7IP3MAgIA -AFnwWjtU/hKjIAgCGPD0TAQgCAIpcPZsBCAQAhCw/imtcBACOfAlEoYjEoQkEoX6EowiAABZcFo4 -Q9ag+hKMIgAAWTBaOED8ypISAABCsP4SlCpIAVQw+xZ9KCoBNDD5FoEmJgE0MPcWgiIuATAw8haA -JkABVDD3Fn8iAAB5sP7iACIiATAw8haDJkwBUDD2FnwiRAFQMPIWfigqAXQw+RZ5Ki4BcDD6Fngo -IgF0MPkWeyomAXAw+hZ6IgAAaPD4FgAgBRBQMFuU+SsSff0dAiH4AkDw/woCIAQQUDAI+jj6oUFg -ABBwMP/c8CHAAktwbaoli5DTD/SxFmAIAkpw/wIAAACXBuD/AgACAJwG4LHu//wEIAgCa3AnEn8r -En0iEn4mEnwcylz6EowvgAQ64PwtEQ9ABD2g/X0CDgkAe7D+3QICAABZMFo4Hi0Sk43Q/MpSECAC -a3D9FpEsJQFsMPoSjC/ABD9g9NgRD4AEO2D47gIMCQB/cP7dAgIAAFlwWjgQJhKHJxKIIhKJ/MpE -EAUQUDD9EpEgCBBYMFuUxCkSlCoSkysSlygSli8SlS4SoyVdAiRNAiQWhfUWhiAgAjGw9haHICAC -OfD3FoggIAIQsPIWiSACAhjwIxaELu0CL/0C+I0CICACWvD7FpcgCAJSsPoWkyAIAkpwKRaUKBaW -LxaV/hajJf7anOAiEorRD4bQaGMP/wIAA/9ymaCL8My2YAB/AIvwy7KwvJzwY/7diND/AgAD/2ge -IIvwZb/pYAAxitBlrsaL8P+zQGACAmLwnPBj/rcAAAAAAAAA+goCIAgQWDD8yg8SAABo8FuUj8cr -0Q/6CgIgCBBYMPzKChIAAGjwW5SKxyvRDwAA+goCIAgQWDD8ygUSAABo8FuUg8cr0Q/6CgIgCBBY -MPzKABIAAGjwW5R+xyvRD9Kg0Q8AwKL8yd8QCBBYMFuUeGAADMCi/MneEAgQWDBblHT8yfUQAhBQ -MPsKCC/7EGgw/RaKIAUQaDBblG0iEorRD8Ci/MnREAgQWDBblGlj/89sECz7yd0SAABQsFo3i/vJ -2hIAABqw/MnkEgAAULBaOoobyeIcx70dx7zzFj4iAABQsFo3oCYKAPkcUCIAAFBw9cncEAAQWDAU -ydsTydsrFj0qFjwpFjvaIPtMAAIAAGGwWjp52iD7PAACAABhsFo6diRNAvM9AiG+CCkw2iBb/Y/T -oPYWTyAEHK6gIxI7JBI8FsnJF8nIJxZLJhZMF8nHFsnI+xJLIgAAULBaN2OaQPsSTCIAAFCwWjdf -+jYAIgAAWfD8CgAiAABQsFo6X9og+2wAAAAQYDBaOlsmbQIpEkwoEksnfQIpnQL4jQIgIAIY8PgW -SyAgAiEw+RZMIUoIKjAmEk/7ya8SAABQsFo3SisSPSZtICkSOyoSPCZsIPmcBCACAlrw+qwEJf+O -muAhFkUcyaAbyaD/yaQQABBAMCgWRi8WR/sWQSCgAlBw+hZEIIACaHAtFj8sFkMtFjgsFkguEkQo -EkWJ44rijeGPgIyDK4IBKIIC/uIAJsgBeDD2FjAuwAF8MP8WKCTIAVww9RYxKsABXDArFin+i0YO -wAFwMP4WSSTIAUAw9BYyKMABQDD4FiouyAFkMP8WMyzAAWAw/BYrKMgBaDAoFi0rFiz+FjQswAFs -MP0WNSrIAUww+xYvLMgBUDD8Fi4qwAFQMPoWNijAAUww+RY3KAMkEaAoCnj6CgEqAyQ2EMDgb1gB -saopCnh1mwGx7m9IAbGqKwp4dLsBse5v+AGxqiwKeH/LAbHuy6DK7m9oCC1tAS3cgC0WMG9YCC5d -AS7sgC4WMW9ICChNASiMgCgWMm/4CCn9ASmcgCkWM/YKACAAECgw8xoAIAAQIDD/bP8gABA4MP4c -fyAAEFAw/uxBIAQQWDBtuhvIYX+hDojg0w8IMzb4VQgEAQBBMPqsASAIAnOw80kMAAgQWDB5uiGx -Zv8CAAQC9ZWg9QoAIAEQUDD6FjkgABAgMPABt2EAEBgwJxY5+QoBIgAAQbD2mDkABBAgMAhEDARU -LPRgJ2TAASAw/h3/If4CebD8EkchgAJzsP5uCgAFEFAw/uJ/IgAAaTBbk6AvEigqCgD/+AdgABBw -MCoKASkSKCgKeHmLAcDhKxIpb7gBsaotEiksCnh9ywGx7i8SKm/4AbGqKRIqKAp4eYsBse4rEitv -uAGxqi0SKywKeH3LAbHuy67L7C4SKNMPb+gIL+0BL/yALxYoKRIpb5gIKp0BKqyAKhYpLBIqb8gI -Lc0BLdyALRYqLxIrb/gIKP0BKIyAKBYr9goAIAAQKDDzGgArgAQ5IPoWQCAAECAw/2z/IAAQODD+ -HH8gABBQMP7sISAEEFgw0w9tuhrIYX+hDSjiAAgzNvhVCAQBAEEw+qwBIAgCc7DzSQwACBBYMP8C -AAgAak7QsWb/AgAEAj4VoMCR9QoAIAAQIDDwAF1hABAYMAAtEkAsEkLaIPsSQywJAGswWjmALhJG -0w/TD/8CAAQCC6OgKRJNLxJFKBJEKhJDLBJBKxJGKq0CLM0C/BZBIAICWvArFkb6FkMgIAJCMPgW -RCAgAnvwLxZFZZ8/LRI5DwIAZd3fLxJFLhI//wIAC/5f+5AbyMEcxpv6LAAAABBoMFo2f/vIwxIA -AFCwWjZdG8it/BI+IgAAULBaOV4byKkcyAf6LAAAABBoMFo2dcAg0Q8AAPoKASIAAEmw9qk5AAQQ -QDAJiAwIWCz3Fk0owAFAMPgWQiAnADWg/h3/IAUQUDD8EkchQAJzsP5uCgH+Anmw/uJ/IgAAajBb -kxwvEkb/AgAF/36L4CgSLCoKAP+IB2AAEHAwKgoBKxIsKQp40w97mwHA4SwSLW/IAbGqLxItLQp4 -f9sBse4oEi5viAGxqisSLikKeA8CAHubAbHuLBIvb8gBsaovEi8tCnh/2wGx7suuy+woEizTD2+I -CCmNASmcgCkWLCsSLW+4CCy9ASzMgCwWLS4SLm/oCC/tAS/8gC8WLikSL2+YCCqdASqsgCoWL/YK -ACAAECgw8xoAIAAQIDDwACRgABA4MPZsASABEEgw9QoAJAFGFaD0CgAhABAYMPcKAC4pADZg/2z/ -IAAQUDD+HH8gCBBYMP7sMSAEEGAw0w9tyhrIYX+hDSjiAAgzNvhVCAQBAEEw+qwBIAgCc7DzSQwC -AABBsPmynHAEEBgwwJH3Fk4oBQAycAgzDANTLPRgJ2LAARww/h3/If4CebD8EkchYAJzsP5uCgAF -EFAw/uJ/IgAAaPBbksMoEkn/PAAAABBQMPsSSSAAEHAw+Qp4KAwAuiDAofwSNSoAA9pQLgoBKBI1 -/Qp4KAwAuyCxqvkSNioAA8NQLuwBLBI2+wp4KAwAumCxqv0SNyoAA+LQLuwBKRI3+Ap4KAwAu2Cx -qnmLAbHuZKBPKhJJZOBJb6gLK60BK7yAKxZJKxY0LRI10w/+3QEoFAC7YC7sgC4WNSkSNvqdASgU -ALpgKqyAKhY2LBI3DwIADwIA/c0BKBQAuyAt3IAtFjf/FjghABAYMPgd/yAAECAw+IzQIAAQKDD4 -FkogABAwMPhhFGAAEDgwKRJJ0w8JMzb5VQgEAQBJMPoSNSIeADmgCjM2+lUIBAEAUTBoYxErEjbT -D9MPCzM2+1UIBAEAWTD4ZBRgCBBYMCwSN9MPDDM2/FUIBAEAYTAuEkoDTQx9uib2bAEgCAJzsP4W -SiT2AL2gIxoA9AoAIAAQKDDwAEdgARA4MAAAAAD6CgEiAABBsPaoOQAEEHgwCP8MD18sDw9G/xY6 -IBwANaAuEkrApfwSRyIAAGvw/uJ/If4CebBbklwvEjovFkhlfzUpEk5j/ccAAAAAACgKePoKACv8 -4DIQ8/m6YAEQcDAcx939EkYgAhBQMFuST8cr0Q8tEjgsEkj43RECAABQsPsSQSwJAGswWjhxY/vQ -AAAcx9L9EkYgAhBQMFuSQ8cr0Q8cx879EkYgAhBQMFuSPscr0Q8cx8v9EkYgAhBQMFuSOscr0Q8A -APzHxxACEFAw/RI9IAgQWDBbkjPSMNEPAGwQChPFu9MPKDJIJzJKG8e+FsW6Aoc493dTADQQQDAI -eBwcxfH9x7kWACBBsPZiACIAAFCwWjVpG8e2HMXr+iwAADIQaDBaNWUbx7Icxef9x2ISAABQsFo1 -YfvHrxIAAFCw/AoCIAIQaDBaNVwbx4z8x6sSAABQsFo4PRvHqfosAAAAEGAwWjg6+TKFI+sANKD5 -q1IKXQFIMAuqDCqsBRvHoRzHofStEQAGEHAw/t0CAgAAULBaNUkTx4wUx4oVx5vaIPwKACIAAFkw -Wjgp2iD7PAAAABBgMFo4JSRNAvM9AiG+CCkwG8eS/MVdEgAAULBaOB9udxj7x48SAABRsFt4I/AA -F2IAABqwAAAAAAAA+8eKEgAAUbBbeBzToPvHhxIAAFCwWjUO1aD7x4USAABQsFo1C9Sg+8eDEgAA -ULBaNQgbx4H8xUsQGRBoMAXdDP09Nw4AIFEw/uwGIBwCa3D/7hENgAQ/YP7dAgIAAFCwWjUa+8dz -EgAAULBaNPnAslt4AtOg+8dxEgAAULBaNPTAslt3/v7FuRwAIFTw+8dsEAQCa3D8x2sd0AQ/YP7d -AgIAAFCwWjUJ+8djEgAAULBaNOfUoPvHZBIAAFCwWjTk06D7x2ISAABQsFo04fo+CAAQAmkw/sUW -HAEAd3Abx1z8x10doAQ/YP7dAgIAAFCwWjT2G8dZ/MdZEgAAULBaN9gbx1f8x1YSAABQsFo31PvH -RxIAAFCwWjTOKwoCW3fXW3e9W5Ci1aD7x08SAABQsFo0x8CyW3fRW3e3W5Cc1KD7x0oSAABQsFo0 -wcCyW3fLW3exW5CW06D7x0USAABQsFo0u8CyW3fFW3erW5CQ+8dAHcAEOOD4ThENQAQ9YP7dAgwJ -AGKw/cwCAgAAULBaN7T7xzgSAABQsFo0rSsKAlt3t1t3nVuQgdWg+8czEgAAULBaNKfAslt3sVt3 -l1uQe9Sg+woCIBkQUDBbd6xbd5JbkHbToPsKAiAoEFAwW3enW3eNW5By+E0RDUAEOWD9zAINwAQ8 -4PvHIRwJAGsw+iwADAkAYrBaN5b7xwkSAABQsFo0j9Og+8cNEgAAULBaNIyqOvqs/iACEFgwW3eU -W3d6W5Be06D7xxISAABQsFo0hMCyW3eOW3d0W5BYG8cO9D0RDYAEOqD9zAICAABQsFo3gPvHCRIA -AFCw/ApgIGAQaDBaNJYbxwUcxT39xTwSAABQsFo0khTGuBPHARXGuBbHAdog/MWZEgAAWXBaN3Da -IPtMAAAAEGAwWjdt2iD8xSASAABY8Fo3aiM9AiVdAvRNAiGeCDFw2iBb/NNmonz7xp0SAABQsPwK -ASABEGgwWjR7+8aZEgAAULD8CgEgABBoMP4cECAUEHgw/hYAIGQQcDBaNFjIr8Ci/MbjEAgQWDBb -kSnHK9EP+8aLEgAAULD8CgEgABBoMFo0aPvGhxIAAFCw/AoBIAEQaDD+CmQgIAJ4cP8WACAUEHgw -WjRGyq7AovzG0hAIEFgwW5EXxyvRDwAAAAAAAAD5S1IKVwFIMAuqDPP8GGAKAlKwAAAAAAD7xnUS -AABQsP3EahAgAmBw/BYAIMgQcDD8xZMQChB4MFo0MMmhwKL8xr4QCBBYMFuRAscr0Q8AABfGvB7E -ifvGuRAYEGgw/RYJIBUQYDD8FgogABAgMPsWCyAAEBgw/i4KAAgQMDD+FgcgBRBwMP4WCCAHECgw -ixeMGSuyiADABPsLGQ//EGAw/MapGhEAZvALC0L7FgUqACBc8Py7CgIAAFCwWjQL3KD7EgsiAABQ -sFo3C/oKBSAIEFgw/MadEgAAaTD/EgUiAABxsFuQ24sXjBorsogAwAT7CxkP/xBgMPzGlRoRAGbw -CwtC+xYGKgAgXPD8uwoCAABQsFoz9dyg+3wAAgAAULBaNvX6CgUgCBBYMPzGiRIAAGkw/xIGIgAA -cXBbkMUnfQKNGYwY+BILIAICITD+Egoh/AIpcPM9ASH8AjGw+I0CIQACGPD4Fgsh9AJzsP4WCiH+ -AmMw/BYIIfQCa3D9FgkvDQC3IBvGKPosAAAIEGAwWjbZ+8ZwEgAAULBaM9PIrPvGbhIAAFCwWjPP -Za39+8ZrEgAAULBaM8z7xmkSAABQsFozyfvGLBIAAFCwWjPG+8ZlEgAAULBaM8QCKgJb+hnSoNEP -0qDRD2wQChfEIw8CAClySChyShTEIwKYOPh4UwA0EEgwCYgcqEQkQgD7xA4SAABRMFt2v/zGVBAF -EDAw+mY3AAoQQDAIZjYIYxD7xCYcCQBg8PwWBCIAAFCwWjauG8QhHMQi+iwAAAAQaDD4HBAgChBw -MPgWACABEHgwWjOn/MZCEkIAtqD7xhcSAABQsFoznf3EFhH2AiqwCVwRDDwC+8QRHAkAazD8FgQi -AABQsFo2mRvEDBzEDPosAAAAEGgw+BwQIAoQcDD4FgAgARB4MFozkWWiDRzEBvvEAhwJAGDw/BYE -IgAAULBaNoobw/4cw/76LAAAABBoMPgcECAKEHAw+BYAIAEQeDBaM4NlofRkIZgrckkqckocw7Id -xhz5HCAoPgFYMAmICoXTjtGP0p+SnpH1lgMqAEBmsP3SACAAEFAw/ZYAIAAQKDD4ggAgARBIMPua -OAACEEgwCpU5/cYMFAkARXAMXBEMPAL7w90cCQBrMPwWBCIAAFCwWjZlG8PZHMPZ+iwAAAAQaDD4 -HBAgChBwMPgWACABEHgwWjNeZaGC+8X8EgAAULBaM1XVoPvFzxIAAFCwWjNS/wIACgBjkWAlXPz8 -VREEAGeWoMCIeosH/wIACgBvxqDAoAepEfgaACQJAE1w/cXrFAkARXAMXBEMPAL7w7scCQBrMPwW -BCIAAFCwWjZDG8O2HMO2+iwAAAAQaDD4HBAgChBwMPgWACABEHgwWjM7ZaEZ+2oaIgAAUTBbdj77 -xbsSABBgMPosAAwBAFMwWjYyG8OmHMOr/BYEIgAAULBaNi77w6ESAABQsPzDoBAKEHAw/RwQIAEQ -eDD9FgAgABBoMFozJmWg6MAg0Q8lXPT8VREABBBAMPhVAgX/nMagwIj/AgAL/5pWEPP/NmH4AlKw -K3JHKnJIY/5jAADAslt2HWP/HgAAAAAA9hYAIAIQUDD7CgggABBoMP4KACAAEHgwW4/jxyvRDwCW -EPzFqB/QBDlg+goCIAgQWDD9CgMgAhB4MFuP28cr0Q+WEPzFoBACEFAw+woIIAMQaDD+CgAgAxB4 -MFuP08cr0Q8AlhD8xZcSAABxcPoKAiAIEFgw/QoDIAEQeDBbj8rHK9EPlhD8xY8SAABxcPoKAiAI -EFgw/QoDIAAQeDBbj8LHK9EPAAAA/MWHEAIQUDD7CgggBRBoMP4KACAAEEgw+RYAIAAQeDBbj7fH -K9EPAGwQChXDP9MP0w8qUkglUkoWwz/TDwKlOPV4UwA0EEgwCYgc+8UQEAEQYDD4ZggAABBoMPNi -ACIAAFCw9QdCBIUBKDBaMuraMPYWBifQEFgwW3XS3KD7xWwSAABQsFo1yBzFa/vFaxIAAFCwDwIA -DDwsWjXDG8Vo/ArIIgAAULBaNcAbxWX8KgAiAABQsFo1vPvFXxIAAFDwW3XAG8VgCqwK/8wRAgAA -ULBaNbUYxV0ERAvTDwhECvtCfyIAAFDwW3W3G8VY+3sJAgAAMrD7sX4iAABQ8Ft1sdeg+0KFIgAA -UPBbda4rQoOaGfcWBSIAAFDwW3WqLEKHG8Lq96wAAgAAUPAMuyxbdaXA1AfXN9twW3Wi9bhRBBwA -vqDwABNgABBQMAAAwOH6CgIh9gJ6sA/qOP6qEAIB0QYgG8U70w8LqgIbxTr8xToQCBBoMPosAAwJ -AG6wWjKl+8U3EgAAULD8CgEgARBoMFoyoPvC9RIAAFCw/AoBIAEQaDD+HBAgFBB4MP4WACAyEHAw -WjJ+yaPAovzFKRAIEFgwW49PxyvRDwAAAAAbxSX6LAAACBBgMFo1cxvFI/osAAABEGAwWjVwG8Ol -/DoAIgAAULBaNWz7xKUSAABQsPwKAiACEGgwWjKDjBYswgEdxRgsFgcMbAz7xRUdgAQ7IP3MAgIA -AFCwWjVfG8US+iwAAAAQYDBaNVwexQ/8xRAcVAEsMA7dHBvFDv3MDAPoEGgwDcws/BYIIgAAULBa -NVKFFxvFCPosAAAEEGAwWjVOjRX6LAAAJBBgMPvEzhwBAGswWjVJ2iD7xMoSAABhsFo1RhvEevos -AAACEGAwWjVCG8S9+iwAAAAQYDBaNT/aIPvE3hIAAGGwWjU72iD7xK4SAABhcFo1OPtCgCIAAFDw -W3U8+8TtEA8QYDD6LAAMAQBTMFo1MftCgSIAAFDwW3U1+8S1EBQQYDD6LAAMAQBTMFo1Kdxg+8Sp -EgAAULBaNSbccPvE3hIAAFCwWjUj+8TcEgAAUPBbdSf7xJkQBBAwMPosAAwBAFGwWjUb+8TWEgAA -UPBbdR/7xI8QBhBgMPosAAwBAFMwWjUU+8TNEgAAUPBbdRgKbDf7xIUSAABQsFo1DRvEyfwqACIA -AFCwWjUK+0KEIgAAUPBbdQ77xMQQAxBgMPosAAwBAFMwWjUC+8TAEgAAUPBbdQf7xL4QChBgMPos -AAwBAFMwWjT7+8JTEgAAUPBbdP+EGPvEfRBAEGAw+iwADAEAUzBaNPP6wjoSAABZMFt09xvEsPys -AAIAAFCwWjTt+8JAEgAAUPBbdPH7xKoQBRAgMPosAAwBAFEwWjTl+8I5EgAAUPBbdOkKTDf7xKMS -AABQsFo034gZJAoDDwIA+EQ3AgAAULD7xJ0SAABhMFo02PvEkxIAAFDwW3Tc+8RIEAwQYDD6LAAM -AQBTMFo00bFM+8SUEgAAULBaNM0bxJL6LAAAABBgMFo0yvvEjxIAAFCw/AofIAAQaDBaMeATwiUb -xIv6LAAAARBgMFo0wfkyhSBnADSg+apSCl0BTDAKuwy1uwW7CAuqCPqs/yACEFgwW3S+3KD7xH4S -AABQsFo0tBvEffosAAAAEGAwWjSx2iD7xHoR/gJpcP0dFAAfEGAwWjHGwCDRDwAexHXz/GNqCQBy -sAAAAAAA+UpSClcBTDAKuwzz/5tgCgJa8ABsEAT7xGwSAABQsFuQhv08AAAAEGAwW477+8HiEAIC -UvBbdJ/AgQiqN1t0ktEPAABsEBD6wfQSGQA0oCaiSiiiSSgWEgZ1U2RRyf8CAAAA4wVgblIMwJ11 -kwfwAAZgARA4MMByE8RVFMRV2iD8xFUSAABY8Fo0gyM9AnQ57BnCNf3EURIMAT1g3ZAbxE/8xE0S -AABQsFoxlhrETdMP0w8KegonoIApoIEooIIqoIMbxEj8iBEJYAQ+YPN3EQvgBDqg+XcCCAkAUjD8 -waoWCQBF8PosAAIAAGnwWjGFLhIS/8GdEAEQUDD+blEGDAC9YMCgG8Q4HMGg+cHGEDQQaDANVRyW -H/jENRQAIE1wJRYQhVL47REOBQBWMP4WDiwJAH9w/RYRL/AEOWD+CkAsCQB3cP7dAgIAAFCwWjFt -KRIS0w8PAgDzxCYYYwFMMPRYEQWABD5g9sQjFAkARXD9XAACAABQsPzBjBIAAFjwWjFgIz0Cdjnm -E8QbFcQc3HD6LAACAABY8Fo0PyM9AnU57CcSEfPEFhBAEEAw9cQVFgkARfDccPosAAIAAFjwWjQ2 -Iz0CdTnswKJbhuwbxA4cwWb6LAAAABBoMFoxSvMKACAyECgwwaRbhuSxM3U59RvEBxzBav3C5hIA -AFCw/gpkICACSHD5FgAgFBB4MFoxI8mrwKL8w/4QCBBYMFuN9Mcr0Q8AAAAA8/5MYAAQODAbw/kc -w/n9wUwQZBBwMPocECAUEHgw+hYAIgAAULBaMRPJrcCi/MPxEAgQWDBbjeTHK9EPJqJIK6JHKxYS -Y/3nAAAbw+v8w+sSAABQsFo0BiMSEIMw+gogIgAAWPBb/2EVw+YXw+baIPzD4xIAAFlwWjP9+gog -IgAAWPBb/1olXQJ3WeH6w98SAABY8Fv/VRvD0hzBuPosAAAAEGgwWjEN+gogIgAAWPBb/04bw9H8 -w70SAABQsFoz7PoKICIAAFjwW/9IFcPN/MEkEgAAULD9w7USAABZcFow//oKICIAAFjwW/9AJV0C -d1nb+gogIgAAWPBb/zwVw6naIPwKACIAAFlwWjPZJV0CdFns+gogIgAAWPBb/zMZwTQnEhIpkoUH -d0P5KFEIMAFMMPRxgmgFABYwih5kpan/AgAAAvuGoP8CAAIDIAKgKxISCw1C/doJDj4BWDD+Eg4q -ACBysAu8QvzPCQpyAVww+fkIAgMkh6CdHJwbKxYKKRYJ/MOiEAgQWDD9fP8h/gJysP9cAAAFEFAw -W42LjRr8w5wQBRBQMP4SCSAIEFgw/dz/IgAAeTBbjYMfw5b4HBYgHxBwMPgWBymQBDzgBPosBf8s -D58sCpks+BYNKAEAz7D5FBQuAQD7sP4UFSAoAiBwHMDTJUAAG8OI0w/8XAICAABQsFozmvs8AAfQ -EFAwW/72HMN32iD7w4AcCQBhcFozk/vDfhIAAFCw/AowIDIQcDD9HBAgFBB4MP0WACAwEGgwWjCM -ZaBeG8Nz+iwAAAAQYDBaM4b7w3ESAABQsFowgP4cFCpgAVAw+hYEIBQIcTCaHWAAHgAVw1SNFPwK -8CIAAFCw/N0RAgAAWXBaMJMlXQJ2WeSOF7FE/wIAD/+qcRAnFhNgACjAovzDXRAIEFgwW41FxyvR -DygSEicWE/8WDShAAUQw+RYMKEsBQDCYG4QfGMNYGsNT98NTFCMBIDAIRAokQn8Ww1H1w1EQABBY -MPQMQwAPEEAwKxYU+hYIJgHBRxArFhT6FggiAdEHICVdAiZtAid9AvqtAiAPEEAw9EQUAAICWvD0 -DEMFmgI+4PoKICIAAFjwW/6sFMM7FcM++iwAAgAAWTD8CoAggBBoMFowYiRNAnVJ5voKICIAAFjw -W/6iFMMw/AqAIgAAULD9CgAiAABZMFowWCRNAnVJ5voKICIAAFjwW/6YHcCYLdKFG8Mq/a5SDFQB -bDD8wHgcBQAXsPjdEQIAAFCwWjBLG8MjHMGQ/cFUEgAAULBaMEcUwyAVwyDaIPzAZRIAAFkwWjMn -JE0CdUns+zwAACAQUDBb/oItEhAt0gsbwxgcwxj43RECAABQsFowOCUSEA8CAIVcE8MT9MMUFYAE -PWD9XAACAABQsPzDDhIAAFjwWjAuIz0CdDnmJRIT+8MMEgAAULD8ChAgEBBoMFowJxTDCBPDCBrD -CYkb/AoCIAEQaDD11TkAABBYMPbDAxoFAC8wC5kK+hINKAAgVnArFgYokID5kIEnwAQ+oPSsEQuA -BD6g/IgRCgkAZvD4mREGCQBd8PmFAgYJAFXw3HD6LAACAABZMFoy8tog+zwAAgAAYXBaMu8kTQLz -PQIhvggxMBPC7BTC7NxQ+iwAAgAAWPBaMucjPQJ0Oewbwuf8wugSAABQsFoy4hvC5vzC5BIAAFCw -WjLfG8Lj/MLhEgAAULBaMtsTwuEUwuHaIPzAERIAAFjwWjLXIz0CdDnsG8Lc/MK0EgAAULBaMtIT -wtkUwtnaIPzABxIAAFjwWjLNIz0CdDnsgxYbwtP8wqoSAABQsFoyx4gcGcLQA4gKqYglgIAogIET -ws78VREJgAQ6IPTCzBQJAEVw2iD7PAACAABhcFoyuyM9AnQ57CgSEhnCxgiIUgmICiSAfCiAfRPC -w/xEEQmABDog9sLBFAkAQTDaIPs8AAIAAGEwWjKtIz0CdjnsE8K7FsK83FD6LAACAABY8FoypyM9 -AnY57BPCtxXCt9xA+iwAAgAAWPBaMqEjPQJ1OezBpFuFV8GkW4VWwKJbhVUoEhKFHxPCrvUFUwhb -AUAw84kRCXAEOiD8VREICQBKMPTCqBQJAEVw/VwAAgAAULD8wqUSAABY8FovqCM9AnQ55ioSEtMP -CupD88KgGUAEPqD4pREJwAQ6oPqIAgQJAE1w9MKbFAkARXDaIPxcAAIAAFjwWjJ+Iz0CdDnswCDR -DwCLGPy/thIAAFCwWjJ42iD8wpASAABZ8Foyddog/MKOEgAAWbBaMnJgACcAixj8v7QSAABQsFoy -bdog/MCSEgAAWfBaMmraIPzChBIAAFmwWjJn2iD7XAAAABBgMFoyZIoYKxIUY/wlJBIS+MJ9GkAB -IDCaHPqqCQo+ASQw+8J4GgAgWrAHdQkKVQoLVQn1UX8qSwEkMPsWCyRyASAwlBoLuwn0RAkKACBe -cJsZC0QKCEQJJEF+Y/pHJBIS+MJrGkABIDCaHPqqCQo+ASQw+8JmGgAgWrAHdQkKVQoLVQn1UX8q -SwEkMPsWCyRyASAwlBoLuwn0RAkKACBecJsZC0QKCEQJJEF+Y/n2KxIS++xRCkABWDD6FgwsSwFc -MP0WCypyAVwwmxoN3Qn6qgkMACBPcJ0Z8/nJagAgYrCZGZsanRycGxjCSgd1CQu0CQpVCghVCRjC -RwlECiVRfwhECSRBfmP5mwBsEATIJmghBMYq0Q8AHL/09r9+EMwQaDANLSgbwj3+YkgsACBrMPzA -3yABEHgw9WJKIAAQGDDy8zgCAABQsP/MEQAFEGgw8+U5DAkAazBaMg4pYkgoYkr0v28YBQAacPh4 -UwA0EEgwCYgcqESEQfpM/CACEFgwW3ILKWJIKGJK979lGAUAGnD4eFMANBBIMAmIHBvCIP7CIRYA -IEXw93IBIf4CSTD1P0EIAAFMMPWtEQjwBD5g9QhCBgABPDD6iBEHYAQ94PndAgYJAEXw//8RDAkA -P3D8whAcCQB/cP7dAgIAAFCwWi8DwCDRDwAAAABsEAQdv2rTD9MP+79pHAAgbLD+CgEiAAB7cNMP -KrJ2DwIAf6cSLLJw/MwQAAAQSDD83wwKADTrEP6nEHACEBAwLLJxDMwQf8tfDP8MfachLLJyDMwQ -f8tX/P8MADAA7rDAofy/VBAAEFgwW4uhxirRD3un6y6yggzuEP/j4nAGEEAwmDCfQP4yACAFEFAw -/L9KEAAQWDBbi5bAINEPmTCdQPP/4WIAAHtwnjCfQGP/1ZIwn0Bj/84AbBAEHL86/vrgID4CaLD6 -woIgPgJY8PjCfSoAQHbw+wsGDABAd3ANqgz0gBBiAEBS8C/CgS7Cfg/+OX4rEsAgwKD8vysQBhBY -MFuLe9EPAADyxoIp//xS0GP/4wBsEAQYvwAkgoMEg1L1wE8WGAA84AS4UmiHKtEPBGxQAioRpaot -ooLH7g7dAQ3MAiymgimigsC+9IKDKAkAXnAppoJj/84fvvDB0P9PAQAAEHAwD945AiwRpcwvwoLG -PwP/AQ/uAi7GgivCgi0K4A27AivGgtEPAABsEAQUv6rzwacQABAQMNogW4ZpCghBaYEh/K8ecgAA -SPAABIsASWEASWEASWEASWH6LAAAABBYMFuGWrEi8z0EKZoCOKDAINEPAAAAbBAE+cGWG7AEOWD2 -TBEKUAQ84Py7AgoJAFHw+SkLCgkAWrAqlkAoHCCIgABqEQqIAiiWQdEPAABsEARuLgHRDxa/HQYm -CyVi4BjBhQQ3EfdHAgQAQEVwB1UCJWbg0Q8AbBAEFr8UBiYLJWLQGMF9BDcR90cCBABARXAHVQIl -ZtDRDwAAbBASFr8L0w8mYoVbhk4TwXUVwXP0v40QABAQMPo0QCABEDgwACAECggb/4cKcAICSLAp -Rn9gAAgqUC1/pxIqMECxImko3fIKACAAEH6QYAFewKD7CgIiAABgsP4KACB4EGgwW4YmY//UAMBw -9AoCIgDwepD0CgQiATD2kP8CAAIBdHKQ/wIAAgG47pD/AgACAftqkP8CAAICPOaQeKd9Khok/L5i -EBIQWDBbhoYcvl/7ChoiAABqsP1V5iGQEFAwW4aAwbX6NEgn/xBgMPc0UC7gAVAw+ho0JgAgdfBb -hnn6FgkgIBB4MP9kAQ4CVP2QwLD4rAIn/xBgMPgiCAGcEFAwW4Zw9qwABKAANSApUEjTDwkJRP8C -AAoCZYJg/L5DEJQQUDDyv0gQHRBYMFuGZSo0USkwRCswQS4wQy8wQicmgP0ify+ABDug8P8RCoAE -PuD/uwIICQB2cP4wQCgJAF5wKRYA+jBIIgAAYrAvMEcoMEYrMEUMDEfwiBEPgAQ/4Pi7EAoJAHqw -+LsCAgAAefD8FgIqCQBasPzBExAAEFgw+hYBIAQQUDBbirrRDwAAKgqc/L4eEA4QWDBbhkIcvhv7 -Ch4iAAB6sP9V3yE4EFAwW4Y89zRRIBEQWDD6NEEgABA4MPc0SSf/EGAw+gdHAKwQUDBbhjMoCiD4 -ZAEIAA9BkBu+iymy0B3A9SysAfTMEQgAQG5wDJkCKbbQ8qwCIAQQWDD8ev8hRBBQMFuGJfoWEiQ6 -ADUgLlBIDg5E/wIACgLcA6AqMEBj/iAAAAAAACoKsPy99hAKEFgwW4YaHL3z+woCIgAAerD/VeAh -SBBQMFuGFPQ0USANEFgw9zRKJ/8QYDD6NEIo4AFQMPh3CADAEFAwW4YL+hYEICAQSDD5ZAEOAafN -kMC4+qwCJ/8QYDD6GlAiACBQsFuGAvoWEyPlADUgK1BICwtE/wIACgKcguAqMEBj/ZsAKgrE/L3U -EAYQWDBbhfccvdH7CgYiAABqsP1V4SFUEFAwW4XywLn6NEMn/xBgMPc0Sy7gAVQw/3cIAAMQcDD+ -NFEg1BBQMFuF6foWCiAgEEAw+GQBDgFsRZDAvPmsAif/EGAw+SIIAVwQUDBbhd/6FhQjkgA1ICpQ -SAoKRP8CAAoCXgKgKjBA9AoEIf6QcpAqCtj8vbAQAhBYMFuF1By9rfsKCiIAAGqw/VXiIWAQUDBb -hc70NFEgBRBYMPo0RCf/EGAw9zRMLuABUDD6CugmACB18FuFxfoWBSAgEHgw/2QBDgEv/ZDBsPis -Aif/EGAw+CIIAWgQUDBbhbz6FhUjPQA1IClQSNMP0w8JCUT/AgAKAh0CYCowQP8CAAH+S+6QKgro -/L2MEB4QWDBbha8cvYn7Cg4iAABqsP1V4yFsEFAwW4WqwLH6NEUn/xBgMPc0TS7gAVAw+gr8JgAg -dfBbhaP6FgYgIBB4MP9kAQ4A9H2QwbT4rAIn/xBgMPgiCAF0EFAwW4WZ+hYWIuoANSApUEjTD9MP -CQlE/wIACgHfgmAqMEDTD/8CAAH+CWqQKgr8/L1oEBoQWDBbhYwcvWb7ChIiAABqsP1V5CF4EFAw -W4WHwb36NEYn/xBgMPc0Ti7gAVAw+hoMJgAgdfBbhX/6FgcgIBB4MP9kAQ4At/2Qwbj4rAIn/xBg -MPgiCAGAEFAwW4V2+hYXIpUANSApUEjTD9MPCQlE/wIACgGhAmAqMED/AgAB/cfmkCoaEPy9RhAW -EFgwW4VpHL1D+woWIgAAarD9VeUhhBBQMFuFZMG5+jRHJ/8QYDD3NE8u4AFQMPoaICYAIHXwW4Vd -+hYIICAQeDD/ZAEOAHx9kMG8+KwCJ/8QYDD4IggBjBBQMFuFU/oWGCJEADUgKVBICQlE/wIACgFl -gmAqMEBj+wgAAIsZwKf7vAEiAABgsFv+jooZY/tGLDBI9AoAK10ANyCxrS0WGSowUCsSGdMP+koI -AgAAYLBb/norMEj0TAEgBAJhsPtD3nIAIGCwY/sqAAAtUC3A6A7dAi1ULWP7KosUwKH7vAEiAABg -sFv+d4oUY/ygixrAovu8ASIAAGCwW/5yihpj/ReLFcCj+7wBIgAAYLBb/m2KFWP9kIsWwKT7vAEi -AABgsFv+aIoWY/4HixfApfu8ASIAAGCwW/5jihdj/oCLGMCm+7wBIgAAYLBb/l6KGGP+9wAAACww -QfQKACvDADcgsa2dGyowSYsb+koIAgAAYLBb/kosEhIrMEH0TAEgBAJjMPtD3nIAIGCwY/uRLTBC -9AoALBgAN2Cxrp4cKjBKixz6SggCAABgsFv+PCwSEyswQvRMASAEAmMw+0PecgAgYLBj++YtMEP0 -CgAsawA3YLGunh0qMEuLHfpKCAIAAGCwW/4uLBIUKzBD9EwBIAQCYzD7Q95yACBgsGP8OS0wRPQK -ACzAADdgsa6eHiowTIse+koIAgAAYLBb/iAsEhUrMET0TAEgBAJjMPtD3nIAIGCwY/yOLTBF9AoA -LRMAN2Cxrp4fKjBNix/6SggCAABgsFv+EiwSFiswRfRMASAEAmMw+0PecgAgYLBj/OEtMEb0CgAt -aAA3YLGuLhYQKjBOKxIQ+koIAgAAYLBb/gQsEhcrMEb0TAEgBAJjMPtD3XIAIGCwY/00LTBH9AoA -LbkAN2Cxri4WESowTysSEfpKCAIAAGCwW/31LBIYKzBH9EwBIAQCYzD7Q91yACBgsGP9hS1QLcDo -Dt0CLVQtY/o9L1AtwIgI/wIvVC1j+rwpUC3AqAqZAilULWP7OQArUC3AyAy7AitULWP7uwAALVAt -wOgO3QItVC1j/DYAAC9QLcCICP8CL1QtY/yzAAApUC3AqAqZAilULWP9KgAAbBAEF70mFr110w8o -cn8aveP1vXEQABAQMPS/WxBbADYg06ApooAFmQL5poAiAABQsFuBxdogW/2HHb9VKGJ/H7xu/L9S -E+gQcDAOiCwI/ywPzCwP3SwO3SgOzCgE3TYtNoMrcn8qPUD0zDYAAgIQsPw2hCv/1tyQGrx4KaDc -L6Ddwb/5CUQADRBgMP8PRAByBGJwK6DB/b3BEDYAfvAs0oEuuv4OzAEs1oFbgUzAINEPAAAAAFuB -Tvev7mIAABKw0Q8AAAAAAAD4oN4hjghb8AgIRHuJvCmg3wkJRHyZsxy/LSvCgB284A27AivGgGP/ -oQAAAGwQBhW/KPa+xRAAEBgw978mEfQQIDDaMFuB1PagR2IAABKwH7xQL/DB8r67EHgAf/BkMG/y -CgAiAABQ8FuBxvhSlyATADagyIvaMFuBqvagFGIAABKw9V0BIAICGPD1XMwjaAI44NEPANow/L8Q -EgAAWLBaLtwiLQJ2KewSvw3aMPwKACIAAFiwWi7WIi0CdynsG78I/L8IEgAAUPBaLtFj/5AAHLw7 -LMLAnBAbvDvArvq2QCABEFAwW4GDHrw3wN/95kAgABAQMMGkW4F/sSJ0KfWPEA/vUf8CAAP/rB/g -GbwuGLw9KJZAY/9HbBAEGbwdHL7yFrwH+JDBIAEQUDDzCgAgFBAoMPQKGC//EDgw8pwAAgDu/hAj -xh8jxh7zxIAgMBBwMCshcB++5QtcRv/PCgoAKPMQj/AK8AAAAG87GilihAAxBACoGgCIEQeMAwyZ -AQmIAihmhGAAJCxiwMHnA+4MAOEEAKkaB50DDcwBDJkCKWbAYAAHANowW4NtwKErIXAHvAP0ywEO -AAknEGi4Umi7N/8CAAQAqiMQ8iwCIAICGPD/AgAAMBBwMP8CAA//uqjQ9wqHIAAQGDDyu+kQDhBY -MPAAVWAUECAwL2LHADEEAKsaB7kDD58BD78CL2bHYAAIADEEAKsaB7kDKGLGCYgBCLgCKGbGY/+f -AHupDPo8AAABEFgwW4L9wL7zPAEh/gIhMPRAt2AEAhCwKiFwd6EXClpGaKIsaKpZ/wIABgBFrpBp -ocVgAIAALWKWHr6h/rw2HABAd3AO3QItZpZj/7oAAAAA2jBbgyj7Cg4vrgC2oC0hcBm+lfiQgCxA -AWww8NEEAAEQYDAAzBoMiAIolIBj/4cA2jBbgxz7Cg4vfgC2oCohcBu7swoKQqurK7DcCwtEW4Lq -Hb6FwM8s1IDz/1pgDhBYMAAAAAD6PAAAARBYMFuCzvP/Q2AOEFgwAABbhFlbhE8fvnkq9h4r9h8u -Yof+ZocgABAQMNEPxirRD8Ag0Q8AAABsEAYavHUbvB4cu9L4CgAgEBBIMNMPbZoVC4kCKcb5+cL5 -IAQCUrCxiAkJTSmlrRa8Sg8CACZhwhi8RwdmEfO8AxYAIEGw+r5iEAEQWDD8CgEgChBoMPgqACAA -EHAw+DY6IAAQeDBaLiYZu4AokMLyvlkSAAAhsPe+WBABEFgw+rg7AAAQKDD4lMIgAR8uoJYQi0KK -QSs2O4lAKjY8KTY9Gr5M+woBIAEQYDD/VhEAChBoMPdoAgAAEHAw+DY6IAAQeDBaLg9mof/6vkEQ -ARBYMP0KCiAAEHAw8mwCAAAQeDD8NjogARBgMFouBfah2WACAilw+V6ZYBgCITAtEgAXvjcSvjf9 -3QYgABAoMP0WACAA3C6gDdQCi0KKQSs2OylCACo2PCk2PRq+KvsKASABEGAw/1YRAAoQaDDyaAIA -ABBwMPg2OiAAEHgwWi3tZqF3+r4fEAEQWDD9CgogABBwMPdsAgAAEHgw/DY6IAEQYDBaLeP2oVFg -AgIpcPlemGAYAiEwLRIAFrtO/d0GIAAQKDD9FgAgAJmuoA3UAo1EjEMtNjuLQiw2PIpBKzY9iUAq -Nj4pNj8avgb7CgEgARBgMP9YEQAKEGgw9ogCAAAQcDD4NjogABB4MFotyfag5WACAilw9EwUL2oC -OWCEEPa9/RAAECgwLU0KjdQsTQqMwy02OytNCouyLDY8Kk0KiqErNj0pTQqJkCo2Pik2Pxq97PsK -ASABEGAw/1gRAAoQaDD2iAIAABBwMPg2OiAAEHgwWi2v9qCFYAICKXD0TBQtTAI5YIQQ9r3kEAAQ -KDAtTQwt0iQsTQwswiMtNjsrTQwrsiIsNjwqTQwqoiErNj0pTQwpkiAqNj4pNj8avdH7CgEgARBg -MP9YEQAKEGgw9ogCAAAQcDD4NjogABB4MFotlPagDGACAilw9EwULUICOWDSoNEP0qDRD9Kg0Q/S -oNEPAAAAbBAI2iBbT1uUEBy79/sKCCIAAGiw/zwAAgAAMrD6CgUiAABxsFuHUsCAFbt1pWUjVoEk -VoIoVoMI5BaYFAECACNSgwPqMPpsAAACEFgwW09FCuowJ1KIyHvaYAPqMMCyW09ACuowiBQI5BYD -qgxbTzXYoP0sAAIAAHHw/LvdEAUQUDD/Uogp0AQ9IAiZLPkWACAIEFgwW4c2wCDRDwAAAGwQBBO9 -nfy7ThABEGgw+AogIgAAUPBtigoroAV7IAJ/t2G8qhu6tS7AgCmw3C201P+w3SAeEFAw/e4CCgAD -zpAuxIAtsN5/owoowIDAkgmIAijEgCiw332jDS7AgMD0DwIAD+4CLsSA+cCAKgAKRpDAqAqZAvnE -gCAAEBAw0Q8AwCDRD46gHL19/eAAIAgQWDD+4AEgAhBQMFuHDdkw/wogIP4QUDBt+g0okAUKiAH4 -lAUgGAJKcMcr0Q8AbBAGKCAA+QqCIgAAULDyLQQgFARKMMcu0Q8AACesFv8CAAoAt5HQFL1omhAT -vWaTERO9ZvAAdmBAECgwAAAAAAC8M3QxVSgwBQWIAfkwBC3iAj4gdpnp2nD7MgAgAhBgMFuCW/wK -AC/qEFgwCss4Zr/OjREsMQOIMtpg+3wDLAAgazALgAD2oRpgARB4MC4wBdMPD+4CLjQFJnAC871M -EAYCQbCod/8CAAoAdBHQAzsC+nwAAAIQYDBbgkXzvUAQCgA2oCZwAmP/e4kQtHr/AgAKAGVSUAl6 -DLSq+gtCAAAQSDBtuQ6LECywALG7+xYAKAAgTzAKOxRksJCIEA8CAA8CACyAACqAAS+AAv6AAygA -IE8w/YAEKAAgTrD8gAUuACBP8K/uDt0I/YAHLAAgazD5gAYh/gJS8PvcAAAQAkIwbalC+YAALAAg -YnD8gAEqACBi8C2AAvmAAyoAIFZw/IAEKgAgXzD9gAUqACBfcPmABioAIF5w+4AHLAAgWzD83AgA -EAJCMAyZCKm5GrosKaTVxKBb/2vSoNEPAPP/7GAAEEgwjjAcvQr94AAgAhBQMP7gASAIEFgwW4aW -Y/7ZAGwQBBm60SqSfymSgAmrEauZ+pYAIBsQQDAolARbfs5bfpbAINEPAABsEAQTu7X6vPkQqhBI -MPQKBiAAEBAwAgo/Agc/Agg/Ags/BAk/CgQ/CQU/AgY/+DJXIIAQUDAIAD9bhXn/vO0QABBgMAoB -P/q86xANEFgw8vR+IAEQcDD+9H0gCBBAMPj0fCIAAHCw+LzkEBgCSrD/CoAgHxAQMNMPbbpA/oZR -KgAgfjD5hlAgLAJrMPmGTywDABdw/oZOIAICYzD6hk0gQAJKcPqGTCBAAlKw/rTJIEACQjAutMgt -tMouhkv0NHwgAhBIMCk0fVt+nRy54hu8yxq8ywAMiwBLYQBLYQBKYQBKYdEPAAAAbBAEGbqj0w8i -kiD7ubQQABBwMP/6/yFNADSg1uD4CgAgABAgMPoKASANEDgwbQhLJZLWIpLfpWUJUxGjIo0rlSAv -JHYrJSmYLCQlEyYkIiokICokIS4kDfYkDCAIEBgwIyQFJyQELJIgIiES9mwBKAAgajD8awd0ACAR -MGP/rSqSIWSglvW8pR//ECAw+goAIAAQMDDwADdggBA4MILbJNQMLNQNJtQimNwr1Sn/1HYvgBAY -MCPUICPUISOSIbCq/MwBIAICMbDza1B4ACASMCOS1y2S36NjCTIR8goOLAAgF3Ai1ATz1gAgCBAY -MPPUBS+rALagsVWnWiqgvbFE/AoBL5oAtqBtCA6xVadaKqC99a+IYAICITBj/+orkiLLt/W5pxAA -EDAw+AoHIA8QODBtCCIvktgtkt+vbwnyEaLdn9Al1hYu1A0o1Awn1AQskiKxZnxrAmP/1sAg0Q8A -AAAAAADz/xdiAABDsGwQBBi6QRy5zBO8ahu8bB+8ai827vs27SABEFAwKjb0KzbvKzbyLDb1+Dbw -IAAQaDD4NvMgARBwMFtNsSsyEIw/jT6OPY88iToqMgkoMgsqNsf6MhQoACBWcCk2yPkyESgAIEow -KDbJ+DITLgAgR/AvNsr/MhIuACB7sC42y/4yHCwAIHdwLTbM/TIdLAAgazAsNs38Mh4qACBm8Cs2 -zvsyHyoAIFqwKjbP+jIgKAAgVnApNtD5MiEoACBKMCg20fgyIi4AIEfwLzbS/zIjLgAge7AuNtP+ -MiQsACB3cC021P0yJiwAIGswLDbV/DInKgAgZvArNtb7MioqACBasCo21/oyKygAIFZw+TbYKAAg -SjD4NtkuACBH8P822iAAEEgw+TbGLgAge7D+NtssACB3cP023CwAIGsw/DbdKgAgZvD7Nt4qACBa -sCo231t+CSwy7voy8y2QBD6g/dwfL+AQcDD/MvIsAEB3cP2qDA+AEFgw9MANYgBAWrAuMu8P/jl+ -KxvAIMCg/LlCEAYQWDBbhZHJKfI24CAAEBAw0Q8A8jbzKf/42pBj/9oAAAAAAPI24C/0EBAw0Q8A -AGwQBBW5EBa5MRK5nxi6Yfe6XxCAEHAw8iJ/IAkQWDD5jKwgDhBgMPqMVCFYAmnw0w9tKRgkUNzT -DwQERGtCFGZAESdmmPVcASAoAjGwwCDRDwAAAPhCLWIAIHVw+EMZbgAgdXBrRwJrRQh7QQV0wtRq -StEtZphj/8sv8JRp98UqZphj/78jMJRoNghpOLYpZphj/7AoZphj/6oAAGwQBha5m/q41BAAECgw -9LjmEAEQGDAlpoElpoMlpoAlpoIoQMHBkPmmiiCEAP4wG7vPLWJNGLvM/7jEEGoQcDAO3SgeuowP -3SwvgoDAzNMP/cw3DgBAd/APzwIvhoAtsoAO3QENzAIstoArsoAbuRz8u8AQABBQMFv95SoKAfy5 -ihAAEFgwW/3iW/oYGbkkwnAokoUvQMAHiAL4loUiVAC74Bi7tPv6/SAEEEgwbZoXKYKQKo0EC5kB -KYaQKaKQKI0IC5kBKaaQGrusKfr/KaYgKaYhKaYiKaYjKaYkW4CKHLkdLQoILsKPLkTAK8KKDbsC -K8aK+7uhEAAQQDD8u3EQiBBIMG2aDQyJCyuWQPWWQSACAkIwH7jeEruZJfaQI/aRIyaAW/m9KCKA -GbuW0w8JiAIoJoBb/QH7QMEgAKMuoH+3DfVleiQAEFAwKmV4YAAIJWV6GrneKmV4J2V9JWV6JWV7 -JWWHCiwULGV5W/xw/WJNIACHrqAXuRr/CmQgAxBwMA/dLA7dLClChP12vCJAAUgw9CFoYkoBTDD/ -AgAAANWEoP8CAAQA0YSg/wIAAADNhOD/AgAEAMmE4G4kBAk4RpgQbjQECdpHmhEZuGP5ko8iAMqY -oP8CAAIAloDgZTGd+WtTAAAQUDD6FgIr8AQ+4CpChwCwBAoKGQoKQVt/GMow/wIAAgCOAOD/AgAG -AMSY4PsSASQAXkCgjBD/AgAOAFlbEMCgZqBYW/wGZqBS/QqAIgAAUTD+CgQg/xBgMNMPbeoMrasr -sIz8uTpwAgJSsMCQLEDB0w9/xzMdu0stdsAtdsBb+7pmoBcfuHUl9nIu8nbHKwLuAf72diAAEBAw -0Q/SoNEPAAt5FGP/xQAAGrs/KGJNCogsKIz+CBgU+kDcKbAEOiD4mAIACBBYMAuIAvh2wCQOADqg -aaOnK3LAxsL8CgUqAEBm8Ay7Ait2wGP/kY0S/AoBIOAQUDD/shENwAQ/YP0NRwIAAFiwW35H+awA -ADwANqBnnymZE2AAtGQ/IWAA0QAA/kKGKnYBTDAPuxEAsAQODhkODkGeEmP+0AAAihJbfcBj/vkA -AAAAAPoK4CIAAFiw/AoDIDAQaDBbfjLz/7FiAABKsN0g/jwAAAIQUDD8uw4QCBBYMFuEiPP+w2/a -EFAw/SwAAAIQUDD8uwkQCBBYMFuEgWP/4QAA/TwAAAIQUDD8uwQQCBBYMFuEe2P/yQAA/TwAAAIQ -UDD8uv8QCBBYMFuEdWP/sQAAAAAAAAD9PAAAAhBQMPy6+BAIEFgw+Q4GAgAAEnBbhGzz/lNiAABQ -sP08AAACEFAw/LrxEAgQWDBbhGVj/jYAAGwQChO37SgwwRK36fUyQiBqAH4wJSZ7HLgiGbrnKiJ7 -KSZ9/MKOI+gQWDALqiwqNjILzCgsJnwLzCz8NjEgABAQMNEPACoayPwK/yAPEFgwW3/b+woXIgAA -IrD6GsggAxBgMFt/18G5/AofIgAAMrD0FgghyBBQMFt/0cG+/AofIgAAIrD2FgchyBBQMFt/zMC4 -/AoDIgAAMrD0FgYhzBBQMFt/x/sKFSIAACKw+hrUIAEQYDBbf8LBtvwKASIAADqw9BYFIdQQUDBb -f70Uurz9ursRTQA2oARuCS7hftMP0w8OXiz1MkIhtBBQMP4fFAAeEFgw/yZ7IP8QYDBbf7D7CgYi -AAA6sPoauCADEGAwW3+rwLj8Ch8iAAAysPcWBCG4EFAwW3+mwL38Ch8iAAA6sPYWAyG4EFAwW3+h -wbf8CgMiAAAysPcWAiG4EFAwW3+c+hYJIAQQWDD6GsQgARBgMFt/l/sKBSIAADqw+hrEIAEQYDBb -f5L0awkAxQA2oCuxftMPC1ssLCAYFbd3FreL+yZ8IM4ANyAbuoopUq8sUrD6UrIgdACicP4ifCAA -0T5QKCJ7KTJC+mxQA+gQeDAP7iz+NjEqBQBmcA+ILPg2Mi3gBD7g/SZ9IAAQEDDRDy0yQv8ieyiA -AWQw9JkJDhYBUDD5kX4qBQB3cP0ifCPoEHAwDv8sCbksDt0s/zYyKeAEPmApJn39NjEgABAQMNEP -wLEHtzlkcjv/AgAAAOGF4P8CAAP/UYHg8/6oYAAQcDDAwQfHOWRxuP8CAAAA1YXg/wIAA/+VgeDz -/ytgABBYMAAALSDkZd8vLlKzL/rAD+4B/lazIAEQUDBbfKgoUrPBkAmIAvhWsyABEFAwW3yjHbdN -KFKyBogCKFayLwqAL1auLFKvHrdGDswBLFavGLdGidmL2orXj9b2uxEIIAQ+YPuqEQgJAF5wCpkC -Cf8CCP8CL1awHrc9LlaxK1KyjtWI2B+3PI3U84gRD4AEO6D8tzgeCQBDsP+7AQwJAHdwDbsCDLsC -+1ayIAEQUDBbfIMpUrIftzL6tzAQEBBYMP0KeCAQEGAw/5kBABQQcDD5VrIiAAB4cFopxWShi8Ci -/LcoEAgQWDBbg5Jj/kwAAAAA+bobFioBYDD8BUQGiAFUMP0yQijgAVAw+YgJCD4BZDD5FgEuFgFQ -MPqBfioFAHdwW4WVHroRjRHTDw7dCf3RfiAAEGAwW4P6HboNDX0J/dF+IAAQYDBbhAQdugkNbQn9 -0X4gABBgMFuEAARdCf3RfiAAEGAwW4P8LiJ8/yJ7KeAEOuD4Jn0j6BAQMALuLAL/LC82Mv42MSAA -EBAw0Q8AAPP88WIAAHFw8/2MYgAAWXAAABu57ooUC6oJ+qF+IgAAWXBbhXEeueyNE9MPDt0J/dF+ -IAAQYDBbg9YeueiNEg7dCf3RfiAAEGAwW4PfHrnkjRnTDw7dCf3RfiAAEGAwW4PaBG0J/dF+IAAQ -YDBbg9Zj/SQAAIoYDaoJ+qF+IgAAWXBbhVkeudSNF9MPDt0J/dF+IAAQYDBbg74eudCNFg7dCf3R -fiAAEGAwW4PHHrnMjRXTDw7dCf3RfiAAEGAwW4PCBG0J/dF+IAAQYDBbg77z/CFiAABy8MGkW3wU -LlKzwv8P7gL+VrMgFBBQMFt8D2P8tQBsEAbAoPsKCCAPEGAwW36zGLm4AaIKi4GMgCwWACsWAfiC -AiIAAGqw+BYCIuYAvqAiIgAoSgDztqcQAC8soHKCbvIyNCQAEFAwW36h/KwAAQAQSDD6LAACAABD -MA8CANMPbZoS+YIAIAgCQjAEmY75pgAgCAJSsPtKACIAAFMwW4Vj8jY0IBQANKDaIFv8AtKgx555 -IWDRD9EPxyvRDwDAovy5lBAIEFgwW4MAxyvRDyIyNBq23Ft+htgg/BoAIgAAWrBtyhGNsPLdGgAI -Alrw/YYAIAgCQjArSgBbhUzyNjQvuAA0oAIqAlv76/evoWIAABKwY/9JwKL8uX8QCBBYMFuC6tEP -AABsEAQTtnIPAgDyMjMgABBQMFt+bfysAACAEEgw+iwAAgAAQzAPAgDTD22aD/mCACAIAkIw+aYA -IAgCUrD7KgAiAABTMFuFL/I2MyAJADSgwCDRDwDHK9EPbBAGGLa5GbllHrYuHbllLZYZ/pYaIAAQ -WDD7lTYgBBBQMCqUbhy5X8fwD8wBLIa2HLleKIKuKZLlmRD4FgEggBB4MFuCwsAg0Q8AAGwQBBu5 -Vxm5VyyygSyW1fuygiAEEGAwLJY1LJY0LJY4LJZDLJZCLJY++5bWIAAQUDD6llIgARBAMCiWQPiW -OyAIEBgwI5YoGbY4ErZjHbeAHrdCIiKB9Ld+FAAQeDD1tz4UABAwMPOQwSAeALywAwJAAv05LeV+ -0Q8IOgIKB0D6lMEkBQA5sCRVftEPbBAEHLk3Grk3GLk0KsZ/+q1AIIgQWDD6hn8gABBgMFt6hR62 -Hh25MC3mMy3dAi3mNNEPAGwQBBq2zPus8CCiADygaCJo9JB+YAICEnD/IhNgARAgMGAANGlkBQWo -CCeGAHJLKPo8AAIAAFkwW4CP+GESYAICITD5Yt1oACAusCeVAGP/26WrJ7QAY//T0Q8roncpooCj -uwm7Efhhb2gAIF5waGJuaWTkpZyXwNEPGbbfqTkpkN1oQDb0kF9gAgIRMHJDn2P/xSyidymyhKPM -+cwRAAICITD4YRtoACBmcGhiG2hkIP8CAAv/vZUQY/+cZZ9RY/+WpZgnhABj/+almielAGP/3qWb -l7Bj/9elnCfEANEPpZ0n1QDRDwDRDwAAAAAAAAAAAAAAAAAAIAMQAAzAAAYgByacIAMQBAjAAAwg -ByacIAMQCDzAABAgByXsIAMQDAbAADggBygAIAMQEAjAADwgByacIAMQFALAAEAgBygAIAMQGAjA -AEQgByacIAMQHAhAAEwgBycsIAMQIAhAAFAgBycsIAMQJAhAAFQgBycsIAMQKAhAAFggBycsIAMQ -LCBAAFwgBycsIAMQMCBAAGwgBycsIAMQNCBAAHwgBycsIAMQOCBAAIwgBycsIAMQPCBAAJwgBycs -IAMQQCBAAKwgBycsIAMQRCBAALwgBycsIAMQSCBAAMwgBycsIAMQTAxAANwgByT8IAMQUAxAAOgg -ByT8IAMQVAxAAPQgByT8IAMQWAxAAQAgByT8IAMQXAxAAQwgByT8IAMQYAxAARggByT8IAMQZAxA -ASQgByT8IAMQaAxAATAgByT8IAMQbAhAATwgBycsIAMQcAhAAUAgBycsIAMQdAhAAUQgBycsIAMQ -eBBAAUggBycsIAMQfBBAAVAgBycsYmNtODQ4NTZfbG9hZHNlcXVlbmNlOiBTdGFydGVkCgBiY204 -NDg1Nl9sb2Fkc2VxdWVuY2U6IFVwbG9hZCBpbWFnZSB0byBQSFkgb24tY2hpcCBtZW1vcnkKAAAA -AAAAYmNtODQ4NTZfbG9hZHNlcXVlbmNlOiBkb25lIGxvYWRpbmcgaW1hZ2UgKGkgPSAldSkKAAAA -AAAAAAAAAAAAAGJjbTg0ODU2X2xvYWRzZXF1ZW5jZTogRE9XTkxPQUQgRkFJTEVEIChsbyA9ICUj -eCwgaGk9JSN4LCBjbnQ9JXUpCgAAAAAAAAAAAAAAAAAAYmNtODQ4NTZfbG9hZHNlcXVlbmNlOiBE -b3dubG9hZCBjb21wbGV0ZWQgYWZ0ZXIgJXUgbG9vcHMKAAAAAAAAAGh3X2NsNDVfaW5pdFsldV0g -YWNhcHMgJSN4CgAAAAAAYmNtODQ4NTZfaW5pdFsldV0KAAAAAAAAAAAAAAAAAABod19iY204NDg1 -Nl9sb3dwb3dlclsldV06IGVuYWJsZT0lZAoAAAAAAAAAAAAAAABod19iY204NDg1Nl9sb3dwb3dl -clsldV0sIGZhaWxlZCB0byBzZXQgMzAuMHg0MDBBIGJpdCA3OyAzMC4weDQwMEUgYml0PTEgYWZ0 -ZXIgNW1zLCByZWc9JXgKAAAAAABod19iY201NDgyX2NmZ21kaVsldV0gc2V0dGluZyB0eXBlICV1 -CgAAAAAAAAAAAAByZW1vdmUgbXVsdGljYXN0IG1hYyBbJXg6JXg6JXg6JXg6JXg6JXhdIGZyb20g -VENBTQoAAAAAAAAAAAAAAAAAaXB2Nl9qb2luX2dycDogaWQgJXUsIHJlZl9jbnQgJXUKAAAAAAAA -AAAAAAAAAAAAZGhjcDZfdGltZXJfY2I6IHJlc2VuZGluZyBESENQNlNPTElDSVQgYWdhaW4KAAAA -ZGhjcDZfdGltZXJfY2I6IHNlbmRpbmcgREhDUDZSRVFVRVNUCgAAAAAAAAAAAAAAZGhjcDZfdGlt -ZXJfY2I6IHNlbmRpbmcgREhDUDZSRU5FVyByZXF1ZXN0CgAAAAAAZGhjcDZfdGltZXJfY2I6IHNl -bmRpbmcgREhDUDZSRUJJTkQgcmVxdWVzdAoAAAAAZGhjcDZfdGltZXJfY2I6IERIQ1A2UkVQTFkg -cmN2ZCwgc3RhdGUgJXUKAAAAAAAAZmFpbGVkIHRvIHJlbmV3L3JlYmluZCBkaGNwdjYgYWRkcmVz -cwoAAAAAAAAAAAAAdHlwZSAleCwgeGlkICV4LCB0eXBlX3hpZCAleAoAAABpcHY2X211bHRpY2Fz -dF9xdWVyeV90aW1lcl9jYiBub2RlX2lkICVkCgAAAAAAAABpcHY2X2dlbmVyYWxfcXVlcnlfdGlt -ZXJfY2IKAAAAAGFkZCBtdWx0aWNhc3QgbWFjIFsleDoleDoleDoleDoleDoleF0gaW4gVENBTQoA -AGNobmV0X2lwdjZfZGFkX2NiOiBoYW5kbGUgJXUsIGFkZHJfaWQgJXUsIGFkZHIgc3RhdGUgJXUK -AAAAAAAAAABpcHY2IHByZWZlcnJlZCBhZGRyIFslMDR4ICUwNHggJTA0eCAlMDR4XQoAAAAAAABT -dGFydGluZyBhZGRyIHZhbGlkaXR5IHRpbWVyIGZvciAldSBzZWNvbmRzCgAAAABWYWxpZGl0eSBl -eHBpcmVkIGZvciBhZGRyX2lkICV1CgAAAAAAAAAAAAAAAAAAAABzZW5kaW5nIGlwdjYgZWNobyBy -ZXBseQoAAAAAAAAAAGNobmV0X2lwdjZfcnNfb3V0cHV0OiBsMmRldl9mYyAweCV4CgAAAAAAAAAA -AAAAAGNobmV0X2lwdjZfbnNfb3V0cHV0OiBsMmRldl9mYyAweCV4LCBmbG93Y19pZCAweCV4LCB2 -bGFuIGZsYWcgMHgleAoAAAAAAAAAAAAAAAAAY2huZXRfaXB2Nl9uYV9vdXRwdXQ6IGwyZGV2X2Zj -IDB4JXgKAAAAAAAAAAAAAAAAY2huZXRfaXB2Nl9tbGR2Ml9yZXBvcnRfb3V0cHV0OiBsMmRldl9m -YyAweCV4CgAAZ2F0aGVyX3Rhc2tzX3RvX3R4X2xpc3Q6IHRhc2sgaW4gdXNlIFsldV0KAAAAAAAA -Z2F0aGVyX3Rhc2tzX3RvX3R4X2xpc3Q6IGlkeCBbJXVdLCB0YXNrIGZpZCBbMHgleF0sIHRhc2sg -c3RhdGUgWzB4JXhdLCB0YXNrIGNvbm4gWzB4JXhdLCB0YXNrIGZmbGFncyBbMHgleF0sIGNvbm4g -ZmlkIFsweCV4XSwgZGRwIFslZF0KAAAAAAAAAAAAZ2F0aGVyX3Rhc2tzX3RvX3R4X2xpc3Q6IHRh -c2sgWzB4JXhdLCBzdGF0ZSBbMHgleF0gb24gY29ubiBbMHgleF0gbm90IHZhbGlkIHRvIGdhdGhl -ciwgc2tpcHBpbmcKAAAAAAAAAAAAAAAAAAAAAGdhdGhlcl90YXNrc190b190eF9saXN0OiB0YXNr -IFsweCV4XSwgc3RpbGwgcXVldWVkIG9uIHR4IHBlbmRpbmcgbGlzdC4gUmVtb3ZpbmcgaXQuCgAA -AAAAAAAAAAAAAGdhdGhlcl90YXNrc190b190eF9saXN0OiBjb25uX2ZjLT5mbG93Y19mbGFncyBb -MHgleF0sIGxpc3RfZW1wdHkgWzB4JXhdLCBhZGRfdGFza19jb3VudCBbMHgleF0KAHRvX3R4X2xp -c3Q6IG5vIHRhc2sgdG8gY2xvc2UgZm9yIGNvbm4gWzB4JXhdLCBiYWlsaW5nIHRvIHJlY292ZXJ5 -IHN0YXRlIFsweCV4XQoAYXV0aGVudGljYXRlX3RhcmdldDogS0VZX0NIQVBfUkVTUCAtIFsweCV4 -JXgleCV4JXgleCV4JXhdCgAAAAAAAGF1dGhlbnRpY2F0ZV90YXJnZXQ6IEtFWV9DSEFQX1JFU1Ag -LSBbMHgleCV4JXgleCV4JXgleCV4XQoAAAAAAABhdXRoZW50aWNhdGVfdGFyZ2V0OiBJbmNvcnJl -Y3QgcGFzc3dvcmQKAAAAAAAAAABDSEFQX0M6IGRpZ2VzdCBleHBhbnNpb24gZXJyb3IKAENIQVBf -TjogVGFyZ2V0IHVzZXJpZCBtaXNtYXRjaAoAQ0hBUF9SOiBkaWdlc3QgZXhwYW5zaW9uIGVycm9y -CgBpU0NTSSBTZWMtcGFyYW1zIHJlY2VpdmVkaGF2ZSBlcnJvcnMhIQoAAAAAAAAAAABUYXJnZXQg -bW92ZWQgdGVtcC4gY29ubiAleCwgc2VzcyAleAoAAAAAAAAAAAAAAABMb2dpbiBGYWlsZWQhIS4g -Y29ubl9mYyBbMHgleF0sIHNlc3NfZmMgWzB4JXhdLCBzdGF0dXNfY2xhc3MgWzB4JXhdCgAAAAAA -AAAAAAAAAFByb3RvY29sIEVycm9yIGNiaXQgJWQgdGJpdCAlZCBjc2cgJWQgbnNnICVkCgAAAHJl -Y3Zfbm9waW46IGN0cmwgdGFzayBhbHJlYWR5IHBlbmRpbmcKAAAAAAAAAAAAAG9mbGRfcnhfZGF0 -YTogYWllZSwgaXNjc2kgY29ubiBbMHgleF0gZm9yIHNlc3MgWzB4JXhdLCB0eXBlIFsweCV4XSB0 -cmFuc2l0ZWQgaW4gdG9lIG1vZGUuIEtpY2tpbmcgcmVjb3ZlcnkgCgAAAABvZmxkX3J4X2RhdGE6 -IGNvbm4gdGlkIFsweCV4XSwgcnhfZGF0YS0+c2VxIFsweCV4XSwgcnhfZGF0YS0+bGVuIFsweCV4 -XSwgcnhfZGF0YS0+c3RhdHVzIFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAb2ZsZF9yeF9kYXRhOiBj -c2sgeyBpZCBbMHgleF0sIGNzb2NrX29mZnNldCBbMHgleF0sIGRsZW4gWzB4JXhdIH0KAAAAAAAA -AAAAAAAAAABhY3RfZXN0OiB0Y2JfZmMgWzB4JXhdLCBmbG93Y19mb2lzY3NpX2Nvbm5fZmxhZ3Mg -WzB4JXhdCgAAAAAAAAAAYWN0X2VzdGFiOiB0Y2JfZmMtPmZsb3djX2J1ZiBbMHgleF0sIHRjYl9m -Yy0+Zmxvd2NfdHlwZSBbMHgleF0gdGNiX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIG5wYWdlcyBb -MHgleF0sIGZsb3djX3RwX3NuZF9tYXggWzB4JXhdCgAAAAAAAAAAAAAAAAAAYWN0X2VzdGFiOiBh -dGlkIFsweCV4XSwgdGlkIFsweCV4XSwgb3AgWzB4JXhdLCByY3ZfaXNuIFsweCV4XSwgc25kX2lz -biBbMHgleF0sIGNzb2NrLT5mbG93Y19zdGF0ZSBbMHgleF0sIHRjcF9vcHQgWzB4JXhdLCB0Y2Jf -ZmMtPmZsb3djX2lkIFsweCV4XSAKAAAAAAAAAAAAAAAAAGNza19mYy0+Zmxvd2NfY3NvY2tfY29v -a2llIFsweCV4XSAKAAAAAAAAAAAAAAAAAG5ldF9sMmRldl9maW5kX2J5X2FkZHI2OiBsMmRldl9m -Yy0+Zmxvd2NfaWQgWzB4JXhdLCBsMmRjLT5scG9ydCBbJXVdLCBsMmRfZmMtPmZsb3djX2lkIFsw -eCV4XSwgYWRkciBbJTA0eCUwNHglMDR4JTA0eF0KAAAAAAAAAAAAY2huZXRfcXVldWVfeG1pdDog -ZmMtPmZsb3djX2lkIFsweCV4XSwgYnVmX2xlbiBbMHgleF0sIGJ1ZmZlcmVkIFsweCV4XSwgZmlm -by5udW1fYnl0ZXMgWyUweF0KAAAAbmV0aWZfZG9fZGhjcHY2OiB3ci0+cGFyYW0udmxhbmlkIFsl -dV0sIGwyZGV2X2ZjLT5mbG93Y19uZXRfbDJkZXZfdmxhbmRldiBbMHgleF0KAAAAAAAAAAAAAAAA -AAAAbmV0aWZfZG9fZGhjcHY2OiBpcHY2IG5vdCBlbmFibGVkCgAAAAAAAAAAAAAAAAAAZGhjcCBy -ZXNwIHRvIGRyaXZlcgoAAAAAAAAAAAAAAABsM2luNl9kZXZfY29uZmlnOiB3ci0+cGFyYW0udmxh -bmlkIFsldV0sIGwyZGV2X2ZjLT5mbG93Y19uZXRfbDJkZXZfdmxhbmRldiBbMHgleF0KAAAAAAAA -AAAAAAAAAABsM2luNl9kZXZfY29uZmlnOiBpcHY2IG5vdCBlbmFibGVkCgAAAAAAAAAAAAAAAABu -ZXRfbDNpbjZfZGV2X2NvbmZpZzogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgYWRkcmVzcyBh -bHJlYWR5IHVzZWQgYnkgcG9ydCAlZCwgYWRkcl9pZCAlZAoAAABuZXRfbDNpbjZfZGV2X2NvbmZp -ZzogIGFkZHIgWzB4JTA0eCUwNHglMDR4JTA0eF0sIHJlZl9jbnQgWzB4JXhdIGluIHVzZQoAAAAA -AAAAAGwzaW40X2Rldl9jb25maWc6IHdyLT5wYXJhbS52bGFuaWQgWyV1XSwgbDJkZXZfZmMtPmZs -b3djX25ldF9sMmRldl92bGFuZGV2IFsweCV4XQoAAAAAAAAAAAAAAAAAAG5ldF9sM2luNF9kZXZf -Y29uZmlnOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBhZGRyZXNzIGFscmVhZHkgdXNlZCBi -eSBwb3J0ICVkCgAAAAAAAAAAAAAAAAAAAG5ldF9sM2luNF9kZXZfY29uZmlnOiAgYWRkciBbMHgl -eF0sIG1hc2sgWzB4JXhdLCBndyBbMHgleF0sIHJlZl9jbnQgWzB4JXhdIGluIHVzZQoAAAAAAAAA -AAAAAAAAAGwyZGV2X2ZjIFsweCV4IF0gRmFpbGVkIHRvIHN0YXJ0IHRpbWVyIGZvciBpcHY0IGRh -ZAoAAAAAAAAAAAAAAAB3cmhfY2huZXRfaWZjb25mOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhd -LCBsMmRldl9mYy0+Zmxvd2NfdHlwZSBbJTB4XSwgaWZjb25mX3dyLT5zdWJvcCBbMHgleF0KAAAA -AAAAAAAAAAAAAAAAd3JoX2NobmV0X2lmY29uZjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwg -dW5rbm93biBzdWJvcCBbMHgleF0KAAAAAAAAAAAAAAAAAAB3cmhfY2huZXRfaWZjb25mOiBsMmRl -dl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCByYyAlZAoAAAAAAAAAAAAAAAAAbmV0aWZfaXBfY29uZmxp -Y3RfdGltZXJfY2I6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIGV4cGVjdGluZyB0aW1lciBo -YW5kbGUgWyVkXSwgYnV0IGdvdCBoYW5kbGUgWyVkXSBleHBpcnkKAG5ldGlmX2lwX2NvbmZsaWN0 -X3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBpbmRldmN0eHQtPnN0YXRlIFsl -ZF0sIGluZGV2Y3R4dC0+cmV0cnlfY250IFslZF0KAAAAAAAAAABuZXRpZl9pcF9jb25mbGljdF90 -aW1lcl9jYjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgaW5kZXZjdHh0IFsweCV4XSwgaW4g -ZnJlZSBzdGF0ZQoAAAAAAAAAAABjbWRoX2NobmV0X2lmYWNlOiBmYyBbMHgleF0sIGZjLT5mbG93 -Y19pZCBbMHgleF0sIGZjLT5mbG93Y190eXBlIFsweCV4XSwgcCBbMHgleF0sIGxlbjE2IFsldV0s -IGxvYyBbMHgleF0KAAAAAAAAY21kaF9jaG5ldF9pZmFjZTpsMmRldl9mYyBbMHgleF0sIGwyZGV2 -X2ZjLT5mbG93Y19pZCBbMHgleF0sIGwyZGV2LT5mbG93Y190eXBlIFsldV0sIGwyZGV2X2ZjLT5m -bG93Y19uZXRfbDJkZXZfZmxhZ3MgWyUweF0KAAAAAABjbWRoX2NobmV0X2lmYWNlOiByMlswXSAl -dSByMlsxXSAldQoAAAAAAAAAAAAAAABjbWRoX2NobmV0X2lmYWNlOiBsMmRldl9mYy0+Zmxvd2Nf -bmV0X2wyZGV2X2ZsYWdzIGNoYW5nZWQgZnJvbSBbJTB4XSB0byBbJTB4XSwgcmMgWyVkXQoAAAAA -AAAAAABjaG5ldF9sMmRldl91cF9tYl9jYjogcmMgWyVkXSwgcG9ydCBbJXVdLCBzdGF0ZSBbJXVd -LCBjb29raWUgWzB4JXhdCgAAAAAAAAAAAAAAAGRoY3BfcHJvY2Vzc19jYjogbDJkZXZfZmMtPmZs -b3djX2lkIFsweCV4XSwgZGhjdHh0LT5zdGF0ZSBbJTB4XSwgZGhjdHh0LT5ydHJ5X2NudCBbJXVd -CgAAAAAAAAAAAGRoY3BfdGltZXJfY2I6IERIQ1BESVNDT1ZFUiBzZW50LCBidXQgbm8gcmVwbHkg -ZnJvbSBhbnkgcG9zc2libGUgc2VydmVyIG9uIHRoZSBuZXR3b3JrLiBSZXRyeWluZyBhZ2FpbgoA -AAAAAAAAAABkaGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBzZW5kaW5n -IERIQ1BESVNDT1ZFUiBmb3IgZGhjdHh0IFsweCV4XSBvbiBwaWQgWyVkXQoAAABkaGNwX3RpbWVy -X2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBESENQT0ZGRVIgcmVjZWl2ZWQgZm9yIGRo -Y3R4dCBbJXhdIHBpZCBbJWRdCgAAAAAAAAAAAABkaGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxv -d2NfaWQgWzB4JXhdLCAgREhDUEFDSyByZWNlaXZlZCBmb3IgZGhjdHh0IFsleF0sIHBpZCBbJWRd -CgAAAAAAAAAAAABkaGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBkaGN0 -eHQtPmlwYWRkciBbMHgleF0KAAAAAAAAAAAAAAAAAAAAAGRoY3BfdGltZXJfY2I6IHN0YXJ0aW5n -IHRpbWVyIGZvciBsZWFzZSBbJXVdIHNlY29uZHMKAAAAAAAAAAAAAABkaGNwX3RpbWVyX2NiOiBs -ZWFzZSB0aW1lIG9mIFsldV0gc2Vjb25kcyBleHBpcmVkLCBzZW5kaW5nIHJlbmV3IHJlcXVlc3QK -AAAAAAAAAGRoY3BfdGltZXJfY2I6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIG5vIHJlcGx5 -IGZyb20gZGhjcCBzZXJ2ZXIsIHRpbWluZyBvdXQKAAAAAAAAAAAAAAAAAAAAAGF1dGhfbmVnb19z -ZWN1cml0eTogc2VuZF9mbGFnIFsweCV4XSwgYXV0aF9wb2xpY3kgWzB4JXhdCgAAAAAAAABhdXRo -X25lZ29fc2VjdXJpdHk6IEtFWV9DSEFQX1JFU1AgLSBoYXNoWzB4JXgleCV4JXgleCV4JXgleF0K -AAAAYXV0aF9uZWdvX3NlY3VyaXR5OiBLRVlfQ0hBUF9SRVNQIC0gaGFzaFsweCV4JXgleCV4JXgl -eCV4JXhdCgAAAGF1dGhfbmVnb19zZWN1cml0eTogS0VZX0NIQVBfUkVTUCAtIGVycm9yIGVuY29k -aW5nIHRvIGhleAoAAAAAAABhdXRoX25lZ29fc2VjdXJpdHk6IEtFWV9DSEFQX1JFU1AgLSBlbGVu -IFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAYXV0aF9uZWdvX3NlY3VyaXR5OiBLRVlfQ0hBUF9DSEFM -IC0gZXJyb3IgZW5jb2RpbmcgdG8gaGV4CgAAAAAAAGF1dGhfbmVnb19zZWN1cml0eTogS0VZX0NI -QVBfQ0hBTCAtIGVsZW4gWzB4JXhdCgAAAAAAAAAAAAAAAAAAAABsb2dvdXRfdGltZWRvdXQ6IGxv -Z291dCByZXF1ZXN0IHRpbWVkb3V0LCBwb3NzaWJsZSBuZXR3b3JrIGlzc3Vlcy4gRm9yY2VmdWxs -eSBicmVha2luZyBwYXRoIGZvciBzZXNzIFsweCV4XQoAAAAAcGluZ190YXJnZXQ6IHBpbmcgdGlt -ZW91dCwga2lja2luZyByZWNvdmVyeSBmb3Igc2VzcyBbMHgleF0KAAAAAGNzb2NrX2ZhaWxlZDog -Y3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBzZXNz -X2ZjLT5mbG93Y19pZCBbMHgleF0sIHNlc3NfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgZXZ0IFsw -eCV4XQoAAAAAAAAAAAAAAGNobmV0X2ZpbmRfaXA2X2wydF9lbnRyeTogZmluZCBwcmVmaXggbWF0 -Y2ggWyUwNHggJTA0eCAlMDR4ICUwNHhdCgAAAAAAAAAAAAAAAAAATm8gcm91dGVyIGNvbmZpZ3Vy -ZWQsIGwyZGV2X2ZjLT5mbG93Y19pZCAweCV4CgAAClJvdXRlciBsaWZlICV1IGV4cGlyZWQuIGRl -bGV0aW5nIHJvdXRlciBbJTA0eCAlMDR4ICUwNHggJTA0eF0KAFVzaW5nIHJvdXRlciBbJTA0eCAl -MDR4ICUwNHggJTA0eF0gdG8gcmVhY2ggWyUwNHggJTA0eCAlMDR4ICUwNHhdCgAAAAAAAAAAAAAA -AAAAbDJ0ZW50IFslMHhdLCBsMnRlbnQtPmlkeCBbJWRdCgByYyBbJWRdLCBjc2tfZmMgWzB4JXhd -LCBjc2tfZmMtPmZsb3djX2lkIFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAcmVjb3ZlcnlfdGltZW91 -dDogc2VzcyBpZCBbMHgleF0gc3RhdGUgWzB4JXhdLCByY291bnQgWyVkXSwgZmxhZ3MgWzB4JXhd -CgAAAAAAAAByZWNvdmVyeV90aW1lb3V0OiBzZXNzIGlkIFsweCV4XSBpbiBsb2dvdXQsIGFib3J0 -IHRoZSBjb25uZWN0aW9uCgAAAAAAAAAAAAAAAAAAAHJlY292ZXJ5X3RpbWVvdXQ6IHNlc3NfZmMt -PmZsb3djX2ZvaXNjc2lfc2Vzc19mbGFncyBbMHgleF0sIGNvbm5lY3Rpb24gcmVxdWVzdCBwZW5k -aW5nLCBiYWlsaW5nIG91dAoAAAAAAAAAAAAAAABmb2lzY3NpOiBSZWNvdmVyeSB0aW1lZCBvdXQg -YWZ0ZXIgWyV1XSByZXRyeSwgYmFpbGluZyBvdXQKAAAAAAAAVENQIGNvbm4gZXN0YWJsaXNobWVu -dCBmYWlsZWQgJWQKAAAAAAAAAAAAAAAAAAAAZGlzY292ZXJ5X2RhdGE6IHNlc3MgeyBpZCBbMHgl -eF0sIGZsYWdzIFsweCV4XSwgYnVmZmVyZWQgWyV1XS4gfQoAAAAAAAAAAAAAAAAAAABkaXNjb3Zl -cnlfZGF0YTogc2VzcyB7IGlkIFsweCV4XSB9LCB1bHB0eGNoIFsldV0gbm8gY3JlZGl0cyBhdmFp -bGFibGUsIHJlc2NoZWR1bGluZyByZXF1ZXN0LgoAAABJbnZhbGlkIG9wY29kZSAweCV4IGluIGN0 -cmwgcGF0aAoAAAAAAAAAAAAAAAAAAABERFAgZXJyb3IgWzB4JXhdLCBhYm9ydGluZyBjb25ubiBb -MHgleF0KAAAAAAAAAAByeF9kYXRhX2RkcDogUmVzcG9uY2UgcmVjaWV2ZWQgZm9yIHRhc2sgWzB4 -JXhdIHdoaWxlIGludmFsaWQgdGFzayBvciBjb25uZWN0aW9uIHN0YXRlLiB0YXNrIHN0YXRlIFsw -eCV4XSwgY29ubiBzdGF0ZSBbMHgleF0sIGNvbm4gZmxhZ3MgWzB4JXhdCgBpc2NzaV9oZHJfcng6 -IFJlc3BvbmNlIHJlY2lldmVkIGZvciB0YXNrIFsweCV4XSB3aGlsZSBpbnZhbGlkIHRhc2sgb3Ig -Y29ubmVjdGlvbiBzdGF0ZS4gdGFzayBzdGF0ZSBbMHgleF0sIGNvbm4gc3RhdGUgWzB4JXhdLCBj -b25uIGZsYWdzIFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAaXNjc2lfaGRyX3J4OiBJbnZhbGlkIHRh -c2sgc3RhdGUgMHgleCBmb3IgdGFzayAweCV4LCBpdHQgWzB4JXhdLCBvcGMgWzB4JXhdCgAAAABw -cm9jZXNzX3RtZl9yZXNwb25zZTogYnVmZmVyZWQgWzB4JXhdLCBpc3Rhc2tfZmMtPmZsb3djX2J1 -Zi0+c2NoZWRfbm9kZS5uZXh0IFsweCV4XSwgaXN0YXNrX2ZjIFsweCV4XSwgaXN0YXNrX2ZjLT5m -bG93Y19pZCBbMHgleF0KAAAAAAAAAAAAAAAAAABwcm9jZXNzX3RtZl9yZXNwb25zZTogd3Igb3Ag -WzB4JXhdLCB0bWYgb3AgWzB4JXhdCgAAAAAAAAAAAAAAAAAAcmV0dXJuX3BlbmRpbmdfdGFzazog -Y29va2llIFsweCUwOHhdLCBbMHglMDh4XQoAcmV0dXJuX3BlbmRpbmdfdGFzazogZGVsYXkgcHJv -Y2Vzc2luZywgY29ubiBmbGFncyBbMHgleF0KAAAAAAAAAHJldHVybl9wZW5kaW5nX3Rhc2s6IERv -bmUgc2VuZGluZyB0YXNrIGVycm9yIHRvIGhvc3QsIHVscHR4bGVuMTYgWyV1XQoAAAAAAAAAAAAA -cmV0dXJuX3BlbmRpbmdfdGFzazogZGVxdWV1ZSB0YXNrIFsweCV4XSwgc3RhdGUgWzB4JXhdIGZy -b20gdHhfbGlzdAoAAAAAAAAAAAAAAAByZXR1cm5fcGVuZGluZ190YXNrOiBhbGwgdGFza3MgcmV0 -dXJuZWQsIHJlY292ZXJ5IHN0YXRlIHRyYW5zIHRvIFsweCV4XQoAAAAAAAAAAGNsZWFyX2RkcF9t -YXA6IGlzdGFza19mYyBbMHgleF0sIGlzdGFza19mYy0+Zmxvd2NfaWQgWzB4JXhdIGJ1ZmZlcmVk -ICV1CgAAAAAAAAAAY2xlYXJfZGRwX21hcDogaXN0YXNrX2ZjLT5mbG93Y19mb2lzY3NpX3Rhc2tf -bnBwb2QgJXUsIG5wcG9kICV1LCBwcGRhZGRyIFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAY2xlYXJf -ZGRwX21hcDogYWxsIHJldHVybmVkIHRhc2tzIGRkcCBjbGVhcmVkLCByZWNvdmVyeSBzdGF0ZSB0 -cmFucyB0byBbMHgleF0KAAB3cmhfZm9pc2NzaV9ub2RlOiBub2RlX3dyLT5mbG93aWRfbGVuMTYg -MiBbJXhdCgB3cmhfZm9pc2NzaV9jaGFwOiBpZF9sZW4gWyV4XSwgc2VjX2xlbiBbJXhdCgAAAAB3 -cmhfZm9pc2NzaV9jaGFwOiB0Z3RfaWRfbGVuIFsleF0sIHRndF9zZWNfbGVuIFsleF0KAAAAAAAA -AAAAAAAAc2Vzc2lvbl9ibG9jazogc2Vzc19mYy0+Zmxvd2NfaWQgWzB4JXhdLCBzZXNzX2ZjLT5m -bG93Y19zdGF0ZSBbMHgleF0sIGNvbm5fZmMtPmZsb3djX2lkIFsweCV4XSwgY29ubl9mYy0+Zmxv -d2Nfc3RhdGUgWzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19z -dGF0ZSBbMHgleF0KAAAAAAAAAAAAAAAAAAAAc2Vzc2lvbl91bmJsb2NrOiBzZXNzX2ZjLT5mbG93 -Y19pZCBbMHgleF0sIHNlc3NfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgY29ubl9mYy0+Zmxvd2Nf -aWQgWzB4JXhdLCBjb25uX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQg -WzB4JXhdLCBjc2tfZmMtPmZsb3djX3N0YXRlIFsweCV4XQoAAAAAAAAAAAAAAAAAc3RhcnRfbG9n -b3V0OiBTZXNzLWlkIFsweCV4XSBhbHJlYWR5IGxvZ2dpbiBvdXQuCgAAAAAAAAAAAAAAAAAAAHBl -ZXJfY29uOiBjc2tfZmMgPT4gZmxvd2lkIFsweCV4XSwgZmxvd2NfYnVmIFsweCV4XQoAAAAAAAAA -AAAAAABhbGxvY19zZXNzOiBsb2dpbl9yZXRyeSBbJWRdLCByZWNvdl90aW1lb3V0IFslZF0KAAAA -AAAAAAAAAAAAAAAAZm9pc2NzaV9jdHJsOiBzdWJvcCBbMHgleF0sIHNlc3NfdHlwZV90b19lcmwg -WzB4JXhdLCBzZXNzX3R5cGUgWzB4JXhdCgAAAAAAAAAAAABmb2lzY3NpX2N0cmw6IHJlY2VpdmVk -IGJsb2NrZWQgZnJvbSBkcml2ZXIsIHRyaWdnZXJpbmcgcmV0dXJuIHRhc2tzIG5vdy4KAAAAAAAA -AHdhdGNoZG9nIGNtZCBoYW5kbGVyICh0aW1lICV1IGFjdGlvbiAldSkKAAAAAAAAAFdBVENIRE9H -OiBkZXZpY2Ugc2h1dGRvd24KAAAAAAAAV0FUQ0hET0c6IHBvcnRbJXVdIHBhdXNlIHdhdGNoZG9n -IHRpbWVvdXQKAAAAAAAAV0FUQ0hET0c6IGJ5cGFzcyB0aW1lb3V0CgAAAAAAAABXQVRDSERPRzog -RkxSIC0gbm90IGltcGxlbWVudGVkIHlldAoAAAAAAAAAAAAAAABXQVRDSERPRzogdGVtcGVyYXR1 -cmUgb2YgJWRDIGV4Y2VlZHMgdGhyZXNob2xkIG9mICVkQwoAAAAAAAAAAAAAZmlsdGVyOiBwb3Jn -cmFtbWluZyB0aWQgJXUgKGxlIHRjYW0gaW5kZXggJXUpLi4uCgAAAAAAAAAAAAAAAAAAAGZpbHRl -cjogcmVxdWVzdGluZyBjb21wbGV0aW9uLi4uCgAAAAAAAAAAAAAAAAAAAGNobmV0X2lwdjZfbGlu -a19jaGFuZ2Vfbm90aWZ5OiBsMmRldl9mYyBbMHgleF0sIHN0YXR1cyAldQoAAAAAAABsMmRldl9z -ZW5kX3BvcnRfZXZlbnQ6IHdyIFsweCV4XSBwZW5kaW5nIG9uIHBvcnQgWyVkXSwgY3VycmVudCB0 -cnkgWyVkXQoAAAAAAAAAAEZDT0UgRnJlZTogc3RpbGwgeWllbGRlZCB3aGVuIGZyZWVpbmcuLi5m -bG93Y19pZCAleCBmbG93Y19mbGFncyAleCAKAAAAAAAAAAAAAAAARkNPRSBCUCBXUiBFUlI6IFdS -IHdpdGggY29va2llICV4JXggZXJyb3JlZCBiYWNrIAoAAAAAAAAAAAAAAAAAAHBvcnQgJWQgc2V0 -IHBmY19lbiA9IDB4JXgKAAAAAAAAcG9ydCAlZCBzZXQgcGZjX2VuID0gMHgleAoAAAAAAABldHNf -c2V0X2NmZ19pZWVlWyV1XSB1bmtub3duIFRTQSBhbGcgZm9yIHByaW8gJXU6ICV1CgAAAAAAAAAA -AAAARkNvRSBERFAgZmFpbGVkIDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAARkNvRSBE -RFAgZmFpbGVkIDogRGRwUmVwb3J0IDB4JXggRGRwVmFsaWQgMHgleAoARkMgeGNoZyBhbGxvYyBm -YWlsZWQ6IGF2YWlsICVkCgBmY29lIG5vdGlmeSA6IFVwZGF0ZSBuZXcgRENCWCB2YWx1ZXMgVkkg -c3RhdGUgMHgleCBwcmkgMHgleCBzY2hlZGNsIDB4JXggZGNieF9kb25lIDB4JXgKAAAAAAAAAABm -Y29lIG5vdGlmeSA6IEZDRiBmbG93aWQgMHgleCwgdWxwY2ggMHgleCAKAAAAAABQUkxJIFJzcCB0 -aW1lZG91dCA6IGZsb3djX2lkIDB4JXggb3hfaWQgMHgleCByeF9pZCAweCV4IAoAAAAAAAAAY2Fu -bm90IGFsbG9jYXRlIG9mZmxvYWRlZCBmaWx0ZXIgY29ubmVjdGlvbgoAAAAAY2Fubm90IGFsbG9j -YXRlIG9mZmxvYWRlZCBmaWx0ZXIgSVB2NiBjb25uZWN0aW9uCgAAAAAAAAAAAAAAAAAAAGRpc3Bh -dGNoX2RlZmVycmVkX2NsYXNzX2NsYXNzX3NoYXBpbmdbJXU6JXVdOiBsaXN0X2VtcHR5CgAAAAAA -AABsb29wYmFjayBidWZmZXIgZ3JvdXBbJXVdIGlzIGRpc2FibGVkCgAAAAAAAAAAAABpbnZhbGlk -IGJ1ZmZlciBncm91cFsldV0gY29uZmlndXJhdGlvbjogbXR1ICV1IGx3bSAldSBod20gJXUgZHdt -ICV1CgAAAAAAAAAAAAAAAGZjICV1IHZmICV1IGdvdCBpdmY9MHgleCxyYW5nZTogJSN4LSUjeCAo -JXUvJXUgdXNlZCkKAAAAAAAAAAAAAABWSSAldSBjYW5ub3QgZ2V0IFJTUyBzbGljZTogTm8gbW9y -ZSBzbGljZXMgYXZhaWxhYmxlICh1c2VkICV1LyV1KQoAAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4g -JXUgd2l0aCBwb3J0IG1hc2sgMHgleCBjYW5ub3QgYWNjZXNzIHBvcnQgJXUsIHJldCAlZAoAAAAA -AAAAAAAAAAAAAAAAcGZuICV1IHZmbiAldSBjb3VsZCBub3QgYWxsb2NhdGUgdmlpZCwgcmV0ICVk -CgAAcGZuICV1IHZmbiAldSBjb3VsZCBtYXAgdmlpZCAgMHgleCB0byBmbG93YywgcmV0ICVkCgAA -AAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgY291bGQgbm90IGFsbG9jYXRlIHV3aXJlIGZ1bmMgJWQg -bWFjIGFkZHIsIHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAbWlpX2luaXRbJXVdOiBhY2FwcyAweCV4 -CgAAAAAAAABtaWlfZm9yY2Vfc3BlZWRbJXVdOiByY2FwcyAweCV4CgAAAAAAAAAAAAAAAAAAAABt -aWlfcGRvd25bJXVdOiBwb3dlcmRvd24gZW4gJXUKAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IHVu -a25vd24gYWN0aW9uIDB4JXgKAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IHVua25vd24gcmVh -ZCBhY3Rpb24gMHgleAoAAAAAAAAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTogdGlkICV1IGNwbCAw -eCUwOHglMDh4CgAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTogdGlkICV1IGNwbCAweCUwOHglMDh4 -IDB4JTA4eCUwOHgKAAAAAAAAAAAAAAAAAAAAY3BsX2Vycl9ub3RpZnk6IHRpZCAldSBsZW4gJXUK -AABGQ09FIEZyZWU6IHN0aWxsIHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxvd2NfaWQgJXggZmxv -d2NfZmxhZ3MgJXggCgAAAAAAAAAAAAAAAHNjc2lfYWJvcnQ6IEVudGVyaW5nIEFib3J0X3Rhc2ss -IGJ1ZmZlcmVkIFsldV0KAHNjc2lfYWJvcnQ6IHJjIFsweCV4XSByZWYgdGFzayBub3Qgb3V0c3Rh -bmRpbmcKAHNjc2lfYWJvcnQ6IGlkYXRhLT5vcCBbMHgleF0sIGZsYWdzIFsweCV4XSwgZnVuYyBb -MHgleF0sIGx1bl9pZHggWzB4JXhdCgAAAAAAAAAAc2NzaV9hYm9ydDogd3ItPmlxaWQgWzB4JXhd -LCBpc3Rhc2tfZmMtPmZsb3djX3NnZV9pcWlkIFsweCV4XSwgaXN0YXNrX2ZjIHRhc2sgZmxhZ3Mg -WzB4JXhdCgAAAAAAc2NzaV9hYm9ydDogY29ubiBbMHgleF0sIGNtZHNuIFsweCV4XSwgc2VudF9j -bWRzbiBbMHgleF0sIG1heF9jbWRzbiBbMHgleF0sIGl0dCBbMHgleF0KAAAAAAAAAAAAYWJvcnQv -Y2xvc2UgV1Igd2l0aCBjb29raWUgMHglbHggd2FzIGlzc3VlZCBvbiBzc24gMHgleCBpbiB3cm9u -ZyBzdGF0ZSAweCV4CgAAAABhYm9ydCBXUiBvbiBzc24gMHgleCBkaWQgbm90IGZpbmQgV1Igd2l0 -aCBjb29raWUgMHgleCV4CgAAAAAAAAAAY2xvc2UgV1Igd2l0aCBjb29raWUgMHglbHggb24gc3Nu -IDB4JXg7ZGlkIG5vdCBmaW5kIFdSIHdpdGggY29va2llIDB4JWx4CgAAAAAAAABhYm9ydCBXUiBv -biBzc24gMHgleCB3YXMgaXNzdWVkIG9uIHhjaGcgMHgleCB3aXRoIHJ4X2lkIDB4JXggaW4gd3Jv -bmcgc3RhdGUgMHgleAoAAAAAAAAAAAAAAAAAAABzY3NpX2x1cjogRW50ZXJpbmcgTFVSIGhhbmRs -ZXIsIGJ1ZmZlcmVkIFsldV0KAABzY3NpX2x1cjogaWRhdGEtPm9wIFsweCV4XSwgZmxhZ3MgWzB4 -JXhdLCBmdW5jIFsweCV4XSwgbHVuX2lkeCBbMHgleF0KAAAAAAAAAAAAAHNjc2lfbHVyOiB3ci0+ -aXFpZCBbMHgleF0sIGlzdGFza19mYy0+Zmxvd2Nfc2dlX2lxaWQgWzB4JXhdLCBpc3Rhc2tfZmMg -dGFzayBmbGFncyBbMHgleF0KAAAAAAAAAHNjc2lfbHVyOiBjb25uIFsweCV4XSwgY21kc24gWzB4 -JXhdLCBzZW50X2NtZHNuIFsweCV4XSwgbWF4X2NtZHNuIFsweCV4XSwgaXR0IFsweCV4XQoAAAAA -AAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9MSU5LVVAKAGRj -YnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gU0VUX0xPQ0FMX1BBUkFNRVRFUlMKAAAAAAAA -AAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfTk9fQURWRVJUSVNF -CgAAAAAAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1BFRVJf -Tk9UX0FEVkVSVElTRV9EQ0JYCgAAAAAAAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZl -YXR1cmVbJXVdIEZFQVRVUkVfUEVFUl9OT1RfQURWRVJUSVNFX0ZFQVRVUkUKAAAAAAAAAAAAAAAA -AGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VUERBVEVfT1BFUl9WRVJT -SU9OCgAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfUEVFUl9VUERB -VEVfT1BFUl9WRVJTSU9OCgAAAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVy -ZVsldV0gRkVBVFVSRV9HRVRfUEVFUl9DRkcKAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVd -IEZlYXR1cmVbJXVdIEZFQVRVUkVfQ0ZHX05PVF9DT01QQVRJQkxFCgAAAAAAZGNieF9jZWVfZmVh -X3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1VTRV9MT0NBTF9DRkcKAAAAAAAAAAAAAGRjYnhf -Y2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VU0VfUEVFUl9DRkcKAAAAAAAAAAAA -AABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfRkVBVFVSRV9ESVNBQkxF -RAoAAAAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0VSUk9SX0NI -QU5HRQoAAAAAAAAAAAAAAEZlYXR1cmUgJXUgc3luYydkPSV1IChlcnJvciAldSkKAAAAAAAAAAAA -AAAAAAAAAGlwdjZfYWRkX3ByZWZpeF9pbl9saXN0OiBub2RlIGZvdW5kIDB4JXgKAAAAAAAAAGlw -djZfYWRkX3ByZWZpeF9pbl9saXN0LCBub2RlIG5vdCBmb3VuZAoAAAAAAAAAAGNobmV0X2FycF91 -cGRhdGVfY2FjaGU6IGFycCBpcDQgZW50cnkgZm91bmQgCgAAAGNobmV0X2FycF91cGRhdGVfY2Fj -aGU6IGFycCBpcDYgZW50cnkgZm91bmQgCgAAAGNobmV0X2FycF91cGRhdGVfY2FjaGU6IGJvdGgg -aXA0IGFuZCBpcDYgYWRkciBjYW5ub3QgYmUgbnVsbAoAAABjaG5ldF9sMnRfdXBkYXRlOiBsMnRf -dXBkYXRlIHJlcXVlc3Qgc2VudCBsMnRlbnQgWyUwOHhdLCBsMnRlbnQtPmlkeCBbJWRdLCBsMnRl -bnQtPnZsYW4gWyVkXQoAAABjaG5ldF9pcHY2X3JhX2lucHV0OiBJbnZhbGlkIFJBCgAAAAAAAAAA -AAAAAAAAAABpcHY2IFJBIHJjdmQKAAAAcm91dGVyIG5vdCBwcmVzZW50IGluIG91ciBsaXN0LiBh -ZGRpbmcgaXQKAAAAAAAASW52YWxpZCBvcHRpb24gbGVuZ3RoICV1IGluIFNMTEEgb3B0aW9uCgAA -AAAAAAAAR09UIFNMTEEgb3B0aW9uIGluIFJBLCBsZW4gJXUKAABJbnZhbGlkIG9wdGlvbiBsZW5n -dGggJXUgaW4gcHJlZml4IG9wdGlvbgoAAAAAAABJbnZhbGlkIG9wdGlvbiBsZW5ndGggJXUgaW4g -bXR1IG9wdGlvbgoAAAAAAAAAAABJbnZhbGlkIHBhY2tldCB3aXRoICV1IGV4dHJhIGJ5dGVzCgAA -AAAAAAAAAAAAAABtbGQ2IHF1ZXJ5IHJjdmQKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2lwdjZfbWxk -Nl9xdWVyeV9pbnB1dDogSW52YWxpZCBNTEQgcXVlcnkKAFVuc3VwcG9ydGVkIHF1ZXJ5IHZlcnNp -b24uIG9ubHkgbWxkdjIgcXVlcnkgc3VwcG9ydGVkCgAAAAAAAAAAAABxdWVyeSByZXNwb25zZSBk -ZWxheSAldSAoaW4gMTBtcyB1bml0KSAKAAAAAAAAAABhbHJlYWR5IGEgZ2VuZXJhbCBxdWVyeSBw -ZW5kaW5nIGluICV1ICgxMG1zKQoAAABEZWJ1ZyB0aGUgY29kZS4gZ3JwX25vZGUgbXVzdCBiZSBw -cmVzZW50CgAAAAAAAABhbHJlYWR5IGEgbXVsdGljYXN0IHF1ZXJ5IHBlbmRpbmcgaW4gJXUgKDEw -bXMpCgBpcHY2IGVjaG8gcmVxIHJjdmQKAAAAAAAAAAAAAAAAAERIQ1B2NiBwYWNrZXQgdHlwZSAl -dSwgb3B0c2xlbiAldSByZWNlaXZlZAoAAAAAAEludmFsaWQgZGhjcCBzdGF0ZSAlZAoAAAAAAAAA -AAAASWdub3JlIERIQ1B2NiBtc2cgeGlkICV4LCAgZGg2Y3R4dC0+eGlkICV4CgAAAAAARXJyb3Ig -aW4gREhDUHY2IG9wdGlvbnMgcGFyc2luZy4gSWdub3JpbmcgbXNnLCBpICVkLCBvcHRzbGVuICVk -CgAAAAAAAAAAAAAAAAAAAABESENQIGZhaWxlZCwgc3RhdHVzY29kZSAlZC4gSWdub3JpbmcgYWR2 -ZXJ0aXNlCgBpY21wNiBjaGVja3N1bSB2YWxpZGF0aW9uIGZhaWxlZCwgb3IgZXJyIHJjdmRpZ25v -cmluZyBpY21wNiBtc2cgJXUsIGRsZW4gJXUKAAAAAG5ldGlmX3Byb2Nlc3NfZGhjcDogbDJkZXZf -ZmMtPmZsb3djX2lkIFsweCV4XSwgcHJvY2Vzc2luZywgb3B0X2xlbiAldQoAAAAAAAAAAAAAY2hu -ZXRfZGhjcF9yZWN2OiB2bGFuaWQgWyV1XSwgbDJkZXZfcGlkX2ZjLT5mbG93Y19uZXRfbDJkZXZf -dmxhbmRldiBbMHgleF0sIGwyZGV2X2ZjIFsweCV4XQoAAAAAY2huZXRfZGhjcF9yZWN2OiBsMmRl -dl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBkaGN0eHQtPnN0YXRlIFslZF0sIG1hbGFjaW91cyBkaGNw -IHJlY3YgZm9yIG5vIHJlcXVlc3QKAAAAAAAAAAAAAAAAAGRoY3R4dC0+c3RhdGUgOiAlZAoAAAAA -AAAAAAAAAAAAbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgQmFkIERIQ1AgY29va2llIHJlY2ll -dmVkLCBhYm9ydGluZwoAAENvdWxkIG5vIGFsbG9jYXRlIHBjYiEhIEZyZWVpbmcgZmNmICEhIQoA -AAAAAAAAAHZuX3BhcnNlIHVua25vd24gc3ViY29kZSAldQoAAAAAdm5fcGFyc2UgdW5rbm93biBk -dHlwZSAldQoAAAAAAABpZ25vcmluZyBmaXAgcmVjdiBmb3IgcGNiIGZsb3c6JXggaW4gb2ZmbGlu -ZSBzdGF0ZQoAAAAAAAAAAAAAAAAAZmlwX3ZuMnZuX3JlY3ZfZXJyIAoAAAAAAAAAAAAAAABDb3Vs -ZCBub3QgYWxsb2NhdGUgZmxvd2MhISEhCgAAAENvdWxkIG5vdCBhbGxvY2F0ZSBTQ0IgZmxvd2Mh -ISEhCgAAAAAAAAAAAAAAAAAAAENvdWxkIG5vdCBmaW5kIHJpZ2h0IHNjYiBmb3IgbG9nbwoAAAAA -AAAAAAAAAAAAAGlnbm9yaW5nIGZpcCByZWN2IGZvciBmY2YgZmxvdzoleCBpbiBvZmZsaW5lIHN0 -YXRlCgAAAAAAAAAAAAAAAABDb3VsZCBub3QgZmluZCByaWdodCBzY2IgZm9yIGZsb2dpCgAAAAAA -AAAAAAAAAABwb3J0IDB4JXgsIHN0YXRlIDB4JXgsIHJldHJ5IG5vdCBzdXBwb3J0ZWQKAAAAAABG -bG9naSByZXNwIHJjdiB3aXRoIHVua25vd24geGNoZyBveF9pZCV4IHNpZCAlMnglMnglMnggZGlk -ICUyeCUyeCUyeAoAAAAAAAAAAAAAAE5fUE9SVCAweCV4JXgleCByZWplY3RlZCBQTE9HSSB3aXRo -IHJlYXNvbiBjb2RlICV4CgAAAAAAAAAAAAAAAABBQlRTIHdoaWxlIGF3YWl0aW5nIFBSTEkgUnNw -OiBmbG93Y19pZCAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleCAKAAAAAAAAAAAAAAAAAEFCVFMg -ZmFrZSBSc3A6IGxvYyAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleAoAAEZDIGZjYiBhbGxvYyBm -YWlsZWQ6IGF2YWlsICVkCgAARkMgZmNiIGFsbG9jIHhpZDolZCBmbG93aWQgJWQKAABsbGRwX3J4 -X3BrdF9oYW5kbGVyWyV1XSBkcm9wIHByZS1pbml0IChjb3VudCA9ICV1KQoAAAAAAAAAAAAAAAAA -JXgleCV4IFJlY2lldmVkIExPR08gZnJvbSAleCV4JXggCgAAAAAAAAAAAAAAAAAARmFpbGVkIHRv -IHBvc3QgeGNoZyBlcnI6IHNzbmkgMHgleCBjb29raWUgMHglbHggcnZhbCAleCAKAAAAAAAAAHRj -cF9yZWxlYXNlX3RpZDogdGlkIFsweCV4XSwgZmxvd2MgZmxhZ3MgWzB4JXhdLCBidWZmZXJlZCBb -MHgleF0KAAAAAAAAAAAAAAAAAAAAdGNwX3JlbGVhc2VfdGlkOiBzaXplb2YodGNiX2ZjLT5mbG93 -Y19mb2lzY3NpX2Nvbm4pIFsldV0sIGJ5dGVzCgAAAAAAAAAAAAAAAAAAAABhY3Rfb3Blbl9ycGw6 -IGF0aWQgWzB4JXhdLCB0aWQgWzB4JXhdLCB0Y2JfZmMtPnsgaWQgWzB4JXhdLCBzdGF0ZSBbMHgl -eF0sIHR5cGUgWzB4JXhdIH0sIGNwbF9vcCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAAAAAAAAAA -AGFjdF9vcGVuX3JwbDogY3NrX2ZjLT57IGlkIFsweCV4XSwgc3RhdGUgWzB4JXhdLCBjc29ja19m -bGFncyBbMHgleF0gfSAKAAAAAAAAAAAAYWN0X29wZW5fcnBsOiByZWN2ZCBuZWcgYWR2aWNlIFsw -eCV4XQoAAAAAAAAAAAAAc2VuZF9hYm9ydF9ycGw6IGNza19mYy0+Zmxvd2NfdHlwZSBbMHgleF0s -IGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCB0aWQgWzB4JXhdLCB1bHB0eGNoIFsldV0sIGJ1ZmZl -cmVkIFsldV0KAAAAAHdyaF9vZmxkX3RjcF9jbG9zZV9jb25fcmVwbHk6IHRjYl9mYy0+Zmxvd2Nf -aWQgWzB4JXhdLCB0Y2JfZmMtPmZsb3djX3R5cGUgWzB4JXhdLCBsZW4xNiBbJXVdLCBsb2MgWyV1 -XQoAAAAAAAAAAAB3cmhfb2ZsZF90Y3BfY2xvc2VfY29uX3JlcGx5OiBycGwtPm9wX1RpZCBbMHgl -eF0sIHJwbD5zdGF0dXMgWzB4JXhdLCBycGwtPnNuZF9ueHQgWzB4JXhdLCBycGwtPnJjdl9ueHQg -WzB4JXhdCgAAdGNwX2Fib3J0X3JwbF9yc3M6IHRpZCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAA -dGNwX2Fib3J0X3JlcV9yc3M6IHRpZCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAAb2ZsZF9hYm9y -dF9yZXFfbmVnYWR2WyV1XTogd3IgMHglMDh4IGNwbF9hYm9ydF9yZXEgREVMSVZFUkVECgAAAGhv -c3Rfd3JbJXVdOiB3ciAweCUwOHggY3BsX2Fib3J0X3JlcSBzdGF0dXMgMHgleAoAAAAAAAAAAAAA -AAAAAABwa3RzY2hlZF9jbF9ybFsldToldV06IG1vZGUgfCB1bml0IHwgcmF0ZSAweCUwNnggbWlu -ICV1IG1heCAldSBwa3RzaXplICV1CgAAAAAAAHBhcmFtX2NobmV0WzB4JXg6MHgleF06IGNobmV0 -IDB4JXggcmVhZCAldSBwZiAldSByZXQgJWQKAAAAAAAAAABwYXJhbV9kbWFxWzB4JXg6MHgleF06 -IGRtYXEgMHgleCByZWFkICV1IHBmICV1IHJldCAlZAoAAAAAAAAAAAAATUNbJXVdIGluaXRfc3Rh -dGVfbWFjaGluZSAweCUwMngKAAAAAAAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24gbm90IGNv -bXBsZXRpbmcsIE1DIGN1cnJlbnQgaW5pdCBzdGF0ZSBpcyAweCUwMngKAAAAAAAAAAAAAAAAAABN -Q1sldV0gX2h3X21jX2luaXRfbWMKAAAAAAAAAAAAAF9od19tY19pbml0X21jX2ZwZ2FbJXVdOiBl -cnJvciAlZAoAAAAAAAAAAAAAAAAAAHBoeTogZmFpbGVkIHRvIGFsbG9jYXRlZCBtZW1vcnkgZm9y -IHBoeSBmdyBmaWxlLCByZXQgJWQKAAAAAAAAAABod19sZV9maWx0ZXJfY3R1cGxlOiB0dXBsZSAl -dSBub3Qgc3BlY2lmaWVkIGJ1dCByZXF1aXJlZCBmb3IgbWFzayAweCV4CgAAAAAAAAAAAGxlIGNv -bmZpZ3VyYXRpb246IGhhc2ggcmVnaW9uIHRvbyBsYXJnZSB0byBlbmFibGUgc2VydmVyIHNyYW0K -AABsZSBjb25maWd1cmF0aW9uOiBjYW5ub3QgZW5hYmxlIHNlcnZlciBzcmFtIHdoZW4gaGFzaCBy -ZWdpb24gaXMgZGlzYWJsZWQKAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiB0aW1lcl9ycyAl -dXVzIHRpbWVzdGFtcF9yZXMgJXV1cyBkZWxheWVkYWNrX3JlcyAldXVzCgAAAAAAaHdfdHBfdGNw -X3NldHRpbmdzX3c6IGRhY2tfdGltZXIgJXV1cyBtc2wgJXV1cyByeHRfbWluLG1heCAldSwldXVz -IHBlcnNfbWluLG1heCAldSwldXVzCgAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGtlZXBf -aWRsZSxpbnR2bCAldSwldXMgbWF4cnR0ICV1dXMgaW5pdHNydHQgJXV1cyBmaW53YWl0Ml90aW1l -ciAldXVzCgAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgZGFja190aW1lciBmcm9t -ICV1IHRvICV1AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIG1zbCBmcm9t -ICV1IHRvICV1AGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHJ4dF9taW4gZnJvbSAldSB0 -byAldQAAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyByeHRfbWF4IGZy -b20gJXUgdG8gJXUAAAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcGVy -c19taW4gZnJvbSAldSB0byAldQAAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBw -aW5nIHBlcnNfbWF4IGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3Nf -dzogY2FwcGluZyBrZWVwX2lkbGUgZnJvbSAldSB0byAldQAAAAAAAAAAAAAAaHdfdHBfdGNwX3Nl -dHRpbmdzX3c6IGNhcHBpbmcga2VlcF9pbnR2bCBmcm9tICV1IHRvICV1AAAAAAAAAAAAAGh3X3Rw -X3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIGluaXRfc3J0dF9tYXhydHQgZnJvbSAldSB0byAldQAA -AABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBpbml0X3NydHRfaW5pdHNydHQgZnJvbSAl -dSB0byAldQAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgZmlud2FpdDJfdGltZXIgZnJv -bSAldSB0byAldQAAAAAAAGxlIGNvbmZpZ3VyYXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNs -aXAgJXUgZmlsdGVyICV1IGFjdGl2ZSAldSBzZXJ2ZXIgJXUgaGFzaCAldQoAAAAAAAAAAAAAAGxl -IGNvbmZpZ3VyYXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IHNl -cnZlciAldSBhY3RpdmUgJXUgaGFzaCAldSBuc2VydmVyc3JhbSAldQoAAAAAAAAAAAAAAABod19z -Z2VfcXVldWVfYmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgZWdyZXNzIHF1ZXVlcywg -JXUKAAAAAAAAAAAAAAAAAAAAAGh3X3NnZV9xdWV1ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51 -bWJlciBvZiBpbmdyZXNzIHF1ZXVlcyB3aXRoIGZyZWVsaXN0IGFuZCBpbnRlcnJ1cHQsICV1CgAA -AGh3X3NnZV9xdWV1ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBvZiBpbmdyZXNzIHF1 -ZXVlcywgJXUKAAAAAAAAAAAAAAAAAAAAc2t1OiBjdXN0b20gc2t1IDEwRyBkb2VzIG5vdCBzdXBw -b3J0IDQwRyBwb3J0cwoAc2t1OiBjdXN0b20gc2t1IDQwR19TTyBkb2VzIG5vdCBzdXBwb3J0IGV4 -dG1lbQoAc2t1OiBjdXN0b20gc2t1IDEwR19TTyBkb2VzIG5vdCBzdXBwb3J0IDQwRyBwb3J0cygl -dSkgb3IgZXh0bWVtKCV1KQoAAAAAAAAAAAAAAABza3U6IGN1c3RvbSBza3UgMHgleCA0MEcgcG9y -dHMoJXUpIGV4dG1lbSgldSkKAABjZl9wYXJzZTogZmlsZSBtZW10eXBlIDB4JXggbWVtYWRkciAw -eCV4IG1hcHBlZCBAICVwOgoAAAAAAAAAAAAAY29uZmlndXJlZCB3aXRoIGNhcHMgbmJtfGxpbmsg -MHglMDh4IHN3aXRjaHxuaWMgMHglMDh4IHRvZXxyZG1hIDB4JTA4eCBpc2NzaXxmY29lIDB4JTA4 -eAoAAAAAAAAAbmV0IFZJIGFsbG9jYXRpb24gZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9y -ICVkCgAAAAAAAAAAAAAAAG5ldCBWSSBtYWMgYWRkcmVzcyBwcm9ncmFtbWluZyBmYWlsZWQgZm9y -IGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAAAAAAAAAAAAAAAAbmV0IFZJIHJ4bW9kZSBwcm9n -cmFtbWluZyBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAG5ldCBWSSByc3Mg -aW5kaXJlY3Rpb24gdGFibGUgcHJvZ3JhbW1pbmcgZm9yIGZjX2lkICV1IGZhaWxlZCB3aXRoIGVy -cm9yICVkCgAAAAAAbmV0IFZJIHJzcyBjb25maWcgY29tbWFuZCBmYWlsZWQgZm9yIGZjX2lkICV1 -IHdpdGggZXJyb3IgJWQKAAAAAG5ldCBWSSBjb21tYW5kIGZhaWxlZCBmb3IgZmNfaWQgJXUgd2l0 -aCBlcnJvciAlZAoAAAAAAAAAAAAAAAAAAABwcm9ncmFtbWVkIEhXIHRhZ20gWzB4JTA4eF0sIEhX -IHBnc3ogZmFjdG9yIFsweCUwOHhdLCBGT2lTQ1NJIHRhZ20gWzB4JTA4eF0sIHJ0YWdtIFsweCUw -OHhdLCBtYXhzel9iaXRzIFsldV0sIHN6X2JpdHMgWyV1XS4KAAAAAGJhc2UgWyAweCUwOHhdLCBs -bGltaXQgWzB4JTA4eF0sIHVsaW1pdCBbMHglMDh4XSwgc2l6ZSBbJXVdLCBtYXhfdHhzeiBbJXVd -LCBtYXhfcnhzeiBbJXVdLCBpb3NpemUgWyV1XQoAAAAAAAAAAABucHBvZHMgWyV1XSwgaWR4X21h -c2sgWzB4JTA4eF0sIGlkeF9maXJzdCBbJXVdLCBpZHhfbGFzdCBbJXVdLCBzY3NpX3BsZF9zaXpl -IFsldV0sIEFMSUdOKHNjc2lfcGxkX3NpemUsIDE2KSBbJXVdLCBwcGRfem9uZXMgWyV1XS4KAAAA -AAAAAAAAAAAAAABmb2lzY3NpX2luaXQ6IGZvaXNjc2lfaW5pdF9kb25lIFsldV0sIGRldi5yZXMu -Zm9pc2NzaV9udGFza3MgWyV1XSwgZGV2LnJlcy5mb2lzY3NpX25zZXNzIFsldV0sIGRldi5yZXMu -bmNzb2NrIFsldV0sIGRldi5yZXMuZm9pc2NzaV9uaW5pdCBbJXVdLCByYyBbJWRdCgAAAAAAAAAA -Y2hfY2xfcmF0ZVsldS8ldV06IGNhcHBlZCBjbGFzcyByYXRlIGZyb20gcmVxdWVzdGVkICV1IHRv -IGNvbmZpZ3VyZWQgKGVmZmVjdGl2ZSkgY2hhbm5lbCByYXRlICV1CgAAAAAAAAAAAAAAAAAAAGNo -X2NsX3JhdGVbJXUvJXVdOiBpbmNyZWFzZWQgZGVmaWNpdF9pbmNyIGZyb20gcmVxdWVzdGVkICV1 -IHRvIHJlcXVpcmVkIG1pbiBvZiAldTsgcmF0ZSAldSAoZWZmICV1KSBkZWZpY2l0X21heCAldQoA -AAAAAAAAAAAAAAAAcGt0c2NoZWQgY2hhbm5lbCAldSBzZXRzIHNwZWVkIChmcm9tICV1KSB0byAl -dSBrYnBzCgAAAAAAAAAAAAAAAG5ldF9sMmRldl9ub3RpZnk6IGwyZGV2X2ZjLT5mbG93Y19pZCBb -MHgleF0sIHBvcnQgWyVkXSwgZXZlbnQgWzB4JXhdLCB1bHB0eGNoIFsldV0sIGNsYXNzIFsweCV4 -XSwgdnByaW8gWzB4JXhdLCB2aWQgWzB4JXhdLCB2aV9yZWFkeSBbJXVdCgAAAAAAAG5ldF9sMmRl -dl9ub3RpZnk6IHBnaWQgWzB4JXhdLCBwcmlvIFsweCV4XSwgY2ggWzB4JXhdCgAAAAAAAAAAAABm -Y29lIG5vdGlmeSA6IEZDb0UgTElOS1VQOiBwb3J0IDB4JXgsIGV2ZW50IDB4JXgKAAAAAAAAAAAA -AAAAAAAAZmNvZSBub3RpZnkgOiBGQ29FIExJTktET1dOOiBwb3J0IDB4JXgsIGV2ZW50IDB4JXgK -AAAAAAAAAAAAAAAAAGZjb2Ugbm90aWZ5IDogRENCWCA6IHBvcnQgMHgleCwgcHJpb3JpdHkgMHgl -eCB1bHB0eGNoIDB4JXggY2xhc3MgMHgleAoAAAAAAAAAAAAAZGNieF90aW1lb3V0WyV1XQoAAAAA -AAAAAAAAAAAAAABwb3J0X2NtZF9oYW5kbGVyOiB1bmtub3duIHUuZGNiLnR5cGUgMHgleAoAAAAA -AABwb3J0WyV1XSBwdHlwZSAldSBsYW5lICV1OiByeGNmZyA9ICUjeAoAAAAAAAAAAABwb3J0WyV1 -XSBwdHlwZSAldSBsYW5lICV1OiB0eGNmZyA9ICUjeAoAAAAAAAAAAABwb3J0WyV1XSBsaW5rIGRv -d24gKCV1KSAobHN0YXR1cyAlI3gpCgAAAAAAAAAAAABod19pMmNfdHJhbnNhY3Rpb246IG5kYXRh -ICV1IGFkZHJfb3AgMHgleCBkYXRhWzBdIDB4JXggZGlmZiAldQoAaHdfaTJjX3RyYW5zYWN0aW9u -OiBuZGF0YSAldSBhZGRyX29wIDB4JXggZGF0YVswXSAweCV4IGRpZmYgJXUgZHBvcyAldSBjb250 -ICV1IGZhaWxlZCB3aXRoIGVyciAlZAoAAAAAAAAAAAAAAAAAAGkyYyB0cmFuc2FjdGlvbiBmYWls -ZWQgdG8gY29tcGxldGUKAAAAAAAAAAAAAAAAAGkyYyBlcnJvciBjYXVzZWQgYnkgbW9kdWxlIHVu -cGx1ZwoAAAAAAAAAAAAAAAAAAHNlbmR0byBwZW5kaW5nOiB3cl9wZW5kICVwIGZvciBwb3J0ICV1 -LCB3YW50IHRvIHNlbmQgdG8gcG9ydCAldQoAAAAAAAAAAAAAAAAAAAAAcG9ydFsldV0gdXBkYXRl -IChmbG93Y2lkICV1IHJjICV1KQoAAAAAAAAAAAAAAAAAcG9ydF9zZXRfbG9vcGJhY2sgcG9ydCAl -I3ggY3VycmVudCAlI3ggbW9kZSAlI3gKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXVdIHNwZWVkIHVw -ZGF0ZTogJSN4CgAAAAAAcG9ydFsldV0gYmVnaW5uaW5nIGRlYm91bmNlCgAAAABRU0ZQIG1vZHVs -ZSB1bnBsdWcgLSByZWluaXRpYWxpemluZyByeF9sb3MgIHRvIDB4ZmYKAAAAAAAAAAAAAAAAZ3Bp -b19xc2ZwX21vZHVsZV91cGRhdGU6IGNoYW5nZWQgcnhfbG9zIGZyb20gMHgleCB0byAweCV4CgAA -AAAAAGdwaW9fcXNmcF9tb2R1bGVfdXBkYXRlOiBjaGFuZ2VkIHR4X2RpcyBmcm9tIDB4JXggdG8g -MHgleAoAAAAAAABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0gcG93ZXJpbmcgZG93bgoAAAAA -AABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0gcG93ZXJpbmcgdXAKAAAAAAAAAABwb3J0X2xp -bmtfc3RhdGVfaGFuZGxlclsldV0gdW5rbm93biBzdGF0ZSAoc3RhdGUgPSAlI3gpCgAAAAAAAAAA -cG9ydF9saW5rX3N0YXRlX2hhbmRsZXI6IFNvbWV0aGluZyB3ZW50IHRlcnJpYmx5IHdyb25nLiBy -ZXQgPSAlZAoAAAAAAAAAAAAAAAAAAABod19zZ2VfbWFtZW1faW5pdDogZW5jb3VudGVyZWQgZXJy -b3IgJWQKAAAAAAAAAABsZSBpbml0aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xp -cCAldSBmaWx0ZXIgJXUgYWN0aXZlICV1IHNlcnZlciAldSBoYXNoICV1CgAAAAAAAAAAAABsZSBp -bml0aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIgJXUgc2Vy -dmVyICV1IGFjdGl2ZSAldSBoYXNoICV1IG5zZXJ2ZXJzcmFtICV1CgAAAAAAAAAAAAAAaHdfdHBf -aW5pdDogdGNiIHJlZ2lvbiAoc3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3Qg -MjU2TUIgb2YgTUEgbWVtb3J5CgAAAAAAAAAAAAAAAAAAaHdfdHBfaW5pdDogcGdtbmd0IHJlZ2lv -biAoc3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2TUIgb2YgTUEgbWVt -b3J5CgAAAAAAAAAAAAAAaHdfdHBfaW5pdDogVFAgcGdtbmd0IGluaXRpYWxpemF0aW9uIGRpZCBu -b3QgY29tcGxldGUKAAAAAAAAAAAAAGJ1Zm1faW5pdDogbiAldSBidWZsbDY0aW50X3NpemUgMHgl -eAoAAAAAAAAAAAAAAGJ1Zm1faW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgaW50 -ZXJuYWwgYnVmbGw2NCBidWZmZXJzCgAAAAAAAAAAAAAAAAAAYnVmbV9pbml0OiBub3QgZW5vdWdo -IG1lbW9yeSB0byBhbGxvY2F0ZSBidWZsbDY0IGJ1ZmZlcnMKAAAAAAAAAG1lbV9pbml0X2J1Zjog -bm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyBidWZmZXJzCgAAAAAAAABtZW1faW5p -dF9idWY6IG5vdCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIHRjYl9jYWNoZSAob2ZmZXJlZCAl -dSB0cnlpbmcgdG8gdXNlICV1IGF2YWlsYWJsZSAldSkKAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlv -bl9vdGhlcnM6IHN0YXJ0IDB4JTA4eCBzaXplICV1ICh1bnVzZWQgJXUpCgAAAAAAAAAAAAAAAG1w -YXJ0aXRpb25fb3RoZXJzOiBzdGFydCAweCUwOHggc2l6ZSAldSAodW51c2VkICV1KQoAAAAAAAAA -AAAAAABtZW1faW5pdDogRURDIG92ZXJjb21taXR0ZWQgYnkgJWQgYnl0ZXMKAAAAAAAAAABtZW1f -aW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyB0YWJsZQoAAAAAAAAAAAAA -AAAAY3hjbmljX2RldmljZV9pbml0OiBjeGNuaWMgWzB4JTB4XSwgY3hjbmljLT5maWx0ZXIgWyUw -eF0KAAAAAAAAAHBvZmNvZSBpbml0IGRvbmUKAAAAAAAAAAAAAAAAAAAAUG9ydFsldV06IFVua25v -d24gU0dNSUkgc3ViLXR5cGUgJSN4CgAAAAAAAAAAAAAAUG9ydFsldV06IFVua25vd24gQlRfWEZJ -IHN1Yi10eXBlICUjeAoAAAAAAAAAAAAAcG9ydF9pbml0WyV1XTogcG9ydCB0eXBlIDB4JXggaXMg -bm90IHN1cHBvcnRlZAoAbXBhcnRpdGlvbl9pbml0OiBtb3ZlZCBwbXJ4X3N0YXJ0IGZyb20gMHgl -MDh4IHRvIDB4JTA4eCB0byBtYWtlIHJvb20gZm9yIExFIEhBU0ggYW5kL29yIFRQIFRDQnMKAAAA -AAAAAAAAAAAAAAAAAG1wYXJ0aXRpb25faW5pdDogbW92ZWQgcG1yeF9zdGFydCBmcm9tIDB4JTA4 -eCB0byAweCUwOHggKEVEUkFNKQoAAAAAAAAAAAAAAAAAAAAARVEgcGZuICV1IHZmbiAldTogZGVz -dHJveWluZyBlcWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFn -cyAweCUwOHgKAAAAAAAAAAAAbDJkZXZfZmMtPmZsb3djX2lkIFsldV0sIGwyZGMtPnBmbiBbJXVd -LCBsMmRjLT52Zm4gWyV1XSwgbDJkYy0+bHBvcnQgWyV1XSwgbDJkZXZfZmMtPmZsb3dpZCBbJXVd -IGwyZGMtPnR4X2NoIFsldV0sIGRldi52cGQucG9ydHZlYyBbJXhdCgAAAAAAAAAAcG9ydHZlYyBb -JXVdCgAAAGwyZGV2X3ZpX2ZzbTogbWIgWzB4JXhdLCBkZWZlcnJlZCwgc3RhdGUgWzB4JXhdLCBw -b3J0IFsweCV4XQoAAABsMmRldl92aV9mc206IHZpaWQgWzB4JXhdIHBvcnQgWzB4JXhdLCBtYWMt -aWQgWyUwMng6JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4XS4gCgAAAAAAAAAAAAAAAAAAAABsMmRl -dl92aV9mc206IHNnZV9lcWlkIFsweCV4XSwgc2dlX2lxaWQgWzB4JXhdLCBzZ2VfZXFjciBbMHgl -eF0sIHJzc19zeiBbMHgleF0KAGwyZGV2X3ZpX2ZzbTogbDJkZXZfZmMtPmZsb3djX25ldF9sMmRl -dl9tdHUgWyV1XSwgbWJfc2NyYXRjaCBbMHgleF0sIHBvcnQgWzB4JXhdCgAAAAAAAAAAAAAAAAAA -AGwyZGV2X3ZpX2ZzbTogdmlpZCBbJWRdLCB2aV9mYy0+Zmxvd2NfdmlfZmxhZ3MgWzB4JXhdCgAA -AAAAAAAAAABsMmRldl92aV9mc206IHBmbiBbMHgleF0sIHZmbiBbMHgleF0sIGwyZGV2X2ZjLT5m -bG93Y19pZCBbMHgleF0sIGxwb3J0IFsweCV4XSwgdmlpZCBbMHgleF0sIGZsYWdzIFsweCV4XQoA -AAAAAAAAbDJkZXZfdmlfZnNtOiBFcnJvciBmcmVlaW5nIFZJLCByYyBbMHgleF0KAAAAAAAAbDJk -ZXZfdmlfZnNtOiBwaWQgWzB4JXhdLCB2aWlkIFsweCV4XSwgbWJfbG9jIFsweCV4XSwgbWJfb3Jp -Z1sweCV4XSwgbDJkZXZfZmxhZ3MgWzB4JXhdLCByYyBbMHgleF0KAAAAAAAAAAAAAAAAAEFoIGhh -Li4uZG91YmxlIGZyZWUgb3hfaWQgMHgleCwgcnhfaWQgMHgleAoAAAAAAEhvc3QgUFJMSSBSZXNw -b25zZSB0aW1lZG91dDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAAAAAAAABGQ09FIEZy +ABBgMFtwdPevp2AAEHAwKRwQ/TwAAAsQeDDTD236FCrQAMmm+pQAIAICc7D93AEgAgJKcP4KCyAW +Amjw91sKAAICG3Dy6AgAIAJQcPaEACAAEGAwW3Bg969XYAIQKDDSoNEPAAAAAPP/nG/qEFAwG81e +iRGMECy0ffm1RCIAABKw0Q/GKtEPbBAI+iwAAD0QWDBbcavzrAABWAA2oBfNDvbMfRAAECAw9Qos +IAAQYDD8FgUgABBQMPAAO2ALEEgwGcx1BB8UB/8KLfKu+goAL/8QcDD+mAMAAgIhMPjdAQALEEgw ++BIFLAkAbvD99q4mAH+RIGWA990QbZoco64r4AD1sRxyAAB6sPSwumACAlKw+9QAIAICa3D/Cgsg +FgJw8NoQ8+wBICACWHDx/ggAABBoMP3kACAAEGAwW3AmCqIC9yBaYgAAcPABGQL/CgAgCxBAMG2K +FCvgAMm2+5QAIAICe/D+7AEgAgJKcP8KCyAWAnDwseP7HBAiAABQcPkKACwAIA/w+dQAIAAQYDBb +cBL2oFpiAAASsC4KAS4WBRrNQ44UKqJ/DqsoLDroDLsse2Mb+c4TE/+E/RDz/wRrAAQ+4AAAAADz +/3Zv6hAQMB/ODfzODRABEFgwCv8s/UwAAAQQUDBbmMobzCtj/8QA0Q/RD2wQDhvOBfocAABIEGAw +W4/H+iwAAD0QWDBbcUzyrAAAfAA2oCigANMPZIBv9woAIJACMHDwAA1iAAAYcAAAAAC4M3YxVoQw +2kBbcU77TAACAAAqsPosAAIAAGFwW5QeZa/dolwqwADC3P2hN3IAAFswZa/L+TIBICQANuAusADS +sPXvr2YJAD5wLxoMf3AMEs3j9yZ/IAAQEDDRD8Yq0Q8AAAAA8//MYAICWzBsEAT6LAAAPRBYMFtx +JfKsAAAbADagE83X2jBbcS/coPs8AAIAAFCwW5QAyKLGKtEPGM3RGs3SIoJ/Gc0OCiIBCSIC8oZ/ +IAAQEDDRDwAAAGwQFhvNy/wKeCIAAFBwW4+I+iwAAD0QWDBbcQ30rAAAgAA2oCigAA8CAA8CAGSA +qfkKACDwAjBw+RYhICwQODDwAA1iAAAQcAAAAAC4InYhToMg2jBbcQz7PAACAAAqsPpMAAIAAGFw +W5PcZa/dpFwqwAD3oVlyAABbMGWvzfkiASAeADbgLBIhKrAA/JwCAgAAIvD8FiEvqAC2oGAAPwDG +KmYgMhrNey0SIC6hfn3sBi2lf9EPAAD+oX8gARBYMPzNnRAEEFAwW5hVxirRDwDz/6pgAgJbMNEP +wPAvFiEiEiEiFiDz/7lgABAQMAAAAGwQFhvNj/wKeCIAAFBwW49M+iwAAD0QWDBbcNH0rAAAiQA2 +oCigAA8CAA8CAGSAl/kKACDwAjBw+RYgICwQODDwAA1iAAAQcAAAAAC4InYhV4Mg2jBbcND7PAAC +AAAqsPpMAAIAAGFwW5OgZa/dpFwqwAD3oUlyAABbMGWvzfkiASAnADbgLBIgKrAA/JwCAgAAIvD8 +FiAvqAC2oB7NQvzlfiAAEBAw0Q8SzT4vIX7/JX4v6hAQMNEPAAAAAAAAAPP/umACAlswGc03wID4 +lX4gABAQMNEPAGwQBi0gAPs8AAIAAGEw+lwAAD0QeDD/0SlwABAwMMU7c9Ef3iBtCBX00EhgAgIx +sC3gAf/RDHACAnOwc9EEY//jAAAXzUubEvwWASAAEBgw+hYAICACIfAlcn/bIPxsAAIAAFFwW5Nr +yKy4d/R56HAQAhjwxirRD9pQW3CRdqnpGst/GM08qjp4oeiLEiitFCiCOYwR/RIAIgAAULALgADS +oNEPbBAG3ED6IAAiAABpcPIWAyAAEDgw/jwAAD0QeDD/oS5yAAAYsMUrcqEk2zAPAgDTD20IFfSg +SGACAjnwKrAB/6EMcAICWvByoQRj/94AABbNIZ4S/BYBIAAQEDD9FgAgoAIpsCRif9sw/HwAAgAA +UTBbkz/IrLhm9WnocBACELDGKtEP2kBbcGV3qekay1MYzRKqKnih6IsSKK0UKIIljBH9EgAiAABQ +8AuAANKg0Q9sEAbcQPogACIAAGlw/wo9IgAAcPDyFgMiAAAYsP+hLHAAEBAwxUt0oSLbMA8CANMP +bQgV9KCNYAICELAqsAH/oQpwAgJa8HShAmP/3hXM+J0SnBGeEBbM9fAAD2AAEDgwALhm9WFdcBAC +OfAkYn/bMPwsAAIAAFEwW5MRZa/i2kBbcDpyqdoayygYzOqqenihMosQabEUjBEtOv99yQwezAIv +4oAu4n+v7p4RixAorRMoghWMEf0SAiIAAFDwC4AA0qDRD8Yq0Q8AAABsEAbcQPogACIAAGlw/wo9 +IgAAcPDyFgMiAAAYsP+hKHAAEBAwxUt0oR4DOwJtCBX0oFpgAgIQsCqwAf+hCnACAlrwdKECY//j +FczJnhKcEZ0QFszG8AAPYAAQODAAuGb1YSpwEAI58CRif9sw/CwAAgAAUTBbkt9lr+LaQFtwCHKp +2hrK9hjMu6p6eKkExirRDwCLEiitEiiCHYwR/RIAIgAAUPALgADSoNEPAAAAAGwQBBrK5xnMsCyi +SPqiSiDMEGgwDS0o9MrlEDQQWDDyyjgIACBucPmQ3Sh3AVAwC4gc88yvFAAgQTD0QgAgygA2YP8C +AAAAYQZg/wIAAgBdAmD/AgACAFkGYP8CAAQAVQJgE8yaCtlByJlokQppkg1gAAcAAAMzFANDFANT +FAMKSVt8twoMX/vMkhIAAFCwWj1kG8uJA9oU0w8LqgJbfLAKDF/7zIwSAABQsFo9XQOqQlt8qwoM +X/vMiBIAAFCwWj1Y+8s7G/AEOSBbfWDcoPvMgxIAAFCwWj1SG8yB+iwAAAoQYDBaPU4bzH/6LAAA +ChBgMFo9SxvMfPzMfBIAAFCwWj1HwCDRD2P/WQBsEAgXyqQTzHkockgnckoUzHYVzHfyhzgAABAw +MPosAAIAAFkwWjo3CuhB+ilBAhoAuiBvkgVvogJusgHAYfosAAIAAFjwWjovJE0C8z0CIZoIKTD6 +TkIMQAFQMPrPQgxIAVQw/903DAEAczANzDf7zGEcACBhsPzMAyIAAFCwWj0l+8xdEgAAULD8Cgcg +ARBoMFo6O/vKnhIAAFCw/AoHIAEQaDD4HBAgChBwMPgWACABEHgwWjoYyaDAovzMUBAIEFgwW5bt +xyvRDwD7zEsSAABQsPwKByACEGgwWjoo+8qMEgAAULD8CgcgAxBoMPkcECAKEHAw+RYAIAEQeDBa +OgbJpsCi/Mw+EAgQWDBbltvHK9EPAAAAAAAAAPvL1hDMEHgwDy8o/QqAIAAQcDD/uwgMOwE4MPm9 +ASo9ATgw+pQ+ICEANyD4wUtgARB4MGjCTGnDFi6UPC6UPWAADQAAAAAAAP6UPiIAAFOwLwr//bwI +D6AEOqD7wLwsAwB/sP3EviIAAFCw/MC9LOABbDBbfKHSoNEPL5Q8L5Q9Y//MLpQ8L5Q9Y//DbBAI ++8wWEgAAULD8CgEgARBoMFo58fvMEhIAAFCw/AoBIAAQaDD+CmQgIAJAcPgWACAUEHgwWjnOyK/A +ovzMCRAIEFgwW5ajxyvRD/vMBBIAAFCw/AoBIAAQaDBaOd77zAASAABQsPwKASABEGgw/gpkICAC +SHD5FgAgFBB4MFo5vMmmwKL8y/gQCBBYMFuWkccr0Q8AAAAAAAAA/MsVEgAAULD9yeYQIAJYcPsW +ACDIEHAw+8vuEAoQeDBaOazIr8Ci/MvrEAgQWDBbloLHK9EPwCDRDwAAbBBa0yD7y9USAABQsP0K +ACIAEGAwWjm6GMvkGsvhGcvhG8veHMvRH8vh/xadIIACaHAtFp8sFpkrFpopFpwqFpv4Fo0gwAJQ +cPoWoCAFEEAw+BaSIAAQSDD5Fpgg/gJwcPvL1BBiAnOwLhah/MvREEACcHAuFp4sFo8rFo4pHQH5 +FqIgoAJKcCkWkGABJwAAAAgiNcCl/MvIEAgQWDD9TAACAABwsFuWVd1A+goFIAgQWDD8y8IQDAIQ +sP4sAAIAAHiwW5ZOJBKN+jwAAgAAWTBaOWzyBUYACBBYMPoCRwWABD1g/Mu3EgkAKLD6CgUiAABo +sFuWQdwg+jwAAgAAWTBaPGQiEpglEo4mEo/3EpAiAABQ8PsSnSAAEGAwWjxdKhKiKRKhLBKeLhKf +LxKgLRKcKxKbKBKdJE0CJm0CJV0C9RaOIAICELAiFpj2Fo8gIAI58CcWkCQWjSiNAiu9Av3dAiAg +Anvw/xagIAgCc7AuFp/9FpwgCAJjMCwWnisWm/gWnSAgAkpw+RahICACUrAqFqIpEpkqEpooEpIp +nQIqrQL6Fpoh/gJCMCgWkvkWmSJYADYg+xKZIgAAUPBaOTEkEo4lEo8mEpAnEqItEp4rHQIuEqAv +EqEvFqj+FqchQAJi8PwWpSFgAlrwKxam+tYAIAAQEDD6PAACAABZcFo5ISoWpPtMAAIAAFDwWjkd +LRKkKBKnLhKoDZ9G/4YALMEBbDD95gAoAQBr8P35Ng7JAVAw/nYAKsEBUDD66zcMAwBTsPwSpigD +AGZw+xKlKAEAWjAqZgAoxgAptgAcy1kpFgMoFgQtFgD+FgEgCBBYMPoWAiIAAHCw/RKYIAUQUDBb +ld70TAggEAIpcPkSqCAIAjGw+BKnIAgCOfD/EqYgAgIQsP4SpSAIAkpw+RaoIAgCQjD4FqcgCAJ7 +8P8WpiAIAnOw/halJf+XmKD7EpoiAABQ8Fo469Kg+xKbIgAAUPBaOOj7EpwmyAEQMPYWcCTAARQw +9RZxJMgBUDD0FnIiwAFQMPIWcyIAAFDwWjjd/WwAAgAAcXD/TAAABBA4MPIWACAIEFgw/MsoEsgB +UDDyFgEgBRBQMFuVsSoSmPMWjCACEHAw+qz8IgAASfD66TgA/xAwMPcKACAAVyZgIhaL9B0CIP8Q +MDDzHQIhQAIhMPSUCgAAEDgw9BapIUACKPD0PLAhgAIY8I9AjVCOMPISiywAIH9wDR0U/tgMAAUQ +UDD4IggCAAB4sPzLCBLAARAw8hYAIAgQWDBblZAoEqn2JjYGAQA8sPM8BCAIAilw+Fm1cAgCITAj +Eoz6Ep8kACAx8AQUFPRM+i/6EEAw9KYAKIABJDDynOAr/kwWYMAl8/yRYgEAknBj/8/aMCoWjFgB +F2akBCoSjBvK7hzK7lo7nSoSjBvK2PwKASABEGgwWji0G8rV+hKMIAEQYDD4HQIgABBoMP4KZCGg +AkIw+BYAIBQQeDBaOJBlo8MqEowbysn8CgEgABBoMFo4pRvKx/oSjCABEGAw+R0CIAEQaDD+CmQh +oAJKcPkWACAUEHgwWjiCZaPGG8q/HMngHciyKhKMKB0C/grIIaACQjD4FgAgChB4MFo4eGWjdBrK +qxnKqx/KxvjKuxAAEGgw/RaKIAAQYDAsFoQoFpUvFqP5FoUgQAJYcPsWlCD+AnBw+haGIIACWHD7 +FpMgwAJQcPoWlyBiAnOwLhaJKR0BHsqqKRaI/haWIKACSnApFocjEockEoglEokmEpcnEpYiEpWM +YI1QKhKMDwIA/90RDXAEOyD9zAICAABYsFo7U4xAjTAqEoz/3RENcAQ7IP3MAgIAAFnwWjtM/hKj +IAgCGPD0TAQgCAIpcPZsBCAQAhCw/imtcBACOfAlEoYjEoQkEoX6EowiAABZcFo4O9ag+hKMIgAA +WTBaODj8yo0SAABCsP4SlCpIAVQw+xZ9KCoBNDD5FoEmJgE0MPcWgiIuATAw8haAJkABVDD3Fn8i +AAB5sP7iACIiATAw8haDJkwBUDD2FnwiRAFQMPIWfigqAXQw+RZ5Ki4BcDD6FngoIgF0MPkWeyom +AXAw+hZ6IgAAaPD4FgAgBRBQMFuU9SsSff0dAiH4AkDw/woCIAQQUDAI+jj6oUFgABBwMP/c8CHA +Aktwbaoli5DTD/SxFmAIAkpw/wIAAACXBuD/AgACAJwG4LHu//wEIAgCa3AnEn8rEn0iEn4mEnwc +ylf6EowvgAQ64PwtEQ9ABD2g/X0CDgkAe7D+3QICAABZMFo4Fi0Sk43Q/MpNECACa3D9FpEsJQFs +MPoSjC/ABD9g9NgRD4AEO2D47gIMCQB/cP7dAgIAAFlwWjgIJhKHJxKIIhKJ/Mo/EAUQUDD9EpEg +CBBYMFuUwCkSlCoSkysSlygSli8SlS4SoyVdAiRNAiQWhfUWhiAgAjGw9haHICACOfD3FoggIAIQ +sPIWiSACAhjwIxaELu0CL/0C+I0CICACWvD7FpcgCAJSsPoWkyAIAkpwKRaUKBaWLxaV/hajJf7a +nOAiEorRD4bQaGMP/wIAA/9ymaCL8My2YAB/AIvwy7KwvJzwY/7diND/AgAD/2geIIvwZb/pYAAx +itBlrsaL8P+zQGACAmLwnPBj/rcAAAAAAAAA+goCIAgQWDD8ygoSAABo8FuUi8cr0Q/6CgIgCBBY +MPzKBRIAAGjwW5SGxyvRDwAA+goCIAgQWDD8ygASAABo8FuUf8cr0Q/6CgIgCBBYMPzJ+xIAAGjw +W5R6xyvRD9Kg0Q8AwKL8ydoQCBBYMFuUdGAADMCi/MnZEAgQWDBblHD8yfAQAhBQMPsKCC/7EGgw +/RaKIAUQaDBblGkiEorRD8Ci/MnMEAgQWDBblGVj/89sECz7ydgSAABQsFo3g/vJ1RIAABqw/Mnf +EgAAULBaOoIbyd0cx7Udx7TzFj4iAABQsFo3mCYKAPkcUCIAAFBw9cnXEAAQWDAUydYTydYrFj0q +FjwpFjvaIPtMAAIAAGGwWjpx2iD7PAACAABhsFo6biRNAvM9AiG+CCkw2iBb/Y/ToPYWTyAEHK6g +IxI7JBI8FsnEF8nDJxZLJhZMF8nCFsnD+xJLIgAAULBaN1uaQPsSTCIAAFCwWjdX+jYAIgAAWfD8 +CgAiAABQsFo6V9og+2wAAAAQYDBaOlMmbQIpEkwoEksnfQIpnQL4jQIgIAIY8PgWSyAgAiEw+RZM +IUoIKjAmEk/7yaoSAABQsFo3QisSPSZtICkSOyoSPCZsIPmcBCACAlrw+qwEJf+OmuAhFkUcyZsb +yZv/yZ8QABBAMCgWRi8WR/sWQSCgAlBw+hZEIIACaHAtFj8sFkMtFjgsFkguEkQoEkWJ44rijeGP +gIyDK4IBKIIC/uIAJsgBeDD2FjAuwAF8MP8WKCTIAVww9RYxKsABXDArFin+i0YOwAFwMP4WSSTI +AUAw9BYyKMABQDD4FiouyAFkMP8WMyzAAWAw/BYrKMgBaDAoFi0rFiz+FjQswAFsMP0WNSrIAUww ++xYvLMgBUDD8Fi4qwAFQMPoWNijAAUww+RY3KAMkEaAoCnj6CgEqAyQ2EMDgb1gBsaopCnh1mwGx +7m9IAbGqKwp4dLsBse5v+AGxqiwKeH/LAbHuy6DK7m9oCC1tAS3cgC0WMG9YCC5dAS7sgC4WMW9I +CChNASiMgCgWMm/4CCn9ASmcgCkWM/YKACAAECgw8xoAIAAQIDD/bP8gABA4MP4cfyAAEFAw/uxB +IAQQWDBtuhvIYX+hDojg0w8IMzb4VQgEAQBBMPqsASAIAnOw80kMAAgQWDB5uiGxZv8CAAQC9ZWg +9QoAIAEQUDD6FjkgABAgMPABt2EAEBgwJxY5+QoBIgAAQbD2mDkABBAgMAhEDARULPRgJ2TAASAw +/h3/If4CebD8EkchgAJzsP5uCgAFEFAw/uJ/IgAAaTBbk5wvEigqCgD/+AdgABBwMCoKASkSKCgK +eHmLAcDhKxIpb7gBsaotEiksCnh9ywGx7i8SKm/4AbGqKRIqKAp4eYsBse4rEitvuAGxqi0SKywK +eH3LAbHuy67L7C4SKNMPb+gIL+0BL/yALxYoKRIpb5gIKp0BKqyAKhYpLBIqb8gILc0BLdyALRYq +LxIrb/gIKP0BKIyAKBYr9goAIAAQKDDzGgArgAQ5IPoWQCAAECAw/2z/IAAQODD+HH8gABBQMP7s +ISAEEFgw0w9tuhrIYX+hDSjiAAgzNvhVCAQBAEEw+qwBIAgCc7DzSQwACBBYMP8CAAgAak7QsWb/ +AgAEAj4VoMCR9QoAIAAQIDDwAF1hABAYMAAtEkAsEkLaIPsSQywJAGswWjl4LhJG0w/TD/8CAAQC +C6OgKRJNLxJFKBJEKhJDLBJBKxJGKq0CLM0C/BZBIAICWvArFkb6FkMgIAJCMPgWRCAgAnvwLxZF +ZZ8/LRI5DwIAZd3fLxJFLhI//wIAC/5f+5AbyLwcxpP6LAAAABBoMFo2d/vIvhIAAFCwWjZVG8io +/BI+IgAAULBaOVYbyKQcx//6LAAAABBoMFo2bcAg0Q8AAPoKASIAAEmw9qk5AAQQQDAJiAwIWCz3 +Fk0owAFAMPgWQiAnADWg/h3/IAUQUDD8EkchQAJzsP5uCgH+Anmw/uJ/IgAAajBbkxgvEkb/AgAF +/36L4CgSLCoKAP+IB2AAEHAwKgoBKxIsKQp40w97mwHA4SwSLW/IAbGqLxItLQp4f9sBse4oEi5v +iAGxqisSLikKeA8CAHubAbHuLBIvb8gBsaovEi8tCnh/2wGx7suuy+woEizTD2+ICCmNASmcgCkW +LCsSLW+4CCy9ASzMgCwWLS4SLm/oCC/tAS/8gC8WLikSL2+YCCqdASqsgCoWL/YKACAAECgw8xoA +IAAQIDDwACRgABA4MPZsASABEEgw9QoAJAFGFaD0CgAhABAYMPcKAC4pADZg/2z/IAAQUDD+HH8g +CBBYMP7sMSAEEGAw0w9tyhrIYX+hDSjiAAgzNvhVCAQBAEEw+qwBIAgCc7DzSQwCAABBsPmynHAE +EBgwwJH3Fk4oBQAycAgzDANTLPRgJ2LAARww/h3/If4CebD8EkchYAJzsP5uCgAFEFAw/uJ/IgAA +aPBbkr8oEkn/PAAAABBQMPsSSSAAEHAw+Qp4KAwAuiDAofwSNSoAA9pQLgoBKBI1/Qp4KAwAuyCx +qvkSNioAA8NQLuwBLBI2+wp4KAwAumCxqv0SNyoAA+LQLuwBKRI3+Ap4KAwAu2CxqnmLAbHuZKBP +KhJJZOBJb6gLK60BK7yAKxZJKxY0LRI10w/+3QEoFAC7YC7sgC4WNSkSNvqdASgUALpgKqyAKhY2 +LBI3DwIADwIA/c0BKBQAuyAt3IAtFjf/FjghABAYMPgd/yAAECAw+IzQIAAQKDD4FkogABAwMPhh +FGAAEDgwKRJJ0w8JMzb5VQgEAQBJMPoSNSIeADmgCjM2+lUIBAEAUTBoYxErEjbTD9MPCzM2+1UI +BAEAWTD4ZBRgCBBYMCwSN9MPDDM2/FUIBAEAYTAuEkoDTQx9uib2bAEgCAJzsP4WSiT2AL2gIxoA +9AoAIAAQKDDwAEdgARA4MAAAAAD6CgEiAABBsPaoOQAEEHgwCP8MD18sDw9G/xY6IBwANaAuEkrA +pfwSRyIAAGvw/uJ/If4CebBbklgvEjovFkhlfzUpEk5j/ccAAAAAACgKePoKACv84DIQ8/m6YAEQ +cDAcx9j9EkYgAhBQMFuSS8cr0Q8tEjgsEkj43RECAABQsPsSQSwJAGswWjhpY/vQAAAcx839EkYg +AhBQMFuSP8cr0Q8cx8n9EkYgAhBQMFuSOscr0Q8cx8b9EkYgAhBQMFuSNscr0Q8AAPzHwhACEFAw +/RI9IAgQWDBbki/SMNEPAGwQChPFs9MPKDJIJzJKG8e5FsWyAoc493dTADQQQDAIeBwcxen9x7QW +ACBBsPZiACIAAFCwWjVhG8exHMXj+iwAADIQaDBaNV0bx60cxd/9x10SAABQsFo1WfvHqhIAAFCw +/AoCIAIQaDBaNVQbx4f8x6YSAABQsFo4NRvHpPosAAAAEGAwWjgy+TKFI+sANKD5q1IKXQFIMAuq +DCqsBRvHnBzHnPStEQAGEHAw/t0CAgAAULBaNUETx4cUx4UVx5baIPwKACIAAFkwWjgh2iD7PAAA +ABBgMFo4HSRNAvM9AiG+CCkwG8eN/MVVEgAAULBaOBdudxj7x4oSAABRsFt4H/AAF2IAABqwAAAA +AAAA+8eFEgAAUbBbeBjToPvHghIAAFCwWjUG1aD7x4ASAABQsFo1A9Sg+8d+EgAAULBaNQAbx3z8 +xUMQGRBoMAXdDP09Nw4AIFEw/uwGIBwCa3D/7hENgAQ/YP7dAgIAAFCwWjUS+8duEgAAULBaNPHA +slt3/tOg+8dsEgAAULBaNOzAslt3+v7FsRwAIFTw+8dnEAQCa3D8x2Yd0AQ/YP7dAgIAAFCwWjUB ++8deEgAAULBaNN/UoPvHXxIAAFCwWjTc06D7x10SAABQsFo02fo+CAAQAmkw/sUOHAEAd3Abx1f8 +x1gdoAQ/YP7dAgIAAFCwWjTuG8dU/MdUEgAAULBaN9Abx1L8x1ESAABQsFo3zPvHQhIAAFCwWjTG +KwoCW3fTW3e5W5Ce1aD7x0oSAABQsFo0v8CyW3fNW3ezW5CY1KD7x0USAABQsFo0ucCyW3fHW3et +W5CS06D7x0ASAABQsFo0s8CyW3fBW3enW5CM+8c7HcAEOOD4ThENQAQ9YP7dAgwJAGKw/cwCAgAA +ULBaN6z7xzMSAABQsFo0pSsKAlt3s1t3mVuQfdWg+8cuEgAAULBaNJ/Aslt3rVt3k1uQd9Sg+woC +IBkQUDBbd6hbd45bkHLToPsKAiAoEFAwW3ejW3eJW5Bu+E0RDUAEOWD9zAINwAQ84PvHHBwJAGsw ++iwADAkAYrBaN477xwQSAABQsFo0h9Og+8cIEgAAULBaNISqOvqs/iACEFgwW3eQW3d2W5Ba06D7 +xw0SAABQsFo0fMCyW3eKW3dwW5BUG8cJ9D0RDYAEOqD9zAICAABQsFo3ePvHBBIAAFCw/ApgIGAQ +aDBaNI4bxwAcxTX9xTQSAABQsFo0ihTGsxPG/BXGsxbG/Nog/MWREgAAWXBaN2jaIPtMAAAAEGAw +Wjdl2iD8xRgSAABY8Fo3YiM9AiVdAvRNAiGeCDFw2iBb/NNmonz7xpgSAABQsPwKASABEGgwWjRz ++8aUEgAAULD8CgEgABBoMP4cECAUEHgw/hYAIGQQcDBaNFDIr8Ci/MbeEAgQWDBbkSXHK9EP+8aG +EgAAULD8CgEgABBoMFo0YPvGghIAAFCw/AoBIAEQaDD+CmQgIAJ4cP8WACAUEHgwWjQ+yq7AovzG +zRAIEFgwW5ETxyvRDwAAAAAAAAD5S1IKVwFIMAuqDPP8GGAKAlKwAAAAAAD7xnASAABQsP3EYhAg +AmBw/BYAIMgQcDD8xYsQChB4MFo0KMmhwKL8xrkQCBBYMFuQ/scr0Q8AABfGtx7EgfvGtBAYEGgw +/RYJIBUQYDD8FgogABAgMPsWCyAAEBgw/i4KAAgQMDD+FgcgBRBwMP4WCCAHECgwixeMGSuyiADA +BPsLGQ//EGAw/MakGhEAZvALC0L7FgUqACBc8Py7CgIAAFCwWjQD3KD7EgsiAABQsFo3A/oKBSAI +EFgw/MaYEgAAaTD/EgUiAABxsFuQ14sXjBorsogAwAT7CxkP/xBgMPzGkBoRAGbwCwtC+xYGKgAg +XPD8uwoCAABQsFoz7dyg+3wAAgAAULBaNu36CgUgCBBYMPzGhBIAAGkw/xIGIgAAcXBbkMEnfQKN +GYwY+BILIAICITD+Egoh/AIpcPM9ASH8AjGw+I0CIQACGPD4Fgsh9AJzsP4WCiH+AmMw/BYIIfQC +a3D9FgkvDQC3IBvGI/osAAAIEGAwWjbR+8ZrEgAAULBaM8vIrPvGaRIAAFCwWjPHZa39+8ZmEgAA +ULBaM8T7xmQSAABQsFozwfvGJxIAAFCwWjO++8ZgEgAAULBaM7wCKgJb+hnSoNEP0qDRD2wQChfE +Gw8CAClySChyShTEGwKYOPh4UwA0EEgwCYgcqEQkQgD7xAYSAABRMFt2u/zGTxAFEDAw+mY3AAoQ +QDAIZjYIYxD7xB4cCQBg8PwWBCIAAFCwWjamG8QZHMQa+iwAAAAQaDD4HBAgChBwMPgWACABEHgw +WjOf/MY9EkIAtqD7xhISAABQsFozlf3EDhH2AiqwCVwRDDwC+8QJHAkAazD8FgQiAABQsFo2kRvE +BBzEBPosAAAAEGgw+BwQIAoQcDD4FgAgARB4MFoziWWiDRzD/vvD+hwJAGDw/BYEIgAAULBaNoIb +w/Ycw/b6LAAAABBoMPgcECAKEHAw+BYAIAEQeDBaM3tlofRkIZgrckkqckocw6odxhf5HCAoPgFY +MAmICoXTjtGP0p+SnpH1lgMqAEBmsP3SACAAEFAw/ZYAIAAQKDD4ggAgARBIMPuaOAACEEgwCpU5 +/cYHFAkARXAMXBEMPAL7w9UcCQBrMPwWBCIAAFCwWjZdG8PRHMPR+iwAAAAQaDD4HBAgChBwMPgW +ACABEHgwWjNWZaGC+8X3EgAAULBaM03VoPvFyhIAAFCwWjNK/wIACgBjkWAlXPz8VREEAGeWoMCI +eosH/wIACgBvxqDAoAepEfgaACQJAE1w/cXmFAkARXAMXBEMPAL7w7McCQBrMPwWBCIAAFCwWjY7 +G8OuHMOu+iwAAAAQaDD4HBAgChBwMPgWACABEHgwWjMzZaEZ+2oaIgAAUTBbdjr7xbYSABBgMPos +AAwBAFMwWjYqG8OeHMOj/BYEIgAAULBaNib7w5kSAABQsPzDmBAKEHAw/RwQIAEQeDD9FgAgABBo +MFozHmWg6MAg0Q8lXPT8VREABBBAMPhVAgX/nMagwIj/AgAL/5pWEPP/NmH4AlKwK3JHKnJIY/5j +AADAslt2GWP/HgAAAAAA9hYAIAIQUDD7CgggABBoMP4KACAAEHgwW4/fxyvRDwCWEPzFox/QBDlg ++goCIAgQWDD9CgMgAhB4MFuP18cr0Q+WEPzFmxACEFAw+woIIAMQaDD+CgAgAxB4MFuPz8cr0Q8A +lhD8xZISAABxcPoKAiAIEFgw/QoDIAEQeDBbj8bHK9EPlhD8xYoSAABxcPoKAiAIEFgw/QoDIAAQ +eDBbj77HK9EPAAAA/MWCEAIQUDD7CgggBRBoMP4KACAAEEgw+RYAIAAQeDBbj7PHK9EPAGwQChXD +N9MP0w8qUkglUkoWwzfTDwKlOPV4UwA0EEgwCYgc+8ULEAEQYDD4ZggAABBoMPNiACIAAFCw9QdC +BIUBKDBaMuLaMPYWBifQEFgwW3XO3KD7xWcSAABQsFo1wBzFZvvFZhIAAFCwDwIADDwsWjW7G8Vj +/ArIIgAAULBaNbgbxWD8KgAiAABQsFo1tPvFWhIAAFDwW3W8G8VbCqwK/8wRAgAAULBaNa0YxVgE +RAvTDwhECvtCfyIAAFDwW3WzG8VT+3sJAgAAMrD7sX4iAABQ8Ft1rdeg+0KFIgAAUPBbdaorQoOa +GfcWBSIAAFDwW3WmLEKHG8Li96wAAgAAUPAMuyxbdaHA1AfXN9twW3We9bhRBBwAvqDwABNgABBQ +MAAAwOH6CgIh9gJ6sA/qOP6qEAIB0QYgG8U20w8LqgIbxTX8xTUQCBBoMPosAAwJAG6wWjKd+8Uy +EgAAULD8CgEgARBoMFoymPvC7RIAAFCw/AoBIAEQaDD+HBAgFBB4MP4WACAyEHAwWjJ2yaPAovzF +JBAIEFgwW49LxyvRDwAAAAAbxSD6LAAACBBgMFo1axvFHvosAAABEGAwWjVoG8Od/DoAIgAAULBa +NWT7xKASAABQsPwKAiACEGgwWjJ7jBYswgEdxRMsFgcMbAz7xRAdgAQ7IP3MAgIAAFCwWjVXG8UN ++iwAAAAQYDBaNVQexQr8xQscVAEsMA7dHBvFCf3MDAPoEGgwDcws/BYIIgAAULBaNUqFFxvFA/os +AAAEEGAwWjVGjRX6LAAAJBBgMPvEyRwBAGswWjVB2iD7xMUSAABhsFo1PhvEdfosAAACEGAwWjU6 +G8S4+iwAAAAQYDBaNTfaIPvE2RIAAGGwWjUz2iD7xKkSAABhcFo1MPtCgCIAAFDwW3U4+8ToEA8Q +YDD6LAAMAQBTMFo1KftCgSIAAFDwW3Ux+8SwEBQQYDD6LAAMAQBTMFo1Idxg+8SkEgAAULBaNR7c +cPvE2RIAAFCwWjUb+8TXEgAAUPBbdSP7xJQQBBAwMPosAAwBAFGwWjUT+8TREgAAUPBbdRv7xIoQ +BhBgMPosAAwBAFMwWjUM+8TIEgAAUPBbdRQKbDf7xIASAABQsFo1BRvExPwqACIAAFCwWjUC+0KE +IgAAUPBbdQr7xL8QAxBgMPosAAwBAFMwWjT6+8S7EgAAUPBbdQP7xLkQChBgMPosAAwBAFMwWjTz ++8JLEgAAUPBbdPuEGPvEeBBAEGAw+iwADAEAUzBaNOv6wjISAABZMFt08xvEq/ysAAIAAFCwWjTl ++8I4EgAAUPBbdO37xKUQBRAgMPosAAwBAFEwWjTd+8IxEgAAUPBbdOUKTDf7xJ4SAABQsFo014gZ +JAoDDwIA+EQ3AgAAULD7xJgSAABhMFo00PvEjhIAAFDwW3TY+8RDEAwQYDD6LAAMAQBTMFo0ybFM ++8SPEgAAULBaNMUbxI36LAAAABBgMFo0wvvEihIAAFCw/AofIAAQaDBaMdgTwh0bxIb6LAAAARBg +MFo0ufkyhSBnADSg+apSCl0BTDAKuwy1uwW7CAuqCPqs/yACEFgwW3S63KD7xHkSAABQsFo0rBvE +ePosAAAAEGAwWjSp2iD7xHUR/gJpcP0dFAAfEGAwWjG+wCDRDwAexHDz/GNqCQBysAAAAAAA+UpS +ClcBTDAKuwzz/5tgCgJa8ABsEAT7xGcSAABQsFuQgv08AAAAEGAwW473+8HaEAICUvBbdJvAgQiq +N1t0jtEPAABsEBD6wewSGQA0oCaiSiiiSSgWEgZ1U2RRyf8CAAAA4wVgblIMwJ11kwfwAAZgARA4 +MMByE8RQFMRQ2iD8xFASAABY8Fo0eyM9AnQ57BnCLf3ETBIMAT1g3ZAbxEr8xEgSAABQsFoxjhrE +SNMP0w8KegonoIApoIEooIIqoIMbxEP8iBEJYAQ+YPN3EQvgBDqg+XcCCAkAUjD8waIWCQBF8Pos +AAIAAGnwWjF9LhIS/8GVEAEQUDD+blEGDAC9YMCgG8QzHMGY+cG+EDQQaDANVRyWH/jEMBQAIE1w +JRYQhVL47REOBQBWMP4WDiwJAH9w/RYRL/AEOWD+CkAsCQB3cP7dAgIAAFCwWjFlKRIS0w8PAgDz +xCEYYwFMMPRYEQWABD5g9sQeFAkARXD9XAACAABQsPzBhBIAAFjwWjFYIz0CdjnmE8QWFcQX3HD6 +LAACAABY8Fo0NyM9AnU57CcSEfPEERBAEEAw9cQQFgkARfDccPosAAIAAFjwWjQuIz0CdTnswKJb +hugbxAkcwV76LAAAABBoMFoxQvMKACAyECgwwaRbhuCxM3U59RvEAhzBYv3C3hIAAFCw/gpkICAC +SHD5FgAgFBB4MFoxG8mrwKL8w/kQCBBYMFuN8Mcr0Q8AAAAA8/5MYAAQODAbw/Qcw/T9wUQQZBBw +MPocECAUEHgw+hYAIgAAULBaMQvJrcCi/MPsEAgQWDBbjeDHK9EPJqJIK6JHKxYSY/3nAAAbw+b8 +w+YSAABQsFoz/iMSEIMw+gogIgAAWPBb/2EVw+EXw+HaIPzD3hIAAFlwWjP1+gogIgAAWPBb/1ol +XQJ3WeH6w9oSAABY8Fv/VRvDzRzBsPosAAAAEGgwWjEF+gogIgAAWPBb/04bw8z8w7gSAABQsFoz +5PoKICIAAFjwW/9IFcPI/MEcEgAAULD9w7ASAABZcFow9/oKICIAAFjwW/9AJV0Cd1nb+gogIgAA +WPBb/zwVw6TaIPwKACIAAFlwWjPRJV0CdFns+gogIgAAWPBb/zMZwSwnEhIpkoUHd0P5KFEIMAFM +MPRxgmgFABYwih5kpan/AgAAAvuGoP8CAAIDIAKgKxISCw1C/doJDj4BWDD+Eg4qACBysAu8QvzP +CQpyAVww+fkIAgMkh6CdHJwbKxYKKRYJ/MOdEAgQWDD9fP8h/gJysP9cAAAFEFAwW42HjRr8w5cQ +BRBQMP4SCSAIEFgw/dz/IgAAeTBbjX8fw5H4HBYgHxBwMPgWBymQBDzgBPosBf8sD58sCpks+BYN +KAEAz7D5FBQuAQD7sP4UFSAoAiBwHMDLJUAAG8OD0w/8XAICAABQsFozkvs8AAfQEFAwW/72HMNy +2iD7w3scCQBhcFozi/vDeRIAAFCw/AowIDIQcDD9HBAgFBB4MP0WACAwEGgwWjCEZaBeG8Nu+iwA +AAAQYDBaM377w2wSAABQsFoweP4cFCpgAVAw+hYEIBQIcTCaHWAAHgAVw0+NFPwK8CIAAFCw/N0R +AgAAWXBaMIslXQJ2WeSOF7FE/wIAD/+qcRAnFhNgACjAovzDWBAIEFgwW41BxyvRDygSEicWE/8W +DShAAUQw+RYMKEsBQDCYG4QfGMNTGsNO98NOFCMBIDAIRAokQn8Ww0z1w0wQABBYMPQMQwAPEEAw +KxYU+hYIJgHBRxArFhT6FggiAdEHICVdAiZtAid9AvqtAiAPEEAw9EQUAAICWvD0DEMFmgI+4PoK +ICIAAFjwW/6sFMM2FcM5+iwAAgAAWTD8CoAggBBoMFowWiRNAnVJ5voKICIAAFjwW/6iFMMr/AqA +IgAAULD9CgAiAABZMFowUCRNAnVJ5voKICIAAFjwW/6YHcCQLdKFG8Ml/a5SDFQBbDD8wHAcBQAX +sPjdEQIAAFCwWjBDG8MeHMGI/cFMEgAAULBaMD8UwxsVwxvaIPzAXRIAAFkwWjMfJE0CdUns+zwA +ACAQUDBb/oItEhAt0gsbwxMcwxP43RECAABQsFowMCUSEA8CAIVcE8MO9MMPFYAEPWD9XAACAABQ +sPzDCRIAAFjwWjAmIz0CdDnmJRIT+8MHEgAAULD8ChAgEBBoMFowHxTDAxPDAxrDBIkb/AoCIAEQ +aDD11TkAABBYMPbC/hoFAC8wC5kK+hINKAAgVnArFgYokID5kIEnwAQ+oPSsEQuABD6g/IgRCgkA +ZvD4mREGCQBd8PmFAgYJAFXw3HD6LAACAABZMFoy6tog+zwAAgAAYXBaMuckTQLzPQIhvggxMBPC +5xTC59xQ+iwAAgAAWPBaMt8jPQJ0OewbwuL8wuMSAABQsFoy2hvC4fzC3xIAAFCwWjLXG8Le/MLc +EgAAULBaMtMTwtwUwtzaIPzACRIAAFjwWjLPIz0CdDnsG8LX/MKvEgAAULBaMsoTwtQUwtTaIPy/ +/xIAAFjwWjLFIz0CdDnsgxYbws78wqUSAABQsFoyv4gcGcLLA4gKqYglgIAogIETwsn8VREJgAQ6 +IPTCxxQJAEVw2iD7PAACAABhcFoysyM9AnQ57CgSEhnCwQiIUgmICiSAfCiAfRPCvvxEEQmABDog +9sK8FAkAQTDaIPs8AAIAAGEwWjKlIz0CdjnsE8K2FsK33FD6LAACAABY8FoynyM9AnY57BPCshXC +stxA+iwAAgAAWPBaMpkjPQJ1OezBpFuFU8GkW4VSwKJbhVEoEhKFHxPCqfUFUwhbAUAw84kRCXAE +OiD8VREICQBKMPTCoxQJAEVw/VwAAgAAULD8wqASAABY8FovoCM9AnQ55ioSEtMPCupD88KbGUAE +PqD4pREJwAQ6oPqIAgQJAE1w9MKWFAkARXDaIPxcAAIAAFjwWjJ2Iz0CdDnswCDRDwCLGPy/rhIA +AFCwWjJw2iD8wosSAABZ8Foybdog/MKJEgAAWbBaMmpgACcAixj8v6wSAABQsFoyZdog/MCKEgAA +WfBaMmLaIPzCfxIAAFmwWjJf2iD7XAAAABBgMFoyXIoYKxIUY/wlJBIS+MJ4GkABIDCaHPqqCQo+ +ASQw+8JzGgAgWrAHdQkKVQoLVQn1UX8qSwEkMPsWCyRyASAwlBoLuwn0RAkKACBecJsZC0QKCEQJ +JEF+Y/pHJBIS+MJmGkABIDCaHPqqCQo+ASQw+8JhGgAgWrAHdQkKVQoLVQn1UX8qSwEkMPsWCyRy +ASAwlBoLuwn0RAkKACBecJsZC0QKCEQJJEF+Y/n2KxIS++xRCkABWDD6FgwsSwFcMP0WCypyAVww +mxoN3Qn6qgkMACBPcJ0Z8/nJagAgYrCZGZsanRycGxjCRQd1CQu0CQpVCghVCRjCQglECiVRfwhE +CSRBfmP5mwBsEATIJmghBMYq0Q8AHMES9r92EMwQaDANLSgbwjj+YkgsACBrMPzA3yABEHgw9WJK +IAAQGDDy8zgCAABQsP/MEQAFEGgw8+U5DAkAazBaMgYpYkgoYkr0v2cYBQAacPh4UwA0EEgwCYgc +qESEQfpM/CACEFgwW3IHKWJIKGJK979dGAUAGnD4eFMANBBIMAmIHBvCG/7CHBYAIEXw93IBIf4C +STD1P0EIAAFMMPWtEQjwBD5g9QhCBgABPDD6iBEHYAQ94PndAgYJAEXw//8RDAkAP3D8wgscCQB/ +cP7dAgIAAFCwWi77wCDRDwAAAABsEAQdv2LTD9MP+79hHAAgbLD+CgEiAAB7cNMPKrJ2DwIAf6cS +LLJw/MwQAAAQSDD83wwKADTrEP6nEHACEBAwLLJxDMwQf8tfDP8MfachLLJyDMwQf8tX/P8MADAA +7rDAofy/TBAAEFgwW4udxirRD3un6y6yggzuEP/j4nAGEEAwmDCfQP4yACAFEFAw/L9CEAAQWDBb +i5LAINEPmTCdQPP/4WIAAHtwnjCfQGP/1ZIwn0Bj/84AbBAEHL8y/vrgID4CaLD6woIgPgJY8PjC +fSoAQHbw+wsGDABAd3ANqgz0gBBiAEBS8C/CgS7Cfg/+OX4rEsAgwKD8vyMQBhBYMFuLd9EPAADy +xoIp//xS0GP/4wBsEAQYvvgkgoMEg1L1wEcWGAA84AS4UmiHKtEPBGxQAioRpaotooLH7g7dAQ3M +AiymgimigsC+9IKDKAkAXnAppoJj/84fvujB0P9PAQAAEHAwD945AiwRpcwvwoLGPwP/AQ/uAi7G +givCgi0K4A27AivGgtEPAABsEAQUv6LzwaIQABAQMNogW4ZlCghBaYEh/K8ecgAASPAABIsASWEA +SWEASWEASWH6LAAAABBYMFuGVrEi8z0EKZoCOKDAINEPAAAAbBAE+cGRG7AEOWD2TBEKUAQ84Py7 +AgoJAFHw+SkLCgkAWrAqlkAoHCCIgABqEQqIAiiWQdEPAABsEARuLgHRDxa/FQYmCyVi4BjBgAQ3 +EfdHAgQAQEVwB1UCJWbg0Q8AbBAEFr8MBiYLJWLQGMF4BDcR90cCBABARXAHVQIlZtDRDwAAbBAS +Fr8D0w8mYoVbhkoTwXAVwW70v4UQABAQMPo0QCABEDgwACAECggb/4cKcAICSLApRn9gAAgqUC1/ +pxIqMECxImko3fIKACAAEH6QYAFewKD7CgIiAABgsP4KACB4EGgwW4YiY//UAMBw9AoCIgDwepD0 +CgQiATD2kP8CAAIBdHKQ/wIAAgG47pD/AgACAftqkP8CAAICPOaQeKd9Khok/L5aEBIQWDBbhoIc +vlf7ChoiAABqsP1V5iGQEFAwW4Z8wbX6NEgn/xBgMPc0UC7gAVAw+ho0JgAgdfBbhnX6FgkgIBB4 +MP9kAQ4CVP2QwLD4rAIn/xBgMPgiCAGcEFAwW4Zs9qwABKAANSApUEjTDwkJRP8CAAoCZYJg/L47 +EJQQUDDyv0AQHRBYMFuGYSo0USkwRCswQS4wQy8wQicmgP0ify+ABDug8P8RCoAEPuD/uwIICQB2 +cP4wQCgJAF5wKRYA+jBIIgAAYrAvMEcoMEYrMEUMDEfwiBEPgAQ/4Pi7EAoJAHqw+LsCAgAAefD8 +FgIqCQBasPzBDhAAEFgw+hYBIAQQUDBbirbRDwAAKgqc/L4WEA4QWDBbhj4cvhP7Ch4iAAB6sP9V +3yE4EFAwW4Y49zRRIBEQWDD6NEEgABA4MPc0SSf/EGAw+gdHAKwQUDBbhi8oCiD4ZAEIAA9BkBu+ +gymy0B3A8CysAfTMEQgAQG5wDJkCKbbQ8qwCIAQQWDD8ev8hRBBQMFuGIfoWEiQ6ADUgLlBIDg5E +/wIACgLcA6AqMEBj/iAAAAAAACoKsPy97hAKEFgwW4YWHL3r+woCIgAAerD/VeAhSBBQMFuGEPQ0 +USANEFgw9zRKJ/8QYDD6NEIo4AFQMPh3CADAEFAwW4YH+hYEICAQSDD5ZAEOAafNkMC4+qwCJ/8Q +YDD6GlAiACBQsFuF/voWEyPlADUgK1BICwtE/wIACgKcguAqMEBj/ZsAKgrE/L3MEAYQWDBbhfMc +vcn7CgYiAABqsP1V4SFUEFAwW4XuwLn6NEMn/xBgMPc0Sy7gAVQw/3cIAAMQcDD+NFEg1BBQMFuF +5foWCiAgEEAw+GQBDgFsRZDAvPmsAif/EGAw+SIIAVwQUDBbhdv6FhQjkgA1ICpQSAoKRP8CAAoC +XgKgKjBA9AoEIf6QcpAqCtj8vagQAhBYMFuF0By9pfsKCiIAAGqw/VXiIWAQUDBbhcr0NFEgBRBY +MPo0RCf/EGAw9zRMLuABUDD6CugmACB18FuFwfoWBSAgEHgw/2QBDgEv/ZDBsPisAif/EGAw+CII +AWgQUDBbhbj6FhUjPQA1IClQSNMP0w8JCUT/AgAKAh0CYCowQP8CAAH+S+6QKgro/L2EEB4QWDBb +hascvYH7Cg4iAABqsP1V4yFsEFAwW4WmwLH6NEUn/xBgMPc0TS7gAVAw+gr8JgAgdfBbhZ/6FgYg +IBB4MP9kAQ4A9H2QwbT4rAIn/xBgMPgiCAF0EFAwW4WV+hYWIuoANSApUEjTD9MPCQlE/wIACgHf +gmAqMEDTD/8CAAH+CWqQKgr8/L1gEBoQWDBbhYgcvV77ChIiAABqsP1V5CF4EFAwW4WDwb36NEYn +/xBgMPc0Ti7gAVAw+hoMJgAgdfBbhXv6FgcgIBB4MP9kAQ4At/2Qwbj4rAIn/xBgMPgiCAGAEFAw +W4Vy+hYXIpUANSApUEjTD9MPCQlE/wIACgGhAmAqMED/AgAB/cfmkCoaEPy9PhAWEFgwW4VlHL07 ++woWIgAAarD9VeUhhBBQMFuFYMG5+jRHJ/8QYDD3NE8u4AFQMPoaICYAIHXwW4VZ+hYIICAQeDD/ +ZAEOAHx9kMG8+KwCJ/8QYDD4IggBjBBQMFuFT/oWGCJEADUgKVBICQlE/wIACgFlgmAqMEBj+wgA +AIsZwKf7vAEiAABgsFv+jooZY/tGLDBI9AoAK10ANyCxrS0WGSowUCsSGdMP+koIAgAAYLBb/nor +MEj0TAEgBAJhsPtD3nIAIGCwY/sqAAAtUC3A6A7dAi1ULWP7KosUwKH7vAEiAABgsFv+d4oUY/yg +ixrAovu8ASIAAGCwW/5yihpj/ReLFcCj+7wBIgAAYLBb/m2KFWP9kIsWwKT7vAEiAABgsFv+aIoW +Y/4HixfApfu8ASIAAGCwW/5jihdj/oCLGMCm+7wBIgAAYLBb/l6KGGP+9wAAACwwQfQKACvDADcg +sa2dGyowSYsb+koIAgAAYLBb/kosEhIrMEH0TAEgBAJjMPtD3nIAIGCwY/uRLTBC9AoALBgAN2Cx +rp4cKjBKixz6SggCAABgsFv+PCwSEyswQvRMASAEAmMw+0PecgAgYLBj++YtMEP0CgAsawA3YLGu +nh0qMEuLHfpKCAIAAGCwW/4uLBIUKzBD9EwBIAQCYzD7Q95yACBgsGP8OS0wRPQKACzAADdgsa6e +HiowTIse+koIAgAAYLBb/iAsEhUrMET0TAEgBAJjMPtD3nIAIGCwY/yOLTBF9AoALRMAN2Cxrp4f +KjBNix/6SggCAABgsFv+EiwSFiswRfRMASAEAmMw+0PecgAgYLBj/OEtMEb0CgAtaAA3YLGuLhYQ +KjBOKxIQ+koIAgAAYLBb/gQsEhcrMEb0TAEgBAJjMPtD3XIAIGCwY/00LTBH9AoALbkAN2Cxri4W +ESowTysSEfpKCAIAAGCwW/31LBIYKzBH9EwBIAQCYzD7Q91yACBgsGP9hS1QLcDoDt0CLVQtY/o9 +L1AtwIgI/wIvVC1j+rwpUC3AqAqZAilULWP7OQArUC3AyAy7AitULWP7uwAALVAtwOgO3QItVC1j +/DYAAC9QLcCICP8CL1QtY/yzAAApUC3AqAqZAilULWP9KgAAbBAEF70eFr1t0w8ocn8avdv1vWkQ +ABAQMPS/VhBbADYg06ApooAFmQL5poAiAABQsFuBwdogW/2HHb9QKGJ/H7xm/L9NE+gQcDAOiCwI +/ywPzCwP3SwO3SgOzCgE3TYtNoMrcn8qPUD0zDYAAgIQsPw2hCv/1tyQGrxwKaDcL6Ddwb/5CUQA +DRBgMP8PRAByBGJwK6DB/b25EDYAfvAs0oEuuv4OzAEs1oFbgUjAINEPAAAAAFuBSvev7mIAABKw +0Q8AAAAAAAD4oN4hjghb8AgIRHuJvCmg3wkJRHyZsxy/KCvCgB282A27AivGgGP/oQAAAGwQBhW/ +I/a+wBAAEBgw978hEfQQIDDaMFuB0PagR2IAABKwH7xIL/DB8r62EHgAf/BkMG/yCgAiAABQ8FuB +wvhSlyATADagyIvaMFuBpvagFGIAABKw9V0BIAICGPD1XMwjaAI44NEPANow/L8LEgAAWLBaLtQi +LQJ2KewSvwjaMPwKACIAAFiwWi7OIi0CdynsG78D/L8DEgAAUPBaLslj/5AAHLwzLMLAnBAbvDPA +rvq2QCABEFAwW4F/HrwvwN/95kAgABAQMMGkW4F7sSJ0KfWPEA/vUf8CAAP/rB/gGbwmGLw1KJZA +Y/9HbBAEGbwVHL7tFrv/+JDBIAEQUDDzCgAgFBAoMPQKGC//EDgw8pwAAgDu/hAjxh8jxh7zxIAg +MBBwMCshcB++4AtcRv/PCgoAKPMQj/AK8AAAAG87GilihAAxBACoGgCIEQeMAwyZAQmIAihmhGAA +JCxiwMHnA+4MAOEEAKkaB50DDcwBDJkCKWbAYAAHANowW4NpwKErIXAHvAP0ywEOAAknEGi4Umi7 +N/8CAAQAqiMQ8iwCIAICGPD/AgAAMBBwMP8CAA//uqjQ9wqHIAAQGDDyu+EQDhBYMPAAVWAUECAw +L2LHADEEAKsaB7kDD58BD78CL2bHYAAIADEEAKsaB7kDKGLGCYgBCLgCKGbGY/+fAHupDPo8AAAB +EFgwW4L5wL7zPAEh/gIhMPRAt2AEAhCwKiFwd6EXClpGaKIsaKpZ/wIABgBFrpBpocVgAIAALWKW +Hr6c/rwuHABAd3AO3QItZpZj/7oAAAAA2jBbgyT7Cg4vrgC2oC0hcBm+kPiQgCxAAWww8NEEAAEQ +YDAAzBoMiAIolIBj/4cA2jBbgxj7Cg4vfgC2oCohcBu7qwoKQqurK7DcCwtEW4LmHb6AwM8s1IDz +/1pgDhBYMAAAAAD6PAAAARBYMFuCyvP/Q2AOEFgwAABbhFVbhEsfvnQq9h4r9h8uYof+ZocgABAQ +MNEPxirRD8Ag0Q8AAABsEAYavG0bvBYcu8r4CgAgEBBIMNMPbZoVC4kCKcb5+cL5IAQCUrCxiAkJ +TSmlrRa8Qg8CACZhwhi8PwdmEfO7+xYAIEGw+r5dEAEQWDD8CgEgChBoMPgqACAAEHAw+DY6IAAQ +eDBaLh4Zu3gokMLyvlQSAAAhsPe+UxABEFgw+rg7AAAQKDD4lMIgAR8uoJYQi0KKQSs2O4lAKjY8 +KTY9Gr5H+woBIAEQYDD/VhEAChBoMPdoAgAAEHAw+DY6IAAQeDBaLgdmof/6vjwQARBYMP0KCiAA +EHAw8mwCAAAQeDD8NjogARBgMFot/fah2WACAilw+V6ZYBgCITAtEgAXvjISvjL93QYgABAoMP0W +ACAA3C6gDdQCi0KKQSs2OylCACo2PCk2PRq+JfsKASABEGAw/1YRAAoQaDDyaAIAABBwMPg2OiAA +EHgwWi3lZqF3+r4aEAEQWDD9CgogABBwMPdsAgAAEHgw/DY6IAEQYDBaLdv2oVFgAgIpcPlemGAY +AiEwLRIAFrtG/d0GIAAQKDD9FgAgAJmuoA3UAo1EjEMtNjuLQiw2PIpBKzY9iUAqNj4pNj8avgH7 +CgEgARBgMP9YEQAKEGgw9ogCAAAQcDD4NjogABB4MFotwfag5WACAilw9EwUL2oCOWCEEPa9+BAA +ECgwLU0KjdQsTQqMwy02OytNCouyLDY8Kk0KiqErNj0pTQqJkCo2Pik2Pxq95/sKASABEGAw/1gR +AAoQaDD2iAIAABBwMPg2OiAAEHgwWi2n9qCFYAICKXD0TBQtTAI5YIQQ9r3fEAAQKDAtTQwt0iQs +TQwswiMtNjsrTQwrsiIsNjwqTQwqoiErNj0pTQwpkiAqNj4pNj8avcz7CgEgARBgMP9YEQAKEGgw +9ogCAAAQcDD4NjogABB4MFotjPagDGACAilw9EwULUICOWDSoNEP0qDRD9Kg0Q/SoNEPAAAAbBAI +2iBbT1eUEBy77/sKCCIAAGiw/zwAAgAAMrD6CgUiAABxsFuHTsCAFbttpWUjVoEkVoIoVoMI5BaY +FAECACNSgwPqMPpsAAACEFgwW09BCuowJ1KIyHvaYAPqMMCyW088CuowiBQI5BYDqgxbTzHYoP0s +AAIAAHHw/LvVEAUQUDD/Uogp0AQ9IAiZLPkWACAIEFgwW4cywCDRDwAAAGwQBBO9mPy7RhABEGgw ++AogIgAAUPBtigoroAV7IAJ/t2G8qhu6rS7AgCmw3C201P+w3SAeEFAw/e4CCgADzpAuxIAtsN5/ +owoowIDAkgmIAijEgCiw332jDS7AgMD0DwIAD+4CLsSA+cCAKgAKRpDAqAqZAvnEgCAAEBAw0Q8A +wCDRD46gHL14/eAAIAgQWDD+4AEgAhBQMFuHCdkw/wogIP4QUDBt+g0okAUKiAH4lAUgGAJKcMcr +0Q8AbBAGKCAA+QqCIgAAULDyLQQgFARKMMcu0Q8AACesFv8CAAoAt5HQFL1jmhATvWGTERO9YfAA +dmBAECgwAAAAAAC8M3QxVSgwBQWIAfkwBC3iAj4gdpnp2nD7MgAgAhBgMFuCV/wKAC/qEFgwCss4 +Zr/OjREsMQOIMtpg+3wDLAAgazALgAD2oRpgARB4MC4wBdMPD+4CLjQFJnAC871HEAYCQbCod/8C +AAoAdBHQAzsC+nwAAAIQYDBbgkHzvTsQCgA2oCZwAmP/e4kQtHr/AgAKAGVSUAl6DLSq+gtCAAAQ +SDBtuQ6LECywALG7+xYAKAAgTzAKOxRksJCIEA8CAA8CACyAACqAAS+AAv6AAygAIE8w/YAEKAAg +TrD8gAUuACBP8K/uDt0I/YAHLAAgazD5gAYh/gJS8PvcAAAQAkIwbalC+YAALAAgYnD8gAEqACBi +8C2AAvmAAyoAIFZw/IAEKgAgXzD9gAUqACBfcPmABioAIF5w+4AHLAAgWzD83AgAEAJCMAyZCKm5 +GrokKaTVxKBb/2vSoNEPAPP/7GAAEEgwjjAcvQX94AAgAhBQMP7gASAIEFgwW4aSY/7ZAGwQBBm6 +yCqSfymSgAmrEauZ+pYAIBsQQDAolARbfspbfpLAINEPAABsEAQTu7D6vPQQqhBIMPQKBiAAEBAw +Ago/Agc/Agg/Ags/BAk/CgQ/CQU/AgY/+DJXIIAQUDAIAD9bhXX/vOgQABBgMAoBP/q85hANEFgw +8vR+IAEQcDD+9H0gCBBAMPj0fCIAAHCw+LzfEBgCSrD/CoAgHxAQMNMPbbpA/oZRKgAgfjD5hlAg +LAJrMPmGTywDABdw/oZOIAICYzD6hk0gQAJKcPqGTCBAAlKw/rTJIEACQjAutMgttMouhkv0NHwg +AhBIMCk0fVt+mRy52hu8xhq8xgAMiwBLYQBLYQBKYQBKYdEPAAAAbBAEGbqb0w8ikiD7uawQABBw +MP/6/yFNADSg1uD4CgAgABAgMPoKASANEDgwbQhLJZLWIpLfpWUJUxGjIo0rlSAvJHYrJSmYLCQl +EyYkIiokICokIS4kDfYkDCAIEBgwIyQFJyQELJIgIiES9mwBKAAgajD8awd0ACARMGP/rSqSIWSg +lvW8oB//ECAw+goAIAAQMDDwADdggBA4MILbJNQMLNQNJtQimNwr1Sn/1HYvgBAYMCPUICPUISOS +IbCq/MwBIAICMbDza1B4ACASMCOS1y2S36NjCTIR8goOLAAgF3Ai1ATz1gAgCBAYMPPUBS+rALag +sVWnWiqgvbFE/AoBL5oAtqBtCA6xVadaKqC99a+IYAICITBj/+orkiLLt/W5nxAAEDAw+AoHIA8Q +ODBtCCIvktgtkt+vbwnyEaLdn9Al1hYu1A0o1Awn1AQskiKxZnxrAmP/1sAg0Q8AAAAAAADz/xdi +AABDsGwQBBi6ORy5xBO8ZRu8Zx+8ZS827vs27SABEFAwKjb0KzbvKzbyLDb1+DbwIAAQaDD4NvMg +ARBwMFtNrSsyEIw/jT6OPY88iToqMgkoMgsqNsf6MhQoACBWcCk2yPkyESgAIEowKDbJ+DITLgAg +R/AvNsr/MhIuACB7sC42y/4yHCwAIHdwLTbM/TIdLAAgazAsNs38Mh4qACBm8Cs2zvsyHyoAIFqw +KjbP+jIgKAAgVnApNtD5MiEoACBKMCg20fgyIi4AIEfwLzbS/zIjLgAge7AuNtP+MiQsACB3cC02 +1P0yJiwAIGswLDbV/DInKgAgZvArNtb7MioqACBasCo21/oyKygAIFZw+TbYKAAgSjD4NtkuACBH +8P822iAAEEgw+TbGLgAge7D+NtssACB3cP023CwAIGsw/DbdKgAgZvD7Nt4qACBasCo231t+BSwy +7voy8y2QBD6g/dwfL+AQcDD/MvIsAEB3cP2qDA+AEFgw9MANYgBAWrAuMu8P/jl+KxvAIMCg/Lk6 +EAYQWDBbhY3JKfI24CAAEBAw0Q8A8jbzKf/42pBj/9oAAAAAAPI24C/0EBAw0Q8AAGwQBBW5CBa5 +KRK5lxi6Wfe6VxCAEHAw8iJ/IAkQWDD5jKwgDhBgMPqMVCFYAmnw0w9tKRgkUNzTDwQERGtCFGZA +ESdmmPVcASAoAjGwwCDRDwAAAPhCLWIAIHVw+EMZbgAgdXBrRwJrRQh7QQV0wtRqStEtZphj/8sv +8JRp98UqZphj/78jMJRoNghpOLYpZphj/7AoZphj/6oAAGwQBha5lfq4zBAAECgw9LjeEAEQGDAl +poElpoMlpoAlpoIoQMHBkPmmiiCEAP4wG7vKLWJNGLvH/7i8EGoQcDAO3SgeuocP3SwvgoDAzNMP +/cw3DgBAd/APzwIvhoAtsoAO3QENzAIstoArsoAbuRT8u7sQABBQMFv95SoKAfy5ghAAEFgwW/3i +W/oYGbkcwnAokoUvQMAHiAL4loUiVAC74Bi7r/v6/SAEEEgwbZoXKYKQKo0EC5kBKYaQKaKQKI0I +C5kBKaaQGrunKfr/KaYgKaYhKaYiKaYjKaYkW4CGHLkVLQoILsKPLkTAK8KKDbsCK8aK+7ucEAAQ +QDD8u2wQiBBIMG2aDQyJCyuWQPWWQSACAkIwH7jWEruUJfaQI/aRIyaAW/m9KCKAGbuR0w8JiAIo +JoBb/QH7QMEgAKMuoH+3DfVleiQAEFAwKmV4YAAIJWV6GrnWKmV4J2V9JWV6JWV7JWWHCiwULGV5 +W/xw/WJNIACHrqAXuRL/CmQgAxBwMA/dLA7dLClChP12vCJAAUgw9CFoYkoBTDD/AgAAANWEoP8C +AAQA0YSg/wIAAADNhOD/AgAEAMmE4G4kBAk4RpgQbjQECdpHmhEZuFv5ko8iAMqYoP8CAAIAloDg +ZTGd+WtTAAAQUDD6FgIr8AQ+4CpChwCwBAoKGQoKQVt/FMow/wIAAgCOAOD/AgAGAMSY4PsSASQA +XkCgjBD/AgAOAFlbEMCgZqBYW/wGZqBS/QqAIgAAUTD+CgQg/xBgMNMPbeoMrasrsIz8uTpwAgJS +sMCQLEDB0w9/xzMdu0YtdsAtdsBb+7pmoBcfuG0l9nIu8nbHKwLuAf72diAAEBAw0Q/SoNEPAAt5 +FGP/xQAAGrs6KGJNCogsKIz+CBgU+kDcKbAEOiD4mAIACBBYMAuIAvh2wCQOADqgaaOnK3LAxsL8 +CgUqAEBm8Ay7Ait2wGP/kY0S/AoBIOAQUDD/shENwAQ/YP0NRwIAAFiwW35D+awAADwANqBnnymZ +E2AAtGQ/IWAA0QAA/kKGKnYBTDAPuxEAsAQODhkODkGeEmP+0AAAihJbfbxj/vkAAAAAAPoK4CIA +AFiw/AoDIDAQaDBbfi7z/7FiAABKsN0g/jwAAAIQUDD8uwkQCBBYMFuEhPP+w2/aEFAw/SwAAAIQ +UDD8uwQQCBBYMFuEfWP/4QAA/TwAAAIQUDD8uv8QCBBYMFuEd2P/yQAA/TwAAAIQUDD8uvoQCBBY +MFuEcWP/sQAAAAAAAAD9PAAAAhBQMPy68xAIEFgw+Q4GAgAAEnBbhGjz/lNiAABQsP08AAACEFAw +/LrsEAgQWDBbhGFj/jYAAGwQChO35SgwwRK34fUyQiBqAH4wJSZ7HLgaGbriKiJ7KSZ9/MKOI+gQ +WDALqiwqNjILzCgsJnwLzCz8NjEgABAQMNEPACoayPwK/yAPEFgwW3/X+woXIgAAIrD6GsggAxBg +MFt/08G5/AofIgAAMrD0FgghyBBQMFt/zcG+/AofIgAAIrD2FgchyBBQMFt/yMC4/AoDIgAAMrD0 +FgYhzBBQMFt/w/sKFSIAACKw+hrUIAEQYDBbf77BtvwKASIAADqw9BYFIdQQUDBbf7kUurf9urYR +TQA2oARuCS7hftMP0w8OXiz1MkIhtBBQMP4fFAAeEFgw/yZ7IP8QYDBbf6z7CgYiAAA6sPoauCAD +EGAwW3+nwLj8Ch8iAAAysPcWBCG4EFAwW3+iwL38Ch8iAAA6sPYWAyG4EFAwW3+dwbf8CgMiAAAy +sPcWAiG4EFAwW3+Y+hYJIAQQWDD6GsQgARBgMFt/k/sKBSIAADqw+hrEIAEQYDBbf470awkAxQA2 +oCuxftMPC1ssLCAYFbdvFreD+yZ8IM4ANyAbuoUpUq8sUrD6UrIgdACicP4ifCAA0T5QKCJ7KTJC ++mxQA+gQeDAP7iz+NjEqBQBmcA+ILPg2Mi3gBD7g/SZ9IAAQEDDRDy0yQv8ieyiAAWQw9JkJDhYB +UDD5kX4qBQB3cP0ifCPoEHAwDv8sCbksDt0s/zYyKeAEPmApJn39NjEgABAQMNEPwLEHtzlkcjv/ +AgAAAOGF4P8CAAP/UYHg8/6oYAAQcDDAwQfHOWRxuP8CAAAA1YXg/wIAA/+VgeDz/ytgABBYMAAA +LSDkZd8vLlKzL/rAD+4B/lazIAEQUDBbfKQoUrPBkAmIAvhWsyABEFAwW3yfHbdFKFKyBogCKFay +LwqAL1auLFKvHrc+DswBLFavGLc+idmL2orXj9b2uxEIIAQ+YPuqEQgJAF5wCpkCCf8CCP8CL1aw +Hrc1LlaxK1KyjtWI2B+3NI3U84gRD4AEO6D8tzAeCQBDsP+7AQwJAHdwDbsCDLsC+1ayIAEQUDBb +fH8pUrIftyr6tygQEBBYMP0KeCAQEGAw/5kBABQQcDD5VrIiAAB4cFopvWShi8Ci/LcgEAgQWDBb +g45j/kwAAAAA+boWFioBYDD8BUQGiAFUMP0yQijgAVAw+YgJCD4BZDD5FgEuFgFQMPqBfioFAHdw +W4WRHroMjRHTDw7dCf3RfiAAEGAwW4P2HboIDX0J/dF+IAAQYDBbhAAdugQNbQn90X4gABBgMFuD +/ARdCf3RfiAAEGAwW4P4LiJ8/yJ7KeAEOuD4Jn0j6BAQMALuLAL/LC82Mv42MSAAEBAw0Q8AAPP8 +8WIAAHFw8/2MYgAAWXAAABu56YoUC6oJ+qF+IgAAWXBbhW0eueeNE9MPDt0J/dF+IAAQYDBbg9Ie +ueONEg7dCf3RfiAAEGAwW4PbHrnfjRnTDw7dCf3RfiAAEGAwW4PWBG0J/dF+IAAQYDBbg9Jj/SQA +AIoYDaoJ+qF+IgAAWXBbhVUeuc+NF9MPDt0J/dF+IAAQYDBbg7oeucuNFg7dCf3RfiAAEGAwW4PD +HrnHjRXTDw7dCf3RfiAAEGAwW4O+BG0J/dF+IAAQYDBbg7rz/CFiAABy8MGkW3wQLlKzwv8P7gL+ +VrMgFBBQMFt8C2P8tQBsEAbAoPsKCCAPEGAwW36vGLmzAaIKi4GMgCwWACsWAfiCAiIAAGqw+BYC +IuYAvqAiIgAoSgDztp8QAC8soHKCbvIyNCQAEFAwW36d/KwAAQAQSDD6LAACAABDMA8CANMPbZoS ++YIAIAgCQjAEmY75pgAgCAJSsPtKACIAAFMwW4Vf8jY0IBQANKDaIFv8AtKgx555IWDRD9EPxyvR +DwDAovy5jxAIEFgwW4L8xyvRDyIyNBq21Ft+gtgg/BoAIgAAWrBtyhGNsPLdGgAIAlrw/YYAIAgC +QjArSgBbhUjyNjQvuAA0oAIqAlv76/evoWIAABKwY/9JwKL8uXoQCBBYMFuC5tEPAABsEAQTtmoP +AgDyMjMgABBQMFt+afysAACAEEgw+iwAAgAAQzAPAgDTD22aD/mCACAIAkIw+aYAIAgCUrD7KgAi +AABTMFuFK/I2MyAJADSgwCDRDwDHK9EPbBAGGLaxGblgHrYmHblgLZYZ/pYaIAAQWDD7lTYgBBBQ +MCqUbhy5WsfwD8wBLIa2HLlZKIKuKZLlmRD4FgEggBB4MFuCvsAg0Q8AAGwQBBu5Uhm5UiyygSyW +1fuygiAEEGAwLJY1LJY0LJY4LJZDLJZCLJY++5bWIAAQUDD6llIgARBAMCiWQPiWOyAIEBgwI5Yo +GbYwErZbHbd4Hrc6IiKB9Ld2FAAQeDD1tzYUABAwMPOQwSAeALywAwJAAv05LeV+0Q8IOgIKB0D6 +lMEkBQA5sCRVftEPbBAEHLkyGrkyGLkvKsZ/+q1AIIgQWDD6hn8gABBgMFt6gR62Fh25Ky3mMy3d +Ai3mNNEPAGwQBBq2w/us8CCiADygaCJo9JB+YAICEnD/IhNgARAgMGAANGlkBQWoCCeGAHJLKPo8 +AAIAAFkwW4CL+GESYAICITD5Yt1oACAusCeVAGP/26WrJ7QAY//T0Q8roncpooCjuwm7Efhhb2gA +IF5waGJuaWTkpZyXwNEPGbbXqTkpkN1oQDb0kF9gAgIRMHJDn2P/xSyidymyhKPM+cwRAAICITD4 +YRtoACBmcGhiG2hkIP8CAAv/vZUQY/+cZZ9RY/+WpZgnhABj/+almielAGP/3qWbl7Bj/9elnCfE +ANEPpZ0n1QDRDwDRDwAAAAAAAAAAAAAAAAAAIAMQAAzAAAYgByasIAMQBAjAAAwgByasIAMQCDzA +ABAgByX8IAMQDAbAADggBygQIAMQEAjAADwgByasIAMQFALAAEAgBygQIAMQGAjAAEQgByasIAMQ +HAhAAEwgByc8IAMQIAhAAFAgByc8IAMQJAhAAFQgByc8IAMQKAhAAFggByc8IAMQLCBAAFwgByc8 +IAMQMCBAAGwgByc8IAMQNCBAAHwgByc8IAMQOCBAAIwgByc8IAMQPCBAAJwgByc8IAMQQCBAAKwg +Byc8IAMQRCBAALwgByc8IAMQSCBAAMwgByc8IAMQTAxAANwgByUMIAMQUAxAAOggByUMIAMQVAxA +APQgByUMIAMQWAxAAQAgByUMIAMQXAxAAQwgByUMIAMQYAxAARggByUMIAMQZAxAASQgByUMIAMQ +aAxAATAgByUMIAMQbAhAATwgByc8IAMQcAhAAUAgByc8IAMQdAhAAUQgByc8IAMQeBBAAUggByc8 +IAMQfBBAAVAgByc8YmNtODQ4NTZfbG9hZHNlcXVlbmNlOiBTdGFydGVkCgBiY204NDg1Nl9sb2Fk +c2VxdWVuY2U6IFVwbG9hZCBpbWFnZSB0byBQSFkgb24tY2hpcCBtZW1vcnkKAAAAAAAAYmNtODQ4 +NTZfbG9hZHNlcXVlbmNlOiBkb25lIGxvYWRpbmcgaW1hZ2UgKGkgPSAldSkKAAAAAAAAAAAAAAAA +AGJjbTg0ODU2X2xvYWRzZXF1ZW5jZTogRE9XTkxPQUQgRkFJTEVEIChsbyA9ICUjeCwgaGk9JSN4 +LCBjbnQ9JXUpCgAAAAAAAAAAAAAAAAAAYmNtODQ4NTZfbG9hZHNlcXVlbmNlOiBEb3dubG9hZCBj +b21wbGV0ZWQgYWZ0ZXIgJXUgbG9vcHMKAAAAAAAAAGh3X2NsNDVfaW5pdFsldV0gYWNhcHMgJSN4 +CgAAAAAAYmNtODQ4NTZfaW5pdFsldV0KAAAAAAAAAAAAAAAAAABod19iY204NDg1Nl9sb3dwb3dl +clsldV06IGVuYWJsZT0lZAoAAAAAAAAAAAAAAABod19iY204NDg1Nl9sb3dwb3dlclsldV0sIGZh +aWxlZCB0byBzZXQgMzAuMHg0MDBBIGJpdCA3OyAzMC4weDQwMEUgYml0PTEgYWZ0ZXIgNW1zLCBy +ZWc9JXgKAAAAAABod19iY201NDgyX2NmZ21kaVsldV0gc2V0dGluZyB0eXBlICV1CgAAAAAAAAAA +AAByZW1vdmUgbXVsdGljYXN0IG1hYyBbJXg6JXg6JXg6JXg6JXg6JXhdIGZyb20gVENBTQoAAAAA +AAAAAAAAAAAAaXB2Nl9qb2luX2dycDogaWQgJXUsIHJlZl9jbnQgJXUKAAAAAAAAAAAAAAAAAAAA +ZGhjcDZfdGltZXJfY2I6IHJlc2VuZGluZyBESENQNlNPTElDSVQgYWdhaW4KAAAAZGhjcDZfdGlt +ZXJfY2I6IHNlbmRpbmcgREhDUDZSRVFVRVNUCgAAAAAAAAAAAAAAZGhjcDZfdGltZXJfY2I6IHNl +bmRpbmcgREhDUDZSRU5FVyByZXF1ZXN0CgAAAAAAZGhjcDZfdGltZXJfY2I6IHNlbmRpbmcgREhD +UDZSRUJJTkQgcmVxdWVzdAoAAAAAZGhjcDZfdGltZXJfY2I6IERIQ1A2UkVQTFkgcmN2ZCwgc3Rh +dGUgJXUKAAAAAAAAZmFpbGVkIHRvIHJlbmV3L3JlYmluZCBkaGNwdjYgYWRkcmVzcwoAAAAAAAAA +AAAAdHlwZSAleCwgeGlkICV4LCB0eXBlX3hpZCAleAoAAABpcHY2X211bHRpY2FzdF9xdWVyeV90 +aW1lcl9jYiBub2RlX2lkICVkCgAAAAAAAABpcHY2X2dlbmVyYWxfcXVlcnlfdGltZXJfY2IKAAAA +AGFkZCBtdWx0aWNhc3QgbWFjIFsleDoleDoleDoleDoleDoleF0gaW4gVENBTQoAAGNobmV0X2lw +djZfZGFkX2NiOiBoYW5kbGUgJXUsIGFkZHJfaWQgJXUsIGFkZHIgc3RhdGUgJXUKAAAAAAAAAABp +cHY2IHByZWZlcnJlZCBhZGRyIFslMDR4ICUwNHggJTA0eCAlMDR4XQoAAAAAAABTdGFydGluZyBh +ZGRyIHZhbGlkaXR5IHRpbWVyIGZvciAldSBzZWNvbmRzCgAAAABWYWxpZGl0eSBleHBpcmVkIGZv +ciBhZGRyX2lkICV1CgAAAAAAAAAAAAAAAAAAAABzZW5kaW5nIGlwdjYgZWNobyByZXBseQoAAAAA +AAAAAGNobmV0X2lwdjZfcnNfb3V0cHV0OiBsMmRldl9mYyAweCV4CgAAAAAAAAAAAAAAAGNobmV0 +X2lwdjZfbnNfb3V0cHV0OiBsMmRldl9mYyAweCV4LCBmbG93Y19pZCAweCV4LCB2bGFuIGZsYWcg +MHgleAoAAAAAAAAAAAAAAAAAY2huZXRfaXB2Nl9uYV9vdXRwdXQ6IGwyZGV2X2ZjIDB4JXgKAAAA +AAAAAAAAAAAAY2huZXRfaXB2Nl9tbGR2Ml9yZXBvcnRfb3V0cHV0OiBsMmRldl9mYyAweCV4CgAA +Z2F0aGVyX3Rhc2tzX3RvX3R4X2xpc3Q6IHRhc2sgaW4gdXNlIFsldV0KAAAAAAAAZ2F0aGVyX3Rh +c2tzX3RvX3R4X2xpc3Q6IGlkeCBbJXVdLCB0YXNrIGZpZCBbMHgleF0sIHRhc2sgc3RhdGUgWzB4 +JXhdLCB0YXNrIGNvbm4gWzB4JXhdLCB0YXNrIGZmbGFncyBbMHgleF0sIGNvbm4gZmlkIFsweCV4 +XSwgZGRwIFslZF0KAAAAAAAAAAAAZ2F0aGVyX3Rhc2tzX3RvX3R4X2xpc3Q6IHRhc2sgWzB4JXhd +LCBzdGF0ZSBbMHgleF0gb24gY29ubiBbMHgleF0gbm90IHZhbGlkIHRvIGdhdGhlciwgc2tpcHBp +bmcKAAAAAAAAAAAAAAAAAAAAAGdhdGhlcl90YXNrc190b190eF9saXN0OiB0YXNrIFsweCV4XSwg +c3RpbGwgcXVldWVkIG9uIHR4IHBlbmRpbmcgbGlzdC4gUmVtb3ZpbmcgaXQuCgAAAAAAAAAAAAAA +AGdhdGhlcl90YXNrc190b190eF9saXN0OiBjb25uX2ZjLT5mbG93Y19mbGFncyBbMHgleF0sIGxp +c3RfZW1wdHkgWzB4JXhdLCBhZGRfdGFza19jb3VudCBbMHgleF0KAHRvX3R4X2xpc3Q6IG5vIHRh +c2sgdG8gY2xvc2UgZm9yIGNvbm4gWzB4JXhdLCBiYWlsaW5nIHRvIHJlY292ZXJ5IHN0YXRlIFsw +eCV4XQoAYXV0aGVudGljYXRlX3RhcmdldDogS0VZX0NIQVBfUkVTUCAtIFsweCV4JXgleCV4JXgl +eCV4JXhdCgAAAAAAAGF1dGhlbnRpY2F0ZV90YXJnZXQ6IEtFWV9DSEFQX1JFU1AgLSBbMHgleCV4 +JXgleCV4JXgleCV4XQoAAAAAAABhdXRoZW50aWNhdGVfdGFyZ2V0OiBJbmNvcnJlY3QgcGFzc3dv +cmQKAAAAAAAAAABDSEFQX0M6IGRpZ2VzdCBleHBhbnNpb24gZXJyb3IKAENIQVBfTjogVGFyZ2V0 +IHVzZXJpZCBtaXNtYXRjaAoAQ0hBUF9SOiBkaWdlc3QgZXhwYW5zaW9uIGVycm9yCgBpU0NTSSBT +ZWMtcGFyYW1zIHJlY2VpdmVkaGF2ZSBlcnJvcnMhIQoAAAAAAAAAAABUYXJnZXQgbW92ZWQgdGVt +cC4gY29ubiAleCwgc2VzcyAleAoAAAAAAAAAAAAAAABMb2dpbiBGYWlsZWQhIS4gY29ubl9mYyBb +MHgleF0sIHNlc3NfZmMgWzB4JXhdLCBzdGF0dXNfY2xhc3MgWzB4JXhdCgAAAAAAAAAAAAAAAFBy +b3RvY29sIEVycm9yIGNiaXQgJWQgdGJpdCAlZCBjc2cgJWQgbnNnICVkCgAAAHJlY3Zfbm9waW46 +IGN0cmwgdGFzayBhbHJlYWR5IHBlbmRpbmcKAAAAAAAAAAAAAG9mbGRfcnhfZGF0YTogYWllZSwg +aXNjc2kgY29ubiBbMHgleF0gZm9yIHNlc3MgWzB4JXhdLCB0eXBlIFsweCV4XSB0cmFuc2l0ZWQg +aW4gdG9lIG1vZGUuIEtpY2tpbmcgcmVjb3ZlcnkgCgAAAABvZmxkX3J4X2RhdGE6IGNvbm4gdGlk +IFsweCV4XSwgcnhfZGF0YS0+c2VxIFsweCV4XSwgcnhfZGF0YS0+bGVuIFsweCV4XSwgcnhfZGF0 +YS0+c3RhdHVzIFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAb2ZsZF9yeF9kYXRhOiBjc2sgeyBpZCBb +MHgleF0sIGNzb2NrX29mZnNldCBbMHgleF0sIGRsZW4gWzB4JXhdIH0KAAAAAAAAAAAAAAAAAABh +Y3RfZXN0OiB0Y2JfZmMgWzB4JXhdLCBmbG93Y19mb2lzY3NpX2Nvbm5fZmxhZ3MgWzB4JXhdCgAA +AAAAAAAAYWN0X2VzdGFiOiB0Y2JfZmMtPmZsb3djX2J1ZiBbMHgleF0sIHRjYl9mYy0+Zmxvd2Nf +dHlwZSBbMHgleF0gdGNiX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIG5wYWdlcyBbMHgleF0sIGZs +b3djX3RwX3NuZF9tYXggWzB4JXhdCgAAAAAAAAAAAAAAAAAAYWN0X2VzdGFiOiBhdGlkIFsweCV4 +XSwgdGlkIFsweCV4XSwgb3AgWzB4JXhdLCByY3ZfaXNuIFsweCV4XSwgc25kX2lzbiBbMHgleF0s +IGNzb2NrLT5mbG93Y19zdGF0ZSBbMHgleF0sIHRjcF9vcHQgWzB4JXhdLCB0Y2JfZmMtPmZsb3dj +X2lkIFsweCV4XSAKAAAAAAAAAAAAAAAAAGNza19mYy0+Zmxvd2NfY3NvY2tfY29va2llIFsweCV4 +XSAKAAAAAAAAAAAAAAAAAG5ldF9sMmRldl9maW5kX2J5X2FkZHI2OiBsMmRldl9mYy0+Zmxvd2Nf +aWQgWzB4JXhdLCBsMmRjLT5scG9ydCBbJXVdLCBsMmRfZmMtPmZsb3djX2lkIFsweCV4XSwgYWRk +ciBbJTA0eCUwNHglMDR4JTA0eF0KAAAAAAAAAAAAY2huZXRfcXVldWVfeG1pdDogZmMtPmZsb3dj +X2lkIFsweCV4XSwgYnVmX2xlbiBbMHgleF0sIGJ1ZmZlcmVkIFsweCV4XSwgZmlmby5udW1fYnl0 +ZXMgWyUweF0KAAAAbmV0aWZfZG9fZGhjcHY2OiB3ci0+cGFyYW0udmxhbmlkIFsldV0sIGwyZGV2 +X2ZjLT5mbG93Y19uZXRfbDJkZXZfdmxhbmRldiBbMHgleF0KAAAAAAAAAAAAAAAAAAAAbmV0aWZf +ZG9fZGhjcHY2OiBpcHY2IG5vdCBlbmFibGVkCgAAAAAAAAAAAAAAAAAAZGhjcCByZXNwIHRvIGRy +aXZlcgoAAAAAAAAAAAAAAABsM2luNl9kZXZfY29uZmlnOiB3ci0+cGFyYW0udmxhbmlkIFsldV0s +IGwyZGV2X2ZjLT5mbG93Y19uZXRfbDJkZXZfdmxhbmRldiBbMHgleF0KAAAAAAAAAAAAAAAAAABs +M2luNl9kZXZfY29uZmlnOiBpcHY2IG5vdCBlbmFibGVkCgAAAAAAAAAAAAAAAABuZXRfbDNpbjZf +ZGV2X2NvbmZpZzogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgYWRkcmVzcyBhbHJlYWR5IHVz +ZWQgYnkgcG9ydCAlZCwgYWRkcl9pZCAlZAoAAABuZXRfbDNpbjZfZGV2X2NvbmZpZzogIGFkZHIg +WzB4JTA0eCUwNHglMDR4JTA0eF0sIHJlZl9jbnQgWzB4JXhdIGluIHVzZQoAAAAAAAAAAGwzaW40 +X2Rldl9jb25maWc6IHdyLT5wYXJhbS52bGFuaWQgWyV1XSwgbDJkZXZfZmMtPmZsb3djX25ldF9s +MmRldl92bGFuZGV2IFsweCV4XQoAAAAAAAAAAAAAAAAAAG5ldF9sM2luNF9kZXZfY29uZmlnOiBs +MmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBhZGRyZXNzIGFscmVhZHkgdXNlZCBieSBwb3J0ICVk +CgAAAAAAAAAAAAAAAAAAAG5ldF9sM2luNF9kZXZfY29uZmlnOiAgYWRkciBbMHgleF0sIG1hc2sg +WzB4JXhdLCBndyBbMHgleF0sIHJlZl9jbnQgWzB4JXhdIGluIHVzZQoAAAAAAAAAAAAAAAAAAGwy +ZGV2X2ZjIFsweCV4IF0gRmFpbGVkIHRvIHN0YXJ0IHRpbWVyIGZvciBpcHY0IGRhZAoAAAAAAAAA +AAAAAAB3cmhfY2huZXRfaWZjb25mOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBsMmRldl9m +Yy0+Zmxvd2NfdHlwZSBbJTB4XSwgaWZjb25mX3dyLT5zdWJvcCBbMHgleF0KAAAAAAAAAAAAAAAA +AAAAd3JoX2NobmV0X2lmY29uZjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgdW5rbm93biBz +dWJvcCBbMHgleF0KAAAAAAAAAAAAAAAAAAB3cmhfY2huZXRfaWZjb25mOiBsMmRldl9mYy0+Zmxv +d2NfaWQgWzB4JXhdLCByYyAlZAoAAAAAAAAAAAAAAAAAbmV0aWZfaXBfY29uZmxpY3RfdGltZXJf +Y2I6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIGV4cGVjdGluZyB0aW1lciBoYW5kbGUgWyVk +XSwgYnV0IGdvdCBoYW5kbGUgWyVkXSBleHBpcnkKAG5ldGlmX2lwX2NvbmZsaWN0X3RpbWVyX2Ni +OiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBpbmRldmN0eHQtPnN0YXRlIFslZF0sIGluZGV2 +Y3R4dC0+cmV0cnlfY250IFslZF0KAAAAAAAAAABuZXRpZl9pcF9jb25mbGljdF90aW1lcl9jYjog +bDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgaW5kZXZjdHh0IFsweCV4XSwgaW4gZnJlZSBzdGF0 +ZQoAAAAAAAAAAABjbWRoX2NobmV0X2lmYWNlOiBmYyBbMHgleF0sIGZjLT5mbG93Y19pZCBbMHgl +eF0sIGZjLT5mbG93Y190eXBlIFsweCV4XSwgcCBbMHgleF0sIGxlbjE2IFsldV0sIGxvYyBbMHgl +eF0KAAAAAAAAY21kaF9jaG5ldF9pZmFjZTpsMmRldl9mYyBbMHgleF0sIGwyZGV2X2ZjLT5mbG93 +Y19pZCBbMHgleF0sIGwyZGV2LT5mbG93Y190eXBlIFsldV0sIGwyZGV2X2ZjLT5mbG93Y19uZXRf +bDJkZXZfZmxhZ3MgWyUweF0KAAAAAABjbWRoX2NobmV0X2lmYWNlOiByMlswXSAldSByMlsxXSAl +dQoAAAAAAAAAAAAAAABjbWRoX2NobmV0X2lmYWNlOiBsMmRldl9mYy0+Zmxvd2NfbmV0X2wyZGV2 +X2ZsYWdzIGNoYW5nZWQgZnJvbSBbJTB4XSB0byBbJTB4XSwgcmMgWyVkXQoAAAAAAAAAAABjaG5l +dF9sMmRldl91cF9tYl9jYjogcmMgWyVkXSwgcG9ydCBbJXVdLCBzdGF0ZSBbJXVdLCBjb29raWUg +WzB4JXhdCgAAAAAAAAAAAAAAAGRoY3BfcHJvY2Vzc19jYjogbDJkZXZfZmMtPmZsb3djX2lkIFsw +eCV4XSwgZGhjdHh0LT5zdGF0ZSBbJTB4XSwgZGhjdHh0LT5ydHJ5X2NudCBbJXVdCgAAAAAAAAAA +AGRoY3BfdGltZXJfY2I6IERIQ1BESVNDT1ZFUiBzZW50LCBidXQgbm8gcmVwbHkgZnJvbSBhbnkg +cG9zc2libGUgc2VydmVyIG9uIHRoZSBuZXR3b3JrLiBSZXRyeWluZyBhZ2FpbgoAAAAAAAAAAABk +aGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBzZW5kaW5nIERIQ1BESVND +T1ZFUiBmb3IgZGhjdHh0IFsweCV4XSBvbiBwaWQgWyVkXQoAAABkaGNwX3RpbWVyX2NiOiBsMmRl +dl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBESENQT0ZGRVIgcmVjZWl2ZWQgZm9yIGRoY3R4dCBbJXhd +IHBpZCBbJWRdCgAAAAAAAAAAAABkaGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4 +JXhdLCAgREhDUEFDSyByZWNlaXZlZCBmb3IgZGhjdHh0IFsleF0sIHBpZCBbJWRdCgAAAAAAAAAA +AABkaGNwX3RpbWVyX2NiOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBkaGN0eHQtPmlwYWRk +ciBbMHgleF0KAAAAAAAAAAAAAAAAAAAAAGRoY3BfdGltZXJfY2I6IHN0YXJ0aW5nIHRpbWVyIGZv +ciBsZWFzZSBbJXVdIHNlY29uZHMKAAAAAAAAAAAAAABkaGNwX3RpbWVyX2NiOiBsZWFzZSB0aW1l +IG9mIFsldV0gc2Vjb25kcyBleHBpcmVkLCBzZW5kaW5nIHJlbmV3IHJlcXVlc3QKAAAAAAAAAGRo +Y3BfdGltZXJfY2I6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIG5vIHJlcGx5IGZyb20gZGhj +cCBzZXJ2ZXIsIHRpbWluZyBvdXQKAAAAAAAAAAAAAAAAAAAAAGF1dGhfbmVnb19zZWN1cml0eTog +c2VuZF9mbGFnIFsweCV4XSwgYXV0aF9wb2xpY3kgWzB4JXhdCgAAAAAAAABhdXRoX25lZ29fc2Vj +dXJpdHk6IEtFWV9DSEFQX1JFU1AgLSBoYXNoWzB4JXgleCV4JXgleCV4JXgleF0KAAAAYXV0aF9u +ZWdvX3NlY3VyaXR5OiBLRVlfQ0hBUF9SRVNQIC0gaGFzaFsweCV4JXgleCV4JXgleCV4JXhdCgAA +AGF1dGhfbmVnb19zZWN1cml0eTogS0VZX0NIQVBfUkVTUCAtIGVycm9yIGVuY29kaW5nIHRvIGhl +eAoAAAAAAABhdXRoX25lZ29fc2VjdXJpdHk6IEtFWV9DSEFQX1JFU1AgLSBlbGVuIFsweCV4XQoA +AAAAAAAAAAAAAAAAAAAAYXV0aF9uZWdvX3NlY3VyaXR5OiBLRVlfQ0hBUF9DSEFMIC0gZXJyb3Ig +ZW5jb2RpbmcgdG8gaGV4CgAAAAAAAGF1dGhfbmVnb19zZWN1cml0eTogS0VZX0NIQVBfQ0hBTCAt +IGVsZW4gWzB4JXhdCgAAAAAAAAAAAAAAAAAAAABsb2dvdXRfdGltZWRvdXQ6IGxvZ291dCByZXF1 +ZXN0IHRpbWVkb3V0LCBwb3NzaWJsZSBuZXR3b3JrIGlzc3Vlcy4gRm9yY2VmdWxseSBicmVha2lu +ZyBwYXRoIGZvciBzZXNzIFsweCV4XQoAAAAAcGluZ190YXJnZXQ6IHBpbmcgdGltZW91dCwga2lj +a2luZyByZWNvdmVyeSBmb3Igc2VzcyBbMHgleF0KAAAAAGNzb2NrX2ZhaWxlZDogY3NrX2ZjLT5m +bG93Y19pZCBbMHgleF0sIGNza19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBzZXNzX2ZjLT5mbG93 +Y19pZCBbMHgleF0sIHNlc3NfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgZXZ0IFsweCV4XQoAAAAA +AAAAAAAAAGNobmV0X2ZpbmRfaXA2X2wydF9lbnRyeTogZmluZCBwcmVmaXggbWF0Y2ggWyUwNHgg +JTA0eCAlMDR4ICUwNHhdCgAAAAAAAAAAAAAAAAAATm8gcm91dGVyIGNvbmZpZ3VyZWQsIGwyZGV2 +X2ZjLT5mbG93Y19pZCAweCV4CgAAClJvdXRlciBsaWZlICV1IGV4cGlyZWQuIGRlbGV0aW5nIHJv +dXRlciBbJTA0eCAlMDR4ICUwNHggJTA0eF0KAFVzaW5nIHJvdXRlciBbJTA0eCAlMDR4ICUwNHgg +JTA0eF0gdG8gcmVhY2ggWyUwNHggJTA0eCAlMDR4ICUwNHhdCgAAAAAAAAAAAAAAAAAAbDJ0ZW50 +IFslMHhdLCBsMnRlbnQtPmlkeCBbJWRdCgByYyBbJWRdLCBjc2tfZmMgWzB4JXhdLCBjc2tfZmMt +PmZsb3djX2lkIFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAcmVjb3ZlcnlfdGltZW91dDogc2VzcyBp +ZCBbMHgleF0gc3RhdGUgWzB4JXhdLCByY291bnQgWyVkXSwgZmxhZ3MgWzB4JXhdCgAAAAAAAABy +ZWNvdmVyeV90aW1lb3V0OiBzZXNzIGlkIFsweCV4XSBpbiBsb2dvdXQsIGFib3J0IHRoZSBjb25u +ZWN0aW9uCgAAAAAAAAAAAAAAAAAAAHJlY292ZXJ5X3RpbWVvdXQ6IHNlc3NfZmMtPmZsb3djX2Zv +aXNjc2lfc2Vzc19mbGFncyBbMHgleF0sIGNvbm5lY3Rpb24gcmVxdWVzdCBwZW5kaW5nLCBiYWls +aW5nIG91dAoAAAAAAAAAAAAAAABmb2lzY3NpOiBSZWNvdmVyeSB0aW1lZCBvdXQgYWZ0ZXIgWyV1 +XSByZXRyeSwgYmFpbGluZyBvdXQKAAAAAAAAVENQIGNvbm4gZXN0YWJsaXNobWVudCBmYWlsZWQg +JWQKAAAAAAAAAAAAAAAAAAAAZGlzY292ZXJ5X2RhdGE6IHNlc3MgeyBpZCBbMHgleF0sIGZsYWdz +IFsweCV4XSwgYnVmZmVyZWQgWyV1XS4gfQoAAAAAAAAAAAAAAAAAAABkaXNjb3ZlcnlfZGF0YTog +c2VzcyB7IGlkIFsweCV4XSB9LCB1bHB0eGNoIFsldV0gbm8gY3JlZGl0cyBhdmFpbGFibGUsIHJl +c2NoZWR1bGluZyByZXF1ZXN0LgoAAABJbnZhbGlkIG9wY29kZSAweCV4IGluIGN0cmwgcGF0aAoA +AAAAAAAAAAAAAAAAAABERFAgZXJyb3IgWzB4JXhdLCBhYm9ydGluZyBjb25ubiBbMHgleF0KAAAA +AAAAAAByeF9kYXRhX2RkcDogUmVzcG9uY2UgcmVjaWV2ZWQgZm9yIHRhc2sgWzB4JXhdIHdoaWxl +IGludmFsaWQgdGFzayBvciBjb25uZWN0aW9uIHN0YXRlLiB0YXNrIHN0YXRlIFsweCV4XSwgY29u +biBzdGF0ZSBbMHgleF0sIGNvbm4gZmxhZ3MgWzB4JXhdCgBpc2NzaV9oZHJfcng6IFJlc3BvbmNl +IHJlY2lldmVkIGZvciB0YXNrIFsweCV4XSB3aGlsZSBpbnZhbGlkIHRhc2sgb3IgY29ubmVjdGlv +biBzdGF0ZS4gdGFzayBzdGF0ZSBbMHgleF0sIGNvbm4gc3RhdGUgWzB4JXhdLCBjb25uIGZsYWdz +IFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAaXNjc2lfaGRyX3J4OiBJbnZhbGlkIHRhc2sgc3RhdGUg +MHgleCBmb3IgdGFzayAweCV4LCBpdHQgWzB4JXhdLCBvcGMgWzB4JXhdCgAAAABwcm9jZXNzX3Rt +Zl9yZXNwb25zZTogYnVmZmVyZWQgWzB4JXhdLCBpc3Rhc2tfZmMtPmZsb3djX2J1Zi0+c2NoZWRf +bm9kZS5uZXh0IFsweCV4XSwgaXN0YXNrX2ZjIFsweCV4XSwgaXN0YXNrX2ZjLT5mbG93Y19pZCBb +MHgleF0KAAAAAAAAAAAAAAAAAABwcm9jZXNzX3RtZl9yZXNwb25zZTogd3Igb3AgWzB4JXhdLCB0 +bWYgb3AgWzB4JXhdCgAAAAAAAAAAAAAAAAAAcmV0dXJuX3BlbmRpbmdfdGFzazogY29va2llIFsw +eCUwOHhdLCBbMHglMDh4XQoAcmV0dXJuX3BlbmRpbmdfdGFzazogZGVsYXkgcHJvY2Vzc2luZywg +Y29ubiBmbGFncyBbMHgleF0KAAAAAAAAAHJldHVybl9wZW5kaW5nX3Rhc2s6IERvbmUgc2VuZGlu +ZyB0YXNrIGVycm9yIHRvIGhvc3QsIHVscHR4bGVuMTYgWyV1XQoAAAAAAAAAAAAAcmV0dXJuX3Bl +bmRpbmdfdGFzazogZGVxdWV1ZSB0YXNrIFsweCV4XSwgc3RhdGUgWzB4JXhdIGZyb20gdHhfbGlz +dAoAAAAAAAAAAAAAAAByZXR1cm5fcGVuZGluZ190YXNrOiBhbGwgdGFza3MgcmV0dXJuZWQsIHJl +Y292ZXJ5IHN0YXRlIHRyYW5zIHRvIFsweCV4XQoAAAAAAAAAAGNsZWFyX2RkcF9tYXA6IGlzdGFz +a19mYyBbMHgleF0sIGlzdGFza19mYy0+Zmxvd2NfaWQgWzB4JXhdIGJ1ZmZlcmVkICV1CgAAAAAA +AAAAY2xlYXJfZGRwX21hcDogaXN0YXNrX2ZjLT5mbG93Y19mb2lzY3NpX3Rhc2tfbnBwb2QgJXUs +IG5wcG9kICV1LCBwcGRhZGRyIFsweCV4XQoAAAAAAAAAAAAAAAAAAAAAY2xlYXJfZGRwX21hcDog +YWxsIHJldHVybmVkIHRhc2tzIGRkcCBjbGVhcmVkLCByZWNvdmVyeSBzdGF0ZSB0cmFucyB0byBb +MHgleF0KAAB3cmhfZm9pc2NzaV9ub2RlOiBub2RlX3dyLT5mbG93aWRfbGVuMTYgMiBbJXhdCgB3 +cmhfZm9pc2NzaV9jaGFwOiBpZF9sZW4gWyV4XSwgc2VjX2xlbiBbJXhdCgAAAAB3cmhfZm9pc2Nz +aV9jaGFwOiB0Z3RfaWRfbGVuIFsleF0sIHRndF9zZWNfbGVuIFsleF0KAAAAAAAAAAAAAAAAc2Vz +c2lvbl9ibG9jazogc2Vzc19mYy0+Zmxvd2NfaWQgWzB4JXhdLCBzZXNzX2ZjLT5mbG93Y19zdGF0 +ZSBbMHgleF0sIGNvbm5fZmMtPmZsb3djX2lkIFsweCV4XSwgY29ubl9mYy0+Zmxvd2Nfc3RhdGUg +WzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19zdGF0ZSBbMHgl +eF0KAAAAAAAAAAAAAAAAAAAAc2Vzc2lvbl91bmJsb2NrOiBzZXNzX2ZjLT5mbG93Y19pZCBbMHgl +eF0sIHNlc3NfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgY29ubl9mYy0+Zmxvd2NfaWQgWzB4JXhd +LCBjb25uX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCBj +c2tfZmMtPmZsb3djX3N0YXRlIFsweCV4XQoAAAAAAAAAAAAAAAAAc3RhcnRfbG9nb3V0OiBTZXNz +LWlkIFsweCV4XSBhbHJlYWR5IGxvZ2dpbiBvdXQuCgAAAAAAAAAAAAAAAAAAAHBlZXJfY29uOiBj +c2tfZmMgPT4gZmxvd2lkIFsweCV4XSwgZmxvd2NfYnVmIFsweCV4XQoAAAAAAAAAAAAAAABhbGxv +Y19zZXNzOiBsb2dpbl9yZXRyeSBbJWRdLCByZWNvdl90aW1lb3V0IFslZF0KAAAAAAAAAAAAAAAA +AAAAZm9pc2NzaV9jdHJsOiBzdWJvcCBbMHgleF0sIHNlc3NfdHlwZV90b19lcmwgWzB4JXhdLCBz +ZXNzX3R5cGUgWzB4JXhdCgAAAAAAAAAAAABmb2lzY3NpX2N0cmw6IHJlY2VpdmVkIGJsb2NrZWQg +ZnJvbSBkcml2ZXIsIHRyaWdnZXJpbmcgcmV0dXJuIHRhc2tzIG5vdy4KAAAAAAAAAHdhdGNoZG9n +IGNtZCBoYW5kbGVyICh0aW1lICV1IGFjdGlvbiAldSkKAAAAAAAAAFdBVENIRE9HOiBkZXZpY2Ug +c2h1dGRvd24KAAAAAAAAV0FUQ0hET0c6IHBvcnRbJXVdIHBhdXNlIHdhdGNoZG9nIHRpbWVvdXQK +AAAAAAAAV0FUQ0hET0c6IGJ5cGFzcyB0aW1lb3V0CgAAAAAAAABXQVRDSERPRzogRkxSIC0gbm90 +IGltcGxlbWVudGVkIHlldAoAAAAAAAAAAAAAAABXQVRDSERPRzogdGVtcGVyYXR1cmUgb2YgJWRD +IGV4Y2VlZHMgdGhyZXNob2xkIG9mICVkQwoAAAAAAAAAAAAAZmlsdGVyOiBwb3JncmFtbWluZyB0 +aWQgJXUgKGxlIHRjYW0gaW5kZXggJXUpLi4uCgAAAAAAAAAAAAAAAAAAAGZpbHRlcjogcmVxdWVz +dGluZyBjb21wbGV0aW9uLi4uCgAAAAAAAAAAAAAAAAAAAGNobmV0X2lwdjZfbGlua19jaGFuZ2Vf +bm90aWZ5OiBsMmRldl9mYyBbMHgleF0sIHN0YXR1cyAldQoAAAAAAABsMmRldl9zZW5kX3BvcnRf +ZXZlbnQ6IHdyIFsweCV4XSBwZW5kaW5nIG9uIHBvcnQgWyVkXSwgY3VycmVudCB0cnkgWyVkXQoA +AAAAAAAAAEZDT0UgRnJlZTogc3RpbGwgeWllbGRlZCB3aGVuIGZyZWVpbmcuLi5mbG93Y19pZCAl +eCBmbG93Y19mbGFncyAleCAKAAAAAAAAAAAAAAAARkNPRSBCUCBXUiBFUlI6IFdSIHdpdGggY29v +a2llICV4JXggZXJyb3JlZCBiYWNrIAoAAAAAAAAAAAAAAAAAAHBvcnQgJWQgc2V0IHBmY19lbiA9 +IDB4JXgKAAAAAAAAcG9ydCAlZCBzZXQgcGZjX2VuID0gMHgleAoAAAAAAABldHNfc2V0X2NmZ19p +ZWVlWyV1XSB1bmtub3duIFRTQSBhbGcgZm9yIHByaW8gJXU6ICV1CgAAAAAAAAAAAAAARkNvRSBE +RFAgZmFpbGVkIDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAARkNvRSBERFAgZmFpbGVk +IDogRGRwUmVwb3J0IDB4JXggRGRwVmFsaWQgMHgleAoARkMgeGNoZyBhbGxvYyBmYWlsZWQ6IGF2 +YWlsICVkCgBmY29lIG5vdGlmeSA6IFVwZGF0ZSBuZXcgRENCWCB2YWx1ZXMgVkkgc3RhdGUgMHgl +eCBwcmkgMHgleCBzY2hlZGNsIDB4JXggZGNieF9kb25lIDB4JXgKAAAAAAAAAABmY29lIG5vdGlm +eSA6IEZDRiBmbG93aWQgMHgleCwgdWxwY2ggMHgleCAKAAAAAABQUkxJIFJzcCB0aW1lZG91dCA6 +IGZsb3djX2lkIDB4JXggb3hfaWQgMHgleCByeF9pZCAweCV4IAoAAAAAAAAAY2Fubm90IGFsbG9j +YXRlIG9mZmxvYWRlZCBmaWx0ZXIgY29ubmVjdGlvbgoAAAAAY2Fubm90IGFsbG9jYXRlIG9mZmxv +YWRlZCBmaWx0ZXIgSVB2NiBjb25uZWN0aW9uCgAAAAAAAAAAAAAAAAAAAGRpc3BhdGNoX2RlZmVy +cmVkX2NsYXNzX2NsYXNzX3NoYXBpbmdbJXU6JXVdOiBsaXN0X2VtcHR5CgAAAAAAAABsb29wYmFj +ayBidWZmZXIgZ3JvdXBbJXVdIGlzIGRpc2FibGVkCgAAAAAAAAAAAABpbnZhbGlkIGJ1ZmZlciBn +cm91cFsldV0gY29uZmlndXJhdGlvbjogbXR1ICV1IGx3bSAldSBod20gJXUgZHdtICV1CgAAAAAA +AAAAAAAAAGZjICV1IHZmICV1IGdvdCBpdmY9MHgleCxyYW5nZTogJSN4LSUjeCAoJXUvJXUgdXNl +ZCkKAAAAAAAAAAAAAABWSSAldSBjYW5ub3QgZ2V0IFJTUyBzbGljZTogTm8gbW9yZSBzbGljZXMg +YXZhaWxhYmxlICh1c2VkICV1LyV1KQoAAAAAAAAAAAAAAAAAAHBmbiAldSB2Zm4gJXUgd2l0aCBw +b3J0IG1hc2sgMHgleCBjYW5ub3QgYWNjZXNzIHBvcnQgJXUsIHJldCAlZAoAAAAAAAAAAAAAAAAA +AAAAcGZuICV1IHZmbiAldSBjb3VsZCBub3QgYWxsb2NhdGUgdmlpZCwgcmV0ICVkCgAAcGZuICV1 +IHZmbiAldSBjb3VsZCBtYXAgdmlpZCAgMHgleCB0byBmbG93YywgcmV0ICVkCgAAAAAAAAAAAAAA +AHBmbiAldSB2Zm4gJXUgY291bGQgbm90IGFsbG9jYXRlIHV3aXJlIGZ1bmMgJWQgbWFjIGFkZHIs +IHJldCAlZAoAAAAAAAAAAAAAAAAAAAAAbWlpX2luaXRbJXVdOiBhY2FwcyAweCV4CgAAAAAAAABt +aWlfZm9yY2Vfc3BlZWRbJXVdOiByY2FwcyAweCV4CgAAAAAAAAAAAAAAAAAAAABtaWlfcGRvd25b +JXVdOiBwb3dlcmRvd24gZW4gJXUKAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IHVua25vd24gYWN0 +aW9uIDB4JXgKAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IHVua25vd24gcmVhZCBhY3Rpb24g +MHgleAoAAAAAAAAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTogdGlkICV1IGNwbCAweCUwOHglMDh4 +CgAAAAAAAAAAAABjcGxfZXJyX25vdGlmeTogdGlkICV1IGNwbCAweCUwOHglMDh4IDB4JTA4eCUw +OHgKAAAAAAAAAAAAAAAAAAAAY3BsX2Vycl9ub3RpZnk6IHRpZCAldSBsZW4gJXUKAABGQ09FIEZy ZWU6IHN0aWxsIHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxvd2NfaWQgJXggZmxvd2NfZmxhZ3Mg -JXggCgAAAAAAAAAAAAAAAEZDIHhjaGcgZnJlZSB4aWQ6JWQgZmxvd2lkICVkCgAAcGZuICV1IHZm -biAldSB2aWEgY29tbWFuZAoAAAAAAABjb25maWd1cmF0aW9uIGZpbGUgcGFyc2VyOiBwbCB0aW1l -b3V0IHZhbHVlIGlzIHRvbyBsYXJnZSwgY2hhbmdpbmcgZnJvbSAldSB0byAldXVzZWNzCgAAAAAA -AAAAAABQTF9QQ0lFX0xJTksuc3BlZWQgb2YgJXUgaXMgbm90IHN1cHBvcnRlZApmaWxlLCByZXQg -RldfRUlPCgAAAAAAc2NoZWRfaW9xdHhfYnBfcHJpb3JpdHk6IGhhcyAldSBlbnRyaWVzIG9ubHks -IHJlcXVpcmVzICV1IGVudHJpZXMKAAAAAAAAAAAAAAAAAAB0cF9iYWNrb2ZmOiBwYXJzZWQgJWQg -aW5zdGVhZCBvZiAldSBlbnRyaWVzCgAAAAB0cF90aW1lcnZhbHM6IHBhcnNlZCAlZCBpbnN0ZWFk -IG9mICV1IGVudHJpZXMKAAB0cF90aW1lcnJlczogcGFyc2VkICVkIGluc3RlYWQgb2YgJXUgZW50 -cmllcwoAAAB0cF9tdHVzIGhhcyAldSBlbnRyaWVzIG9ubHksIHJlcXVpcmVzICV1IGVudHJpZXMK -AAAAAAAAAAAAAAAAAAAAdHBfbXR1c1sldV0gaXMgJXUgYnl0ZXMgd2hpY2ggaXMgbm90IHN1cHBv -cnRlZAoAY29uZmlndXJhdGlvbiBmaWxlIHBhcnNlcjogc2dlIHRpbWVyIHZhbHVlWyVpXSBpcyB0 -b28gbGFyZ2UsIGNoYW5naW5nIGZyb20gJXUgdG8gJXV1c2VjcwoAAAAAAAAAZmlsdGVybWFzayAw -eCV4IGlzIG5vdCBlcXVhbC9zdWJzZXQgdG8vb2YgZmlsdGVybW9kZQoAAAAAAAAAAAAAAGh3X2xl -X2NsaXBfaGFuZGxlcjogcmVtb3ZlZCBwb3M9JXUgKD1pZHggJXUpCgAAAGh3X2xlX2NsaXBfaGFu -ZGxlcjogYWRkaW5nIHRvIHBvcz0ldSAoPWlkeCAldSkKAG1vZHVsZVsldV06IHBvcnQgbW9kdWxl -IGluc2VydGVkIGFuZCByZWFkeQoAAAAAAG1vZHVsZVsldV06IHBvcnQgbW9kdWxlIHJlbW92ZWQK -AAAAAAAAAAAAAAAAAAAAAG1vZHVsZVsldV06IHVua25vd24gbW9kdWxlIGlkZW50aWZpZXIgMHgl -MDJ4CgAAAG1vZHVsZVsldV06IGdwaW8gJXUgdHJhbnMgMTBHIDB4JTAyeCAxRyAweCUwMnggKGxl -bmd0aCAldSkgY2FibGUgMHglMDJ4IChsZW5ndGggJXUpIG1vZHVsZV90eXBlIDB4JTAyeAoAAAAA -AAAAAABtb2R1bGVbJXVdOiBncGlvICV1IHRyYW5zIDEwRyAweCUwMnggMUcgMHglMDJ4IChsZW5n -dGggJXUpIGNhYmxlIDB4JTAyeCAobGVuZ3RoICV1KSBtb2R1bGVfdHlwZSAweCUwMngKAAAAAAAA -AAAAY3JfbW9kdWxlX3J4X2xvc1sldV06IHJ4X2xvcyBjaGFuZ2VkIHRvICV1CgAAAAAATUM6IGV4 -cGVjdGVkIHN0YXRlIHRvIHN3aXRjaCB0byBDRkcuAAAAAAAAAAAAAAAATUM6IGV4cGVjdGVkIHN0 -YXRlIHRvIHN3aXRjaCB0byBBY2Nlc3MuAAAAAAAAAAAATUM6IGV4cGVjdGVkIHN0YXRlIHRvIHN3 -aXRjaCB0byBDRkcuAAAAAAAAAAAAAAAATUM6IGV4cGVjdGVkIHN0YXRlIHRvIHN3aXRjaCB0byBB -Y2Nlc3MuAAAAAAAAAAAASUkuMS5ieCBkcDE4WyV1XSBxWyV1XSAlI3ggJSN4ICUjeCAlI3ggbWlu -ICUjeCBtYXggJSN4CgAAAAAAAAAAAElJLjEuYy1kLiAlI3ggJSN4ICUjeCAlI3ggYWxsICAlI3gK -AAAAAAAAAAAAAAAAAElJLjIuYiAoJSN4IC0gJSN4ICsgJSN4KSAlIDEyOCA9ICUjeAoAAAAAAAAA -AAAAAElJLjMgaW5ld18xZSBhZnRlciBsaW1pdCBjb21wdXRlIGl0ZW1wXzFlICV4LCBpbmV3XzFl -ICV4CgAAAAAAAABJSS4zLiBpdGVtcF8xZSAlI3ggaW5ld18xZSAlI3ggaW5ld18xZSAlZAoAAAAA -AABJSS40LiBzZXRfMWUgJSN4CgAAAAAAAAAAAAAAAAAAAE1DOiBjYWxpYnJhdGlvbiBmYWlsZWQg -Zm9yIGVycmF0YTI5IGRwMTggJXUKAAAAAElWLjEuIGRwMThbJXVdIHBoYXNlX3NlbCBiZWZvcmUg -JSN4IGFmdGVyICUjeCwgZ2F0ZV9kZWxheSAlI3gKAABNQyBlcnJhdGEyOSBpc3N1ZTogZHAxOCAl -dSBxdWFkICV1IGNhbm5vdCBiZSBkZWNyZWFzZWQKAAAAAAAAAAAATUMgZXJyYXRhMjkgaXNzdWU6 -IGRwMTggJXUgcXVhZCAldSBjYW5ub3QgYmUgZGVjcmVhc2VkCgAAAAAAAAAAAE1DIGVycmF0YTI5 -IGlzc3VlOiBkcDE4ICV1IHF1YWQgJXUgY2Fubm90IGJlIGRlY3JlYXNlZAoAAAAAAAAAAABNQyBl -cnJhdGEyOSBpc3N1ZTogZHAxOCAldSBxdWFkICV1IGNhbm5vdCBiZSBkZWNyZWFzZWQKAAAAAAAA -AAAAdGVtcDJfMWUrMHgxMCA9ICUjeAoAAAAAAAAAAAAAAABNQzogY2FsaWJyYXRpb24gZmFpbGVk -IGZvciBlcnJhdGEyMSBpdGVyYXRpb24gJXUKAAAAAAAAAAAAAAAAAAAATUMgZXJyYXRhIDIxOiBk -cDE4WyV1XSBwcjAgbjAyIGZhaWxlZCB0byBnZXQgYXZlcmFnZQoAAAAAAAAAAAAAAE1DIGVycmF0 -YSAyMTogZHAxOFsldV0gcHIwIG4xMyBmYWlsZWQgdG8gZ2V0IGF2ZXJhZ2UKAAAAAAAAAAAAAABN -QyBlcnJhdGEgMjE6IGRwMThbJXVdIHByMSBuMDIgZmFpbGVkIHRvIGdldCBhdmVyYWdlCgAAAAAA -AAAAAAAATUMgZXJyYXRhIDIxOiBkcDE4WyV1XSBwcjEgbjEzIGZhaWxlZCB0byBnZXQgYXZlcmFn -ZQoAAAAAAAAAAAAAAE1DIGluaXRpYWxpemF0aW9uIGZhaWxlZDogREZJIGluaXQgbm90IGdvaW5n -IHRvIDAKAAAAAAAAAAAAAAAAAABNQyBpbml0aWFsaXphdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5v -dCBjb21wbGV0aW5nCgAAAAAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24gZmFpbGVkOiBDYWxp -YnJhdGlvbiBkaWRuJ3QgY29tcGxldGUuCgAAAAAAAAAAAERQMTggJXUsIGJ5dGVfbGFuZSAldSwg -Yml0X3NlbGVjdCAldQoAAAAAAAAAAAAAAERQMTggJXUsIGJ5dGVfbGFuZSAldSwgYml0X3NlbGVj -dCAldQoAAAAAAAAAAAAAAE1DIGZhaWxlZCB0byBnZXQgVVBDVEwgcG93ZXIgdXAgZG9uZQoAAAAA -AAAAAAAAAE1DIGluaXRpYWxpemF0aW9uIGZhaWxlZDogRGlkbid0IGdldCBhbGwgRFAxOHMgbG9j -a2VkCgAAAAAAAAAAAABNQyBpbml0aWFsaXphdGlvbiBmYWlsZWQ6IERpZG4ndCBnZXQgYm90aCBB -RFJzIGxvY2tlZAoAAAAAAAAAAAAAQ3VycmVudCBTbGV3IHR4X3JvdyAlZDogdHhfY29sICVkLCB2 -YWwgJWQKAAAAAAAAQ3VycmVudCBTbGV3IGFkZHJfcm93ICVkOiBhZGRyX2NvbCAlZCwgdmFsICVk -CgAATUMgaW5pdGlhbGl6YXRpb24gZmFpbGVkOiBTTEVXX0RPTkVfU1RBVFVTIG5ldmVyIHRvZ2ds -ZWQAAAAAAAAAAGZscl9wZnZmX2ZzbVsldToldV06IHVua25vd24gc3RhdGUgJXUKAAAAAAAAAAAA -AGh3IHBmIGJpdG1hcCAweCUwMnggdmZpZCBiaXRtYXAgMHglMDh4OjB4JTA4eDoweCUwOHg6MHgl -MDh4CgAAAABhZnRlciB2ZmlkIGZpeHVwLCB2ZmlkIGJpdG1hcCAweCUwOHg6MHglMDh4OjB4JTA4 -eDoweCUwOHgKAAAAAAAATUNbJXVdOiBmYWlsZWQgdG8gc3dpdGNoIGNvbnRyb2xsZXIgdG8gQ0ZH -IHN0YXRlCgAAAAAAAAAAAAAAAAAAAE1DWyV1XTogZmFpbGVkIHRvIHN3aXRjaCBjb250cm9sbGVy -IHRvIElOSVRfTUVNIHN0YXRlCgAAAAAAAAAAAABNQ1sldV06IGZhaWxlZCB0byBzd2l0Y2ggY29u -dHJvbGxlciB0byBDRkcgc3RhdGUKAAAAAAAAAAAAAAAAAAAATUNbJXVdOiBwZXJpb2RpYyBjYWxp -YnJhdGlvbiBmYWlsZWQgd2l0aCBlcnJvciAldQoAAAAAAAAAAAAAAAAAAHRpbWVyIHF1ZXVlICV1 -IGxvc3QgYSB0aWNrISBuZXh0ICVwIGxhc3QgJXAgbnVtZSAldQoAAAAAAAAAAAAAAABmbHJfdGlt -ZXJfc3RhcnQ6IGZsb3djX2lkICV1ICVwIGJ1ZiAlcAoAAAAAAAAAAABNQUM6IFBMTHMgZGlkbid0 -IGxvY2sKAAAAAAAAAAAAAHBjaWU6IHJlYWQgZnJvbSBzZXJjZmcgcGNpZV9pcF91cl9tYXhmdW5j -IDB4JXggcGZiaXRtYXAgMHgleAoAAABwY2llOiBucGYgJXUgKHBmYml0bWFwIDB4JTAyeCkgbnZm -ICV1IChwZiAwLi43IDB4JTA4eCUwOHgpIHZmc3RyaWRlICV1CgAAAAAAAAAAAGZhaWxlZCB0byBm -aW5kIHRoZSAlYyVjIFZQRCBwYXJhbWV0ZXIKAAAAAAAAAAAAAGZhaWxlZCB0byBwYXJzZSB0aGUg -JWMlYyBWUEQgcGFyYW1ldGVyCgAAAAAAAAAAAGZhaWxlZCB0byBzdWNjZXNzZnVsbHkgZmluZCBD -aGVsc2lvIFZQRAoAAAAAAAAAAGxvZyBpbml0aWFsaXplZCBAIDB4JTA4eCBzaXplICV1ICgldSBl -bnRyaWVzKSBmd3JldiAweCUwOHggcGNpZV9mdyAweCUwOHgKAAAAAAAAYm9vdHN0cmFwIGZpcm13 -YXJlIHRvb2sgJXUgbXNlY3MgdG8gcnVuCgAAAAAAAAAAUEkgZXJyb3IgZmxvd2lkX2xlbjE2IDB4 -JXgsIGFwcF90YWcgMHgleCwgcmVmX3RhZyAweCV4LCBwaXNjICUwNHggJTA0eCAlMDR4ICUwNHgK -AAAAAAAAAAAAAAAAAAAAZmxvd2MgJXUgKFNHRSBlcWlkICV1KSAoRVRIQ1RSTCBxdWV1ZSkgZXhw -ZXJpZW5jZWQgYSBQQ0kgRE1BIFJFQUQgd29yayByZXF1ZXN0IGVycm9yIChpbmJvdW5kIHF1ZXVl -ICV1KQoAAAAAAAAAAGZsb3djICV1IChTR0UgZXFpZCAldSkgZXhwZXJpZW5jZWQgYW4gdW5leHBl -Y3RlZCBQQ0kgRE1BIFJFQUQgd29yayByZXF1ZXN0IGVycm9yIChpbmJvdW5kIHF1ZXVlICV1KQoA -AAAAAAAAAAAAAABmbG93YyAldSBleHBlcmllbmNlZCBhbiB1bmV4cGVjdGVkIFBDSSBETUEgUkVB -RCBlcnJvciAoaW5ib3VuZCBxdWV1ZSAldSkKAAAAAAAAAGdhdGhlcl90YXNrc19mb3JfdG1mOiBp -ZHggWzB4JXhdLCB0YXNrLWlkIFsweCV4XSwgY21kLWlkIFsweCV4XSwgYWN0aXZlIHRhc2tzIFsw -eCV4XS4gY29ubi1pZCBbMHgleF0sIGNtZCBjb25uLWlkIFsweCV4XSwgdGFzayBjb25uLWlkIFsw -eCV4XQoAAGdhdGhlcl90YXNrc19mb3JfdG1mOiBJbnZhbGlkIHR5cGUgWzB4JXhdLCBiYWlsaW5n -IG91dC4KAAAAAAAAAABnYXRoZXJfdGFza3NfZm9yX3RtZjogdGFzayBpZCBbMHgleF0sIHN0YXRl -IFsweCV4XSwgbGlkeCBbMHgleF0sIGNvb2tpZSBoaSBbMHglMDh4XSA6IGxvIFsweCUwOHhdCgAA -AAAAAAAAAAAAAAAAZ2F0aGVyX3Rhc2tzX2Zvcl90bWY6IHJjIFsweCV4XSwgWzB4JXhdIHRhc2sg -Z2F0aGVyZWQgZm9yIHRtZiB0eXBlIFsweCV4XSBwcm9jZXNzaW5nLgoAAAAAAAAAAAAAc2NzaV9k -YXRhX291dDogY29ubl9mYyBbMHgleF0sIHN0YXRlIFsweCV4XSwgc2Vzc19mYyBbMHgleF0gaW4g -cmVjb3ZlcnkuIFNraXBwaW5nIGlzdGFza19mYyBbMHgleF0gZnJvbSBUWC4KAAAAAHNlbmRfYWJv -cnRfcmVxOiBjc2tfZmMtPmZsb3djX3R5cGUgWzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsweCV4 -XSwgdGlkIFsweCV4XSwgdWxwdHhjaCBbJXVdLCBidWZmZXJlZCBbJXVdCgAAAABodyByZWdpc3Rl -ciBvcGVyYXRpb24gbm90IGNvbXBsZXRpbmcsIHJlZyAweCUwOHggbWFzayAweCUwOHggdmFsdWUg -MHglMDh4IChyZWcgMHglMDh4KQoAAAAAAAAAAABNRElPIENMNDU6IGZhaWxlZCB0byBzZXQgdXAg -TU1EIGFkZHIKAAAAAAAAAAAAAABNRElPOiBmYWlsZWQgdG8gcmVhZAoAAAAAAAAAAAAAAGh3X2Jj -bTg0ODU2X2NoZWNrIGVudHJ5CgAAAAAAAAAAaHdfYmNtODQ4NTZfY2hlY2sgbG9vcCAldSAoY2hl -Y2sgJSN4KQoAAAAAAAAAAAAAaHdfYmNtODQ4NTZfY2hlY2sgdXBfcnVubmluZyAobG9vcF9jbnQ9 -JXUpCgAAAAAAaHdfYmNtODQ4NTZfY2hlY2sgZmFpbGVkIChiYWQgQ1JDKQoAAAAAAAAAAAAAAAAA -UEhZIGZpcm13YXJlIGxvYWQgc3VjY2Vzc2Z1bCEgKHdvdy4uLikKAAAAAAAAAAAATURJTyBDTDQ1 -OiBmYWlsZWQgdG8gc2V0IHVwIE1NRCBhZGRyCgAAAAAAAAAAAAAATURJTzogZmFpbGVkIHRvIHdy -aXRlCgAAAAAAAAAAAABtaWlfYWR2X2ZjWyV1XTogcmNhcHMgMHgleAoAAAAAAG1paV9hZHZfc3Bl -ZWRbJXVdOiByY2FwcyAweCV4CgAAbmV0aWZfc2V0X21hYzogbDJkZXZfZmMtPmZsb3djX25ldF9s -MmRldl9tYnMgWzB4JXhdCgAAAAAAAAAAAAAAAHJlbW92aW5nIG1hYwoAAABub2RlLT5ncnAgWyUw -NHggJTA0eCAlMDR4ICUwNHhdLCBub2RlX2lkICV1LCByZWZfY250ICV1CgAAAAAAAAAAREFEIGZv -ciBhZGRyIFslMDR4ICUwNHggJTA0eCAlMDR4XQoAAAAAAAAAAAAAAAAAY3BsX3R4X3BrdDogdmxh -bmlkIFsweCV4XQoAAAAAAABjcGxfdHhfcGt0OiB2bGFuaWQgWzB4JXhdCgAAAAAAAGZsb3djX2lk -IFsldV0gbDJkZXZfZmMgWzB4JXhdIGFscmVhZHkgcmVjZWl2ZWQgUkEsIG5vdCBzZW5kaW5nIFJT -CgAAAAAAAAAAAAAAAAAAZmxvd2NpZCBbJXVdIGwyZGV2X2ZjIFsweCV4XSBObyBJUHY2IHJvdXRl -cgoAAAAAc2VuZF9jbG9zZV9yZXE6IGNza19mYy0+Zmxvd2NfdHlwZSBbMHgleF0sIGNza19mYy0+ -Zmxvd2NfaWQgWzB4JXhdLCBjc2tfZmMtPnRjYl9zdGF0ZSBbMHgleF0KAAAAc2VuZF9jbG9zZV9y -ZXE6IGNza19mYy0+Zmxvd2NfdHlwZSBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCB0 -aWQgWzB4JXhdLCB1bHB0eGNoIFsldV0sYnVmZmVyZWQgWyV1XQoAAAAAAG9mbGRfdGNwX2RvX2Fj -dGl2ZV9jbG9zZTogY3NrX2ZjIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19m -Yy0+dGNiX3N0YXRlIFsweCV4XQoAAAAAAG9mbGRfdGNwX2RvX2FjdGl2ZV9jbG9zZTogY3NrX2Zj -IFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+dGNiX3N0YXRlIFsweCV4 -XQoAAAAAAG9mbGRfdGNwX2Rpc2Nvbm5lY3Q6IHRjYl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBjc2tf -ZmMtPmZsb3djX2lkIFsweCV4XSwgY3NrLT50Y2Jfc3RhdGUgWzB4JXhdCgAAAGRlY29kZV9iYXNl -NjRfc3RyaW5nOiBkbGVuIFslZF0KAAAAAAAAAAAAAAAAAAAAAGRlY29kZV9oZXhfc3RyaW5nOiBk -bGVuIFslZF0KAAAAZm9pc2NzaV92YWxpZGF0ZV9sb2dpbl9zdGFnZTogLSAxCgAAAAAAAAAAAAAA -AAAAYXN5bmNfcGR1OiBsb2dvdXQgcmVxdWVzdGVkIGJsb2NraW5nIHNlc3Npb24KAAAAYXN5bmNf -cGR1OiBzZXNzL2Nvbm4gZHJvcCByZXF1ZXN0ZWQgYmxvY2tpbmcgc2Vzc2lvbgoAAAAAAAAAAAAA -AGNwbF90eF9wa3Q6IHZsYW5pZCBbMHgleF0KAAAAAAAAcmVpbml0IGxpbmstbG9jYWwgYWRkcmVz -cwoAAAAAAABuZXRfbDJkZXZfZmluZF9ieV9hZGRyOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhd -LCBsMmRjLT5scG9ydCBbJXVdLCBsMmRfZmMtPmZsb3djX2lkIFsweCV4XSwgbDJkYy0+aW40X2Rl -di5pbl9hZGRyLmFkZHIgWzB4JXhdLCBhZGRyIFsweCV4XQoAAABuZXRfbDJkZXZfbXR1X2NvbmZp -ZzogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgbXR1ICV1CgAAAAAAAAAAbmV0aWZfZG9fZGhj -cDogd3ItPnBhcmFtLnZsYW5pZCBbJXVdLCBsMmRldl9mYy0+Zmxvd2NfbmV0X2wyZGV2X3ZsYW5k -ZXYgWzB4JXhdCgBjcGxfdHhfcGt0OiB2bGFuaWQgWzB4JXhdCgAAAAAAAGVuY29kZSBoZXggc3Ry -aW5nOiBkbGVuIFslZF0KAAAAY2huZXRfZmluZF9sMnRfZW50cnk6IGRhZGRyIFslMDh4XSwgWzB4 -JTA4eF0sIGxvY2FsIG5ldHdvcmsgWyVkXQoAAAAAAAAAAAAAAAAAAABsMnRlbnQgWyUweF0sIGwy -dGVudC0+aWR4IFslZF0KAHRjcF9zZW5kX2FvcGVuX3JlcTogY3NrX2ZjLT5mbG93Y19pZCBbMHgl -eF0sIGNza19mYy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBidWZmZXJlZCBbJXVdLCByZXNfY250IFsw -eCV4XSwgaXFfaWR4IFsweCV4XQoAAAAAAAAAAAAAdGNwX3NlbmRfYW9wZW5fcmVxOiBjc2tfZmMt -PmZsb3djX2lkIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIG5vIHZhbGlkIGwy -dF9lbnR5LiBEZWxheWluZyBhbm90aGVyIHJldHJ5IGZvciAxIHNlY29uZHMuCgAAAAAAAAAAAAAA -AAAAYW9wZW5fcmVxOiBod19sZV9maWx0ZXJfY3R1cGxlIGZhaWxlZAoAAAAAAAAAAAAAb2ZsZF90 -Y3Bfc2VuZF9hb3Blbl9yZXE6IGNwbF9yZXEtPkZpbHRlcl9oaSBbMHglMHhdLCBjcGxfcmVxLT5G -aWx0ZXJfbG9fRkNvRU1hc2sgWzB4JTB4XSwgY3R1cGxlc1swXSBbMHgleF0sIGN0dXBsZXNbMV0g -WzB4JXhdCgBjb25uZWN0aW9uIG92ZXIgaXB2NiwgbDJkZXYgZmxvd2NfaWQgMHgleAoAAAAAAABj -c29ja19hbGxvYzogdHhfY2ggWzB4JXhdLCBscG9ydCBbMHgleF0sIGNvb2tpZSBbJTA4eF0KAAAA -AAAAAAAAY3NvY2tfYWxsb2M6IGF2YWlsYWJsZSBbJXVdLCBuY3NvY2sgWyV1XSwgcG9zOmF0aWQg -WzB4JXhdLCBjc2tfZmMgWzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwgc3BvcnQgWyV1 -XQoAAFdBVENIRE9HOiBObyB0ZW1wZXJhdHVyZSBzZW5zb3IgYXZhaWxhYmxlLgoAAAAAAHdhdGNo -ZG9nIGNtZCByZWZyZXNoIChhY3Rpb24gJXUpCgAAAAAAAAAAAAAAAAAAAFdBVENIRE9HOiBBY3Rp -dmF0aW5nCgAAAAAAAAAAAAAAV0FUQ0hET0cgLSBFbmFibGUgYWN0aW9uICV1IHRpbWUgJXUKAAAA -AAAAAAAAAAAAV0FUQ0hET0cgLSBEaXNhYmxlIGFjdGlvbiAldQoAAABXQVRDSERPRzogRGUtYWN0 -aXZhdGluZwoAAAAAAAAAAHBvcnRbJXVdIHNldCBQQVVTRSBQQVJBTVM6IHBwcGVuICV1IHR4cGUg -JSN4IHJ4cGUgJSN4CgAAAAAAAAAAAABtcHNfbGlua191cFsldV0gYWNhcHMgJSN4ICg4MDIuMyAl -I3gpICsgbHBhY2FwcyAlI3ggPT4gJSN4CgAAAAAAaXB2Nl9oYW5kbGVfbGlua19kb3duIGZsb3dj -X2lkIDB4JXgKAAAAAAAAAAAAAAAAaXB2Nl9oYW5kbGVfbGlua191cCBmbG93Y19pZCAweCV4CgAA -AAAAAAAAAAAAAAAAZm9pc2NzaSBjb25uX2ZjIFsweCV4XSwgZmxvd2Nfc2NoZWRjbCBbMHgleF0s -IGluZ19jaCBbMHgleF0sIGVncl9jaCBbMHgleF0KAAAAAABsMmRldl9ub3RpZnkgd2l0aCB1bmtu -b3duIGZsYWcgWzB4JXhdCgAAAAAAAAAAAABGQ29FIEZDQiBsaW5rZG93bjogaW9fcmVxIDB4JXgl -eCBpcWlkIDB4JXggZmxvd2lkIDB4JXggb3AgMHgleAoAY2FuY2VsIGZjYjoleCBzY2I6JXggc3Rh -dGU6JXgKAABSREVWIG1zZyBmbG93YzoleCBzdGF0ZSAweCV4IGV2ZW50IDB4JXgKAAAAAAAAAAB2 -bjJ2bjogcG9ydCAweCV4IGRpZDoweCV4JXgleCBVUAoAAAAAAAAAAAAAAAAAAAB2bjJ2bjogcG9y -dCAweCV4IGRpZDoweCV4JXgleCBET1dOCgAAAAAAAAAAAAAAAABmY19zZW5kX2FsbG9jX2NwbDog -ZmFpbGVkIHRvIHNldHVwIGZpbHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRl -X2N0dXBsZSAweCV4OiV4CgAAAABjb21wdXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8gc2V0dXAgZmls -dGVyIGN0dXBsZQoAAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSB2bGFuICV4IHZp -aWQgJXggcG9ydCAleCBtcHNfaWR4ICV4CgAAAAAAAAAAAEFwcGx5IEFQUDogcG9ydCAlZCBwcmlv -ciAlZCBzZWxlY3QgJWQgcHJvdG9jb2xJRCAweCUwNHgKAAAAAAAAAABjaF9jbF9yYXRlWyV1LyV1 -XTogY2FwcGVkIGRlZmljaXRfaW5jciBmcm9tIHJlcXVpcmVkICV1IHRvICV1OyByYXRlICV1IChl -ZmYgJXUpIGRlZmljaXRfbWF4ICV1CgBmY19zZW5kX2FsbG9jX2NwbDogZmFpbGVkIHRvIHNldHVw -IGZpbHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSAweCV4OiV4 -CgAAAABjb21wdXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAA -AAAAAAAAAAAAAAAARkNvRSBGQ0YgdGltZXI6IGZsb3djIHN0YXRlIDB4JXgsIHBvcnQgMHgleCAs -ZmNmIDB4JXgsIGZsb3djX2lkIDB4JXgKAAAAAAAAAAAAAAByaV93cl9pbml0WyV1XTogbXNzICV1 -IGlzIG5vdCA4LWJ5dGUgYWxpZ25lZAoAAABjb3JlX3Byb2dyYW1fdGNiOiB0aWQgJSN4IHRfc3Rh -dGUgJSN4IHJjdl9hZHYgMHglMDh4IHJjdl9zY2FsZSAlI3ggdHhfbWF4ICUjeCByY3Zfbnh0ICUj -eCBhdGlkICUjeAoAAAAAAAAAAAAAAAAACW9wdDAgJSN4JXggb3B0MiAlI3ggaXB2NiAlI3ggZmxh -Z3NfdGltZXIgMHglMDh4CgAAAAAAAAAAAAAAAAAAAG9mbGRfY29ubmVjdGlvbl93cjogY29ubmVj -dGlvbiB3aXRoIDUtdHVwbGUgbHAgMHglMDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4JTA4eCBwaXAg -MHglMDh4JTA4eCBmaWx0ZXIgMHglMDh4IGV4aXN0cyBAIExFIGluZGV4ICV1CgAAAAAAAAAAAAAA -AAAAAG9mbGRfY29ubmVjdGlvbl93cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUgbHAgMHglMDR4 -IGZwIDB4JTA0eCBsaXAgMHglMDh4IHBpcCAweCUwOHggZmlsdGVyIDB4JTA4eCBleGlzdHMgQCBM -RSBpbmRleCAldQoAAAAAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10 -dXBsZSBscCAweCUwNHggZnAgMHglMDR4IGxpcCAweCUwOHglMDh4IHBpcCAweCUwOHglMDh4IGZp -bHRlciAweCUwOHgKAAAAAG9mbGRfY29ubmVjdGlvbl93cjogY29ubmVjdGlvbiB3aXRoIDUtdHVw -bGUgbHAgMHglMDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4IHBpcCAweCUwOHggZmlsdGVyIDB4JTA4 -eAoAAAAAAAAAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxZXNpemUgJXUgdG9vIHNtYWxs -CgAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxaWQgJXUgdG9vIGxhcmdlIChtYXggJXUpCgAA -AAAAAAAAAAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBpcWlkICV1IG5vdCBhbGxvY2F0ZWQK -AAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDBpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAA -AAAAAAAAAAAAAElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwwaWQgJXUgbm90IGFsbG9jYXRlZAoA -AElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwxaWQgJXUgdG9vIGxhcmdlIChtYXggJXUpCgAAAAAA -AAAAAAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IG5vdCBhbGxvY2F0ZWQKAABJ -UUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IGlzIHZhbGlkIGJ1dCBub3QgZmwwaWQgJXUK -AAAAAAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSBpcyB2YWxpZCBidXQgaGVhZGVy -IHNwbGl0IGZlYXR1cmUgaXMgbm90IGVuYWJsZWQKAAAAAAAAAAAAAAAAAAAAaHdfdWxwdHhfd29y -a2Fyb3VuZF9wcjE2OTQ5X2VuYWJsZWRfcGY6IHBmICV1IGVuYWJsZWQgJXUKAAAAAAAAAGh3X3Vs -cHR4X3dvcmthcm91bmRfcHIxNjk0OV9lbmFibGVkX3ZmaWQ6IHZmaWQgJXUgZW5hYmxlZCAldQoA -AABFUSBwZm4gJXUgdmZuICV1OiBjcmVhdGluZyBFVEggZXFpZCAldSB3aXRoIHBlbmRpbmcgV1Io -cykgKG51bV9ieXRlcyAldSBhbmQgZmxhZ3MgMHglMDh4CgAAAAAAAABFUSBwZm4gJXUgdmZuICV1 -OiBjcmVhdGluZyBDVFJMIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1fYnl0ZXMgJXUg -YW5kIGZsYWdzIDB4JTA4eAoAAAAAAABFUSBwZm4gJXUgdmZuICV1OiBlcWlkICV1IHRvbyBsYXJn -ZSAobWF4ICV1KQoAAABFUSBwZm4gJXUgdmZuICV1OiBlcWlkICV1IG5vdCBhbGxvY2F0ZWQKAAAA -AAAAAABwb3J0X2JsaW5rX2xlZF9yZXN0b3JlCgAAAAAAAAAAAHBvcnRfYmxpbms6IGJsaW5rZHVy -PTB4JXggYmxpbmtfcmVmY250CgAAAAAAAAAAAHBvcnRfYmxpbms6IAlibGlua19yZWZjbnQ9MHgl -eAoAcG9ydF9ibGluazogCWJsaW5rX3JlZmNudD0weCV4CgBtaWlfYW5yZXN0YXJ0WyV1XTogYWNh -cHMgMHgleAoAAHBvcnRfY21kX2hhbmRsZXI6IHVua25vd24gdS5kY2IudHlwZSAweCV4CgAAAAAA -AHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IGwxY2ZnLCBpbnZhbGlkIHJlcXVlc3QsIHBjYXBzIDB4 -JXggYWNhcHMgMHgleCByY2FwcyAweCV4CgAAAAAAAAAAAAAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4 -JTAyeF06IGwxY2ZnLCBwY2FwcyAlI3ggYWNhcHMgJSN4IHJjYXBzICUjeCBtY2FwcyAlI3gKAAAA -AAAAAAAAcG9ydFsldToweCUwMng6MHglMDJ4XTogbDFjZmcsIG1kaSBpc3N1ZSBwY2FwcyAweCV4 -IGFjYXBzIDB4JXggcmNhcHMgMHgleAoAAAAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiBsMWNm -ZywgY2Fubm90IGZvcmNlIG5vL211bHRpcGxlIHNwZWVkKHMpLCBwY2FwcyAweCV4IGFjYXBzIDB4 -JXggcmNhcHMgMHgleAoAAAAAAAAAAAAAAAAAZXRoX2Zsb3djX2hhbmRsZXJbMHgleF06IGZsYWdz -IDB4JTA4eCBudW1fYnl0ZXMgJXUgc2NoZWRjbCAweCV4IC0+IDB4JXgKAAAAAAAAAABzY3NpX2Nt -ZDogcmVjZWl2ZWQgVE1GIG9wIFsweCV4XSBmdW5jIFsweCV4XSBvbiBjb25uIFsweCV4XSB0aHJv -dWdoIGNvbW1hbmQgcGF0aC4KAAAAAAAAAAAAAAAAAABzY3NpX2NtZDogY29ubl9mYyBbMHgleF0s -IHN0YXRlIFsweCV4XSwgc2Vzc19mYyBbMHgleF0gaW4gcmVjb3ZlcnkuIFNraXBwaW5nIGlzdGFz -a19mYyBbMHgleF0gZnJvbSBUWC4KAAAAAAAAAAAAc2NzaV9jbWQ6IGlTQ1NJIGNvbW1hbmQgc2Vx -dWVuY2Ugd2luZG93IGNsb3NlZC4gY29ubiBbMHgleF0sIG9wIFsweCV4XSwgIGNtZHNuIFsweCV4 -XSwgc2VudF9jbWRzbiBbMHgleF0sIG1heF9jbWRzbiBbMHgleF0sIGl0dCBbMHgleF0KAAAAAAAA -AAAAc2NzaV9yZWFkOiBjb25uX2ZjIFsweCV4XSwgc3RhdGUgWzB4JXhdLCBzZXNzX2ZjIFsweCV4 -XSBpbiByZWNvdmVyeS4gU2tpcHBpbmcgaXN0YXNrX2ZjIFsweCV4XSBmcm9tIFRYLgoAAAAAAAAA -AHNjc2lfcmVhZDogaVNDU0kgY29tbWFuZCBzZXF1ZW5jZSB3aW5kb3cgY2xvc2VkLiBjb25uIFsw -eCV4XSwgY21kc24gWzB4JXhdLCBzZW50X2NtZHNuIFsweCV4XSwgbWF4X2NtZHNuIFsweCV4XQoA -AAAAAAAAAAAAAAAAAAAAc2NzaV93cml0ZTogY29ubl9mYyBbMHgleF0sIHN0YXRlIFsweCV4XSwg -c2Vzc19mYyBbMHgleF0gaW4gcmVjb3ZlcnkuIFNraXBwaW5nIGlzdGFza19mYyBbMHgleF0gZnJv -bSBUWC4KAAAAAAAAAHNjc2lfd3JpdGU6IGlTQ1NJIGNvbW1hbmQgc2VxdWVuY2Ugd2luZG93IGNs -b3NlZC4gY29ubiBbMHgleF0sIGNtZHNuIFsweCV4XSwgc2VudF9jbWRzbiBbMHgleF0sIG1heF9j -bWRzbiBbMHgleF0sIGl0dCBbMHgleF0KAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX0xJ -TktVUAoAAAAAAAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1VQREFURV9EQ0JY -X1RMVgoAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1BFRVJfTk9UX0FEVkVSVElTRV9E -Q0JYCgAAAAAAAAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9VUERBVEVfT1BFUl9W -RVJTSU9OCgAAAAAAAAAAAAAAAAAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfUFJPQ0VT -U19QRUVSX1RMVgoAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfQUNLX1BFRVIKAAAAAAAA -AAAAAABkY2J4X2llZWVfdmFsaWRhdGVbJXVdIGVycm9yIChvdWkgJSN4IHN1YnR5cGUgJSN4IGxl -biAlI3gpCgAAAAAAZGNieF9jZWVfdmFsaWRhdGVbJXVdIGVycm9yCgAAAABjaG5ldF9sMnRfdXBk -YXRlOiBsMmRldl9mYyBbMHgleF0sIGwyZGV2X2ZjLT5mbG93Y19pZCBbJXVdIGwyZGV2X2ZjLT5m -bG93Y19mbGFncyBbMHgleF0sIGludGYgWzB4JXhdCgAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0 -ZTogbDJkZXZfZmMtPmZsb3djX2lkIFsldV0gYWxyZWFkeSBzY2hlZHVsZWQKAAAAAGNobmV0X2wy -dF91cGRhdGU6IGluIGRlbGF5ZWRfcHJvY2Vzc2luZywgbDJ0ZW50IFslMDh4XQoAAAAAAAAAAABE -SENQdjYgUkVQTFkgcmVjZWl2ZWQgc3RhdGUgJXUKAGRoY3AgcmVwbHkgcmVjZWl2ZWQgaW4gd3Jv -bmcgc3RhdGUgJWQKAAAAAAAAAAAAAHVua25vd24gc2VydmVyaWQuIElnbm9yaW5nIGRoY3AgcmVw -bHkKAAAAAAAAAAAAAHJlY2VpdmVkIHJlcGx5IHdpdGggZGlmZmVyZW50IGFkZHJlc3MuIGlnbm9y -aW5nIGRoY3AgcmVwbHkKAAAAAABESENQdjYgQURWRVJUSVNFIHJlY2VpdmVkCgAAAAAAAGRoY3Ag -YWR2ZXJ0aXNlIHJlY2VpdmVkIGluIHdyb25nIHN0YXRlICVkCgAAAAAAAGlnbm9yaW5nIHJjdmQg -YWR2ZXJ0aXNlIHByZWZlcmVuY2UgJXUKAAAAAAAAAAAAAHByZWZpeCBub2RlIDB4JXgsIHZhbGlk -X2xpZmV0aW1lICV1LCBjdXJyZW50X3RpbWUgJXUgZXhwaXJlZCwgZGVsZXRpbmcgaXQKAAAAAAAA -RGVsZXRlZCBwcmVmaXg6IDB4WyUwNHggJTA0eCAlMDR4ICUwNHhdCgAAAAAAAAAAU3RhcnQgREhD -UHY2IHRvIGdldCB0aGUgaXAgYWRkcmVzcwoAAAAAAAAAAAAAAAAATm8gZGhjcCwgZGhjcCBzdGF0 -ZSAlZCwgYWRkciBzdGF0ZSAlZAoAAAAAAAAAAAAAcGluZyByZXEgcGF5bG9hZCB0b28gbGFyZ2Ug -JXUuIElnbm9yaW5nIHJlcS4KAAAAUlIgcmN2ZAoAAAAAAAAAAGNobmV0X2lwdjZfcmRfaW5wdXQ6 -IEludmFsaWQgUmVkaXJlY3QKAAAAAAAAAAAAAGNobmV0X2lwdjZfbmFfaW5wdXQ6IEludmFsaWQg -TkEKAAAAAAAAAAAAAAAAAAAAAGlwdjYgTkEgcmN2ZAoAAABjaG5ldF9pcHY2X25hX2lucHV0OiBE -dXBsaWNhdGUgYWRkcmVzcyBkZXRlY3RlZCEKAAAAAAAAAAAAAAAAAAAATkEgaW4gcmVwb25zZSBv -ZiBOUwoAAAAAAAAAAAAAAABjaG5ldF9pcHY2X25zX2lucHV0OiBJbnZhbGlkIE5TCgAAAAAAAAAA -AAAAAAAAAABjaG5ldF9pcHY2X25zX2lucHV0OiBJbnZhbGlkIE5TIGlwdjZoLT5wbGVuICV1CgBp -cHY2IE5TIHJjdmQKAAAAY2huZXRfaXB2Nl9uc19pbnB1dDogRHVwbGljYXRlIGFkZHJlc3MgZGV0 -ZWN0ZWQKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2lwdjZfbnNfaW5wdXQ6IHNvbWVib2R5IHRyeWlu -ZyB0byB1c2Ugb3VyIGFkZHJlc3MKAAAAAAAAAABjaG5ldF9pcHY2X25zX2lucHV0OiByZXEgZm9y -IGFkZHIgcmVzb2x1dGlvbgoAAABIb3AgYnkgSG9wIG9wdGlvbgoAAAAAAAAAAAAAAAAAAHByb2Nl -c3NfZGhjcF9vcHRzOiByb290IHBhdGggbGVuIFslZF0gYnl0ZXMKAAAAAG5ldGlmX3Byb2Nlc3Nf -ZGhjcF9vcHRzOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBNU0dfVFlQRSBbJWRdLCBkaGN0 -eHQtPnN0YXRlIFslZF0KAAAAAAAAAAAAAGljbXBfcmVjdjogbDJkZXZfZmMtPmZsb3djX2lkIFsw -eCV4XSwgcGlkIFsweCV4XSwgaWNtcCB0eXBlIFsweCV4XQoAAAAAAAAAAAAAAAAAQUJUUyBBQ0Mg -YXdhaXRpbmcgUFJMSSBSc3A6IGZsb3djX2lkIDB4JXggb3hfaWQgMHgleCByeF9pZCAweCV4IGlx -aWQgMHgleAoAAAAAAABwb3J0IDB4JXgsIHN0YXRlIDB4JXgsIGNvbW1hbmQgZmFpbGVkIHJldHJp -ZXMgMHgleAoAAAAAAAAAAAAAAAAAYXJwX3JlY3Y6IGlwaWQgWzB4JXhdLCBpbl9hZGRyLmFkZHIg -WzB4JXhdLCBzaXAgWzB4JXhdLCByaXAgWzB4JXhdLCBhcnBfb3AgWzB4JXhdCgAAAAAAAAAAAAAA -AAAAY2huZXRfYXJwX3JlY3Y6IGlwIGNvbmZsaWN0IGRldGVjdGVkCgAAAAAAAAAAAAAAY2huZXRf -YXJwX3JlY3Y6IHBpZCBbJXVdLCB2bGFuIFsweCV4XSwgYXJwIG9wIFsweCV4XSwgc2lwIFsweCV4 -XSwgcmlwIFsweCV4XQoAAABjaG5ldF9pcHY2X3JlY3Y6IHZsYW4gZXh0cmFjdGVkLCB2bGFuaWQg -WyV1XSwgbDJkZXZfZmMtPmZsb3djX25ldF9sMmRldl92bGFuZGV2IFsweCV4XQoAAAAAAAAAAABJ -bnZhbGlkIGRhdGEgbGVuZ3RoIGRsZW4gJXUsIHBhY2tldCBpbmRpY2F0ZXMgJXUgYnl0ZXMKAAAA -AAAAAAAAVW5rbm93biBJUHY2IG54dCBwcm90b2NvbCAldQoAAABJbnZhbGlkIGRpZDp4JTJ4JTJ4 -JTJ4IHJjdmQgb24gcG9ydDolZC5Ecm9waW5nIGZyYW1lCgAAAAAAAAAAAAAAcmN0OngleCBzaWQ6 -eCUyeCUyeCUyeCByY3ZkIG9uIGZsb3djOiVkLkRyb3BpbmcgZnJhbWUKAAAAAAAAAAAAAGNzb2Nr -X2ZyZWU6IHNpemVvZihjc2tfZmMtPnUuY3NvY2spIFsldV0sIGJ5dGVzCgAAAAAAAAAAAAAAAAAA -AABHb3QgQ09OTl9FWElTVCBmb3IgeGlkOjB4JXgsIHRhZzoweCV4LCByZXRyeWluZy4KAAAAAAAA -AAAAAAAAAAAAY3NvY2tfcGVlcl9jbG9zZTogY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIHRjYl9m -Yy0+Zmxvd2NfaWQgWzB4JXhdLCBjc2tfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgdGNiX2ZjLT5m -bG93Y19zdGF0ZSBbMHgleF0KAAAAAABjc29ja19wZWVyX2Nsb3NlOiBjc2tfZmMtPmZsb3djX2lk -IFsweCV4XSwgY3NrX2ZjLT5mbG93Y19zdGF0ZSAgWzB4JXhdCgAAAAAAAAAAAHRjcF9jbHNfYWJy -dF9ycGw6IHRjYiB0aWQgWzB4JTA2eF0sIGZsb3djX3R5cGUgWzB4JXhdLCBjcGxvcCBbMHgleF0g -CgAAAAAAAAAAAAAAY2hfcmF0ZVsldV06IGNhcHBlZCB0aWNrIGZyb20gcmVxdWlyZWQgJXUgdG8g -c3VwcG9ydGVkICV1OyByYXRlICV1IChlZmYgJXUpIGRlZmljaXRfaW5jciAldSB0aWNrICV1CgAA -AAAAAAAAAAAAAHBrdHNjaGVkX2NoX3JsWyV1XTogY2hhbm5lbCBybCBub3QgYXZhaWxhYmxlIGlu -IGNvbmp1bmN0aW9uIHdpdGggZmxvdyBzaGFwaW5nCgAAcGt0c2NoZWRfY2hfcmxbJXVdOiByYXRl -ICV1IG1heCAldQoAAAAAAAAAAAAAAAAAcGt0c2NoZWRfY2xfd3JyWyV1OiV1XTogd2VpZ2h0ICV1 -CgAAAAAAAAAAAAAAAAAAZXFfcGFyYW1zWzB4JXg6MHgleF06IGRtYXEgMHgleCByZWFkICV1IHBm -ICV1IGVxaWRfYXBpICV1IHJldCAlZAoAAAAAAAAAAAAAAAAAAABNQyBDTEsgc2V0dGluZyBmYWls -ZWQ6IFBMTF9NX0xPQ0sgbmV2ZXIgdG9nZ2xlZAoAAAAAAAAAAAAAAAAAAAAAd2FpdF9mb3JfY2Fs -aWJfZG9uZTogcmV0ICVkIGluICV1IGF0dGVtcHRzCgAAAAAAaHdfbWFfYWRkcl90b19tZW1fdHlw -ZV9vZmY6IE1BIGFkZHJlc3MgMHglMDh4IGlzIG5vdCBtYXBwZWQKAAAAAGh3X21hX2FkZHJfdG9f -bWVtX3R5cGVfb2ZmOiBNQSBhZGRyZXNzIDB4JTA4eCBtYXBzIHRvIHR5cGUgJXUgb2Zmc2V0IDB4 -JXgKAAAAAAAAbWVtX21hbGxvY190ZW1wOiBmYWlsZWQgdG8gYWxsb2NhdGUgJXUgYnl0ZXMsIHJl -dHVybmluZyBOVUxMCgAAAG1lbV9tYWxsb2M6IGZhaWxlZCB0byBhbGxvY2F0ZSAldSBieXRlcywg -cmV0dXJuaW5nIE5VTEwKAAAAAAAAAABsZSBjb25maWd1cmF0aW9uOiBoYXNoIG1vZGUgcmVxdWly -ZXMgYXQgbGVhc3QgMTYgZW50cmllcywgbmhhc2ggJXUKAAAAAAAAAAAAAAAAAGxlIGNvbmZpZ3Vy -YXRpb246IGhhc2ggbW9kZSByZXF1aXJlcyBhdCBlbnRyaWVzIHRvIGJlIGEgcG93ZXIgb2YgMiwg -bmhhc2ggJXUKAAAAbGUgY29uZmlndXJhdGlvbjogcmVxdWVzdGVkICV1IHRjYW0gZW50cmllcyBi -dXQgb25seSAldSBhdmFpbGFibGUgKG5yb3V0ZSAldSBuY2xpcCAldSBuZmlsdGVyICV1IG5zZXJ2 -ZXIgJXUKAAAAAGxlIGNvbmZpZ3VyYXRpb246IHRjYW0gcmVnaW9ucyBtdXN0IGhhdmUgbXVsdGlw -bGUgb2YgMzIgZW50cmllcywgbnJvdXRlICV1IG5jbGlwICV1IG5maWx0ZXIgJXUgbnNlcnZlciAl -dQoAAAAAAABod190cF90Y3BfdHVuaW5nczogdHVuaW5nIGZvciBjbHVzdGVyIGVudmlyb25tZW50 -CgAAAAAAAAAAAAAAAAAAaHdfdHBfdGNwX3R1bmluZ3M6IHR1bmluZyBmb3IgTEFOIGVudmlyb25t -ZW50CgAAaHdfdHBfdGNwX3R1bmluZ3M6IHR1bmluZyBmb3IgV0FOIGVudmlyb25tZW50CgAAaHdf -dHBfdGNwX3R1bmluZ3M6IG1hbnVhbCB0dW5pbmcKAAAAAAAAAAAAAAAAAAAAX2h3X2NpbV9mbGFz -aF9tZW1jcHk6IG1lbWNweVggc3RhcnQKAAAAAAAAAAAAAAAAX2h3X2NpbV9mbGFzaF9tZW1jcHk6 -IGRzdCAweCUwOCBvZmZzZXQgMHglMDh4IHNpemUgJXUsIHdpZHRoIG9mICV1IGlzIG5vdCBzdXBw -b3J0ZWQKAAAAAAAAAAAAAAAAX2h3X2NpbV9mbGFzaF9tZW1jcHk6IG1lbWNweVggZW5kCgAAAAAA -AAAAAAAAAAAAY29uZmlndXJhdGlvbiBmaWxlIHBhcnNlciBlbmNvdW50ZXJlZCBlcnJvciBAIGxp -bmUgJXU6CgAAAAAAAAAAAEhPU1QgUEFHRV9TSVpFIFsweCUwbHhdIHRvbyBzbWFsbCwgbWluIFsw -eCUwbHhdIHJlcXVpcmVkCgAAAAAAAABwYWdlIHNpemUgWyVsdV0gbWlzbWF0Y2gKAAAAAAAAAFBB -R0Ugc2l6ZSAlbHUgdW5zdXBwb3J0ZWQsIGRkcCBkaXNhYmxlZAoAAAAAAAAAAEhvc3QgcGFnZV9z -aXplICVsdSwgZGRwX2lkeCAldQoARkNvRSBERFAgaW5pdDogZmNvZSBsbGltaXQgMHgleCwgZmNv -ZSB1bGltaXQgMHgleCBnYmwgbGxpbWl0IDB4JXggZ2JsIHVsaW1pdCAweCV4IHBjYnN6ICV4CgAA -AAAARkNvRSBERFAgaW5pdDogZmNvZSBwcG9kIG9mZiAweCV4LCBmY29lIHN0IHBwb2QgYWRkciAw -eCV4IGZjb2UgbnVtIHBwb2RzIDB4JXgKAABmY29lIHhjaGcgbWdyIGluaXQ6IE51bWJlciBvZiBE -RFAgZXhjaGFuZ2VzIGZvciBGQ29FIGlzICV4CgAAAAAAZmNvZSB4Y2hnIG1nciBpbml0OiBOdW1i -ZXIgb2YgdHVubmVsIGV4Y2hzIGZvciBGQ29FIGlzICV4CgAAAAAAAGZjb2VfbDJ0X2luaXQ6IE5v -IHVscHR4IGNyZWRpdCBjaDpbJXVdCgAAAAAAAAAAAGZjb2VfbDJ0X2luaXQ6IGNoOlsldV0gbDJ0 -X2lkeCBbJXVdCgAAAAAAAAAAAAAAAG5vIGwydCBlbnRyaWVzIGNvbmZpZ3VyZWQ7IGZvcmNpbmcg -JXUgZW50cmllcywgc3RhcnRpbmcgYXQgJXUKAABkY2J4IHVwZGF0ZVsldV0gc2VudCB0byBkcml2 -ZXIgKHR5cGUgJSN4IHN1YnR5cGUgJSN4IGZsb3djaWQgJXUpCgAAAAAAAAAAAAAAAAAAAGRjYnhf -cnVuX3ZlcnNpb25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JVTl9JRUVFCgAAAAAAAAAAAAAAAAAA -AABkY2J4X3J1bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fQ0VFCgBkY2J4X3J1 -bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fTk9ORQoAAAAAAAAAAAAAAAAAAAAA -TUFDIGZhaWxlZCB0byByZXN5bmMgdHgKAAAAAAAAAABwb3J0WyV1XSBsaW5rIHVwICgldSkgKHNw -ZWVkICUjeCBhY2FwcyAlI3ggbHBjYXBzICUjeCkKAAAAAAAAAAAAcG9ydF9oc3Nfc2lnZGV0WyV1 -XTogaHNzX3NpZ2RldCBjaGFuZ2VkIHRvIDB4JXgKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXVdIGlu -aXRpYWxpemluZyBLUgoAAAAAAAAAZGlzYWJsaW5nIHR4ICUjeCByeCAlI3gKAAAAAAAAAABDYWxj -dWxhdGlvbiBvdXQgb2YgYm91bmRzIGZ1cmluZyBpbml0OiAlI3ggJSN4ICUjeAoAAAAAAAAAAAAA -AAAAX2h3X3RwX3BnbW5ndDogdHhfcGFnZV9tYXggJXUgcnhfcGFnZV9tYXggJXUgcHN0cnVjdHMg -JXUgc2l6ZSAldQoAAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX290aGVyc190b3RhbDogZGRwICV1 -IGRkcF9pc2NzaSAldSBzdGFnICV1IHBibCAldSBycSAldSBycXVkcCAldSAtPiAldQoAAAAAAAAA -AAAAAAAAAABfbXBhcnRpdGlvbl9iYW5rc19tY1g6IG5iYW5rc19wbXR4ICV1ICgldU1CKSBuYmFu -a3NfcG1yeCAldSAoJXVNQikgbmJhbmtzX290aGVycyAldSAoJXVNQikgbmJhbmtzX2Z3ICV1ICgl -dU1CKQoAX21wYXJ0aXRpb25fYmFua3NfbWMxOiBuYmFua3NfcG10eCAldSAoJXVNQikgbmJhbmtz -X290aGVycyAldSAoJXVNQikgbmJhbmtzX2Z3ICV1ICgldU1CKQoAAAAAAAAAX21wYXJ0aXRpb25f -YmFua3NfbWMwOiBuYmFua3NfcG1yeCAldSAoJXVNQikgbmJhbmtzX290aGVycyAldSAoJXVNQikK -AAAAAAAAAAAAAABtZW1fbWFsbG9jX2ludGVybmFsOiBmYWlsZWQgdG8gYWxsb2NhdGUgJXUgYnl0 -ZXMsIHJldHVybmluZyBOVUxMCgAAAAAAAAAAAAAAAAAAAGh3X2VkY19iaXN0WyV1XTogYmlzdF9j -bWRbMHglMDh4XSBhZGRyIDB4JXggbGVuIDB4JXgKAAAAAAAAAAAAAABod19lZGNfYmlzdFsldV06 -IGRvbmUsIGVuY291bnRlcmVkICV1IGVycm9ycyBvbiBmaXJzdCBhbmQgJXUgZXJyb3JzIG9uIHNl -Y29uZCBhdHRlbXB0ICgldWdicHMpCgBtZW1faW5pdF9jYWNoZXM6IGNhY2hlX3NpemUgJXUgZmxv -d2NfYnVmX3RjYl9jYWNoZV9zaXplICV1IGJ1ZmxsNjRfY2FjaGVfc2l6ZSAldQoAAAAAAAAAAAAA -AAAAAABtcGFydGl0aW9uX3BtdHg6IG0gMHglMDh4IHNpemUgJXUKAAAAAAAAAAAAAAAAAABtcGFy -dGl0aW9uX3Btcng6IG0gMHglMDh4IHNpemUgJXUKAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX2Vk -YyAobm8gZXh0bWVtKTogbSAweCUwOHggc2l6ZSAldQoAAABtcGFydGl0aW9uX2VkY19lc3RpbWF0 -ZTogaHcgbW9kdWxlcyByZXF1aXJlICVkIGJ5dGVzIGluIEVEQwoAAAAAVGVtcGVyYXR1cmUvVm9s -dGFnZSBTZW5zb3I6IENvcmUgY2xvY2sgJWQgPiA1MDA7IHVzaW5nIDUwMCB0byBzdGF5IGluIGNv -bXBsaWFuY2Ugd2l0aCBoYXJkd2FyZS4KAAAAAAAAAAAAAAAAAAAAAGNobmV0X2J5ZTpsMmRldl9m -Yy0+Zmxvd2NfaWQgWzB4JXhdLCBsMmRldl9mYy0+Zmxvd2NfcGNpZV9wZm4gWzB4JXhdLCBsMmRl -dl9mYy0+Zmxvd2NfcGNpZV92Zm4gWzB4JXhdLCBwb3J0IFsweCV4XQoAAAAAAAAAAAAAAAAAY2hu -ZXRfYnllOnZsYW5kZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgdmxhbmRldl9mYy0+Zmxvd2NfcGNp -ZV9wZm4gWzB4JXhdLCB2bGFuZGV2X2ZjLT5mbG93Y19wY2llX3ZmbiBbMHgleF0sIHBvcnQgWzB4 -JXhdCgAAAAAAAABod19tYWNfYWVjX2NvbXBsZXRlWyV1XSBvbiBsYW5lcyAlI3ggKHNpZ2RldCAl -I3gpCgAAAAAAAAAAAAAAAAAAYWVjX2ZzbVsldV0gOiBzdGF0ZSBTVEFSVCAoc2lnZGV0ICUjeCkK -AAAAAAAAAAAAYWVjX2ZzbVsldV0gOiB0cmFuc2l0aW9uaW5nIHRvIFRSQUlOSU5HCgAAAAAAAAAA -YWVjX2ZzbVsldV0gOiBUUkFJTklOR19DT01QTEVURQoAAAAAAAAAAAAAAAAAAAAAYWVjX2ZzbVsl -dV0gOiBET05FCgAAAAAAAAAAAAAAAABhZWNfZnNtWyV1XSA6IHRpbWVkIG91dCB0cmFpbmluZwoA -AAAAAAAAAAAAAAAAAABiZWFuX2ZzbVsldV0gOiBzdGF0ZSBTVEFSVCAoY291bnQgPSAldSkKAAAA -AAAAAABiZWFuX2ZzbVsldV0gOiBlbnRlcmluZyBzdGF0ZSBXQUlUX1NJR0RFVAoAAAAAAABiZWFu -X2ZzbVsldV0gOiBlbnRlcmluZyBzdGF0ZSBOWFBfSEFORExFCgAAAAAAAABiZWFuX2ZzbVsldV0g -OiBlbnRlcmluZyBzdGF0ZSBXQUlUX0NPTVBMRVRFCgAAAABiZWFuX2ZzbVsldV0gOiBzdGF0ZSBE -T05FCgAAAAAAAGJlYW5fZnNtWyV1XSA6IHN0YXRlIFJFU1RBUlQKAAAAYmVhbl9mc21bJXVdIFRJ -TUVPVVQ7IHN0YXRlICV1IGV0aF9zdGF0dXMgJSN4IGJlYW5fc3RhdHVzICUjeCBoc3Mgc2lnZGV0 -ICUjeCByZXRyeV9jbnQgJXUKAAAAAAAAcG9ydCAldSBuZWdvdGlhdGVkIHVuc3VwcG9ydGVkIHNw -ZWVkICUjeAoAAAAAAAAAYmVhbi9hZWMgY29tcGxldGUgKHJldHJ5OiAldSkKAABwb3J0WyV1XSBy -ZXNldHRpbmcgS1IKAAAAAAAAAAAAAFJhbmdlIGNhbGM6IEF2ZXJhZ2VkICUjeCBidXQgaWdub3Jl -ZCB2YWx1ZSAlI3ggKGl0ZXJhdGlvbiAldSkKAABNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IERGSSBp -bml0IG5vdCBnb2luZyB0byAwCgBNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5vdCBj -b21wbGV0aW5nCgBNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IENhbGlicmF0aW9uIGRpZG4ndCBjb21w -bGV0ZS4KAAAAAAAAAAAAAAAATUMgY29tbWFuZCBmYWlsZWQgdG8gY29tcGxldGUob3Bjb2RlICUj -eCBjYWRkciAlI3ggYmFkZHIgJSN4IGRlbGF5ICVkKQoAAAAAAAAAAABwZm5fYml0bWFwIDB4JXgK -AAAAAAAAAAAAAAAAAAAAAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29k -ZSAweCV4ID4gTEFTVEMyRSAweCV4CgBtYWlsYm94IGNtZCBub3QgeWV0IHN1cHBvcnRlZDogcGZu -IDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCV4CgAAYmFkIG1haWxib3ggY21kOiBwZm4gMHgleCB2 -Zm4gMHgleDsgb3Bjb2RlIDB4JXggaXMgdmFsaWQgcG9zdCBkZXZpY2UgaW5pdCBvbmx5CgBiYWQg -bWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyBvcGNvZGUgMHglMDJ4IHJhbWFzayAweCV4 -IGNtZCByYW1hc2sgMHgleAoAAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9w -Y29kZSAweCUwMnggbGVuMTYgMHgleCB2ZXJzdXMgZXhwZWN0ZWQgbGVuMTYgMHgleAoAAAAAAAAA -AGluc3VmZmljaWVudCBjYXBzIHRvIHByb2Nlc3MgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAw -eCV4OyByX2NhcHMgMHgleCB3eF9jYXBzIDB4JXggcmVxdWlyZWQgcl9jYXBzIDB4JXggd19jYXBz -IDB4JXgKAAAAAAAAAAAAaW5zdWZmaWNpZW50IGNhcHMgdG8gcHJvY2VzcyBtYWlsYm94IGNtZDog -cGZuIDB4JXggdmZuIDB4JXg7IHJfY2FwcyAweCV4IHd4X2NhcHMgMHgleCByZXF1aXJlZCByX2Nh -cHMgMHgleCB3X2NhcHMgMHgleAoAAAAAAAAAAABod19wb3dlcl9wcmVwOiBWREQ9Tk9ORSBidXQg -VkNTPSVkCgAAAAAAAAAAAAAAAABod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBleHRlcm5hbCBh -ZGp1c3RhYmxlIHBvd2VyIHJlZ3VsYXRvcnMgVkREPSVkLCBWQ1M9JWQKAGh3X3Bvd2VyX3ByZXA6 -IHVuc3VwcG9ydGVkIFZERD0lZAoAAAAAAAAAAAAAAAAAAGh3X3Bvd2VyX3ByZXA6IHVuc3VwcG9y -dGVkIFZDUz0lZAoAAAAAAAAAAAAAAAAAAGh3X3Bvd2VyX3ByZXA6IGkyYyB3cml0ZSBlcnJvciwg -VkREPSVkLHJldD0lZAoAAGh3X3Bvd2VyX3ByZXA6IHVuc3VwcG9ydGVkIFZERD0lZAoAAAAAAAAA -AAAAAAAAAGh3X3Bvd2VyX3ByZXA6IGkyYyB3cml0ZSBlcnJvciwgVkNTPSVkLHJldD0lZAoAAGh3 -X3Bvd2VyX3ByZXA6IHVuc3VwcG9ydGVkIFZDUz0lZAoAAAAAAAAAAAAAAAAAAFZQRCByZWdpb24g -aXMgdG9vIHNtYWxsIChTRVJDRkdfU1JfUEZOVlBEU0laRSAweCV4KQoAAAAAAAAAAAAAAABjZjog -ZmFpbGVkIHRvIGFsbG9jYXRlZCBtZW1vcnkgZm9yIGNvbmZpZ3VyYXRpb24gZmlsZSwgcmV0ICVk -CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +JXggCgAAAAAAAAAAAAAAAHNjc2lfYWJvcnQ6IEVudGVyaW5nIEFib3J0X3Rhc2ssIGJ1ZmZlcmVk +IFsldV0KAHNjc2lfYWJvcnQ6IHJjIFsweCV4XSByZWYgdGFzayBub3Qgb3V0c3RhbmRpbmcKAHNj +c2lfYWJvcnQ6IGlkYXRhLT5vcCBbMHgleF0sIGZsYWdzIFsweCV4XSwgZnVuYyBbMHgleF0sIGx1 +bl9pZHggWzB4JXhdCgAAAAAAAAAAc2NzaV9hYm9ydDogd3ItPmlxaWQgWzB4JXhdLCBpc3Rhc2tf +ZmMtPmZsb3djX3NnZV9pcWlkIFsweCV4XSwgaXN0YXNrX2ZjIHRhc2sgZmxhZ3MgWzB4JXhdCgAA +AAAAc2NzaV9hYm9ydDogY29ubiBbMHgleF0sIGNtZHNuIFsweCV4XSwgc2VudF9jbWRzbiBbMHgl +eF0sIG1heF9jbWRzbiBbMHgleF0sIGl0dCBbMHgleF0KAAAAAAAAAAAAYWJvcnQvY2xvc2UgV1Ig +d2l0aCBjb29raWUgMHglbHggd2FzIGlzc3VlZCBvbiBzc24gMHgleCBpbiB3cm9uZyBzdGF0ZSAw +eCV4CgAAAABhYm9ydCBXUiBvbiBzc24gMHgleCBkaWQgbm90IGZpbmQgV1Igd2l0aCBjb29raWUg +MHgleCV4CgAAAAAAAAAAY2xvc2UgV1Igd2l0aCBjb29raWUgMHglbHggb24gc3NuIDB4JXg7ZGlk +IG5vdCBmaW5kIFdSIHdpdGggY29va2llIDB4JWx4CgAAAAAAAABhYm9ydCBXUiBvbiBzc24gMHgl +eCB3YXMgaXNzdWVkIG9uIHhjaGcgMHgleCB3aXRoIHJ4X2lkIDB4JXggaW4gd3Jvbmcgc3RhdGUg +MHgleAoAAAAAAAAAAAAAAAAAAABzY3NpX2x1cjogRW50ZXJpbmcgTFVSIGhhbmRsZXIsIGJ1ZmZl +cmVkIFsldV0KAABzY3NpX2x1cjogaWRhdGEtPm9wIFsweCV4XSwgZmxhZ3MgWzB4JXhdLCBmdW5j +IFsweCV4XSwgbHVuX2lkeCBbMHgleF0KAAAAAAAAAAAAAHNjc2lfbHVyOiB3ci0+aXFpZCBbMHgl +eF0sIGlzdGFza19mYy0+Zmxvd2Nfc2dlX2lxaWQgWzB4JXhdLCBpc3Rhc2tfZmMgdGFzayBmbGFn +cyBbMHgleF0KAAAAAAAAAHNjc2lfbHVyOiBjb25uIFsweCV4XSwgY21kc24gWzB4JXhdLCBzZW50 +X2NtZHNuIFsweCV4XSwgbWF4X2NtZHNuIFsweCV4XSwgaXR0IFsweCV4XQoAAAAAAAAAAAAAAGRj +YnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9MSU5LVVAKAGRjYnhfY2VlX2Zl +YV9zbVsldV0gRmVhdHVyZVsldV0gU0VUX0xPQ0FMX1BBUkFNRVRFUlMKAAAAAAAAAAAAAABkY2J4 +X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfTk9fQURWRVJUSVNFCgAAAAAAAAAA +AAAAZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX1BFRVJfTk9UX0FEVkVS +VElTRV9EQ0JYCgAAAAAAAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVd +IEZFQVRVUkVfUEVFUl9OT1RfQURWRVJUSVNFX0ZFQVRVUkUKAAAAAAAAAAAAAAAAAGRjYnhfY2Vl +X2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VUERBVEVfT1BFUl9WRVJTSU9OCgAAAABk +Y2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfUEVFUl9VUERBVEVfT1BFUl9W +RVJTSU9OCgAAAAAAAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9zbVsldV0gRmVhdHVyZVsldV0gRkVB +VFVSRV9HRVRfUEVFUl9DRkcKAAAAAAAAAAAAAABkY2J4X2NlZV9mZWFfc21bJXVdIEZlYXR1cmVb +JXVdIEZFQVRVUkVfQ0ZHX05PVF9DT01QQVRJQkxFCgAAAAAAZGNieF9jZWVfZmVhX3NtWyV1XSBG +ZWF0dXJlWyV1XSBGRUFUVVJFX1VTRV9MT0NBTF9DRkcKAAAAAAAAAAAAAGRjYnhfY2VlX2ZlYV9z +bVsldV0gRmVhdHVyZVsldV0gRkVBVFVSRV9VU0VfUEVFUl9DRkcKAAAAAAAAAAAAAABkY2J4X2Nl +ZV9mZWFfc21bJXVdIEZlYXR1cmVbJXVdIEZFQVRVUkVfRkVBVFVSRV9ESVNBQkxFRAoAAAAAAAAA +ZGNieF9jZWVfZmVhX3NtWyV1XSBGZWF0dXJlWyV1XSBGRUFUVVJFX0VSUk9SX0NIQU5HRQoAAAAA +AAAAAAAAAEZlYXR1cmUgJXUgc3luYydkPSV1IChlcnJvciAldSkKAAAAAAAAAAAAAAAAAAAAAGlw +djZfYWRkX3ByZWZpeF9pbl9saXN0OiBub2RlIGZvdW5kIDB4JXgKAAAAAAAAAGlwdjZfYWRkX3By +ZWZpeF9pbl9saXN0LCBub2RlIG5vdCBmb3VuZAoAAAAAAAAAAGNobmV0X2FycF91cGRhdGVfY2Fj +aGU6IGFycCBpcDQgZW50cnkgZm91bmQgCgAAAGNobmV0X2FycF91cGRhdGVfY2FjaGU6IGFycCBp +cDYgZW50cnkgZm91bmQgCgAAAGNobmV0X2FycF91cGRhdGVfY2FjaGU6IGJvdGggaXA0IGFuZCBp +cDYgYWRkciBjYW5ub3QgYmUgbnVsbAoAAABjaG5ldF9sMnRfdXBkYXRlOiBsMnRfdXBkYXRlIHJl +cXVlc3Qgc2VudCBsMnRlbnQgWyUwOHhdLCBsMnRlbnQtPmlkeCBbJWRdLCBsMnRlbnQtPnZsYW4g +WyVkXQoAAABjaG5ldF9pcHY2X3JhX2lucHV0OiBJbnZhbGlkIFJBCgAAAAAAAAAAAAAAAAAAAABp +cHY2IFJBIHJjdmQKAAAAcm91dGVyIG5vdCBwcmVzZW50IGluIG91ciBsaXN0LiBhZGRpbmcgaXQK +AAAAAAAASW52YWxpZCBvcHRpb24gbGVuZ3RoICV1IGluIFNMTEEgb3B0aW9uCgAAAAAAAAAAR09U +IFNMTEEgb3B0aW9uIGluIFJBLCBsZW4gJXUKAABJbnZhbGlkIG9wdGlvbiBsZW5ndGggJXUgaW4g +cHJlZml4IG9wdGlvbgoAAAAAAABJbnZhbGlkIG9wdGlvbiBsZW5ndGggJXUgaW4gbXR1IG9wdGlv +bgoAAAAAAAAAAABJbnZhbGlkIHBhY2tldCB3aXRoICV1IGV4dHJhIGJ5dGVzCgAAAAAAAAAAAAAA +AABtbGQ2IHF1ZXJ5IHJjdmQKAAAAAAAAAAAAAAAAAAAAAGNobmV0X2lwdjZfbWxkNl9xdWVyeV9p +bnB1dDogSW52YWxpZCBNTEQgcXVlcnkKAFVuc3VwcG9ydGVkIHF1ZXJ5IHZlcnNpb24uIG9ubHkg +bWxkdjIgcXVlcnkgc3VwcG9ydGVkCgAAAAAAAAAAAABxdWVyeSByZXNwb25zZSBkZWxheSAldSAo +aW4gMTBtcyB1bml0KSAKAAAAAAAAAABhbHJlYWR5IGEgZ2VuZXJhbCBxdWVyeSBwZW5kaW5nIGlu +ICV1ICgxMG1zKQoAAABEZWJ1ZyB0aGUgY29kZS4gZ3JwX25vZGUgbXVzdCBiZSBwcmVzZW50CgAA +AAAAAABhbHJlYWR5IGEgbXVsdGljYXN0IHF1ZXJ5IHBlbmRpbmcgaW4gJXUgKDEwbXMpCgBpcHY2 +IGVjaG8gcmVxIHJjdmQKAAAAAAAAAAAAAAAAAERIQ1B2NiBwYWNrZXQgdHlwZSAldSwgb3B0c2xl +biAldSByZWNlaXZlZAoAAAAAAEludmFsaWQgZGhjcCBzdGF0ZSAlZAoAAAAAAAAAAAAASWdub3Jl +IERIQ1B2NiBtc2cgeGlkICV4LCAgZGg2Y3R4dC0+eGlkICV4CgAAAAAARXJyb3IgaW4gREhDUHY2 +IG9wdGlvbnMgcGFyc2luZy4gSWdub3JpbmcgbXNnLCBpICVkLCBvcHRzbGVuICVkCgAAAAAAAAAA +AAAAAAAAAABESENQIGZhaWxlZCwgc3RhdHVzY29kZSAlZC4gSWdub3JpbmcgYWR2ZXJ0aXNlCgBp +Y21wNiBjaGVja3N1bSB2YWxpZGF0aW9uIGZhaWxlZCwgb3IgZXJyIHJjdmRpZ25vcmluZyBpY21w +NiBtc2cgJXUsIGRsZW4gJXUKAAAAAG5ldGlmX3Byb2Nlc3NfZGhjcDogbDJkZXZfZmMtPmZsb3dj +X2lkIFsweCV4XSwgcHJvY2Vzc2luZywgb3B0X2xlbiAldQoAAAAAAAAAAAAAY2huZXRfZGhjcF9y +ZWN2OiB2bGFuaWQgWyV1XSwgbDJkZXZfcGlkX2ZjLT5mbG93Y19uZXRfbDJkZXZfdmxhbmRldiBb +MHgleF0sIGwyZGV2X2ZjIFsweCV4XQoAAAAAY2huZXRfZGhjcF9yZWN2OiBsMmRldl9mYy0+Zmxv +d2NfaWQgWzB4JXhdLCBkaGN0eHQtPnN0YXRlIFslZF0sIG1hbGFjaW91cyBkaGNwIHJlY3YgZm9y +IG5vIHJlcXVlc3QKAAAAAAAAAAAAAAAAAGRoY3R4dC0+c3RhdGUgOiAlZAoAAAAAAAAAAAAAAAAA +bDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgQmFkIERIQ1AgY29va2llIHJlY2lldmVkLCBhYm9y +dGluZwoAAENvdWxkIG5vIGFsbG9jYXRlIHBjYiEhIEZyZWVpbmcgZmNmICEhIQoAAAAAAAAAAHZu +X3BhcnNlIHVua25vd24gc3ViY29kZSAldQoAAAAAdm5fcGFyc2UgdW5rbm93biBkdHlwZSAldQoA +AAAAAABpZ25vcmluZyBmaXAgcmVjdiBmb3IgcGNiIGZsb3c6JXggaW4gb2ZmbGluZSBzdGF0ZQoA +AAAAAAAAAAAAAAAAZmlwX3ZuMnZuX3JlY3ZfZXJyIAoAAAAAAAAAAAAAAABDb3VsZCBub3QgYWxs +b2NhdGUgZmxvd2MhISEhCgAAAENvdWxkIG5vdCBhbGxvY2F0ZSBTQ0IgZmxvd2MhISEhCgAAAAAA +AAAAAAAAAAAAAENvdWxkIG5vdCBmaW5kIHJpZ2h0IHNjYiBmb3IgbG9nbwoAAAAAAAAAAAAAAAAA +AGlnbm9yaW5nIGZpcCByZWN2IGZvciBmY2YgZmxvdzoleCBpbiBvZmZsaW5lIHN0YXRlCgAAAAAA +AAAAAAAAAABDb3VsZCBub3QgZmluZCByaWdodCBzY2IgZm9yIGZsb2dpCgAAAAAAAAAAAAAAAABw +b3J0IDB4JXgsIHN0YXRlIDB4JXgsIHJldHJ5IG5vdCBzdXBwb3J0ZWQKAAAAAABGbG9naSByZXNw +IHJjdiB3aXRoIHVua25vd24geGNoZyBveF9pZCV4IHNpZCAlMnglMnglMnggZGlkICUyeCUyeCUy +eAoAAAAAAAAAAAAAAE5fUE9SVCAweCV4JXgleCByZWplY3RlZCBQTE9HSSB3aXRoIHJlYXNvbiBj +b2RlICV4CgAAAAAAAAAAAAAAAABBQlRTIHdoaWxlIGF3YWl0aW5nIFBSTEkgUnNwOiBmbG93Y19p +ZCAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleCAKAAAAAAAAAAAAAAAAAEFCVFMgZmFrZSBSc3A6 +IGxvYyAweCV4IG94X2lkIDB4JXggcnhfaWQgMHgleAoAAEZDIGZjYiBhbGxvYyBmYWlsZWQ6IGF2 +YWlsICVkCgAARkMgZmNiIGFsbG9jIHhpZDolZCBmbG93aWQgJWQKAABsbGRwX3J4X3BrdF9oYW5k +bGVyWyV1XSBkcm9wIHByZS1pbml0IChjb3VudCA9ICV1KQoAAAAAAAAAAAAAAAAAJXgleCV4IFJl +Y2lldmVkIExPR08gZnJvbSAleCV4JXggCgAAAAAAAAAAAAAAAAAARmFpbGVkIHRvIHBvc3QgeGNo +ZyBlcnI6IHNzbmkgMHgleCBjb29raWUgMHglbHggcnZhbCAleCAKAAAAAAAAAHRjcF9yZWxlYXNl +X3RpZDogdGlkIFsweCV4XSwgZmxvd2MgZmxhZ3MgWzB4JXhdLCBidWZmZXJlZCBbMHgleF0KAAAA +AAAAAAAAAAAAAAAAdGNwX3JlbGVhc2VfdGlkOiBzaXplb2YodGNiX2ZjLT5mbG93Y19mb2lzY3Np +X2Nvbm4pIFsldV0sIGJ5dGVzCgAAAAAAAAAAAAAAAAAAAABhY3Rfb3Blbl9ycGw6IGF0aWQgWzB4 +JXhdLCB0aWQgWzB4JXhdLCB0Y2JfZmMtPnsgaWQgWzB4JXhdLCBzdGF0ZSBbMHgleF0sIHR5cGUg +WzB4JXhdIH0sIGNwbF9vcCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAAAAAAAAAAAGFjdF9vcGVu +X3JwbDogY3NrX2ZjLT57IGlkIFsweCV4XSwgc3RhdGUgWzB4JXhdLCBjc29ja19mbGFncyBbMHgl +eF0gfSAKAAAAAAAAAAAAYWN0X29wZW5fcnBsOiByZWN2ZCBuZWcgYWR2aWNlIFsweCV4XQoAAAAA +AAAAAAAAc2VuZF9hYm9ydF9ycGw6IGNza19mYy0+Zmxvd2NfdHlwZSBbMHgleF0sIGNza19mYy0+ +Zmxvd2NfaWQgWzB4JXhdLCB0aWQgWzB4JXhdLCB1bHB0eGNoIFsldV0sIGJ1ZmZlcmVkIFsldV0K +AAAAAHdyaF9vZmxkX3RjcF9jbG9zZV9jb25fcmVwbHk6IHRjYl9mYy0+Zmxvd2NfaWQgWzB4JXhd +LCB0Y2JfZmMtPmZsb3djX3R5cGUgWzB4JXhdLCBsZW4xNiBbJXVdLCBsb2MgWyV1XQoAAAAAAAAA +AAB3cmhfb2ZsZF90Y3BfY2xvc2VfY29uX3JlcGx5OiBycGwtPm9wX1RpZCBbMHgleF0sIHJwbD5z +dGF0dXMgWzB4JXhdLCBycGwtPnNuZF9ueHQgWzB4JXhdLCBycGwtPnJjdl9ueHQgWzB4JXhdCgAA +dGNwX2Fib3J0X3JwbF9yc3M6IHRpZCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAAdGNwX2Fib3J0 +X3JlcV9yc3M6IHRpZCBbMHgleF0sIHN0YXR1cyBbMHgleF0KAAAAb2ZsZF9hYm9ydF9yZXFfbmVn +YWR2WyV1XTogd3IgMHglMDh4IGNwbF9hYm9ydF9yZXEgREVMSVZFUkVECgAAAGhvc3Rfd3JbJXVd +OiB3ciAweCUwOHggY3BsX2Fib3J0X3JlcSBzdGF0dXMgMHgleAoAAAAAAAAAAAAAAAAAAABwa3Rz +Y2hlZF9jbF9ybFsldToldV06IG1vZGUgfCB1bml0IHwgcmF0ZSAweCUwNnggbWluICV1IG1heCAl +dSBwa3RzaXplICV1CgAAAAAAAHBhcmFtX2NobmV0WzB4JXg6MHgleF06IGNobmV0IDB4JXggcmVh +ZCAldSBwZiAldSByZXQgJWQKAAAAAAAAAABwYXJhbV9kbWFxWzB4JXg6MHgleF06IGRtYXEgMHgl +eCByZWFkICV1IHBmICV1IHJldCAlZAoAAAAAAAAAAAAATUNbJXVdIGluaXRfc3RhdGVfbWFjaGlu +ZSAweCUwMngKAAAAAAAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24gbm90IGNvbXBsZXRpbmcs +IE1DIGN1cnJlbnQgaW5pdCBzdGF0ZSBpcyAweCUwMngKAAAAAAAAAAAAAAAAAABNQ1sldV0gX2h3 +X21jX2luaXRfbWMKAAAAAAAAAAAAAF9od19tY19pbml0X21jX2ZwZ2FbJXVdOiBlcnJvciAlZAoA +AAAAAAAAAAAAAAAAAHBoeTogZmFpbGVkIHRvIGFsbG9jYXRlZCBtZW1vcnkgZm9yIHBoeSBmdyBm +aWxlLCByZXQgJWQKAAAAAAAAAABod19sZV9maWx0ZXJfY3R1cGxlOiB0dXBsZSAldSBub3Qgc3Bl +Y2lmaWVkIGJ1dCByZXF1aXJlZCBmb3IgbWFzayAweCV4CgAAAAAAAAAAAGxlIGNvbmZpZ3VyYXRp +b246IGhhc2ggcmVnaW9uIHRvbyBsYXJnZSB0byBlbmFibGUgc2VydmVyIHNyYW0KAABsZSBjb25m +aWd1cmF0aW9uOiBjYW5ub3QgZW5hYmxlIHNlcnZlciBzcmFtIHdoZW4gaGFzaCByZWdpb24gaXMg +ZGlzYWJsZWQKAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiB0aW1lcl9ycyAldXVzIHRpbWVz +dGFtcF9yZXMgJXV1cyBkZWxheWVkYWNrX3JlcyAldXVzCgAAAAAAaHdfdHBfdGNwX3NldHRpbmdz +X3c6IGRhY2tfdGltZXIgJXV1cyBtc2wgJXV1cyByeHRfbWluLG1heCAldSwldXVzIHBlcnNfbWlu +LG1heCAldSwldXVzCgAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGtlZXBfaWRsZSxpbnR2 +bCAldSwldXMgbWF4cnR0ICV1dXMgaW5pdHNydHQgJXV1cyBmaW53YWl0Ml90aW1lciAldXVzCgAA +AAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgZGFja190aW1lciBmcm9tICV1IHRvICV1 +AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIG1zbCBmcm9tICV1IHRvICV1 +AGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHJ4dF9taW4gZnJvbSAldSB0byAldQAAAAAA +AAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyByeHRfbWF4IGZyb20gJXUgdG8g +JXUAAAAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgcGVyc19taW4gZnJv +bSAldSB0byAldQAAAAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0aW5nc193OiBjYXBwaW5nIHBlcnNf +bWF4IGZyb20gJXUgdG8gJXUAAAAAAAAAAAAAAABod190cF90Y3Bfc2V0dGluZ3NfdzogY2FwcGlu +ZyBrZWVwX2lkbGUgZnJvbSAldSB0byAldQAAAAAAAAAAAAAAaHdfdHBfdGNwX3NldHRpbmdzX3c6 +IGNhcHBpbmcga2VlcF9pbnR2bCBmcm9tICV1IHRvICV1AAAAAAAAAAAAAGh3X3RwX3RjcF9zZXR0 +aW5nc193OiBjYXBwaW5nIGluaXRfc3J0dF9tYXhydHQgZnJvbSAldSB0byAldQAAAABod190cF90 +Y3Bfc2V0dGluZ3NfdzogY2FwcGluZyBpbml0X3NydHRfaW5pdHNydHQgZnJvbSAldSB0byAldQAA +aHdfdHBfdGNwX3NldHRpbmdzX3c6IGNhcHBpbmcgZmlud2FpdDJfdGltZXIgZnJvbSAldSB0byAl +dQAAAAAAAGxlIGNvbmZpZ3VyYXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmls +dGVyICV1IGFjdGl2ZSAldSBzZXJ2ZXIgJXUgaGFzaCAldQoAAAAAAAAAAAAAAGxlIGNvbmZpZ3Vy +YXRpb246IG5lbnRyaWVzICV1IHJvdXRlICV1IGNsaXAgJXUgZmlsdGVyICV1IHNlcnZlciAldSBh +Y3RpdmUgJXUgaGFzaCAldSBuc2VydmVyc3JhbSAldQoAAAAAAAAAAAAAAABod19zZ2VfcXVldWVf +YmFzZV9tYXBbJXVdOiBleGNlZWRlZCBudW1iZXIgb2YgZWdyZXNzIHF1ZXVlcywgJXUKAAAAAAAA +AAAAAAAAAAAAAGh3X3NnZV9xdWV1ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBvZiBp +bmdyZXNzIHF1ZXVlcyB3aXRoIGZyZWVsaXN0IGFuZCBpbnRlcnJ1cHQsICV1CgAAAGh3X3NnZV9x +dWV1ZV9iYXNlX21hcFsldV06IGV4Y2VlZGVkIG51bWJlciBvZiBpbmdyZXNzIHF1ZXVlcywgJXUK +AAAAAAAAAAAAAAAAAAAAc2t1OiBjdXN0b20gc2t1IDEwRyBkb2VzIG5vdCBzdXBwb3J0IDQwRyBw +b3J0cwoAc2t1OiBjdXN0b20gc2t1IDQwR19TTyBkb2VzIG5vdCBzdXBwb3J0IGV4dG1lbQoAc2t1 +OiBjdXN0b20gc2t1IDEwR19TTyBkb2VzIG5vdCBzdXBwb3J0IDQwRyBwb3J0cygldSkgb3IgZXh0 +bWVtKCV1KQoAAAAAAAAAAAAAAABza3U6IGN1c3RvbSBza3UgMHgleCA0MEcgcG9ydHMoJXUpIGV4 +dG1lbSgldSkKAABjZl9wYXJzZTogZmlsZSBtZW10eXBlIDB4JXggbWVtYWRkciAweCV4IG1hcHBl +ZCBAICVwOgoAAAAAAAAAAAAAY29uZmlndXJlZCB3aXRoIGNhcHMgbmJtfGxpbmsgMHglMDh4IHN3 +aXRjaHxuaWMgMHglMDh4IHRvZXxyZG1hIDB4JTA4eCBpc2NzaXxmY29lIDB4JTA4eAoAAAAAAAAA +bmV0IFZJIGFsbG9jYXRpb24gZmFpbGVkIGZvciBmY19pZCAldSB3aXRoIGVycm9yICVkCgAAAAAA +AAAAAAAAAG5ldCBWSSBtYWMgYWRkcmVzcyBwcm9ncmFtbWluZyBmYWlsZWQgZm9yIGZjX2lkICV1 +IHdpdGggZXJyb3IgJWQKAAAAAAAAAAAAAAAAAAAAbmV0IFZJIHJ4bW9kZSBwcm9ncmFtbWluZyBm +YWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJyb3IgJWQKAAAAAG5ldCBWSSByc3MgaW5kaXJlY3Rp +b24gdGFibGUgcHJvZ3JhbW1pbmcgZm9yIGZjX2lkICV1IGZhaWxlZCB3aXRoIGVycm9yICVkCgAA +AAAAbmV0IFZJIHJzcyBjb25maWcgY29tbWFuZCBmYWlsZWQgZm9yIGZjX2lkICV1IHdpdGggZXJy +b3IgJWQKAAAAAG5ldCBWSSBjb21tYW5kIGZhaWxlZCBmb3IgZmNfaWQgJXUgd2l0aCBlcnJvciAl +ZAoAAAAAAAAAAAAAAAAAAABwcm9ncmFtbWVkIEhXIHRhZ20gWzB4JTA4eF0sIEhXIHBnc3ogZmFj +dG9yIFsweCUwOHhdLCBGT2lTQ1NJIHRhZ20gWzB4JTA4eF0sIHJ0YWdtIFsweCUwOHhdLCBtYXhz +el9iaXRzIFsldV0sIHN6X2JpdHMgWyV1XS4KAAAAAGJhc2UgWyAweCUwOHhdLCBsbGltaXQgWzB4 +JTA4eF0sIHVsaW1pdCBbMHglMDh4XSwgc2l6ZSBbJXVdLCBtYXhfdHhzeiBbJXVdLCBtYXhfcnhz +eiBbJXVdLCBpb3NpemUgWyV1XQoAAAAAAAAAAABucHBvZHMgWyV1XSwgaWR4X21hc2sgWzB4JTA4 +eF0sIGlkeF9maXJzdCBbJXVdLCBpZHhfbGFzdCBbJXVdLCBzY3NpX3BsZF9zaXplIFsldV0sIEFM +SUdOKHNjc2lfcGxkX3NpemUsIDE2KSBbJXVdLCBwcGRfem9uZXMgWyV1XS4KAAAAAAAAAAAAAAAA +AABmb2lzY3NpX2luaXQ6IGZvaXNjc2lfaW5pdF9kb25lIFsldV0sIGRldi5yZXMuZm9pc2NzaV9u +dGFza3MgWyV1XSwgZGV2LnJlcy5mb2lzY3NpX25zZXNzIFsldV0sIGRldi5yZXMubmNzb2NrIFsl +dV0sIGRldi5yZXMuZm9pc2NzaV9uaW5pdCBbJXVdLCByYyBbJWRdCgAAAAAAAAAAY2hfY2xfcmF0 +ZVsldS8ldV06IGNhcHBlZCBjbGFzcyByYXRlIGZyb20gcmVxdWVzdGVkICV1IHRvIGNvbmZpZ3Vy +ZWQgKGVmZmVjdGl2ZSkgY2hhbm5lbCByYXRlICV1CgAAAAAAAAAAAAAAAAAAAGNoX2NsX3JhdGVb +JXUvJXVdOiBpbmNyZWFzZWQgZGVmaWNpdF9pbmNyIGZyb20gcmVxdWVzdGVkICV1IHRvIHJlcXVp +cmVkIG1pbiBvZiAldTsgcmF0ZSAldSAoZWZmICV1KSBkZWZpY2l0X21heCAldQoAAAAAAAAAAAAA +AAAAcGt0c2NoZWQgY2hhbm5lbCAldSBzZXRzIHNwZWVkIChmcm9tICV1KSB0byAldSBrYnBzCgAA +AAAAAAAAAAAAAG5ldF9sMmRldl9ub3RpZnk6IGwyZGV2X2ZjLT5mbG93Y19pZCBbMHgleF0sIHBv +cnQgWyVkXSwgZXZlbnQgWzB4JXhdLCB1bHB0eGNoIFsldV0sIGNsYXNzIFsweCV4XSwgdnByaW8g +WzB4JXhdLCB2aWQgWzB4JXhdLCB2aV9yZWFkeSBbJXVdCgAAAAAAAG5ldF9sMmRldl9ub3RpZnk6 +IHBnaWQgWzB4JXhdLCBwcmlvIFsweCV4XSwgY2ggWzB4JXhdCgAAAAAAAAAAAABmY29lIG5vdGlm +eSA6IEZDb0UgTElOS1VQOiBwb3J0IDB4JXgsIGV2ZW50IDB4JXgKAAAAAAAAAAAAAAAAAAAAZmNv +ZSBub3RpZnkgOiBGQ29FIExJTktET1dOOiBwb3J0IDB4JXgsIGV2ZW50IDB4JXgKAAAAAAAAAAAA +AAAAAGZjb2Ugbm90aWZ5IDogRENCWCA6IHBvcnQgMHgleCwgcHJpb3JpdHkgMHgleCB1bHB0eGNo +IDB4JXggY2xhc3MgMHgleAoAAAAAAAAAAAAAZGNieF90aW1lb3V0WyV1XQoAAAAAAAAAAAAAAAAA +AABwb3J0X2NtZF9oYW5kbGVyOiB1bmtub3duIHUuZGNiLnR5cGUgMHgleAoAAAAAAABwb3J0WyV1 +XSBwdHlwZSAldSBsYW5lICV1OiByeGNmZyA9ICUjeAoAAAAAAAAAAABwb3J0WyV1XSBwdHlwZSAl +dSBsYW5lICV1OiB0eGNmZyA9ICUjeAoAAAAAAAAAAABwb3J0WyV1XSBsaW5rIGRvd24gKCV1KSAo +bHN0YXR1cyAlI3gpCgAAAAAAAAAAAABod19pMmNfdHJhbnNhY3Rpb246IG5kYXRhICV1IGFkZHJf +b3AgMHgleCBkYXRhWzBdIDB4JXggZGlmZiAldQoAaHdfaTJjX3RyYW5zYWN0aW9uOiBuZGF0YSAl +dSBhZGRyX29wIDB4JXggZGF0YVswXSAweCV4IGRpZmYgJXUgZHBvcyAldSBjb250ICV1IGZhaWxl +ZCB3aXRoIGVyciAlZAoAAAAAAAAAAAAAAAAAAGkyYyB0cmFuc2FjdGlvbiBmYWlsZWQgdG8gY29t +cGxldGUKAAAAAAAAAAAAAAAAAGkyYyBlcnJvciBjYXVzZWQgYnkgbW9kdWxlIHVucGx1ZwoAAAAA +AAAAAAAAAAAAAHNlbmR0byBwZW5kaW5nOiB3cl9wZW5kICVwIGZvciBwb3J0ICV1LCB3YW50IHRv +IHNlbmQgdG8gcG9ydCAldQoAAAAAAAAAAAAAAAAAAAAAcG9ydFsldV0gdXBkYXRlIChmbG93Y2lk +ICV1IHJjICV1KQoAAAAAAAAAAAAAAAAAcG9ydF9zZXRfbG9vcGJhY2sgcG9ydCAlI3ggY3VycmVu +dCAlI3ggbW9kZSAlI3gKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXVdIHNwZWVkIHVwZGF0ZTogJSN4 +CgAAAAAAcG9ydFsldV0gYmVnaW5uaW5nIGRlYm91bmNlCgAAAABRU0ZQIG1vZHVsZSB1bnBsdWcg +LSByZWluaXRpYWxpemluZyByeF9sb3MgIHRvIDB4ZmYKAAAAAAAAAAAAAAAAZ3Bpb19xc2ZwX21v +ZHVsZV91cGRhdGU6IGNoYW5nZWQgcnhfbG9zIGZyb20gMHgleCB0byAweCV4CgAAAAAAAGdwaW9f +cXNmcF9tb2R1bGVfdXBkYXRlOiBjaGFuZ2VkIHR4X2RpcyBmcm9tIDB4JXggdG8gMHgleAoAAAAA +AABwb3J0X2xpbmtfc3RhdGVfaGFuZGxlclsldV0gcG93ZXJpbmcgZG93bgoAAAAAAABwb3J0X2xp +bmtfc3RhdGVfaGFuZGxlclsldV0gcG93ZXJpbmcgdXAKAAAAAAAAAABwb3J0X2xpbmtfc3RhdGVf +aGFuZGxlclsldV0gdW5rbm93biBzdGF0ZSAoc3RhdGUgPSAlI3gpCgAAAAAAAAAAcG9ydF9saW5r +X3N0YXRlX2hhbmRsZXI6IFNvbWV0aGluZyB3ZW50IHRlcnJpYmx5IHdyb25nLiByZXQgPSAlZAoA +AAAAAAAAAAAAAAAAAABod19zZ2VfbWFtZW1faW5pdDogZW5jb3VudGVyZWQgZXJyb3IgJWQKAAAA +AAAAAABsZSBpbml0aWFsaXphdGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0 +ZXIgJXUgYWN0aXZlICV1IHNlcnZlciAldSBoYXNoICV1CgAAAAAAAAAAAABsZSBpbml0aWFsaXph +dGlvbjogbmVudHJpZXMgJXUgcm91dGUgJXUgY2xpcCAldSBmaWx0ZXIgJXUgc2VydmVyICV1IGFj +dGl2ZSAldSBoYXNoICV1IG5zZXJ2ZXJzcmFtICV1CgAAAAAAAAAAAAAAaHdfdHBfaW5pdDogdGNi +IHJlZ2lvbiAoc3RhcnQgMHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2TUIgb2Yg +TUEgbWVtb3J5CgAAAAAAAAAAAAAAAAAAaHdfdHBfaW5pdDogcGdtbmd0IHJlZ2lvbiAoc3RhcnQg +MHglMDhzIHNpemUgJXUpIG11c3QgYmUgaW4gZmlyc3QgMjU2TUIgb2YgTUEgbWVtb3J5CgAAAAAA +AAAAAAAAaHdfdHBfaW5pdDogVFAgcGdtbmd0IGluaXRpYWxpemF0aW9uIGRpZCBub3QgY29tcGxl +dGUKAAAAAAAAAAAAAGJ1Zm1faW5pdDogbiAldSBidWZsbDY0aW50X3NpemUgMHgleAoAAAAAAAAA +AAAAAGJ1Zm1faW5pdDogbm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgaW50ZXJuYWwgYnVm +bGw2NCBidWZmZXJzCgAAAAAAAAAAAAAAAAAAYnVmbV9pbml0OiBub3QgZW5vdWdoIG1lbW9yeSB0 +byBhbGxvY2F0ZSBidWZsbDY0IGJ1ZmZlcnMKAAAAAAAAAG1lbV9pbml0X2J1Zjogbm90IGVub3Vn +aCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyBidWZmZXJzCgAAAAAAAABtZW1faW5pdF9idWY6IG5v +dCBlbm91Z2ggbWVtb3J5IHRvIGFsbG9jYXRlIHRjYl9jYWNoZSAob2ZmZXJlZCAldSB0cnlpbmcg +dG8gdXNlICV1IGF2YWlsYWJsZSAldSkKAAAAAAAAAAAAAAAAAAAAbXBhcnRpdGlvbl9vdGhlcnM6 +IHN0YXJ0IDB4JTA4eCBzaXplICV1ICh1bnVzZWQgJXUpCgAAAAAAAAAAAAAAAG1wYXJ0aXRpb25f +b3RoZXJzOiBzdGFydCAweCUwOHggc2l6ZSAldSAodW51c2VkICV1KQoAAAAAAAAAAAAAAABtZW1f +aW5pdDogRURDIG92ZXJjb21taXR0ZWQgYnkgJWQgYnl0ZXMKAAAAAAAAAABtZW1faW5pdDogbm90 +IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgZmxvdyB0YWJsZQoAAAAAAAAAAAAAAAAAY3hjbmlj +X2RldmljZV9pbml0OiBjeGNuaWMgWzB4JTB4XSwgY3hjbmljLT5maWx0ZXIgWyUweF0KAAAAAAAA +AHBvZmNvZSBpbml0IGRvbmUKAAAAAAAAAAAAAAAAAAAAUG9ydFsldV06IFVua25vd24gU0dNSUkg +c3ViLXR5cGUgJSN4CgAAAAAAAAAAAAAAUG9ydFsldV06IFVua25vd24gQlRfWEZJIHN1Yi10eXBl +ICUjeAoAAAAAAAAAAAAAcG9ydF9pbml0WyV1XTogcG9ydCB0eXBlIDB4JXggaXMgbm90IHN1cHBv +cnRlZAoAbXBhcnRpdGlvbl9pbml0OiBtb3ZlZCBwbXJ4X3N0YXJ0IGZyb20gMHglMDh4IHRvIDB4 +JTA4eCB0byBtYWtlIHJvb20gZm9yIExFIEhBU0ggYW5kL29yIFRQIFRDQnMKAAAAAAAAAAAAAAAA +AAAAAG1wYXJ0aXRpb25faW5pdDogbW92ZWQgcG1yeF9zdGFydCBmcm9tIDB4JTA4eCB0byAweCUw +OHggKEVEUkFNKQoAAAAAAAAAAAAAAAAAAAAARVEgcGZuICV1IHZmbiAldTogZGVzdHJveWluZyBl +cWlkICV1IHdpdGggcGVuZGluZyBXUihzKSAobnVtX2J5dGVzICV1IGFuZCBmbGFncyAweCUwOHgK +AAAAAAAAAAAAbDJkZXZfZmMtPmZsb3djX2lkIFsldV0sIGwyZGMtPnBmbiBbJXVdLCBsMmRjLT52 +Zm4gWyV1XSwgbDJkYy0+bHBvcnQgWyV1XSwgbDJkZXZfZmMtPmZsb3dpZCBbJXVdIGwyZGMtPnR4 +X2NoIFsldV0sIGRldi52cGQucG9ydHZlYyBbJXhdCgAAAAAAAAAAcG9ydHZlYyBbJXVdCgAAAGwy +ZGV2X3ZpX2ZzbTogbWIgWzB4JXhdLCBkZWZlcnJlZCwgc3RhdGUgWzB4JXhdLCBwb3J0IFsweCV4 +XQoAAABsMmRldl92aV9mc206IHZpaWQgWzB4JXhdIHBvcnQgWzB4JXhdLCBtYWMtaWQgWyUwMng6 +JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4XS4gCgAAAAAAAAAAAAAAAAAAAABsMmRldl92aV9mc206 +IHNnZV9lcWlkIFsweCV4XSwgc2dlX2lxaWQgWzB4JXhdLCBzZ2VfZXFjciBbMHgleF0sIHJzc19z +eiBbMHgleF0KAGwyZGV2X3ZpX2ZzbTogbDJkZXZfZmMtPmZsb3djX25ldF9sMmRldl9tdHUgWyV1 +XSwgbWJfc2NyYXRjaCBbMHgleF0sIHBvcnQgWzB4JXhdCgAAAAAAAAAAAAAAAAAAAGwyZGV2X3Zp +X2ZzbTogdmlpZCBbJWRdLCB2aV9mYy0+Zmxvd2NfdmlfZmxhZ3MgWzB4JXhdCgAAAAAAAAAAAABs +MmRldl92aV9mc206IHBmbiBbMHgleF0sIHZmbiBbMHgleF0sIGwyZGV2X2ZjLT5mbG93Y19pZCBb +MHgleF0sIGxwb3J0IFsweCV4XSwgdmlpZCBbMHgleF0sIGZsYWdzIFsweCV4XQoAAAAAAAAAbDJk +ZXZfdmlfZnNtOiBFcnJvciBmcmVlaW5nIFZJLCByYyBbMHgleF0KAAAAAAAAbDJkZXZfdmlfZnNt +OiBwaWQgWzB4JXhdLCB2aWlkIFsweCV4XSwgbWJfbG9jIFsweCV4XSwgbWJfb3JpZ1sweCV4XSwg +bDJkZXZfZmxhZ3MgWzB4JXhdLCByYyBbMHgleF0KAAAAAAAAAAAAAAAAAEFoIGhhLi4uZG91Ymxl +IGZyZWUgb3hfaWQgMHgleCwgcnhfaWQgMHgleAoAAAAAAEhvc3QgUFJMSSBSZXNwb25zZSB0aW1l +ZG91dDogb3hfaWQgMHgleCByeF9pZCAweCV4CgAAAAAAAAAAAAAAAABGQ09FIEZyZWU6IHN0aWxs +IHlpZWxkZWQgd2hlbiBmcmVlaW5nLi4uZmxvd2NfaWQgJXggZmxvd2NfZmxhZ3MgJXggCgAAAAAA +AAAAAAAAAEZDIHhjaGcgZnJlZSB4aWQ6JWQgZmxvd2lkICVkCgAAcGZuICV1IHZmbiAldSB2aWEg +Y29tbWFuZAoAAAAAAABjb25maWd1cmF0aW9uIGZpbGUgcGFyc2VyOiBwbCB0aW1lb3V0IHZhbHVl +IGlzIHRvbyBsYXJnZSwgY2hhbmdpbmcgZnJvbSAldSB0byAldXVzZWNzCgAAAAAAAAAAAABQTF9Q +Q0lFX0xJTksuc3BlZWQgb2YgJXUgaXMgbm90IHN1cHBvcnRlZApmaWxlLCByZXQgRldfRUlPCgAA +AAAAc2NoZWRfaW9xdHhfYnBfcHJpb3JpdHk6IGhhcyAldSBlbnRyaWVzIG9ubHksIHJlcXVpcmVz +ICV1IGVudHJpZXMKAAAAAAAAAAAAAAAAAAB0cF9iYWNrb2ZmOiBwYXJzZWQgJWQgaW5zdGVhZCBv +ZiAldSBlbnRyaWVzCgAAAAB0cF90aW1lcnZhbHM6IHBhcnNlZCAlZCBpbnN0ZWFkIG9mICV1IGVu +dHJpZXMKAAB0cF90aW1lcnJlczogcGFyc2VkICVkIGluc3RlYWQgb2YgJXUgZW50cmllcwoAAAB0 +cF9tdHVzIGhhcyAldSBlbnRyaWVzIG9ubHksIHJlcXVpcmVzICV1IGVudHJpZXMKAAAAAAAAAAAA +AAAAAAAAdHBfbXR1c1sldV0gaXMgJXUgYnl0ZXMgd2hpY2ggaXMgbm90IHN1cHBvcnRlZAoAY29u +ZmlndXJhdGlvbiBmaWxlIHBhcnNlcjogc2dlIHRpbWVyIHZhbHVlWyVpXSBpcyB0b28gbGFyZ2Us +IGNoYW5naW5nIGZyb20gJXUgdG8gJXV1c2VjcwoAAAAAAAAAZmlsdGVybWFzayAweCV4IGlzIG5v +dCBlcXVhbC9zdWJzZXQgdG8vb2YgZmlsdGVybW9kZQoAAAAAAAAAAAAAAGh3X2xlX2NsaXBfaGFu +ZGxlcjogcmVtb3ZlZCBwb3M9JXUgKD1pZHggJXUpCgAAAGh3X2xlX2NsaXBfaGFuZGxlcjogYWRk +aW5nIHRvIHBvcz0ldSAoPWlkeCAldSkKAG1vZHVsZVsldV06IHBvcnQgbW9kdWxlIGluc2VydGVk +IGFuZCByZWFkeQoAAAAAAG1vZHVsZVsldV06IHBvcnQgbW9kdWxlIHJlbW92ZWQKAAAAAAAAAAAA +AAAAAAAAAG1vZHVsZVsldV06IHVua25vd24gbW9kdWxlIGlkZW50aWZpZXIgMHglMDJ4CgAAAG1v +ZHVsZVsldV06IGdwaW8gJXUgdHJhbnMgMTBHIDB4JTAyeCAxRyAweCUwMnggKGxlbmd0aCAldSkg +Y2FibGUgMHglMDJ4IChsZW5ndGggJXUpIG1vZHVsZV90eXBlIDB4JTAyeAoAAAAAAAAAAABtb2R1 +bGVbJXVdOiBncGlvICV1IHRyYW5zIDEwRyAweCUwMnggMUcgMHglMDJ4IChsZW5ndGggJXUpIGNh +YmxlIDB4JTAyeCAobGVuZ3RoICV1KSBtb2R1bGVfdHlwZSAweCUwMngKAAAAAAAAAAAAY3JfbW9k +dWxlX3J4X2xvc1sldV06IHJ4X2xvcyBjaGFuZ2VkIHRvICV1CgAAAAAATUM6IGV4cGVjdGVkIHN0 +YXRlIHRvIHN3aXRjaCB0byBDRkcuAAAAAAAAAAAAAAAATUM6IGV4cGVjdGVkIHN0YXRlIHRvIHN3 +aXRjaCB0byBBY2Nlc3MuAAAAAAAAAAAATUM6IGV4cGVjdGVkIHN0YXRlIHRvIHN3aXRjaCB0byBD +RkcuAAAAAAAAAAAAAAAATUM6IGV4cGVjdGVkIHN0YXRlIHRvIHN3aXRjaCB0byBBY2Nlc3MuAAAA +AAAAAAAASUkuMS5ieCBkcDE4WyV1XSBxWyV1XSAlI3ggJSN4ICUjeCAlI3ggbWluICUjeCBtYXgg +JSN4CgAAAAAAAAAAAElJLjEuYy1kLiAlI3ggJSN4ICUjeCAlI3ggYWxsICAlI3gKAAAAAAAAAAAA +AAAAAElJLjIuYiAoJSN4IC0gJSN4ICsgJSN4KSAlIDEyOCA9ICUjeAoAAAAAAAAAAAAAAElJLjMg +aW5ld18xZSBhZnRlciBsaW1pdCBjb21wdXRlIGl0ZW1wXzFlICV4LCBpbmV3XzFlICV4CgAAAAAA +AABJSS4zLiBpdGVtcF8xZSAlI3ggaW5ld18xZSAlI3ggaW5ld18xZSAlZAoAAAAAAABJSS40LiBz +ZXRfMWUgJSN4CgAAAAAAAAAAAAAAAAAAAE1DOiBjYWxpYnJhdGlvbiBmYWlsZWQgZm9yIGVycmF0 +YTI5IGRwMTggJXUKAAAAAElWLjEuIGRwMThbJXVdIHBoYXNlX3NlbCBiZWZvcmUgJSN4IGFmdGVy +ICUjeCwgZ2F0ZV9kZWxheSAlI3gKAABNQyBlcnJhdGEyOSBpc3N1ZTogZHAxOCAldSBxdWFkICV1 +IGNhbm5vdCBiZSBkZWNyZWFzZWQKAAAAAAAAAAAATUMgZXJyYXRhMjkgaXNzdWU6IGRwMTggJXUg +cXVhZCAldSBjYW5ub3QgYmUgZGVjcmVhc2VkCgAAAAAAAAAAAE1DIGVycmF0YTI5IGlzc3VlOiBk +cDE4ICV1IHF1YWQgJXUgY2Fubm90IGJlIGRlY3JlYXNlZAoAAAAAAAAAAABNQyBlcnJhdGEyOSBp +c3N1ZTogZHAxOCAldSBxdWFkICV1IGNhbm5vdCBiZSBkZWNyZWFzZWQKAAAAAAAAAAAAdGVtcDJf +MWUrMHgxMCA9ICUjeAoAAAAAAAAAAAAAAABNQzogY2FsaWJyYXRpb24gZmFpbGVkIGZvciBlcnJh +dGEyMSBpdGVyYXRpb24gJXUKAAAAAAAAAAAAAAAAAAAATUMgZXJyYXRhIDIxOiBkcDE4WyV1XSBw +cjAgbjAyIGZhaWxlZCB0byBnZXQgYXZlcmFnZQoAAAAAAAAAAAAAAE1DIGVycmF0YSAyMTogZHAx +OFsldV0gcHIwIG4xMyBmYWlsZWQgdG8gZ2V0IGF2ZXJhZ2UKAAAAAAAAAAAAAABNQyBlcnJhdGEg +MjE6IGRwMThbJXVdIHByMSBuMDIgZmFpbGVkIHRvIGdldCBhdmVyYWdlCgAAAAAAAAAAAAAATUMg +ZXJyYXRhIDIxOiBkcDE4WyV1XSBwcjEgbjEzIGZhaWxlZCB0byBnZXQgYXZlcmFnZQoAAAAAAAAA +AAAAAE1DIGluaXRpYWxpemF0aW9uIGZhaWxlZDogREZJIGluaXQgbm90IGdvaW5nIHRvIDAKAAAA +AAAAAAAAAAAAAABNQyBpbml0aWFsaXphdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5vdCBjb21wbGV0 +aW5nCgAAAAAAAAAAAAAAAAAATUMgaW5pdGlhbGl6YXRpb24gZmFpbGVkOiBDYWxpYnJhdGlvbiBk +aWRuJ3QgY29tcGxldGUuCgAAAAAAAAAAAERQMTggJXUsIGJ5dGVfbGFuZSAldSwgYml0X3NlbGVj +dCAldQoAAAAAAAAAAAAAAERQMTggJXUsIGJ5dGVfbGFuZSAldSwgYml0X3NlbGVjdCAldQoAAAAA +AAAAAAAAAE1DIGZhaWxlZCB0byBnZXQgVVBDVEwgcG93ZXIgdXAgZG9uZQoAAAAAAAAAAAAAAE1D +IGluaXRpYWxpemF0aW9uIGZhaWxlZDogRGlkbid0IGdldCBhbGwgRFAxOHMgbG9ja2VkCgAAAAAA +AAAAAABNQyBpbml0aWFsaXphdGlvbiBmYWlsZWQ6IERpZG4ndCBnZXQgYm90aCBBRFJzIGxvY2tl +ZAoAAAAAAAAAAAAAQ3VycmVudCBTbGV3IHR4X3JvdyAlZDogdHhfY29sICVkLCB2YWwgJWQKAAAA +AAAAQ3VycmVudCBTbGV3IGFkZHJfcm93ICVkOiBhZGRyX2NvbCAlZCwgdmFsICVkCgAATUMgaW5p +dGlhbGl6YXRpb24gZmFpbGVkOiBTTEVXX0RPTkVfU1RBVFVTIG5ldmVyIHRvZ2dsZWQAAAAAAAAA +AGZscl9wZnZmX2ZzbVsldToldV06IHVua25vd24gc3RhdGUgJXUKAAAAAAAAAAAAAGh3IHBmIGJp +dG1hcCAweCUwMnggdmZpZCBiaXRtYXAgMHglMDh4OjB4JTA4eDoweCUwOHg6MHglMDh4CgAAAABh +ZnRlciB2ZmlkIGZpeHVwLCB2ZmlkIGJpdG1hcCAweCUwOHg6MHglMDh4OjB4JTA4eDoweCUwOHgK +AAAAAAAATUNbJXVdOiBmYWlsZWQgdG8gc3dpdGNoIGNvbnRyb2xsZXIgdG8gQ0ZHIHN0YXRlCgAA +AAAAAAAAAAAAAAAAAE1DWyV1XTogZmFpbGVkIHRvIHN3aXRjaCBjb250cm9sbGVyIHRvIElOSVRf +TUVNIHN0YXRlCgAAAAAAAAAAAABNQ1sldV06IGZhaWxlZCB0byBzd2l0Y2ggY29udHJvbGxlciB0 +byBDRkcgc3RhdGUKAAAAAAAAAAAAAAAAAAAATUNbJXVdOiBwZXJpb2RpYyBjYWxpYnJhdGlvbiBm +YWlsZWQgd2l0aCBlcnJvciAldQoAAAAAAAAAAAAAAAAAAHRpbWVyIHF1ZXVlICV1IGxvc3QgYSB0 +aWNrISBuZXh0ICVwIGxhc3QgJXAgbnVtZSAldQoAAAAAAAAAAAAAAABmbHJfdGltZXJfc3RhcnQ6 +IGZsb3djX2lkICV1ICVwIGJ1ZiAlcAoAAAAAAAAAAABNQUM6IFBMTHMgZGlkbid0IGxvY2sKAAAA +AAAAAAAAAHBjaWU6IHJlYWQgZnJvbSBzZXJjZmcgcGNpZV9pcF91cl9tYXhmdW5jIDB4JXggcGZi +aXRtYXAgMHgleAoAAABwY2llOiBucGYgJXUgKHBmYml0bWFwIDB4JTAyeCkgbnZmICV1IChwZiAw +Li43IDB4JTA4eCUwOHgpIHZmc3RyaWRlICV1CgAAAAAAAAAAAGZhaWxlZCB0byBmaW5kIHRoZSAl +YyVjIFZQRCBwYXJhbWV0ZXIKAAAAAAAAAAAAAGZhaWxlZCB0byBwYXJzZSB0aGUgJWMlYyBWUEQg +cGFyYW1ldGVyCgAAAAAAAAAAAGZhaWxlZCB0byBzdWNjZXNzZnVsbHkgZmluZCBDaGVsc2lvIFZQ +RAoAAAAAAAAAAGxvZyBpbml0aWFsaXplZCBAIDB4JTA4eCBzaXplICV1ICgldSBlbnRyaWVzKSBm +d3JldiAweCUwOHggcGNpZV9mdyAweCUwOHgKAAAAAAAAYm9vdHN0cmFwIGZpcm13YXJlIHRvb2sg +JXUgbXNlY3MgdG8gcnVuCgAAAAAAAAAAUEkgZXJyb3IgZmxvd2lkX2xlbjE2IDB4JXgsIGFwcF90 +YWcgMHgleCwgcmVmX3RhZyAweCV4LCBwaXNjICUwNHggJTA0eCAlMDR4ICUwNHgKAAAAAAAAAAAA +AAAAAAAAZmxvd2MgJXUgKFNHRSBlcWlkICV1KSAoRVRIQ1RSTCBxdWV1ZSkgZXhwZXJpZW5jZWQg +YSBQQ0kgRE1BIFJFQUQgd29yayByZXF1ZXN0IGVycm9yIChpbmJvdW5kIHF1ZXVlICV1KQoAAAAA +AAAAAGZsb3djICV1IChTR0UgZXFpZCAldSkgZXhwZXJpZW5jZWQgYW4gdW5leHBlY3RlZCBQQ0kg +RE1BIFJFQUQgd29yayByZXF1ZXN0IGVycm9yIChpbmJvdW5kIHF1ZXVlICV1KQoAAAAAAAAAAAAA +AABmbG93YyAldSBleHBlcmllbmNlZCBhbiB1bmV4cGVjdGVkIFBDSSBETUEgUkVBRCBlcnJvciAo +aW5ib3VuZCBxdWV1ZSAldSkKAAAAAAAAAGdhdGhlcl90YXNrc19mb3JfdG1mOiBpZHggWzB4JXhd +LCB0YXNrLWlkIFsweCV4XSwgY21kLWlkIFsweCV4XSwgYWN0aXZlIHRhc2tzIFsweCV4XS4gY29u +bi1pZCBbMHgleF0sIGNtZCBjb25uLWlkIFsweCV4XSwgdGFzayBjb25uLWlkIFsweCV4XQoAAGdh +dGhlcl90YXNrc19mb3JfdG1mOiBJbnZhbGlkIHR5cGUgWzB4JXhdLCBiYWlsaW5nIG91dC4KAAAA +AAAAAABnYXRoZXJfdGFza3NfZm9yX3RtZjogdGFzayBpZCBbMHgleF0sIHN0YXRlIFsweCV4XSwg +bGlkeCBbMHgleF0sIGNvb2tpZSBoaSBbMHglMDh4XSA6IGxvIFsweCUwOHhdCgAAAAAAAAAAAAAA +AAAAZ2F0aGVyX3Rhc2tzX2Zvcl90bWY6IHJjIFsweCV4XSwgWzB4JXhdIHRhc2sgZ2F0aGVyZWQg +Zm9yIHRtZiB0eXBlIFsweCV4XSBwcm9jZXNzaW5nLgoAAAAAAAAAAAAAc2NzaV9kYXRhX291dDog +Y29ubl9mYyBbMHgleF0sIHN0YXRlIFsweCV4XSwgc2Vzc19mYyBbMHgleF0gaW4gcmVjb3Zlcnku +IFNraXBwaW5nIGlzdGFza19mYyBbMHgleF0gZnJvbSBUWC4KAAAAAHNlbmRfYWJvcnRfcmVxOiBj +c2tfZmMtPmZsb3djX3R5cGUgWzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwgdGlkIFsw +eCV4XSwgdWxwdHhjaCBbJXVdLCBidWZmZXJlZCBbJXVdCgAAAABodyByZWdpc3RlciBvcGVyYXRp +b24gbm90IGNvbXBsZXRpbmcsIHJlZyAweCUwOHggbWFzayAweCUwOHggdmFsdWUgMHglMDh4IChy +ZWcgMHglMDh4KQoAAAAAAAAAAABNRElPIENMNDU6IGZhaWxlZCB0byBzZXQgdXAgTU1EIGFkZHIK +AAAAAAAAAAAAAABNRElPOiBmYWlsZWQgdG8gcmVhZAoAAAAAAAAAAAAAAGh3X2JjbTg0ODU2X2No +ZWNrIGVudHJ5CgAAAAAAAAAAaHdfYmNtODQ4NTZfY2hlY2sgbG9vcCAldSAoY2hlY2sgJSN4KQoA +AAAAAAAAAAAAaHdfYmNtODQ4NTZfY2hlY2sgdXBfcnVubmluZyAobG9vcF9jbnQ9JXUpCgAAAAAA +aHdfYmNtODQ4NTZfY2hlY2sgZmFpbGVkIChiYWQgQ1JDKQoAAAAAAAAAAAAAAAAAUEhZIGZpcm13 +YXJlIGxvYWQgc3VjY2Vzc2Z1bCEgKHdvdy4uLikKAAAAAAAAAAAATURJTyBDTDQ1OiBmYWlsZWQg +dG8gc2V0IHVwIE1NRCBhZGRyCgAAAAAAAAAAAAAATURJTzogZmFpbGVkIHRvIHdyaXRlCgAAAAAA +AAAAAABtaWlfYWR2X2ZjWyV1XTogcmNhcHMgMHgleAoAAAAAAG1paV9hZHZfc3BlZWRbJXVdOiBy +Y2FwcyAweCV4CgAAbmV0aWZfc2V0X21hYzogbDJkZXZfZmMtPmZsb3djX25ldF9sMmRldl9tYnMg +WzB4JXhdCgAAAAAAAAAAAAAAAHJlbW92aW5nIG1hYwoAAABub2RlLT5ncnAgWyUwNHggJTA0eCAl +MDR4ICUwNHhdLCBub2RlX2lkICV1LCByZWZfY250ICV1CgAAAAAAAAAAREFEIGZvciBhZGRyIFsl +MDR4ICUwNHggJTA0eCAlMDR4XQoAAAAAAAAAAAAAAAAAY3BsX3R4X3BrdDogdmxhbmlkIFsweCV4 +XQoAAAAAAABjcGxfdHhfcGt0OiB2bGFuaWQgWzB4JXhdCgAAAAAAAGZsb3djX2lkIFsldV0gbDJk +ZXZfZmMgWzB4JXhdIGFscmVhZHkgcmVjZWl2ZWQgUkEsIG5vdCBzZW5kaW5nIFJTCgAAAAAAAAAA +AAAAAAAAZmxvd2NpZCBbJXVdIGwyZGV2X2ZjIFsweCV4XSBObyBJUHY2IHJvdXRlcgoAAAAAc2Vu +ZF9jbG9zZV9yZXE6IGNza19mYy0+Zmxvd2NfdHlwZSBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQg +WzB4JXhdLCBjc2tfZmMtPnRjYl9zdGF0ZSBbMHgleF0KAAAAc2VuZF9jbG9zZV9yZXE6IGNza19m +Yy0+Zmxvd2NfdHlwZSBbMHgleF0sIGNza19mYy0+Zmxvd2NfaWQgWzB4JXhdLCB0aWQgWzB4JXhd +LCB1bHB0eGNoIFsldV0sYnVmZmVyZWQgWyV1XQoAAAAAAG9mbGRfdGNwX2RvX2FjdGl2ZV9jbG9z +ZTogY3NrX2ZjIFsweCV4XSwgY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+dGNiX3N0 +YXRlIFsweCV4XQoAAAAAAG9mbGRfdGNwX2RvX2FjdGl2ZV9jbG9zZTogY3NrX2ZjIFsweCV4XSwg +Y3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19mYy0+dGNiX3N0YXRlIFsweCV4XQoAAAAAAG9m +bGRfdGNwX2Rpc2Nvbm5lY3Q6IHRjYl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBjc2tfZmMtPmZsb3dj +X2lkIFsweCV4XSwgY3NrLT50Y2Jfc3RhdGUgWzB4JXhdCgAAAGRlY29kZV9iYXNlNjRfc3RyaW5n +OiBkbGVuIFslZF0KAAAAAAAAAAAAAAAAAAAAAGRlY29kZV9oZXhfc3RyaW5nOiBkbGVuIFslZF0K +AAAAZm9pc2NzaV92YWxpZGF0ZV9sb2dpbl9zdGFnZTogLSAxCgAAAAAAAAAAAAAAAAAAYXN5bmNf +cGR1OiBsb2dvdXQgcmVxdWVzdGVkIGJsb2NraW5nIHNlc3Npb24KAAAAYXN5bmNfcGR1OiBzZXNz +L2Nvbm4gZHJvcCByZXF1ZXN0ZWQgYmxvY2tpbmcgc2Vzc2lvbgoAAAAAAAAAAAAAAGNwbF90eF9w +a3Q6IHZsYW5pZCBbMHgleF0KAAAAAAAAcmVpbml0IGxpbmstbG9jYWwgYWRkcmVzcwoAAAAAAABu +ZXRfbDJkZXZfZmluZF9ieV9hZGRyOiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBsMmRjLT5s +cG9ydCBbJXVdLCBsMmRfZmMtPmZsb3djX2lkIFsweCV4XSwgbDJkYy0+aW40X2Rldi5pbl9hZGRy +LmFkZHIgWzB4JXhdLCBhZGRyIFsweCV4XQoAAABuZXRfbDJkZXZfbXR1X2NvbmZpZzogbDJkZXZf +ZmMtPmZsb3djX2lkIFsweCV4XSwgbXR1ICV1CgAAAAAAAAAAbmV0aWZfZG9fZGhjcDogd3ItPnBh +cmFtLnZsYW5pZCBbJXVdLCBsMmRldl9mYy0+Zmxvd2NfbmV0X2wyZGV2X3ZsYW5kZXYgWzB4JXhd +CgBjcGxfdHhfcGt0OiB2bGFuaWQgWzB4JXhdCgAAAAAAAGVuY29kZSBoZXggc3RyaW5nOiBkbGVu +IFslZF0KAAAAY2huZXRfZmluZF9sMnRfZW50cnk6IGRhZGRyIFslMDh4XSwgWzB4JTA4eF0sIGxv +Y2FsIG5ldHdvcmsgWyVkXQoAAAAAAAAAAAAAAAAAAABsMnRlbnQgWyUweF0sIGwydGVudC0+aWR4 +IFslZF0KAHRjcF9zZW5kX2FvcGVuX3JlcTogY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIGNza19m +Yy0+Zmxvd2Nfc3RhdGUgWzB4JXhdLCBidWZmZXJlZCBbJXVdLCByZXNfY250IFsweCV4XSwgaXFf +aWR4IFsweCV4XQoAAAAAAAAAAAAAdGNwX3NlbmRfYW9wZW5fcmVxOiBjc2tfZmMtPmZsb3djX2lk +IFsweCV4XSwgY3NrX2ZjLT5mbG93Y19zdGF0ZSBbMHgleF0sIG5vIHZhbGlkIGwydF9lbnR5LiBE +ZWxheWluZyBhbm90aGVyIHJldHJ5IGZvciAxIHNlY29uZHMuCgAAAAAAAAAAAAAAAAAAYW9wZW5f +cmVxOiBod19sZV9maWx0ZXJfY3R1cGxlIGZhaWxlZAoAAAAAAAAAAAAAb2ZsZF90Y3Bfc2VuZF9h +b3Blbl9yZXE6IGNwbF9yZXEtPkZpbHRlcl9oaSBbMHglMHhdLCBjcGxfcmVxLT5GaWx0ZXJfbG9f +RkNvRU1hc2sgWzB4JTB4XSwgY3R1cGxlc1swXSBbMHgleF0sIGN0dXBsZXNbMV0gWzB4JXhdCgBj +b25uZWN0aW9uIG92ZXIgaXB2NiwgbDJkZXYgZmxvd2NfaWQgMHgleAoAAAAAAABjc29ja19hbGxv +YzogdHhfY2ggWzB4JXhdLCBscG9ydCBbMHgleF0sIGNvb2tpZSBbJTA4eF0KAAAAAAAAAAAAY3Nv +Y2tfYWxsb2M6IGF2YWlsYWJsZSBbJXVdLCBuY3NvY2sgWyV1XSwgcG9zOmF0aWQgWzB4JXhdLCBj +c2tfZmMgWzB4JXhdLCBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwgc3BvcnQgWyV1XQoAAFdBVENI +RE9HOiBObyB0ZW1wZXJhdHVyZSBzZW5zb3IgYXZhaWxhYmxlLgoAAAAAAHdhdGNoZG9nIGNtZCBy +ZWZyZXNoIChhY3Rpb24gJXUpCgAAAAAAAAAAAAAAAAAAAFdBVENIRE9HOiBBY3RpdmF0aW5nCgAA +AAAAAAAAAAAAV0FUQ0hET0cgLSBFbmFibGUgYWN0aW9uICV1IHRpbWUgJXUKAAAAAAAAAAAAAAAA +V0FUQ0hET0cgLSBEaXNhYmxlIGFjdGlvbiAldQoAAABXQVRDSERPRzogRGUtYWN0aXZhdGluZwoA +AAAAAAAAAHBvcnRbJXVdIHNldCBQQVVTRSBQQVJBTVM6IHBwcGVuICV1IHR4cGUgJSN4IHJ4cGUg +JSN4CgAAAAAAAAAAAABtcHNfbGlua191cFsldV0gYWNhcHMgJSN4ICg4MDIuMyAlI3gpICsgbHBh +Y2FwcyAlI3ggPT4gJSN4CgAAAAAAaXB2Nl9oYW5kbGVfbGlua19kb3duIGZsb3djX2lkIDB4JXgK +AAAAAAAAAAAAAAAAaXB2Nl9oYW5kbGVfbGlua191cCBmbG93Y19pZCAweCV4CgAAAAAAAAAAAAAA +AAAAZm9pc2NzaSBjb25uX2ZjIFsweCV4XSwgZmxvd2Nfc2NoZWRjbCBbMHgleF0sIGluZ19jaCBb +MHgleF0sIGVncl9jaCBbMHgleF0KAAAAAABsMmRldl9ub3RpZnkgd2l0aCB1bmtub3duIGZsYWcg +WzB4JXhdCgAAAAAAAAAAAABGQ29FIEZDQiBsaW5rZG93bjogaW9fcmVxIDB4JXgleCBpcWlkIDB4 +JXggZmxvd2lkIDB4JXggb3AgMHgleAoAY2FuY2VsIGZjYjoleCBzY2I6JXggc3RhdGU6JXgKAABS +REVWIG1zZyBmbG93YzoleCBzdGF0ZSAweCV4IGV2ZW50IDB4JXgKAAAAAAAAAAB2bjJ2bjogcG9y +dCAweCV4IGRpZDoweCV4JXgleCBVUAoAAAAAAAAAAAAAAAAAAAB2bjJ2bjogcG9ydCAweCV4IGRp +ZDoweCV4JXgleCBET1dOCgAAAAAAAAAAAAAAAABmY19zZW5kX2FsbG9jX2NwbDogZmFpbGVkIHRv +IHNldHVwIGZpbHRlciBjdHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSAw +eCV4OiV4CgAAAABjb21wdXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBs +ZQoAAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSB2bGFuICV4IHZpaWQgJXggcG9y +dCAleCBtcHNfaWR4ICV4CgAAAAAAAAAAAEFwcGx5IEFQUDogcG9ydCAlZCBwcmlvciAlZCBzZWxl +Y3QgJWQgcHJvdG9jb2xJRCAweCUwNHgKAAAAAAAAAABjaF9jbF9yYXRlWyV1LyV1XTogY2FwcGVk +IGRlZmljaXRfaW5jciBmcm9tIHJlcXVpcmVkICV1IHRvICV1OyByYXRlICV1IChlZmYgJXUpIGRl +ZmljaXRfbWF4ICV1CgBmY19zZW5kX2FsbG9jX2NwbDogZmFpbGVkIHRvIHNldHVwIGZpbHRlciBj +dHVwbGUKAAAAAAAAAAAAAAAAAAAAZmNvZV9jb21wdXRlX2N0dXBsZSAweCV4OiV4CgAAAABjb21w +dXRlX2N0dXBsZSgpOiBmYWlsZWQgdG8gc2V0dXAgZmlsdGVyIGN0dXBsZQoAAAAAAAAAAAAAAAAA +AAAARkNvRSBGQ0YgdGltZXI6IGZsb3djIHN0YXRlIDB4JXgsIHBvcnQgMHgleCAsZmNmIDB4JXgs +IGZsb3djX2lkIDB4JXgKAAAAAAAAAAAAAAByaV93cl9pbml0WyV1XTogbXNzICV1IGlzIG5vdCA4 +LWJ5dGUgYWxpZ25lZAoAAABjb3JlX3Byb2dyYW1fdGNiOiB0aWQgJSN4IHRfc3RhdGUgJSN4IHJj +dl9hZHYgMHglMDh4IHJjdl9zY2FsZSAlI3ggdHhfbWF4ICUjeCByY3Zfbnh0ICUjeCBhdGlkICUj +eAoAAAAAAAAAAAAAAAAACW9wdDAgJSN4JXggb3B0MiAlI3ggaXB2NiAlI3ggZmxhZ3NfdGltZXIg +MHglMDh4CgAAAAAAAAAAAAAAAAAAAG9mbGRfY29ubmVjdGlvbl93cjogY29ubmVjdGlvbiB3aXRo +IDUtdHVwbGUgbHAgMHglMDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4JTA4eCBwaXAgMHglMDh4JTA4 +eCBmaWx0ZXIgMHglMDh4IGV4aXN0cyBAIExFIGluZGV4ICV1CgAAAAAAAAAAAAAAAAAAAG9mbGRf +Y29ubmVjdGlvbl93cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUgbHAgMHglMDR4IGZwIDB4JTA0 +eCBsaXAgMHglMDh4IHBpcCAweCUwOHggZmlsdGVyIDB4JTA4eCBleGlzdHMgQCBMRSBpbmRleCAl +dQoAAAAAAAAAb2ZsZF9jb25uZWN0aW9uX3dyOiBjb25uZWN0aW9uIHdpdGggNS10dXBsZSBscCAw +eCUwNHggZnAgMHglMDR4IGxpcCAweCUwOHglMDh4IHBpcCAweCUwOHglMDh4IGZpbHRlciAweCUw +OHgKAAAAAG9mbGRfY29ubmVjdGlvbl93cjogY29ubmVjdGlvbiB3aXRoIDUtdHVwbGUgbHAgMHgl +MDR4IGZwIDB4JTA0eCBsaXAgMHglMDh4IHBpcCAweCUwOHggZmlsdGVyIDB4JTA4eAoAAAAAAAAA +AAAAAABJUUZMSU5UIHBmbiAldSB2Zm4gJXU6IGlxZXNpemUgJXUgdG9vIHNtYWxsCgAAAABJUUZM +SU5UIHBmbiAldSB2Zm4gJXU6IGlxaWQgJXUgdG9vIGxhcmdlIChtYXggJXUpCgAAAAAAAAAAAAAA +AAAASVFGTElOVCBwZm4gJXUgdmZuICV1OiBpcWlkICV1IG5vdCBhbGxvY2F0ZWQKAAAASVFGTElO +VCBwZm4gJXUgdmZuICV1OiBmbDBpZCAldSB0b28gbGFyZ2UgKG1heCAldSkKAAAAAAAAAAAAAAAA +AElRRkxJTlQgcGZuICV1IHZmbiAldTogZmwwaWQgJXUgbm90IGFsbG9jYXRlZAoAAElRRkxJTlQg +cGZuICV1IHZmbiAldTogZmwxaWQgJXUgdG9vIGxhcmdlIChtYXggJXUpCgAAAAAAAAAAAAAAAABJ +UUZMSU5UIHBmbiAldSB2Zm4gJXU6IGZsMWlkICV1IG5vdCBhbGxvY2F0ZWQKAABJUUZMSU5UIHBm +biAldSB2Zm4gJXU6IGZsMWlkICV1IGlzIHZhbGlkIGJ1dCBub3QgZmwwaWQgJXUKAAAAAAAASVFG +TElOVCBwZm4gJXUgdmZuICV1OiBmbDFpZCAldSBpcyB2YWxpZCBidXQgaGVhZGVyIHNwbGl0IGZl +YXR1cmUgaXMgbm90IGVuYWJsZWQKAAAAAAAAAAAAAAAAAAAAaHdfdWxwdHhfd29ya2Fyb3VuZF9w +cjE2OTQ5X2VuYWJsZWRfcGY6IHBmICV1IGVuYWJsZWQgJXUKAAAAAAAAAGh3X3VscHR4X3dvcmth +cm91bmRfcHIxNjk0OV9lbmFibGVkX3ZmaWQ6IHZmaWQgJXUgZW5hYmxlZCAldQoAAABFUSBwZm4g +JXUgdmZuICV1OiBjcmVhdGluZyBFVEggZXFpZCAldSB3aXRoIHBlbmRpbmcgV1IocykgKG51bV9i +eXRlcyAldSBhbmQgZmxhZ3MgMHglMDh4CgAAAAAAAABFUSBwZm4gJXUgdmZuICV1OiBjcmVhdGlu +ZyBDVFJMIGVxaWQgJXUgd2l0aCBwZW5kaW5nIFdSKHMpIChudW1fYnl0ZXMgJXUgYW5kIGZsYWdz +IDB4JTA4eAoAAAAAAABFUSBwZm4gJXUgdmZuICV1OiBlcWlkICV1IHRvbyBsYXJnZSAobWF4ICV1 +KQoAAABFUSBwZm4gJXUgdmZuICV1OiBlcWlkICV1IG5vdCBhbGxvY2F0ZWQKAAAAAAAAAABwb3J0 +X2JsaW5rX2xlZF9yZXN0b3JlCgAAAAAAAAAAAHBvcnRfYmxpbms6IGJsaW5rZHVyPTB4JXggYmxp +bmtfcmVmY250CgAAAAAAAAAAAHBvcnRfYmxpbms6IAlibGlua19yZWZjbnQ9MHgleAoAcG9ydF9i +bGluazogCWJsaW5rX3JlZmNudD0weCV4CgBtaWlfYW5yZXN0YXJ0WyV1XTogYWNhcHMgMHgleAoA +AHBvcnRfY21kX2hhbmRsZXI6IHVua25vd24gdS5kY2IudHlwZSAweCV4CgAAAAAAAHBvcnRbJXU6 +MHglMDJ4OjB4JTAyeF06IGwxY2ZnLCBpbnZhbGlkIHJlcXVlc3QsIHBjYXBzIDB4JXggYWNhcHMg +MHgleCByY2FwcyAweCV4CgAAAAAAAAAAAAAAAAAAAHBvcnRbJXU6MHglMDJ4OjB4JTAyeF06IGwx +Y2ZnLCBwY2FwcyAlI3ggYWNhcHMgJSN4IHJjYXBzICUjeCBtY2FwcyAlI3gKAAAAAAAAAAAAcG9y +dFsldToweCUwMng6MHglMDJ4XTogbDFjZmcsIG1kaSBpc3N1ZSBwY2FwcyAweCV4IGFjYXBzIDB4 +JXggcmNhcHMgMHgleAoAAAAAAABwb3J0WyV1OjB4JTAyeDoweCUwMnhdOiBsMWNmZywgY2Fubm90 +IGZvcmNlIG5vL211bHRpcGxlIHNwZWVkKHMpLCBwY2FwcyAweCV4IGFjYXBzIDB4JXggcmNhcHMg +MHgleAoAAAAAAAAAAAAAAAAAZXRoX2Zsb3djX2hhbmRsZXJbMHgleF06IGZsYWdzIDB4JTA4eCBu +dW1fYnl0ZXMgJXUgc2NoZWRjbCAweCV4IC0+IDB4JXgKAAAAAAAAAABzY3NpX2NtZDogcmVjZWl2 +ZWQgVE1GIG9wIFsweCV4XSBmdW5jIFsweCV4XSBvbiBjb25uIFsweCV4XSB0aHJvdWdoIGNvbW1h +bmQgcGF0aC4KAAAAAAAAAAAAAAAAAABzY3NpX2NtZDogY29ubl9mYyBbMHgleF0sIHN0YXRlIFsw +eCV4XSwgc2Vzc19mYyBbMHgleF0gaW4gcmVjb3ZlcnkuIFNraXBwaW5nIGlzdGFza19mYyBbMHgl +eF0gZnJvbSBUWC4KAAAAAAAAAAAAc2NzaV9jbWQ6IGlTQ1NJIGNvbW1hbmQgc2VxdWVuY2Ugd2lu +ZG93IGNsb3NlZC4gY29ubiBbMHgleF0sIG9wIFsweCV4XSwgIGNtZHNuIFsweCV4XSwgc2VudF9j +bWRzbiBbMHgleF0sIG1heF9jbWRzbiBbMHgleF0sIGl0dCBbMHgleF0KAAAAAAAAAAAAc2NzaV9y +ZWFkOiBjb25uX2ZjIFsweCV4XSwgc3RhdGUgWzB4JXhdLCBzZXNzX2ZjIFsweCV4XSBpbiByZWNv +dmVyeS4gU2tpcHBpbmcgaXN0YXNrX2ZjIFsweCV4XSBmcm9tIFRYLgoAAAAAAAAAAHNjc2lfcmVh +ZDogaVNDU0kgY29tbWFuZCBzZXF1ZW5jZSB3aW5kb3cgY2xvc2VkLiBjb25uIFsweCV4XSwgY21k +c24gWzB4JXhdLCBzZW50X2NtZHNuIFsweCV4XSwgbWF4X2NtZHNuIFsweCV4XQoAAAAAAAAAAAAA +AAAAAAAAc2NzaV93cml0ZTogY29ubl9mYyBbMHgleF0sIHN0YXRlIFsweCV4XSwgc2Vzc19mYyBb +MHgleF0gaW4gcmVjb3ZlcnkuIFNraXBwaW5nIGlzdGFza19mYyBbMHgleF0gZnJvbSBUWC4KAAAA +AAAAAHNjc2lfd3JpdGU6IGlTQ1NJIGNvbW1hbmQgc2VxdWVuY2Ugd2luZG93IGNsb3NlZC4gY29u +biBbMHgleF0sIGNtZHNuIFsweCV4XSwgc2VudF9jbWRzbiBbMHgleF0sIG1heF9jbWRzbiBbMHgl +eF0sIGl0dCBbMHgleF0KAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX0xJTktVUAoAAAAA +AAAAAAAAAAAAZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1VQREFURV9EQ0JYX1RMVgoAAAAA +ZGNieF9jb250cm9sX3NtWyV1XSBDT05UUk9MX1BFRVJfTk9UX0FEVkVSVElTRV9EQ0JYCgAAAAAA +AAAAAAAAAGRjYnhfY29udHJvbF9zbVsldV0gQ09OVFJPTF9VUERBVEVfT1BFUl9WRVJTSU9OCgAA +AAAAAAAAAAAAAAAAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfUFJPQ0VTU19QRUVSX1RM +VgoAAABkY2J4X2NvbnRyb2xfc21bJXVdIENPTlRST0xfQUNLX1BFRVIKAAAAAAAAAAAAAABkY2J4 +X2llZWVfdmFsaWRhdGVbJXVdIGVycm9yIChvdWkgJSN4IHN1YnR5cGUgJSN4IGxlbiAlI3gpCgAA +AAAAZGNieF9jZWVfdmFsaWRhdGVbJXVdIGVycm9yCgAAAABjaG5ldF9sMnRfdXBkYXRlOiBsMmRl +dl9mYyBbMHgleF0sIGwyZGV2X2ZjLT5mbG93Y19pZCBbJXVdIGwyZGV2X2ZjLT5mbG93Y19mbGFn +cyBbMHgleF0sIGludGYgWzB4JXhdCgAAAAAAAAAAAAAAY2huZXRfbDJ0X3VwZGF0ZTogbDJkZXZf +ZmMtPmZsb3djX2lkIFsldV0gYWxyZWFkeSBzY2hlZHVsZWQKAAAAAGNobmV0X2wydF91cGRhdGU6 +IGluIGRlbGF5ZWRfcHJvY2Vzc2luZywgbDJ0ZW50IFslMDh4XQoAAAAAAAAAAABESENQdjYgUkVQ +TFkgcmVjZWl2ZWQgc3RhdGUgJXUKAGRoY3AgcmVwbHkgcmVjZWl2ZWQgaW4gd3Jvbmcgc3RhdGUg +JWQKAAAAAAAAAAAAAHVua25vd24gc2VydmVyaWQuIElnbm9yaW5nIGRoY3AgcmVwbHkKAAAAAAAA +AAAAAHJlY2VpdmVkIHJlcGx5IHdpdGggZGlmZmVyZW50IGFkZHJlc3MuIGlnbm9yaW5nIGRoY3Ag +cmVwbHkKAAAAAABESENQdjYgQURWRVJUSVNFIHJlY2VpdmVkCgAAAAAAAGRoY3AgYWR2ZXJ0aXNl +IHJlY2VpdmVkIGluIHdyb25nIHN0YXRlICVkCgAAAAAAAGlnbm9yaW5nIHJjdmQgYWR2ZXJ0aXNl +IHByZWZlcmVuY2UgJXUKAAAAAAAAAAAAAHByZWZpeCBub2RlIDB4JXgsIHZhbGlkX2xpZmV0aW1l +ICV1LCBjdXJyZW50X3RpbWUgJXUgZXhwaXJlZCwgZGVsZXRpbmcgaXQKAAAAAAAARGVsZXRlZCBw +cmVmaXg6IDB4WyUwNHggJTA0eCAlMDR4ICUwNHhdCgAAAAAAAAAAU3RhcnQgREhDUHY2IHRvIGdl +dCB0aGUgaXAgYWRkcmVzcwoAAAAAAAAAAAAAAAAATm8gZGhjcCwgZGhjcCBzdGF0ZSAlZCwgYWRk +ciBzdGF0ZSAlZAoAAAAAAAAAAAAAcGluZyByZXEgcGF5bG9hZCB0b28gbGFyZ2UgJXUuIElnbm9y +aW5nIHJlcS4KAAAAUlIgcmN2ZAoAAAAAAAAAAGNobmV0X2lwdjZfcmRfaW5wdXQ6IEludmFsaWQg +UmVkaXJlY3QKAAAAAAAAAAAAAGNobmV0X2lwdjZfbmFfaW5wdXQ6IEludmFsaWQgTkEKAAAAAAAA +AAAAAAAAAAAAAGlwdjYgTkEgcmN2ZAoAAABjaG5ldF9pcHY2X25hX2lucHV0OiBEdXBsaWNhdGUg +YWRkcmVzcyBkZXRlY3RlZCEKAAAAAAAAAAAAAAAAAAAATkEgaW4gcmVwb25zZSBvZiBOUwoAAAAA +AAAAAAAAAABjaG5ldF9pcHY2X25zX2lucHV0OiBJbnZhbGlkIE5TCgAAAAAAAAAAAAAAAAAAAABj +aG5ldF9pcHY2X25zX2lucHV0OiBJbnZhbGlkIE5TIGlwdjZoLT5wbGVuICV1CgBpcHY2IE5TIHJj +dmQKAAAAY2huZXRfaXB2Nl9uc19pbnB1dDogRHVwbGljYXRlIGFkZHJlc3MgZGV0ZWN0ZWQKAAAA +AAAAAAAAAAAAAAAAAGNobmV0X2lwdjZfbnNfaW5wdXQ6IHNvbWVib2R5IHRyeWluZyB0byB1c2Ug +b3VyIGFkZHJlc3MKAAAAAAAAAABjaG5ldF9pcHY2X25zX2lucHV0OiByZXEgZm9yIGFkZHIgcmVz +b2x1dGlvbgoAAABIb3AgYnkgSG9wIG9wdGlvbgoAAAAAAAAAAAAAAAAAAHByb2Nlc3NfZGhjcF9v +cHRzOiByb290IHBhdGggbGVuIFslZF0gYnl0ZXMKAAAAAG5ldGlmX3Byb2Nlc3NfZGhjcF9vcHRz +OiBsMmRldl9mYy0+Zmxvd2NfaWQgWzB4JXhdLCBNU0dfVFlQRSBbJWRdLCBkaGN0eHQtPnN0YXRl +IFslZF0KAAAAAAAAAAAAAGljbXBfcmVjdjogbDJkZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgcGlk +IFsweCV4XSwgaWNtcCB0eXBlIFsweCV4XQoAAAAAAAAAAAAAAAAAQUJUUyBBQ0MgYXdhaXRpbmcg +UFJMSSBSc3A6IGZsb3djX2lkIDB4JXggb3hfaWQgMHgleCByeF9pZCAweCV4IGlxaWQgMHgleAoA +AAAAAABwb3J0IDB4JXgsIHN0YXRlIDB4JXgsIGNvbW1hbmQgZmFpbGVkIHJldHJpZXMgMHgleAoA +AAAAAAAAAAAAAAAAYXJwX3JlY3Y6IGlwaWQgWzB4JXhdLCBpbl9hZGRyLmFkZHIgWzB4JXhdLCBz +aXAgWzB4JXhdLCByaXAgWzB4JXhdLCBhcnBfb3AgWzB4JXhdCgAAAAAAAAAAAAAAAAAAY2huZXRf +YXJwX3JlY3Y6IGlwIGNvbmZsaWN0IGRldGVjdGVkCgAAAAAAAAAAAAAAY2huZXRfYXJwX3JlY3Y6 +IHBpZCBbJXVdLCB2bGFuIFsweCV4XSwgYXJwIG9wIFsweCV4XSwgc2lwIFsweCV4XSwgcmlwIFsw +eCV4XQoAAABjaG5ldF9pcHY2X3JlY3Y6IHZsYW4gZXh0cmFjdGVkLCB2bGFuaWQgWyV1XSwgbDJk +ZXZfZmMtPmZsb3djX25ldF9sMmRldl92bGFuZGV2IFsweCV4XQoAAAAAAAAAAABJbnZhbGlkIGRh +dGEgbGVuZ3RoIGRsZW4gJXUsIHBhY2tldCBpbmRpY2F0ZXMgJXUgYnl0ZXMKAAAAAAAAAAAAVW5r +bm93biBJUHY2IG54dCBwcm90b2NvbCAldQoAAABJbnZhbGlkIGRpZDp4JTJ4JTJ4JTJ4IHJjdmQg +b24gcG9ydDolZC5Ecm9waW5nIGZyYW1lCgAAAAAAAAAAAAAAcmN0OngleCBzaWQ6eCUyeCUyeCUy +eCByY3ZkIG9uIGZsb3djOiVkLkRyb3BpbmcgZnJhbWUKAAAAAAAAAAAAAGNzb2NrX2ZyZWU6IHNp +emVvZihjc2tfZmMtPnUuY3NvY2spIFsldV0sIGJ5dGVzCgAAAAAAAAAAAAAAAAAAAABHb3QgQ09O +Tl9FWElTVCBmb3IgeGlkOjB4JXgsIHRhZzoweCV4LCByZXRyeWluZy4KAAAAAAAAAAAAAAAAAAAA +Y3NvY2tfcGVlcl9jbG9zZTogY3NrX2ZjLT5mbG93Y19pZCBbMHgleF0sIHRjYl9mYy0+Zmxvd2Nf +aWQgWzB4JXhdLCBjc2tfZmMtPmZsb3djX3N0YXRlIFsweCV4XSwgdGNiX2ZjLT5mbG93Y19zdGF0 +ZSBbMHgleF0KAAAAAABjc29ja19wZWVyX2Nsb3NlOiBjc2tfZmMtPmZsb3djX2lkIFsweCV4XSwg +Y3NrX2ZjLT5mbG93Y19zdGF0ZSAgWzB4JXhdCgAAAAAAAAAAAHRjcF9jbHNfYWJydF9ycGw6IHRj +YiB0aWQgWzB4JTA2eF0sIGZsb3djX3R5cGUgWzB4JXhdLCBjcGxvcCBbMHgleF0gCgAAAAAAAAAA +AAAAY2hfcmF0ZVsldV06IGNhcHBlZCB0aWNrIGZyb20gcmVxdWlyZWQgJXUgdG8gc3VwcG9ydGVk +ICV1OyByYXRlICV1IChlZmYgJXUpIGRlZmljaXRfaW5jciAldSB0aWNrICV1CgAAAAAAAAAAAAAA +AHBrdHNjaGVkX2NoX3JsWyV1XTogY2hhbm5lbCBybCBub3QgYXZhaWxhYmxlIGluIGNvbmp1bmN0 +aW9uIHdpdGggZmxvdyBzaGFwaW5nCgAAcGt0c2NoZWRfY2hfcmxbJXVdOiByYXRlICV1IG1heCAl +dQoAAAAAAAAAAAAAAAAAcGt0c2NoZWRfY2xfd3JyWyV1OiV1XTogd2VpZ2h0ICV1CgAAAAAAAAAA +AAAAAAAAZXFfcGFyYW1zWzB4JXg6MHgleF06IGRtYXEgMHgleCByZWFkICV1IHBmICV1IGVxaWRf +YXBpICV1IHJldCAlZAoAAAAAAAAAAAAAAAAAAABNQyBDTEsgc2V0dGluZyBmYWlsZWQ6IFBMTF9N +X0xPQ0sgbmV2ZXIgdG9nZ2xlZAoAAAAAAAAAAAAAAAAAAAAAd2FpdF9mb3JfY2FsaWJfZG9uZTog +cmV0ICVkIGluICV1IGF0dGVtcHRzCgAAAAAAaHdfbWFfYWRkcl90b19tZW1fdHlwZV9vZmY6IE1B +IGFkZHJlc3MgMHglMDh4IGlzIG5vdCBtYXBwZWQKAAAAAGh3X21hX2FkZHJfdG9fbWVtX3R5cGVf +b2ZmOiBNQSBhZGRyZXNzIDB4JTA4eCBtYXBzIHRvIHR5cGUgJXUgb2Zmc2V0IDB4JXgKAAAAAAAA +bWVtX21hbGxvY190ZW1wOiBmYWlsZWQgdG8gYWxsb2NhdGUgJXUgYnl0ZXMsIHJldHVybmluZyBO +VUxMCgAAAG1lbV9tYWxsb2M6IGZhaWxlZCB0byBhbGxvY2F0ZSAldSBieXRlcywgcmV0dXJuaW5n +IE5VTEwKAAAAAAAAAABsZSBjb25maWd1cmF0aW9uOiBoYXNoIG1vZGUgcmVxdWlyZXMgYXQgbGVh +c3QgMTYgZW50cmllcywgbmhhc2ggJXUKAAAAAAAAAAAAAAAAAGxlIGNvbmZpZ3VyYXRpb246IGhh +c2ggbW9kZSByZXF1aXJlcyBhdCBlbnRyaWVzIHRvIGJlIGEgcG93ZXIgb2YgMiwgbmhhc2ggJXUK +AAAAbGUgY29uZmlndXJhdGlvbjogcmVxdWVzdGVkICV1IHRjYW0gZW50cmllcyBidXQgb25seSAl +dSBhdmFpbGFibGUgKG5yb3V0ZSAldSBuY2xpcCAldSBuZmlsdGVyICV1IG5zZXJ2ZXIgJXUKAAAA +AGxlIGNvbmZpZ3VyYXRpb246IHRjYW0gcmVnaW9ucyBtdXN0IGhhdmUgbXVsdGlwbGUgb2YgMzIg +ZW50cmllcywgbnJvdXRlICV1IG5jbGlwICV1IG5maWx0ZXIgJXUgbnNlcnZlciAldQoAAAAAAABo +d190cF90Y3BfdHVuaW5nczogdHVuaW5nIGZvciBjbHVzdGVyIGVudmlyb25tZW50CgAAAAAAAAAA +AAAAAAAAaHdfdHBfdGNwX3R1bmluZ3M6IHR1bmluZyBmb3IgTEFOIGVudmlyb25tZW50CgAAaHdf +dHBfdGNwX3R1bmluZ3M6IHR1bmluZyBmb3IgV0FOIGVudmlyb25tZW50CgAAaHdfdHBfdGNwX3R1 +bmluZ3M6IG1hbnVhbCB0dW5pbmcKAAAAAAAAAAAAAAAAAAAAX2h3X2NpbV9mbGFzaF9tZW1jcHk6 +IG1lbWNweVggc3RhcnQKAAAAAAAAAAAAAAAAX2h3X2NpbV9mbGFzaF9tZW1jcHk6IGRzdCAweCUw +OCBvZmZzZXQgMHglMDh4IHNpemUgJXUsIHdpZHRoIG9mICV1IGlzIG5vdCBzdXBwb3J0ZWQKAAAA +AAAAAAAAAAAAX2h3X2NpbV9mbGFzaF9tZW1jcHk6IG1lbWNweVggZW5kCgAAAAAAAAAAAAAAAAAA +Y29uZmlndXJhdGlvbiBmaWxlIHBhcnNlciBlbmNvdW50ZXJlZCBlcnJvciBAIGxpbmUgJXU6CgAA +AAAAAAAAAEhPU1QgUEFHRV9TSVpFIFsweCUwbHhdIHRvbyBzbWFsbCwgbWluIFsweCUwbHhdIHJl +cXVpcmVkCgAAAAAAAABwYWdlIHNpemUgWyVsdV0gbWlzbWF0Y2gKAAAAAAAAAFBBR0Ugc2l6ZSAl +bHUgdW5zdXBwb3J0ZWQsIGRkcCBkaXNhYmxlZAoAAAAAAAAAAEhvc3QgcGFnZV9zaXplICVsdSwg +ZGRwX2lkeCAldQoARkNvRSBERFAgaW5pdDogZmNvZSBsbGltaXQgMHgleCwgZmNvZSB1bGltaXQg +MHgleCBnYmwgbGxpbWl0IDB4JXggZ2JsIHVsaW1pdCAweCV4IHBjYnN6ICV4CgAAAAAARkNvRSBE +RFAgaW5pdDogZmNvZSBwcG9kIG9mZiAweCV4LCBmY29lIHN0IHBwb2QgYWRkciAweCV4IGZjb2Ug +bnVtIHBwb2RzIDB4JXgKAABmY29lIHhjaGcgbWdyIGluaXQ6IE51bWJlciBvZiBERFAgZXhjaGFu +Z2VzIGZvciBGQ29FIGlzICV4CgAAAAAAZmNvZSB4Y2hnIG1nciBpbml0OiBOdW1iZXIgb2YgdHVu +bmVsIGV4Y2hzIGZvciBGQ29FIGlzICV4CgAAAAAAAGZjb2VfbDJ0X2luaXQ6IE5vIHVscHR4IGNy +ZWRpdCBjaDpbJXVdCgAAAAAAAAAAAGZjb2VfbDJ0X2luaXQ6IGNoOlsldV0gbDJ0X2lkeCBbJXVd +CgAAAAAAAAAAAAAAAG5vIGwydCBlbnRyaWVzIGNvbmZpZ3VyZWQ7IGZvcmNpbmcgJXUgZW50cmll +cywgc3RhcnRpbmcgYXQgJXUKAABkY2J4IHVwZGF0ZVsldV0gc2VudCB0byBkcml2ZXIgKHR5cGUg +JSN4IHN1YnR5cGUgJSN4IGZsb3djaWQgJXUpCgAAAAAAAAAAAAAAAAAAAGRjYnhfcnVuX3ZlcnNp +b25fc21bJXVdIERDQlhfVkVSX1NUQVRFX1JVTl9JRUVFCgAAAAAAAAAAAAAAAAAAAABkY2J4X3J1 +bl92ZXJzaW9uX3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fQ0VFCgBkY2J4X3J1bl92ZXJzaW9u +X3NtWyV1XSBEQ0JYX1ZFUl9TVEFURV9SVU5fTk9ORQoAAAAAAAAAAAAAAAAAAAAATUFDIGZhaWxl +ZCB0byByZXN5bmMgdHgKAAAAAAAAAABwb3J0WyV1XSBsaW5rIHVwICgldSkgKHNwZWVkICUjeCBh +Y2FwcyAlI3ggbHBjYXBzICUjeCkKAAAAAAAAAAAAcG9ydF9oc3Nfc2lnZGV0WyV1XTogaHNzX3Np +Z2RldCBjaGFuZ2VkIHRvIDB4JXgKAAAAAAAAAAAAAAAAAAAAAHBvcnRbJXVdIGluaXRpYWxpemlu +ZyBLUgoAAAAAAAAAZGlzYWJsaW5nIHR4ICUjeCByeCAlI3gKAAAAAAAAAABDYWxjdWxhdGlvbiBv +dXQgb2YgYm91bmRzIGZ1cmluZyBpbml0OiAlI3ggJSN4ICUjeAoAAAAAAAAAAAAAAAAAX2h3X3Rw +X3BnbW5ndDogdHhfcGFnZV9tYXggJXUgcnhfcGFnZV9tYXggJXUgcHN0cnVjdHMgJXUgc2l6ZSAl +dQoAAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX290aGVyc190b3RhbDogZGRwICV1IGRkcF9pc2Nz +aSAldSBzdGFnICV1IHBibCAldSBycSAldSBycXVkcCAldSAtPiAldQoAAAAAAAAAAAAAAAAAAABf +bXBhcnRpdGlvbl9iYW5rc19tY1g6IG5iYW5rc19wbXR4ICV1ICgldU1CKSBuYmFua3NfcG1yeCAl +dSAoJXVNQikgbmJhbmtzX290aGVycyAldSAoJXVNQikgbmJhbmtzX2Z3ICV1ICgldU1CKQoAX21w +YXJ0aXRpb25fYmFua3NfbWMxOiBuYmFua3NfcG10eCAldSAoJXVNQikgbmJhbmtzX290aGVycyAl +dSAoJXVNQikgbmJhbmtzX2Z3ICV1ICgldU1CKQoAAAAAAAAAX21wYXJ0aXRpb25fYmFua3NfbWMw +OiBuYmFua3NfcG1yeCAldSAoJXVNQikgbmJhbmtzX290aGVycyAldSAoJXVNQikKAAAAAAAAAAAA +AABtZW1fbWFsbG9jX2ludGVybmFsOiBmYWlsZWQgdG8gYWxsb2NhdGUgJXUgYnl0ZXMsIHJldHVy +bmluZyBOVUxMCgAAAAAAAAAAAAAAAAAAAGh3X2VkY19iaXN0WyV1XTogYmlzdF9jbWRbMHglMDh4 +XSBhZGRyIDB4JXggbGVuIDB4JXgKAAAAAAAAAAAAAABod19lZGNfYmlzdFsldV06IGRvbmUsIGVu +Y291bnRlcmVkICV1IGVycm9ycyBvbiBmaXJzdCBhbmQgJXUgZXJyb3JzIG9uIHNlY29uZCBhdHRl +bXB0ICgldWdicHMpCgBtZW1faW5pdF9jYWNoZXM6IGNhY2hlX3NpemUgJXUgZmxvd2NfYnVmX3Rj +Yl9jYWNoZV9zaXplICV1IGJ1ZmxsNjRfY2FjaGVfc2l6ZSAldQoAAAAAAAAAAAAAAAAAAABtcGFy +dGl0aW9uX3BtdHg6IG0gMHglMDh4IHNpemUgJXUKAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX3Bt +cng6IG0gMHglMDh4IHNpemUgJXUKAAAAAAAAAAAAAAAAAABtcGFydGl0aW9uX2VkYyAobm8gZXh0 +bWVtKTogbSAweCUwOHggc2l6ZSAldQoAAABtcGFydGl0aW9uX2VkY19lc3RpbWF0ZTogaHcgbW9k +dWxlcyByZXF1aXJlICVkIGJ5dGVzIGluIEVEQwoAAAAAVGVtcGVyYXR1cmUvVm9sdGFnZSBTZW5z +b3I6IENvcmUgY2xvY2sgJWQgPiA1MDA7IHVzaW5nIDUwMCB0byBzdGF5IGluIGNvbXBsaWFuY2Ug +d2l0aCBoYXJkd2FyZS4KAAAAAAAAAAAAAAAAAAAAAGNobmV0X2J5ZTpsMmRldl9mYy0+Zmxvd2Nf +aWQgWzB4JXhdLCBsMmRldl9mYy0+Zmxvd2NfcGNpZV9wZm4gWzB4JXhdLCBsMmRldl9mYy0+Zmxv +d2NfcGNpZV92Zm4gWzB4JXhdLCBwb3J0IFsweCV4XQoAAAAAAAAAAAAAAAAAY2huZXRfYnllOnZs +YW5kZXZfZmMtPmZsb3djX2lkIFsweCV4XSwgdmxhbmRldl9mYy0+Zmxvd2NfcGNpZV9wZm4gWzB4 +JXhdLCB2bGFuZGV2X2ZjLT5mbG93Y19wY2llX3ZmbiBbMHgleF0sIHBvcnQgWzB4JXhdCgAAAAAA +AABod19tYWNfYWVjX2NvbXBsZXRlWyV1XSBvbiBsYW5lcyAlI3ggKHNpZ2RldCAlI3gpCgAAAAAA +AAAAAAAAAAAAYWVjX2ZzbVsldV0gOiBzdGF0ZSBTVEFSVCAoc2lnZGV0ICUjeCkKAAAAAAAAAAAA +YWVjX2ZzbVsldV0gOiB0cmFuc2l0aW9uaW5nIHRvIFRSQUlOSU5HCgAAAAAAAAAAYWVjX2ZzbVsl +dV0gOiBUUkFJTklOR19DT01QTEVURQoAAAAAAAAAAAAAAAAAAAAAYWVjX2ZzbVsldV0gOiBET05F +CgAAAAAAAAAAAAAAAABhZWNfZnNtWyV1XSA6IHRpbWVkIG91dCB0cmFpbmluZwoAAAAAAAAAAAAA +AAAAAABiZWFuX2ZzbVsldV0gOiBzdGF0ZSBTVEFSVCAoY291bnQgPSAldSkKAAAAAAAAAABiZWFu +X2ZzbVsldV0gOiBlbnRlcmluZyBzdGF0ZSBXQUlUX1NJR0RFVAoAAAAAAABiZWFuX2ZzbVsldV0g +OiBlbnRlcmluZyBzdGF0ZSBOWFBfSEFORExFCgAAAAAAAABiZWFuX2ZzbVsldV0gOiBlbnRlcmlu +ZyBzdGF0ZSBXQUlUX0NPTVBMRVRFCgAAAABiZWFuX2ZzbVsldV0gOiBzdGF0ZSBET05FCgAAAAAA +AGJlYW5fZnNtWyV1XSA6IHN0YXRlIFJFU1RBUlQKAAAAYmVhbl9mc21bJXVdIFRJTUVPVVQ7IHN0 +YXRlICV1IGV0aF9zdGF0dXMgJSN4IGJlYW5fc3RhdHVzICUjeCBoc3Mgc2lnZGV0ICUjeCByZXRy +eV9jbnQgJXUKAAAAAAAAcG9ydCAldSBuZWdvdGlhdGVkIHVuc3VwcG9ydGVkIHNwZWVkICUjeAoA +AAAAAAAAYmVhbi9hZWMgY29tcGxldGUgKHJldHJ5OiAldSkKAABwb3J0WyV1XSByZXNldHRpbmcg +S1IKAAAAAAAAAAAAAFJhbmdlIGNhbGM6IEF2ZXJhZ2VkICUjeCBidXQgaWdub3JlZCB2YWx1ZSAl +I3ggKGl0ZXJhdGlvbiAldSkKAABNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5vdCBn +b2luZyB0byAwCgBNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IERGSSBpbml0IG5vdCBjb21wbGV0aW5n +CgBNQyBjYWxpYnJhdGlvbiBmYWlsZWQ6IENhbGlicmF0aW9uIGRpZG4ndCBjb21wbGV0ZS4KAAAA +AAAAAAAAAAAATUMgY29tbWFuZCBmYWlsZWQgdG8gY29tcGxldGUob3Bjb2RlICUjeCBjYWRkciAl +I3ggYmFkZHIgJSN4IGRlbGF5ICVkKQoAAAAAAAAAAABwZm5fYml0bWFwIDB4JXgKAAAAAAAAAAAA +AAAAAAAAAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCV4ID4g +TEFTVEMyRSAweCV4CgBtYWlsYm94IGNtZCBub3QgeWV0IHN1cHBvcnRlZDogcGZuIDB4JXggdmZu +IDB4JXg7IG9wY29kZSAweCV4CgAAYmFkIG1haWxib3ggY21kOiBwZm4gMHgleCB2Zm4gMHgleDsg +b3Bjb2RlIDB4JXggaXMgdmFsaWQgcG9zdCBkZXZpY2UgaW5pdCBvbmx5CgBiYWQgbWFpbGJveCBj +bWQ6IHBmbiAweCV4IHZmbiAweCV4OyBvcGNvZGUgMHglMDJ4IHJhbWFzayAweCV4IGNtZCByYW1h +c2sgMHgleAoAAGJhZCBtYWlsYm94IGNtZDogcGZuIDB4JXggdmZuIDB4JXg7IG9wY29kZSAweCUw +MnggbGVuMTYgMHgleCB2ZXJzdXMgZXhwZWN0ZWQgbGVuMTYgMHgleAoAAAAAAAAAAGluc3VmZmlj +aWVudCBjYXBzIHRvIHByb2Nlc3MgbWFpbGJveCBjbWQ6IHBmbiAweCV4IHZmbiAweCV4OyByX2Nh +cHMgMHgleCB3eF9jYXBzIDB4JXggcmVxdWlyZWQgcl9jYXBzIDB4JXggd19jYXBzIDB4JXgKAAAA +AAAAAAAAaW5zdWZmaWNpZW50IGNhcHMgdG8gcHJvY2VzcyBtYWlsYm94IGNtZDogcGZuIDB4JXgg +dmZuIDB4JXg7IHJfY2FwcyAweCV4IHd4X2NhcHMgMHgleCByZXF1aXJlZCByX2NhcHMgMHgleCB3 +X2NhcHMgMHgleAoAAAAAAAAAAABod19wb3dlcl9wcmVwOiBWREQ9Tk9ORSBidXQgVkNTPSVkCgAA +AAAAAAAAAAAAAABod19wb3dlcl9wcmVwOiB1bnN1cHBvcnRlZCBleHRlcm5hbCBhZGp1c3RhYmxl +IHBvd2VyIHJlZ3VsYXRvcnMgVkREPSVkLCBWQ1M9JWQKAGh3X3Bvd2VyX3ByZXA6IHVuc3VwcG9y +dGVkIFZERD0lZAoAAAAAAAAAAAAAAAAAAGh3X3Bvd2VyX3ByZXA6IHVuc3VwcG9ydGVkIFZDUz0l +ZAoAAAAAAAAAAAAAAAAAAGh3X3Bvd2VyX3ByZXA6IGkyYyB3cml0ZSBlcnJvciwgVkREPSVkLHJl +dD0lZAoAAGh3X3Bvd2VyX3ByZXA6IHVuc3VwcG9ydGVkIFZERD0lZAoAAAAAAAAAAAAAAAAAAGh3 +X3Bvd2VyX3ByZXA6IGkyYyB3cml0ZSBlcnJvciwgVkNTPSVkLHJldD0lZAoAAGh3X3Bvd2VyX3By +ZXA6IHVuc3VwcG9ydGVkIFZDUz0lZAoAAAAAAAAAAAAAAAAAAFZQRCByZWdpb24gaXMgdG9vIHNt +YWxsIChTRVJDRkdfU1JfUEZOVlBEU0laRSAweCV4KQoAAAAAAAAAAAAAAABjZjogZmFpbGVkIHRv +IGFsbG9jYXRlZCBtZW1vcnkgZm9yIGNvbmZpZ3VyYXRpb24gZmlsZSwgcmV0ICVkCgAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA diff --git a/sys/modules/cxgbe/t4_firmware/Makefile b/sys/modules/cxgbe/t4_firmware/Makefile index 16be94005f55..391632c3ec72 100644 --- a/sys/modules/cxgbe/t4_firmware/Makefile +++ b/sys/modules/cxgbe/t4_firmware/Makefile @@ -17,7 +17,7 @@ FIRMWS+= ${F}:${F:C/.txt//}:1.0.0.0 .endif .endfor -T4FW_VER= 1.14.2.0 +T4FW_VER= 1.14.4.0 FIRMWS+= t4fw.fw:t4fw:${T4FW_VER} CLEANFILES+= t4fw.fw diff --git a/sys/modules/cxgbe/t5_firmware/Makefile b/sys/modules/cxgbe/t5_firmware/Makefile index eba2faa20b43..c74e3c1a00e9 100644 --- a/sys/modules/cxgbe/t5_firmware/Makefile +++ b/sys/modules/cxgbe/t5_firmware/Makefile @@ -17,7 +17,7 @@ FIRMWS+= ${F}:${F:C/.txt//}:1.0.0.0 .endif .endfor -T5FW_VER= 1.14.2.0 +T5FW_VER= 1.14.4.0 FIRMWS+= t5fw.fw:t5fw:${T5FW_VER} CLEANFILES+= t5fw.fw From f5a15df7d8807c0d659fea99898d3698ef551e00 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Wed, 5 Aug 2015 21:11:32 +0000 Subject: [PATCH 256/314] Add regression tests for a bug reported in stable/10 While pw(8) on head is not affected it is worth adding more regression tests ensuring this bug will not happen unnoticed in the futur --- usr.sbin/pw/tests/pw_usermod.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/usr.sbin/pw/tests/pw_usermod.sh b/usr.sbin/pw/tests/pw_usermod.sh index 7acc7a526122..236fd27661eb 100755 --- a/usr.sbin/pw/tests/pw_usermod.sh +++ b/usr.sbin/pw/tests/pw_usermod.sh @@ -195,6 +195,14 @@ user_mod_renamehome_body() { test -d ${HOME}/home/bar || atf_fail "Directory not created" } +atf_test_case user_mod_uid +user_mod_uid_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:0 ${PW} usermod foo -u 5000 +} + atf_init_test_cases() { atf_add_test_case user_mod atf_add_test_case user_mod_noupdate @@ -210,4 +218,5 @@ atf_init_test_cases() { atf_add_test_case user_mod_h atf_add_test_case user_mod_H atf_add_test_case user_mod_renamehome + atf_add_test_case user_mod_uid } From 66b870f3cb571af2a0b923c3f56287449338b9d0 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 5 Aug 2015 21:16:12 +0000 Subject: [PATCH 257/314] Add a missing method - ath_hal_settsf64(). This is required for TDMA slave mode. --- sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c index 5bdd74f31ca5..6118b8292293 100644 --- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c +++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c @@ -97,6 +97,18 @@ ar9300_freebsd_get_cts_timeout(struct ath_hal *ah) return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ } +static void +ar9300_freebsd_set_tsf64(struct ath_hal *ah, uint64_t tsf64) +{ + + /* + * XXX TODO: read ar5416SetTsf64() - we should wait before we do + * this. + */ + OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff); + OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff); +} + void ar9300_attach_freebsd_ops(struct ath_hal *ah) { @@ -182,6 +194,7 @@ ar9300_attach_freebsd_ops(struct ath_hal *ah) ah->ah_getTsf32 = ar9300_get_tsf32; ah->ah_getTsf64 = ar9300_get_tsf64; ah->ah_resetTsf = ar9300_reset_tsf; + ah->ah_setTsf64 = ar9300_freebsd_set_tsf64; ah->ah_detectCardPresent = ar9300_detect_card_present; // ah->ah_updateMibCounters = ar9300_update_mib_counters; ah->ah_getRfGain = ar9300_get_rfgain; From 70c81b207714430bcc047ad31ddbfc38fe252793 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Wed, 5 Aug 2015 21:22:25 +0000 Subject: [PATCH 258/314] Add a hack-around to this fatal taskqueue running whilst the NIC is detaching. This mostly fixes a panic - the reset path shouldn't run whilst the NIC is being torn down. It's not locked, so it's "mostly" ok, but most of the rest of the driver doesn't read sc->invalid with sensible locking. Grr. The real solution is to cleanly tear down taskqueues in the detach/suspend phase, but .. --- sys/dev/ath/if_ath.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 4aac93bb0f5b..2c935a2b857d 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -2318,6 +2318,9 @@ ath_fatal_proc(void *arg, int pending) u_int32_t len; void *sp; + if (sc->sc_invalid) + return; + device_printf(sc->sc_dev, "hardware error; resetting\n"); /* * Fatal errors are unrecoverable. Typically these From a2925a5ae39e7be8ff9e834f608dbea9d95654b9 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Wed, 5 Aug 2015 21:33:30 +0000 Subject: [PATCH 259/314] find: Fix segfault with very long path in -exec/-ok ... {} \;. If the resulting argument is longer than MAXPATHLEN, realloc() was called to extend the space, but the new pointer was not correctly stored. Different from what OpenBSD has done, rewrite brace_subst() to calculate the necessary space first and realloc() at most once. As before, the e_len fields are not updated in case of a realloc. Therefore, a following long argument will do another realloc. PR: 201750 MFC after: 1 week --- usr.bin/find/extern.h | 2 +- usr.bin/find/misc.c | 38 ++++++++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h index 3afe6e4f7d15..b2e344acd7a8 100644 --- a/usr.bin/find/extern.h +++ b/usr.bin/find/extern.h @@ -32,7 +32,7 @@ #include -void brace_subst(char *, char **, char *, int); +void brace_subst(char *, char **, char *, size_t); PLAN *find_create(char ***); int find_execute(PLAN *, char **); PLAN *find_formplan(char **); diff --git a/usr.bin/find/misc.c b/usr.bin/find/misc.c index 11a26beccf9c..df2e5025457c 100644 --- a/usr.bin/find/misc.c +++ b/usr.bin/find/misc.c @@ -57,23 +57,33 @@ __FBSDID("$FreeBSD$"); * Replace occurrences of {} in s1 with s2 and return the result string. */ void -brace_subst(char *orig, char **store, char *path, int len) +brace_subst(char *orig, char **store, char *path, size_t len) { - int plen; - char ch, *p; + const char *pastorigend, *p, *q; + char *dst; + size_t newlen, plen; plen = strlen(path); - for (p = *store; (ch = *orig) != '\0'; ++orig) - if (ch == '{' && orig[1] == '}') { - while ((p - *store) + plen > len) - if (!(*store = realloc(*store, len *= 2))) - err(1, NULL); - memmove(p, path, plen); - p += plen; - ++orig; - } else - *p++ = ch; - *p = '\0'; + newlen = strlen(orig) + 1; + pastorigend = orig + newlen; + for (p = orig; (q = strstr(p, "{}")) != NULL; p = q + 2) { + if (plen > 2 && newlen + plen - 2 < newlen) + errx(2, "brace_subst overflow"); + newlen += plen - 2; + } + if (newlen > len) { + *store = reallocf(*store, newlen); + if (*store == NULL) + err(2, NULL); + } + dst = *store; + for (p = orig; (q = strstr(p, "{}")) != NULL; p = q + 2) { + memcpy(dst, p, q - p); + dst += q - p; + memcpy(dst, path, plen); + dst += plen; + } + memcpy(dst, p, pastorigend - p); } /* From f2a20b166a1efde194b39d8fae5841b843819f4d Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 5 Aug 2015 21:58:32 +0000 Subject: [PATCH 260/314] Relax serialization of SYNCHRONIZE CACHE commands. Before this change SYNCHRONIZE CACHE commands were executed exclusively, as if they had ORDERED tag. But looking through SCSI specs I've found no any reason to be so strict. For reads this ordering seems pointless. For writes it looks less obvious, so I left ordering against preceeding write commands, while following ones are no longer required to wait. MFC after: 2 weeks Sponsored by: iXsystems, Inc. --- sys/cam/ctl/ctl_cmd_table.c | 8 ++++---- sys/cam/ctl/ctl_private.h | 1 + sys/cam/ctl/ctl_ser_table.c | 29 +++++++++++++++-------------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c index b07ea9355708..fbf0d126f8b9 100644 --- a/sys/cam/ctl/ctl_cmd_table.c +++ b/sys/cam/ctl/ctl_cmd_table.c @@ -785,8 +785,8 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 35 SYNCHRONIZE CACHE(10) */ -{ctl_sync_cache, CTL_SERIDX_START, CTL_CMD_FLAG_OK_ON_SLUN | - CTL_FLAG_DATA_NONE, +{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN | + CTL_FLAG_DATA_NONE, CTL_LUN_PAT_NONE, 10, {0, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}}, @@ -1138,8 +1138,8 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, /* 91 SYNCHRONIZE CACHE(16) */ -{ctl_sync_cache, CTL_SERIDX_START, CTL_CMD_FLAG_OK_ON_SLUN | - CTL_FLAG_DATA_NONE, +{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN | + CTL_FLAG_DATA_NONE, CTL_LUN_PAT_NONE, 16, {0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h index 8a00b5cae909..a038552e3c4b 100644 --- a/sys/cam/ctl/ctl_private.h +++ b/sys/cam/ctl/ctl_private.h @@ -141,6 +141,7 @@ typedef enum { CTL_SERIDX_READ, CTL_SERIDX_WRITE, CTL_SERIDX_UNMAP, + CTL_SERIDX_SYNC, CTL_SERIDX_MD_SNS, CTL_SERIDX_MD_SEL, CTL_SERIDX_RQ_SNS, diff --git a/sys/cam/ctl/ctl_ser_table.c b/sys/cam/ctl/ctl_ser_table.c index ee2d019b528a..8d5d6bce81ba 100644 --- a/sys/cam/ctl/ctl_ser_table.c +++ b/sys/cam/ctl/ctl_ser_table.c @@ -63,19 +63,20 @@ static ctl_serialize_action ctl_serialize_table[CTL_SERIDX_COUNT][CTL_SERIDX_COUNT] = { -/**>IDX_ :: 2nd:TUR RD WRT UNM MDSN MDSL RQSN INQ RDCP RES LSNS FMT STR*/ -/*TUR */{ pS, pS, pS, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK}, -/*READ */{ pS, xS, xT, bO, bK, bK, bK, pS, pS, bK, pS, bK, bK}, -/*WRITE */{ pS, xT, xT, bO, bK, bK, bK, pS, pS, bK, pS, bK, bK}, -/*UNMAP */{ pS, xO, xO, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK}, -/*MD_SNS */{ bK, bK, bK, bK, pS, bK, bK, pS, pS, bK, pS, bK, bK}, -/*MD_SEL */{ bK, bK, bK, bK, bK, bK, bK, pS, pS, bK, pS, bK, bK}, -/*RQ_SNS */{ pS, pS, pS, pS, pS, pS, bK, pS, pS, bK, pS, bK, bK}, -/*INQ */{ pS, pS, pS, pS, pS, pS, bK, pS, pS, pS, pS, bK, bK}, -/*RD_CAP */{ pS, pS, pS, pS, pS, pS, bK, pS, pS, pS, pS, bK, pS}, -/*RES */{ bK, bK, bK, bK, bK, bK, bK, pS, bK, bK, bK, bK, bK}, -/*LOG_SNS */{ pS, pS, pS, pS, pS, bK, bK, pS, pS, bK, pS, bK, bK}, -/*FORMAT */{ pS, bK, bK, bK, bK, bK, pS, pS, bK, bK, bK, bK, bK}, -/*START */{ bK, bK, bK, bK, bK, bK, bK, pS, bK, bK, bK, bK, bK}, +/**>IDX_ :: 2nd:TUR RD WRT UNM SYN MDSN MDSL RQSN INQ RDCP RES LSNS FMT STR*/ +/*TUR */{ pS, pS, pS, pS, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK}, +/*READ */{ pS, xS, xT, bO, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK}, +/*WRITE */{ pS, xT, xT, bO, bO, bK, bK, bK, pS, pS, bK, pS, bK, bK}, +/*UNMAP */{ pS, xO, xO, pS, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK}, +/*SYNC */{ pS, pS, pS, pS, pS, bK, bK, bK, pS, pS, bK, pS, bK, bK}, +/*MD_SNS */{ bK, bK, bK, bK, bK, pS, bK, bK, pS, pS, bK, pS, bK, bK}, +/*MD_SEL */{ bK, bK, bK, bK, bK, bK, bK, bK, pS, pS, bK, pS, bK, bK}, +/*RQ_SNS */{ pS, pS, pS, pS, pS, pS, pS, bK, pS, pS, bK, pS, bK, bK}, +/*INQ */{ pS, pS, pS, pS, pS, pS, pS, bK, pS, pS, pS, pS, bK, bK}, +/*RD_CAP */{ pS, pS, pS, pS, pS, pS, pS, bK, pS, pS, pS, pS, bK, pS}, +/*RES */{ bK, bK, bK, bK, bK, bK, bK, bK, pS, bK, bK, bK, bK, bK}, +/*LOG_SNS */{ pS, pS, pS, pS, pS, pS, bK, bK, pS, pS, bK, pS, bK, bK}, +/*FORMAT */{ pS, bK, bK, bK, bK, bK, bK, pS, pS, bK, bK, bK, bK, bK}, +/*START */{ bK, bK, bK, bK, bK, bK, bK, bK, pS, bK, bK, bK, bK, bK}, }; From 3fd78bfab2cdb03bf9a701097e68c8ead33722a2 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 5 Aug 2015 22:04:54 +0000 Subject: [PATCH 261/314] Fix shell injection vulnerability in patch(1) via ed(1) by tightening sanity check of the input. [1] While I'm there also replace ed(1) with red(1) because we do not need the unrestricted functionality. [2] Obtained from: Bitrig [1], DragonFly [2] Security: CVE-2015-1418 [1] --- usr.bin/patch/pathnames.h | 2 +- usr.bin/patch/pch.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/usr.bin/patch/pathnames.h b/usr.bin/patch/pathnames.h index d31300ea843a..79d8faea6285 100644 --- a/usr.bin/patch/pathnames.h +++ b/usr.bin/patch/pathnames.h @@ -9,4 +9,4 @@ #include -#define _PATH_ED "/bin/ed" +#define _PATH_RED "/bin/red" diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c index e731ca1f9e8f..5fadf6292f67 100644 --- a/usr.bin/patch/pch.c +++ b/usr.bin/patch/pch.c @@ -1,4 +1,3 @@ - /*- * Copyright 1986, Larry Wall * @@ -1410,13 +1409,14 @@ do_ed_script(void) char *t; off_t beginning_of_this_line; FILE *pipefp = NULL; + int continuation; if (!skip_rest_of_patch) { if (copy_file(filearg[0], TMPOUTNAME) < 0) { unlink(TMPOUTNAME); fatal("can't create temp file %s", TMPOUTNAME); } - snprintf(buf, buf_size, "%s%s%s", _PATH_ED, + snprintf(buf, buf_size, "%s%s%s", _PATH_RED, verbose ? " " : " -s ", TMPOUTNAME); pipefp = popen(buf, "w"); } @@ -1434,7 +1434,19 @@ do_ed_script(void) (*t == 'a' || *t == 'c' || *t == 'd' || *t == 'i' || *t == 's')) { if (pipefp != NULL) fputs(buf, pipefp); - if (*t != 'd') { + if (*t == 's') { + for (;;) { + continuation = 0; + t = strchr(buf, '\0') - 1; + while (--t >= buf && *t == '\\') + continuation = !continuation; + if (!continuation || + pgets(true) == 0) + break; + if (pipefp != NULL) + fputs(buf, pipefp); + } + } else if (*t != 'd') { while (pgets(true)) { p_input_line++; if (pipefp != NULL) From b07d93f53871940d82923340575bf5310dc4e561 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 5 Aug 2015 22:04:56 +0000 Subject: [PATCH 262/314] Fix a bug which could make routed(8) daemon exit by sending a special RIP query from a remote machine, similar to SA-14:21.routed. Submitted by: hrs --- sbin/routed/input.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sbin/routed/input.c b/sbin/routed/input.c index 895ef507db7e..bc030283e15f 100644 --- a/sbin/routed/input.c +++ b/sbin/routed/input.c @@ -160,6 +160,12 @@ input(struct sockaddr_in *from, /* received from this IP address */ trace_rip("Recv", "from", from, sifp, rip, cc); + if (sifp == 0) { + trace_pkt(" discard a request from an indirect router" + " (possibly an attack)"); + return; + } + if (rip->rip_vers == 0) { msglim(&bad_router, FROM_NADDR, "RIP version 0, cmd %d, packet received from %s", From 7d0d4342e3649b5a1894a77c3b1af102aae854c6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 5 Aug 2015 22:24:49 +0000 Subject: [PATCH 263/314] Pass SYNCHRONIZE CACHE command parameters to backends. At this point IMMED flag is translated to MNT_NOWAIT flag of VOP_FSYNC(), hoping that file system implements that (ZFS seems doesn't). MFC after: 2 weeks Sponsored by: iXsystems, Inc. --- sys/cam/ctl/ctl.c | 9 ++++ sys/cam/ctl/ctl_backend_block.c | 88 ++++++++++++++------------------- sys/cam/ctl/ctl_cmd_table.c | 4 +- 3 files changed, 49 insertions(+), 52 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 3d562d02c8f2..3889ca8eb642 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -5507,9 +5507,11 @@ ctl_sync_cache(struct ctl_scsiio *ctsio) { struct ctl_lun *lun; struct ctl_softc *softc; + struct ctl_lba_len_flags *lbalen; uint64_t starting_lba; uint32_t block_count; int retval; + uint8_t byte2; CTL_DEBUG_PRINT(("ctl_sync_cache\n")); @@ -5524,6 +5526,7 @@ ctl_sync_cache(struct ctl_scsiio *ctsio) starting_lba = scsi_4btoul(cdb->begin_lba); block_count = scsi_2btoul(cdb->lb_count); + byte2 = cdb->byte2; break; } case SYNCHRONIZE_CACHE_16: { @@ -5532,6 +5535,7 @@ ctl_sync_cache(struct ctl_scsiio *ctsio) starting_lba = scsi_8btou64(cdb->begin_lba); block_count = scsi_4btoul(cdb->lb_count); + byte2 = cdb->byte2; break; } default: @@ -5562,6 +5566,11 @@ ctl_sync_cache(struct ctl_scsiio *ctsio) goto bailout; } + lbalen = (struct ctl_lba_len_flags *)&ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; + lbalen->lba = starting_lba; + lbalen->len = block_count; + lbalen->flags = byte2; + /* * Check to see whether we're configured to send the SYNCHRONIZE * CACHE command directly to the back end. diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index 8ea52aa323df..5bb3121688a3 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -224,6 +224,7 @@ struct ctl_be_block_io { devstat_trans_flags ds_trans_type; uint64_t io_len; uint64_t io_offset; + int io_arg; struct ctl_be_block_softc *softc; struct ctl_be_block_lun *lun; void (*beio_cont)(struct ctl_be_block_io *beio); /* to continue processing */ @@ -581,7 +582,8 @@ ctl_be_block_flush_file(struct ctl_be_block_lun *be_lun, vn_lock(be_lun->vn, lock_flags | LK_RETRY); - error = VOP_FSYNC(be_lun->vn, MNT_WAIT, curthread); + error = VOP_FSYNC(be_lun->vn, beio->io_arg ? MNT_NOWAIT : MNT_WAIT, + curthread); VOP_UNLOCK(be_lun->vn, 0); vn_finished_write(mountpoint); @@ -674,9 +676,6 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun, * ZFS pays attention to IO_SYNC (which translates into the * Solaris define FRSYNC for zfs_read()) for reads. It * attempts to sync the file before reading. - * - * So, to attempt to provide some barrier semantics in the - * BIO_ORDERED case, set both IO_DIRECT and IO_SYNC. */ error = VOP_READ(be_lun->vn, &xuio, flags, file_data->cred); @@ -711,9 +710,6 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun, * ZFS pays attention to IO_SYNC (a.k.a. FSYNC or FRSYNC) * for writes. It will flush the transaction from the * cache before returning. - * - * So if we've got the BIO_ORDERED flag set, we want - * IO_SYNC in either the UFS or ZFS case. */ error = VOP_WRITE(be_lun->vn, &xuio, flags, file_data->cred); VOP_UNLOCK(be_lun->vn, 0); @@ -981,7 +977,6 @@ ctl_be_block_flush_dev(struct ctl_be_block_lun *be_lun, bio = g_alloc_bio(); bio->bio_cmd = BIO_FLUSH; - bio->bio_flags |= BIO_ORDERED; bio->bio_dev = dev_data->cdev; bio->bio_offset = 0; bio->bio_data = 0; @@ -1166,6 +1161,26 @@ ctl_be_block_getattr_dev(struct ctl_be_block_lun *be_lun, const char *attrname) return (arg.value.off); } +static void +ctl_be_block_cw_dispatch_sync(struct ctl_be_block_lun *be_lun, + union ctl_io *io) +{ + struct ctl_be_block_io *beio; + struct ctl_lba_len_flags *lbalen; + + DPRINTF("entered\n"); + beio = (struct ctl_be_block_io *)PRIV(io)->ptr; + lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; + + beio->io_len = lbalen->len * be_lun->blocksize; + beio->io_offset = lbalen->lba * be_lun->blocksize; + beio->io_arg = (lbalen->flags & SSC_IMMED) != 0; + beio->bio_cmd = BIO_FLUSH; + beio->ds_trans_type = DEVSTAT_NO_DATA; + DPRINTF("SYNC\n"); + be_lun->lun_flush(be_lun, beio); +} + static void ctl_be_block_cw_done_ws(struct ctl_be_block_io *beio) { @@ -1188,7 +1203,6 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun, union ctl_io *io) { struct ctl_be_block_io *beio; - struct ctl_be_block_softc *softc; struct ctl_lba_len_flags *lbalen; uint64_t len_left, lba; uint32_t pb, pbo, adj; @@ -1198,7 +1212,6 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun, DPRINTF("entered\n"); beio = (struct ctl_be_block_io *)PRIV(io)->ptr; - softc = be_lun->softc; lbalen = ARGS(beio->io); if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP | SWS_ANCHOR | SWS_NDOB) || @@ -1214,21 +1227,6 @@ ctl_be_block_cw_dispatch_ws(struct ctl_be_block_lun *be_lun, return; } - switch (io->scsiio.tag_type) { - case CTL_TAG_ORDERED: - beio->ds_tag_type = DEVSTAT_TAG_ORDERED; - break; - case CTL_TAG_HEAD_OF_QUEUE: - beio->ds_tag_type = DEVSTAT_TAG_HEAD; - break; - case CTL_TAG_UNTAGGED: - case CTL_TAG_SIMPLE: - case CTL_TAG_ACA: - default: - beio->ds_tag_type = DEVSTAT_TAG_SIMPLE; - break; - } - if (lbalen->flags & (SWS_UNMAP | SWS_ANCHOR)) { beio->io_offset = lbalen->lba * be_lun->blocksize; beio->io_len = (uint64_t)lbalen->len * be_lun->blocksize; @@ -1303,13 +1301,11 @@ ctl_be_block_cw_dispatch_unmap(struct ctl_be_block_lun *be_lun, union ctl_io *io) { struct ctl_be_block_io *beio; - struct ctl_be_block_softc *softc; struct ctl_ptr_len_flags *ptrlen; DPRINTF("entered\n"); beio = (struct ctl_be_block_io *)PRIV(io)->ptr; - softc = be_lun->softc; ptrlen = (struct ctl_ptr_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN]; if ((ptrlen->flags & ~SU_ANCHOR) != 0 || be_lun->unmap == NULL) { @@ -1324,29 +1320,11 @@ ctl_be_block_cw_dispatch_unmap(struct ctl_be_block_lun *be_lun, return; } - switch (io->scsiio.tag_type) { - case CTL_TAG_ORDERED: - beio->ds_tag_type = DEVSTAT_TAG_ORDERED; - break; - case CTL_TAG_HEAD_OF_QUEUE: - beio->ds_tag_type = DEVSTAT_TAG_HEAD; - break; - case CTL_TAG_UNTAGGED: - case CTL_TAG_SIMPLE: - case CTL_TAG_ACA: - default: - beio->ds_tag_type = DEVSTAT_TAG_SIMPLE; - break; - } - beio->io_len = 0; beio->io_offset = -1; - beio->bio_cmd = BIO_DELETE; beio->ds_trans_type = DEVSTAT_FREE; - DPRINTF("UNMAP\n"); - be_lun->unmap(be_lun, beio); } @@ -1417,16 +1395,26 @@ ctl_be_block_cw_dispatch(struct ctl_be_block_lun *be_lun, beio->io = io; beio->lun = be_lun; beio->beio_cont = ctl_be_block_cw_done; + switch (io->scsiio.tag_type) { + case CTL_TAG_ORDERED: + beio->ds_tag_type = DEVSTAT_TAG_ORDERED; + break; + case CTL_TAG_HEAD_OF_QUEUE: + beio->ds_tag_type = DEVSTAT_TAG_HEAD; + break; + case CTL_TAG_UNTAGGED: + case CTL_TAG_SIMPLE: + case CTL_TAG_ACA: + default: + beio->ds_tag_type = DEVSTAT_TAG_SIMPLE; + break; + } PRIV(io)->ptr = (void *)beio; switch (io->scsiio.cdb[0]) { case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: - beio->bio_cmd = BIO_FLUSH; - beio->ds_trans_type = DEVSTAT_NO_DATA; - beio->ds_tag_type = DEVSTAT_TAG_ORDERED; - beio->io_len = 0; - be_lun->lun_flush(be_lun, beio); + ctl_be_block_cw_dispatch_sync(be_lun, io); break; case WRITE_SAME_10: case WRITE_SAME_16: diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c index fbf0d126f8b9..08ff88adefa9 100644 --- a/sys/cam/ctl/ctl_cmd_table.c +++ b/sys/cam/ctl/ctl_cmd_table.c @@ -788,7 +788,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_NONE, CTL_LUN_PAT_NONE, - 10, {0, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}}, + 10, {0x02, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}}, /* 36 LOCK UNLOCK CACHE(10) */ {NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, @@ -1141,7 +1141,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] = {ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_NONE, CTL_LUN_PAT_NONE, - 16, {0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 16, {0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}}, /* 92 LOCK UNLOCK CACHE(16) */ From b5af3f30a752cb607b8ab430cdc46c9bc463f227 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Wed, 5 Aug 2015 22:27:30 +0000 Subject: [PATCH 264/314] nfsclient: Protest loudly when GETATTR responses are invalid BROKEN NFS SERVER OR MIDDLEWARE: Certain WAN "accelerators" attempt to cache NFS GETATTR traffic, but actually corrupt it (e.g., responding to requests with attributes for totally different files). Warn very verbosely when this is detected. Linux' NFS client has a similar warning. Adds a sysctl/tunable (vfs.nfs.fileid_maxwarnings) to configure the quantity of warnings; default to 10. (Zero disables; -1 is unlimited.) Adds a failpoint to aid in validating the warning / behavior with a non-broken server. Use something like: sysctl 'debug.fail_point.nfscl_force_fileid_warning=10%return(1)' Reviewed by: rmacklem Approved by: markj (mentor) Sponsored by: EMC / Isilon Storage Division Differential Revision: https://reviews.freebsd.org/D3304 --- sys/fs/nfsclient/nfs_clport.c | 85 ++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index d3bac30bdc74..a6a216727133 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -42,7 +42,9 @@ __FBSDID("$FreeBSD$"); * generally, I don't like #includes inside .h files, but it seems to * be the easiest way to handle the port. */ +#include #include +#include #include #include #include @@ -83,6 +85,16 @@ NFSDLOCKMUTEX; extern void (*ncl_call_invalcaches)(struct vnode *); +SYSCTL_DECL(_vfs_nfs); +static int ncl_fileid_maxwarnings = 10; +SYSCTL_INT(_vfs_nfs, OID_AUTO, fileid_maxwarnings, CTLFLAG_RWTUN, + &ncl_fileid_maxwarnings, 0, + "Limit fileid corruption warnings; 0 is off; -1 is unlimited"); +static volatile int ncl_fileid_nwarnings; + +static void nfscl_warn_fileid(struct nfsmount *, struct nfsvattr *, + struct nfsvattr *); + /* * Comparison function for vfs_hash functions. */ @@ -343,6 +355,37 @@ nfscl_ngetreopen(struct mount *mntp, u_int8_t *fhp, int fhsize, return (EINVAL); } +static void +nfscl_warn_fileid(struct nfsmount *nmp, struct nfsvattr *oldnap, + struct nfsvattr *newnap) +{ + int off; + + if (ncl_fileid_maxwarnings >= 0 && + ncl_fileid_nwarnings >= ncl_fileid_maxwarnings) + return; + off = 0; + if (ncl_fileid_maxwarnings >= 0) { + if (++ncl_fileid_nwarnings >= ncl_fileid_maxwarnings) + off = 1; + } + + printf("newnfs: server '%s' error: fileid changed. " + "fsid %jx:%jx: expected fileid %#jx, got %#jx. " + "(BROKEN NFS SERVER OR MIDDLEWARE)\n", + nmp->nm_com.nmcom_hostname, + (uintmax_t)nmp->nm_fsid[0], + (uintmax_t)nmp->nm_fsid[1], + (uintmax_t)oldnap->na_fileid, + (uintmax_t)newnap->na_fileid); + + if (off) + printf("newnfs: Logged %d times about fileid corruption; " + "going quiet to avoid spamming logs excessively. (Limit " + "is: %d).\n", ncl_fileid_nwarnings, + ncl_fileid_maxwarnings); +} + /* * Load the attribute cache (that lives in the nfsnode entry) with * the attributes of the second argument and @@ -361,7 +404,11 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper, struct nfsmount *nmp; struct timespec mtime_save; u_quad_t nsize; - int setnsize; + int setnsize, error, force_fid_err; + + error = 0; + setnsize = 0; + nsize = 0; /* * If v_type == VNON it is a new node, so fill in the v_type, @@ -389,6 +436,34 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper, np->n_vattr.na_fsid = nap->na_fsid; np->n_vattr.na_mode = nap->na_mode; } else { + force_fid_err = 0; + KFAIL_POINT_ERROR(DEBUG_FP, nfscl_force_fileid_warning, + force_fid_err); + /* + * BROKEN NFS SERVER OR MIDDLEWARE + * + * Certain NFS servers (certain old proprietary filers ca. + * 2006) or broken middleboxes (e.g. WAN accelerator products) + * will respond to GETATTR requests with results for a + * different fileid. + * + * The WAN accelerator we've observed not only serves stale + * cache results for a given file, it also occasionally serves + * results for wholly different files. This causes surprising + * problems; for example the cached size attribute of a file + * may truncate down and then back up, resulting in zero + * regions in file contents read by applications. We observed + * this reliably with Clang and .c files during parallel build. + * A pcap revealed packet fragmentation and GETATTR RPC + * responses with wholly wrong fileids. + */ + if ((np->n_vattr.na_fileid != 0 && + np->n_vattr.na_fileid != nap->na_fileid) || + force_fid_err) { + nfscl_warn_fileid(nmp, &np->n_vattr, nap); + error = EIDRM; + goto out; + } NFSBCOPY((caddr_t)nap, (caddr_t)&np->n_vattr, sizeof (struct nfsvattr)); } @@ -419,8 +494,6 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper, } else vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; np->n_attrstamp = time_second; - setnsize = 0; - nsize = 0; if (vap->va_size != np->n_size) { if (vap->va_type == VREG) { if (dontshrink && vap->va_size < np->n_size) { @@ -490,14 +563,16 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper, vaper->va_mtime = np->n_mtim; } } + +out: #ifdef KDTRACE_HOOKS if (np->n_attrstamp != 0) - KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, 0); + KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, error); #endif NFSUNLOCKNODE(np); if (setnsize) vnode_pager_setsize(vp, nsize); - return (0); + return (error); } /* From d98d7ba0b4de199558880f524d41a9e9c83b7558 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 01:49:18 +0000 Subject: [PATCH 265/314] Add recently added values of various flags and enumerations including kevent filters, kevent flags, flags to mmap, seek locations, fcntl operations, file flags, socket domains, open flags, resource limits, and pathconf values. --- usr.bin/truss/syscalls.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index b758ddbda221..e8eea832900a 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -297,12 +297,14 @@ struct xlat { static struct xlat kevent_filters[] = { X(EVFILT_READ) X(EVFILT_WRITE) X(EVFILT_AIO) X(EVFILT_VNODE) X(EVFILT_PROC) X(EVFILT_SIGNAL) X(EVFILT_TIMER) - X(EVFILT_FS) X(EVFILT_READ) XEND + X(EVFILT_PROCDESC) X(EVFILT_FS) X(EVFILT_LIO) X(EVFILT_USER) + X(EVFILT_SENDFILE) XEND }; static struct xlat kevent_flags[] = { X(EV_ADD) X(EV_DELETE) X(EV_ENABLE) X(EV_DISABLE) X(EV_ONESHOT) - X(EV_CLEAR) X(EV_FLAG1) X(EV_ERROR) X(EV_EOF) XEND + X(EV_CLEAR) X(EV_RECEIPT) X(EV_DISPATCH) X(EV_FORCEONESHOT) + X(EV_DROP) X(EV_FLAG1) X(EV_ERROR) X(EV_EOF) XEND }; static struct xlat poll_flags[] = { @@ -315,7 +317,7 @@ static struct xlat mmap_flags[] = { X(MAP_SHARED) X(MAP_PRIVATE) X(MAP_FIXED) X(MAP_RESERVED0020) X(MAP_RESERVED0040) X(MAP_RESERVED0080) X(MAP_RESERVED0100) X(MAP_HASSEMAPHORE) X(MAP_STACK) X(MAP_NOSYNC) X(MAP_ANON) - X(MAP_NOCORE) X(MAP_PREFAULT_READ) + X(MAP_EXCL) X(MAP_NOCORE) X(MAP_PREFAULT_READ) #ifdef MAP_32BIT X(MAP_32BIT) #endif @@ -327,7 +329,7 @@ static struct xlat mprot_flags[] = { }; static struct xlat whence_arg[] = { - X(SEEK_SET) X(SEEK_CUR) X(SEEK_END) XEND + X(SEEK_SET) X(SEEK_CUR) X(SEEK_END) X(SEEK_DATA) X(SEEK_HOLE) XEND }; static struct xlat sigaction_flags[] = { @@ -337,7 +339,10 @@ static struct xlat sigaction_flags[] = { static struct xlat fcntl_arg[] = { X(F_DUPFD) X(F_GETFD) X(F_SETFD) X(F_GETFL) X(F_SETFL) - X(F_GETOWN) X(F_SETOWN) X(F_GETLK) X(F_SETLK) X(F_SETLKW) XEND + X(F_GETOWN) X(F_SETOWN) X(F_OGETLK) X(F_OSETLK) X(F_OSETLKW) + X(F_DUP2FD) X(F_GETLK) X(F_SETLK) X(F_SETLKW) X(F_SETLK_REMOTE) + X(F_READAHEAD) X(F_RDAHEAD) X(F_DUPFD_CLOEXEC) X(F_DUP2FD_CLOEXEC) + XEND }; static struct xlat fcntlfd_arg[] = { @@ -346,7 +351,7 @@ static struct xlat fcntlfd_arg[] = { static struct xlat fcntlfl_arg[] = { X(O_APPEND) X(O_ASYNC) X(O_FSYNC) X(O_NONBLOCK) X(O_NOFOLLOW) - X(O_DIRECT) XEND + X(FRDAHEAD) X(O_DIRECT) XEND }; static struct xlat sockdomain_arg[] = { @@ -357,7 +362,8 @@ static struct xlat sockdomain_arg[] = { X(PF_LINK) X(PF_XTP) X(PF_COIP) X(PF_CNT) X(PF_SIP) X(PF_IPX) X(PF_RTIP) X(PF_PIP) X(PF_ISDN) X(PF_KEY) X(PF_INET6) X(PF_NATM) X(PF_ATM) X(PF_NETGRAPH) X(PF_SLOW) X(PF_SCLUSTER) - X(PF_ARP) X(PF_BLUETOOTH) XEND + X(PF_ARP) X(PF_BLUETOOTH) X(PF_IEEE80211) X(PF_INET_SDP) + X(PF_INET6_SDP) XEND }; static struct xlat socktype_arg[] = { @@ -369,7 +375,8 @@ static struct xlat open_flags[] = { X(O_RDONLY) X(O_WRONLY) X(O_RDWR) X(O_ACCMODE) X(O_NONBLOCK) X(O_APPEND) X(O_SHLOCK) X(O_EXLOCK) X(O_ASYNC) X(O_FSYNC) X(O_NOFOLLOW) X(O_CREAT) X(O_TRUNC) X(O_EXCL) X(O_NOCTTY) - X(O_DIRECT) X(O_DIRECTORY) X(O_EXEC) X(O_TTY_INIT) X(O_CLOEXEC) XEND + X(O_DIRECT) X(O_DIRECTORY) X(O_EXEC) X(O_TTY_INIT) X(O_CLOEXEC) + X(O_VERIFY) XEND }; static struct xlat shutdown_arg[] = { @@ -379,7 +386,8 @@ static struct xlat shutdown_arg[] = { static struct xlat resource_arg[] = { X(RLIMIT_CPU) X(RLIMIT_FSIZE) X(RLIMIT_DATA) X(RLIMIT_STACK) X(RLIMIT_CORE) X(RLIMIT_RSS) X(RLIMIT_MEMLOCK) X(RLIMIT_NPROC) - X(RLIMIT_NOFILE) X(RLIMIT_SBSIZE) X(RLIMIT_VMEM) XEND + X(RLIMIT_NOFILE) X(RLIMIT_SBSIZE) X(RLIMIT_VMEM) X(RLIMIT_NPTS) + X(RLIMIT_SWAP) X(RLIMIT_KQUEUES) XEND }; static struct xlat pathconf_arg[] = { @@ -392,12 +400,12 @@ static struct xlat pathconf_arg[] = { X(_PC_REC_MIN_XFER_SIZE) X(_PC_REC_XFER_ALIGN) X(_PC_SYMLINK_MAX) X(_PC_ACL_EXTENDED) X(_PC_ACL_PATH_MAX) X(_PC_CAP_PRESENT) X(_PC_INF_PRESENT) X(_PC_MAC_PRESENT) - XEND + X(_PC_ACL_NFS4) X(_PC_MIN_HOLE_SIZE) XEND }; static struct xlat rfork_flags[] = { - X(RFPROC) X(RFNOWAIT) X(RFFDG) X(RFCFDG) X(RFTHREAD) X(RFMEM) - X(RFSIGSHARE) X(RFTSIGZMB) X(RFLINUXTHPN) XEND + X(RFFDG) X(RFPROC) X(RFMEM) X(RFNOWAIT) X(RFCFDG) X(RFTHREAD) + X(RFSIGSHARE) X(RFLINUXTHPN) X(RFTSIGZMB) X(RFPPWAIT) XEND }; static struct xlat wait_options[] = { From 0f85ff377ba631b70bbddf521132c12b1d5dd250 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Thu, 6 Aug 2015 06:47:28 +0000 Subject: [PATCH 266/314] Add file_open(): the underlying system call of openat(). CloudABI purely operates on file descriptor rights (CAP_*). File descriptor access modes (O_ACCMODE) are emulated on top of rights. Instead of accepting the traditional flags argument, file_open() copies in an fdstat_t object that contains the initial rights the descriptor should have, but also file descriptor flags that should persist after opening (APPEND, NONBLOCK, *SYNC). Only flags that don't persist (EXCL, TRUNC, CREAT, DIRECTORY) are passed in as an argument. file_open() first converts the rights, the persistent flags and the non-persistent flags to fflags. It then calls into vn_open(). If successful, it installs the file descriptor with the requested rights, trimming off rights that don't apply to the type of the file that has been opened. Unlike kern_openat(), this function does not support /dev/fd/*. I can't think of a reason why we need to support this for CloudABI. Obtained from: https://github.com/NuxiNL/freebsd Differential Revision: https://reviews.freebsd.org/D3235 --- sys/compat/cloudabi/cloudabi_fd.c | 21 ++++- sys/compat/cloudabi/cloudabi_file.c | 123 +++++++++++++++++++++++++++- sys/compat/cloudabi/cloudabi_util.h | 7 ++ 3 files changed, 148 insertions(+), 3 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_fd.c b/sys/compat/cloudabi/cloudabi_fd.c index 1fed2e7dcf4f..f16d66855ad4 100644 --- a/sys/compat/cloudabi/cloudabi_fd.c +++ b/sys/compat/cloudabi/cloudabi_fd.c @@ -290,7 +290,7 @@ cloudabi_convert_filetype(const struct file *fp) } /* Removes rights that conflict with the file descriptor type. */ -static void +void cloudabi_remove_conflicting_rights(cloudabi_filetype_t filetype, cloudabi_rights_t *base, cloudabi_rights_t *inheriting) { @@ -499,6 +499,25 @@ cloudabi_sys_fd_stat_get(struct thread *td, return (copyout(&fsb, (void *)uap->buf, sizeof(fsb))); } +/* Converts CloudABI rights to a set of Capsicum capabilities. */ +int +cloudabi_convert_rights(cloudabi_rights_t in, cap_rights_t *out) +{ + + cap_rights_init(out); +#define MAPPING(cloudabi, ...) do { \ + if (in & (cloudabi)) { \ + cap_rights_set(out, ##__VA_ARGS__); \ + in &= ~(cloudabi); \ + } \ +} while (0); + RIGHTS_MAPPINGS +#undef MAPPING + if (in != 0) + return (ENOTCAPABLE); + return (0); +} + int cloudabi_sys_fd_stat_put(struct thread *td, struct cloudabi_sys_fd_stat_put_args *uap) diff --git a/sys/compat/cloudabi/cloudabi_file.c b/sys/compat/cloudabi/cloudabi_file.c index cdec170e96d1..893825265eae 100644 --- a/sys/compat/cloudabi/cloudabi_file.c +++ b/sys/compat/cloudabi/cloudabi_file.c @@ -197,9 +197,128 @@ int cloudabi_sys_file_open(struct thread *td, struct cloudabi_sys_file_open_args *uap) { + cloudabi_fdstat_t fds; + cap_rights_t rights; + struct filecaps fcaps = {}; + struct nameidata nd; + struct file *fp; + struct vnode *vp; + char *path; + int error, fd, fflags; + bool read, write; - /* Not implemented. */ - return (ENOSYS); + error = copyin(uap->fds, &fds, sizeof(fds)); + if (error != 0) + return (error); + + /* All the requested rights should be set on the descriptor. */ + error = cloudabi_convert_rights( + fds.fs_rights_base | fds.fs_rights_inheriting, &rights); + if (error != 0) + return (error); + cap_rights_set(&rights, CAP_LOOKUP); + + /* Convert rights to corresponding access mode. */ + read = (fds.fs_rights_base & (CLOUDABI_RIGHT_FD_READ | + CLOUDABI_RIGHT_FILE_READDIR | CLOUDABI_RIGHT_MEM_MAP_EXEC)) != 0; + write = (fds.fs_rights_base & (CLOUDABI_RIGHT_FD_DATASYNC | + CLOUDABI_RIGHT_FD_WRITE | CLOUDABI_RIGHT_FILE_ALLOCATE | + CLOUDABI_RIGHT_FILE_STAT_FPUT_SIZE)) != 0; + fflags = read ? write ? FREAD | FWRITE : FREAD : FWRITE; + + /* Convert open flags. */ + if ((uap->oflags & CLOUDABI_O_CREAT) != 0) { + fflags |= O_CREAT; + cap_rights_set(&rights, CAP_CREATE); + } + if ((uap->oflags & CLOUDABI_O_DIRECTORY) != 0) + fflags |= O_DIRECTORY; + if ((uap->oflags & CLOUDABI_O_EXCL) != 0) + fflags |= O_EXCL; + if ((uap->oflags & CLOUDABI_O_TRUNC) != 0) { + fflags |= O_TRUNC; + cap_rights_set(&rights, CAP_FTRUNCATE); + } + if ((fds.fs_flags & CLOUDABI_FDFLAG_APPEND) != 0) + fflags |= O_APPEND; + if ((fds.fs_flags & CLOUDABI_FDFLAG_NONBLOCK) != 0) + fflags |= O_NONBLOCK; + if ((fds.fs_flags & (CLOUDABI_FDFLAG_SYNC | CLOUDABI_FDFLAG_DSYNC | + CLOUDABI_FDFLAG_RSYNC)) != 0) { + fflags |= O_SYNC; + cap_rights_set(&rights, CAP_FSYNC); + } + if ((uap->fd & CLOUDABI_LOOKUP_SYMLINK_FOLLOW) == 0) + fflags |= O_NOFOLLOW; + if (write && (fflags & (O_APPEND | O_TRUNC)) == 0) + cap_rights_set(&rights, CAP_SEEK); + + /* Allocate new file descriptor. */ + error = falloc_noinstall(td, &fp); + if (error != 0) + return (error); + fp->f_flag = fflags & FMASK; + + /* Open path. */ + error = copyin_path(uap->path, uap->pathlen, &path); + if (error != 0) { + fdrop(fp, td); + return (error); + } + NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, uap->fd, + &rights, td); + error = vn_open(&nd, &fflags, 0777 & ~td->td_proc->p_fd->fd_cmask, fp); + cloudabi_freestr(path); + if (error != 0) { + /* Custom operations provided. */ + if (error == ENXIO && fp->f_ops != &badfileops) + goto success; + + /* + * POSIX compliance: return ELOOP in case openat() is + * called on a symbolic link and O_NOFOLLOW is set. + */ + if (error == EMLINK) + error = ELOOP; + fdrop(fp, td); + return (error); + } + NDFREE(&nd, NDF_ONLY_PNBUF); + filecaps_free(&nd.ni_filecaps); + fp->f_vnode = vp = nd.ni_vp; + + /* Install vnode operations if no custom operations are provided. */ + if (fp->f_ops == &badfileops) { + fp->f_seqcount = 1; + finit(fp, (fflags & FMASK) | (fp->f_flag & FHASLOCK), + DTYPE_VNODE, vp, &vnops); + } + VOP_UNLOCK(vp, 0); + + /* Truncate file. */ + if (fflags & O_TRUNC) { + error = fo_truncate(fp, 0, td->td_ucred, td); + if (error != 0) { + fdrop(fp, td); + return (error); + } + } + +success: + /* Determine which Capsicum rights to set on the file descriptor. */ + cloudabi_remove_conflicting_rights(cloudabi_convert_filetype(fp), + &fds.fs_rights_base, &fds.fs_rights_inheriting); + cloudabi_convert_rights(fds.fs_rights_base | fds.fs_rights_inheriting, + &fcaps.fc_rights); + if (cap_rights_is_set(&fcaps.fc_rights)) + fcaps.fc_fcntls = CAP_FCNTL_SETFL; + + error = finstall(td, fp, &fd, fflags, &fcaps); + fdrop(fp, td); + if (error != 0) + return (error); + td->td_retval[0] = fd; + return (0); } /* Converts a FreeBSD directory entry structure and writes it to userspace. */ diff --git a/sys/compat/cloudabi/cloudabi_util.h b/sys/compat/cloudabi/cloudabi_util.h index a263c94cf146..10da229a2104 100644 --- a/sys/compat/cloudabi/cloudabi_util.h +++ b/sys/compat/cloudabi/cloudabi_util.h @@ -50,6 +50,13 @@ void cloudabi_convert_sockaddr(const struct sockaddr *, socklen_t, /* Converts a file descriptor to a CloudABI file descriptor type. */ cloudabi_filetype_t cloudabi_convert_filetype(const struct file *); +/* Converts CloudABI rights to a set of Capsicum capabilities. */ +int cloudabi_convert_rights(cloudabi_rights_t, cap_rights_t *); + +/* Removes rights that conflict with the file descriptor type. */ +void cloudabi_remove_conflicting_rights(cloudabi_filetype_t, + cloudabi_rights_t *, cloudabi_rights_t *); + /* Converts a struct timespec to a CloudABI timestamp. */ int cloudabi_convert_timespec(const struct timespec *, cloudabi_timestamp_t *); From 6be30a30012c3308ed0ff48399f236860092cf89 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 6 Aug 2015 07:47:13 +0000 Subject: [PATCH 267/314] Tweak mdconfig(8) manual page, in particular revise the EXAMPLES section. This removes stuff that doesn't really belong there, and simplifies examples for the basic operations. Reviewed by: wblock@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3198 --- sbin/mdconfig/mdconfig.8 | 93 ++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/sbin/mdconfig/mdconfig.8 b/sbin/mdconfig/mdconfig.8 index 04d3391c0b16..f6d0aee098ae 100644 --- a/sbin/mdconfig/mdconfig.8 +++ b/sbin/mdconfig/mdconfig.8 @@ -37,12 +37,12 @@ .\" .\" $FreeBSD$ .\" -.Dd November 30, 2013 +.Dd August 6, 2015 .Dt MDCONFIG 8 .Os .Sh NAME .Nm mdconfig -.Nd configure and enable memory disks +.Nd create and control memory disks .Sh SYNOPSIS .Nm .Fl a @@ -75,7 +75,7 @@ .Sh DESCRIPTION The .Nm -utility configures and enables +utility creates and controls .Xr md 4 devices. .Pp @@ -103,7 +103,7 @@ If the .Fl o Cm reserve option is not set, creating and filling a large malloc-backed memory disk is a very easy way to -panic a system. +panic the system. .It Cm vnode A file specified with .Fl f Ar file @@ -164,7 +164,9 @@ or .Cm t which denotes byte, kilobyte, megabyte, gigabyte and terabyte respectively. -The +When used without the +.Fl r +option, the .Fl a and .Fl t Ar swap @@ -206,6 +208,11 @@ Enable/disable compression features to reduce memory usage. .It Oo Cm no Oc Ns Cm force Disable/enable extra sanity checks to prevent the user from doing something that might adversely affect the system. +This can be used with the +.Fl u +flag to forcibly destroy an +.Xr md 4 +disk that is still in use. .It Oo Cm no Oc Ns Cm readonly Enable/disable readonly mode. .El @@ -227,66 +234,58 @@ is provided for convenience as an abbreviation of .Fl t Ar vnode .Fl f Ar file . .Sh EXAMPLES -Create a 4 megabyte -.Xr malloc 9 -backed memory disk. -The name of the allocated unit will be printed on stdout, such as -.Dq Li md3 : -.Pp -.Dl mdconfig -a -t malloc -s 4m -.Pp -Create a disk named -.Pa /dev/md4 -with +Create a disk with .Pa /tmp/boot.flp -as backing storage: +as backing storage. +The name of the allocated unit will be printed on stdout, such as +.Dq Li md0 : +.Bd -literal -offset indent +mdconfig /tmp/boot.flp +.Ed .Pp -.Dl mdconfig -a -t vnode -f /tmp/boot.flp -u md4 +Create a 1 gigabyte swap backed memory disk named +.Dq Li md3 : +.Bd -literal -offset indent +mdconfig -s 1g -u md3 +.Ed .Pp Detach and free all resources used by -.Pa /dev/md4 : +.Pa /dev/md3 : +.Bd -literal -offset indent +mdconfig -du md3 +.Ed .Pp -.Dl mdconfig -d -u md4 +Show detailed information on current memory disks: +.Bd -literal -offset indent +mdconfig -lv +.Ed .Pp -Create a 128MByte swap backed disk, initialize an +Resize the +.Dq Li md3 +memory disk to 2 gigabytes: +.Bd -literal -offset indent +mdconfig -rs 2g -u md3 +.Ed +.Pp +Create a 1 gigabyte swap backed disk, initialize an .Xr ffs 7 file system on it, and mount it on .Pa /tmp : .Bd -literal -offset indent -mdconfig -a -t swap -s 128M -u md10 +mdconfig -s 1g -u md10 newfs -U /dev/md10 mount /dev/md10 /tmp chmod 1777 /tmp .Ed .Pp -Create a 5MB file-backed disk -.Po Fl a -and -.Fl t Ar vnode -are implied -.Pc : -.Bd -literal -offset indent -dd if=/dev/zero of=somebackingfile bs=1k count=5k -mdconfig -f somebackingfile -u md0 -bsdlabel -w md0 auto -newfs md0c -mount /dev/md0c /mnt -.Ed -.Pp -Create an +Create a memory disk out of an ISO 9660 CD image file, +using the first available .Xr md 4 -device out of an ISO 9660 CD image file -.Po Fl a -and -.Fl t Ar vnode -are implied -.Pc , using the first available -.Xr md 4 -device, and then mount the new memory disk: +device, and then mount it: .Bd -literal -offset indent mount -t cd9660 /dev/`mdconfig -f cdimage.iso` /mnt -.Pp .Ed +.Pp Create a file-backed device from a hard disk image that begins with 512K of raw header information. .Xr gnop 8 @@ -294,7 +293,7 @@ is used to skip over the header information, positioning .Pa md1.nop to the start of the filesystem in the image. .Bd -literal -offset indent -mdconfig -f diskimage.img -u md1 +mdconfig -u md1 -f diskimage.img gnop create -o 512K md1 mount /dev/md1.nop /mnt .Ed From 3bb60789858d5ae0fb74ca7507e28390635efa64 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Thu, 6 Aug 2015 07:49:34 +0000 Subject: [PATCH 268/314] Whoops, wrong flag. MFC after: 1 month Sponsored by: The FreeBSD Foundation --- sbin/mdconfig/mdconfig.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/mdconfig/mdconfig.8 b/sbin/mdconfig/mdconfig.8 index f6d0aee098ae..264532721531 100644 --- a/sbin/mdconfig/mdconfig.8 +++ b/sbin/mdconfig/mdconfig.8 @@ -209,7 +209,7 @@ Enable/disable compression features to reduce memory usage. Disable/enable extra sanity checks to prevent the user from doing something that might adversely affect the system. This can be used with the -.Fl u +.Fl d flag to forcibly destroy an .Xr md 4 disk that is still in use. From e369e734f4bb096423b39663a08b72a32405cf28 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Thu, 6 Aug 2015 14:05:17 +0000 Subject: [PATCH 269/314] Make it compilable. No idea if it works. --- sys/dev/wtap/if_wtap.c | 4 ++-- sys/dev/wtap/if_wtapvar.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c index 7e2eca783e97..f6dbe77666f2 100644 --- a/sys/dev/wtap/if_wtap.c +++ b/sys/dev/wtap/if_wtap.c @@ -163,13 +163,13 @@ wtap_media_change(struct ifnet *ifp) */ static void wtap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, - int subtype, int rssi, int nf) + int subtype, const struct ieee80211_rx_stats *stats, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; #if 0 DWTAP_PRINTF("[%d] %s\n", myath_id(ni), __func__); #endif - WTAP_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, nf); + WTAP_VAP(vap)->av_recv_mgmt(ni, m, subtype, stats, rssi, nf); } static int diff --git a/sys/dev/wtap/if_wtapvar.h b/sys/dev/wtap/if_wtapvar.h index 3bdc8980b387..a886be93258b 100644 --- a/sys/dev/wtap/if_wtapvar.h +++ b/sys/dev/wtap/if_wtapvar.h @@ -120,7 +120,7 @@ struct wtap_vap { struct callout av_swba; /* software beacon alert */ uint32_t av_bcinterval; /* beacon interval */ void (*av_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int); + struct mbuf *, int, const struct ieee80211_rx_stats *, int, int); int (*av_newstate)(struct ieee80211vap *, enum ieee80211_state, int); void (*av_bmiss)(struct ieee80211vap *); From cdc3fa11f71a9c8e4f6228ec1354cbb55258f331 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Thu, 6 Aug 2015 14:13:01 +0000 Subject: [PATCH 270/314] Fix a typo. Submitted by: pkelsey Sponsored by: The FreeBSD Foundation --- release/doc/en_US.ISO8859-1/relnotes/article.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.xml b/release/doc/en_US.ISO8859-1/relnotes/article.xml index 3e2a6f3cdae7..fbf35b59ecab 100644 --- a/release/doc/en_US.ISO8859-1/relnotes/article.xml +++ b/release/doc/en_US.ISO8859-1/relnotes/article.xml @@ -1405,7 +1405,7 @@ &os;. - Network Procols + Network Protocols Support for the IPX network transport protocol has been removed, and will not be supported in From 756e25bfd7b7190188e7225fcd3dd326d123ef8b Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Thu, 6 Aug 2015 14:49:23 +0000 Subject: [PATCH 271/314] Fill in dump_avail based on the physical memory from EFI. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation --- sys/arm64/arm64/machdep.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index 55994b65d43e..d63ee7aa5214 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -822,8 +822,13 @@ initarm(struct arm64_bootparams *abp) /* Print the memory map */ mem_len = 0; - for (i = 0; i < physmap_idx; i += 2) + for (i = 0; i < physmap_idx; i += 2) { + dump_avail[i] = physmap[i]; + dump_avail[i + 1] = physmap[i + 1]; mem_len += physmap[i + 1] - physmap[i]; + } + dump_avail[i] = 0; + dump_avail[i + 1] = 0; /* Set the pcpu data, this is needed by pmap_bootstrap */ pcpup = &__pcpu[0]; From fcc8461cfb6f7c126c21eddc2655751769dbd7a9 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Thu, 6 Aug 2015 15:30:14 +0000 Subject: [PATCH 272/314] Make some debug printf's into DPRINTF's to reduce noise on attach/detach Differential Revision: https://reviews.freebsd.org/D3306 MFC after: 1 week Reviewed by: loos Sponsored by: EMC / Isilon Storage Division --- sys/geom/uzip/g_uzip.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/geom/uzip/g_uzip.c b/sys/geom/uzip/g_uzip.c index 732de9d5e8d0..8363d06ebaec 100644 --- a/sys/geom/uzip/g_uzip.c +++ b/sys/geom/uzip/g_uzip.c @@ -94,8 +94,8 @@ g_uzip_softc_free(struct g_uzip_softc *sc, struct g_geom *gp) { if (gp != NULL) { - printf("%s: %d requests, %d cached\n", - gp->name, sc->req_total, sc->req_cached); + DPRINTF(("%s: %d requests, %d cached\n", + gp->name, sc->req_total, sc->req_cached)); } if (sc->offsets != NULL) { free(sc->offsets, M_GEOM_UZIP); @@ -519,7 +519,7 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags) gp->name, pp2->sectorsize, (intmax_t)pp2->mediasize, pp2->stripeoffset, pp2->stripesize, pp2->flags)); - printf("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz); + DPRINTF(("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz)); return (gp); err: @@ -547,7 +547,7 @@ g_uzip_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp) g_topology_assert(); if (gp->softc == NULL) { - printf("%s(%s): gp->softc == NULL\n", __func__, gp->name); + DPRINTF(("%s(%s): gp->softc == NULL\n", __func__, gp->name)); return (ENXIO); } From 9322ac3f6ed0bca8d1a451a5813b90468d876ccb Mon Sep 17 00:00:00 2001 From: Allan Jude Date: Thu, 6 Aug 2015 16:07:27 +0000 Subject: [PATCH 273/314] Remove guards around overwriting loader.rc and menu.rc There have been .local version of each for user modifications for some time This allows users to receive future updates to these files PR: 183765 Submitted by: Bertram Scharpf, Nikolai Lifanov (patch) Reviewed by: dteske, loos, eadler Approved by: bapt (mentor) MFC after: 1 month Relnotes: yes Sponsored by: ScaleEngine Inc. Differential Revision: https://reviews.freebsd.org/D3176 --- UPDATING | 5 +++++ sys/boot/forth/loader.rc | 3 +++ sys/boot/forth/menu.rc | 3 +++ sys/boot/i386/loader/Makefile | 7 +------ sys/boot/mips/beri/loader/Makefile | 8 +------- sys/boot/pc98/loader/Makefile | 7 +------ sys/boot/powerpc/kboot/Makefile | 8 +------- sys/boot/powerpc/ofw/Makefile | 8 +------- sys/boot/powerpc/ps3/Makefile | 8 +------- sys/boot/sparc64/loader/Makefile | 8 +------- 10 files changed, 18 insertions(+), 47 deletions(-) diff --git a/UPDATING b/UPDATING index 3b6c0359ec93..bc05d3c39d6f 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20150806: + The menu.rc and loader.rc files will now be replaced during + upgrades. Please migrate local changes to menu.rc.local and + loader.rc.local instead. + 20150805: GNU Binutils versions of addr2line, c++filt, nm, readelf, size, strings and strip have been removed. The src.conf(5) knob diff --git a/sys/boot/forth/loader.rc b/sys/boot/forth/loader.rc index b4a6d51c4c4a..0bc66579cd0f 100644 --- a/sys/boot/forth/loader.rc +++ b/sys/boot/forth/loader.rc @@ -1,6 +1,9 @@ \ Loader.rc \ $FreeBSD$ \ +\ You should not edit this file! Put any overrides in loader.rc.local +\ instead as this file can be replaced during system updates. +\ \ Includes additional commands include /boot/loader.4th try-include /boot/loader.rc.local diff --git a/sys/boot/forth/menu.rc b/sys/boot/forth/menu.rc index e65084803123..7ffeef40aced 100644 --- a/sys/boot/forth/menu.rc +++ b/sys/boot/forth/menu.rc @@ -1,6 +1,9 @@ \ Menu.rc \ $FreeBSD$ \ +\ You should not edit this file! Put any overrides in menu.rc.local +\ instead as this file can be replaced during system updates. +\ \ Load required Forth modules include /boot/version.4th include /boot/brand.4th diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile index ade605439ff6..bcbe0b86c627 100644 --- a/sys/boot/i386/loader/Makefile +++ b/sys/boot/i386/loader/Makefile @@ -110,12 +110,7 @@ FILESMODE_${LOADER}= ${BINMODE} -b .include "${.CURDIR}/../../forth/Makefile.inc" FILES+= pcibios.4th -.if !exists(${DESTDIR}/boot/loader.rc) -FILES+= loader.rc -.endif -.if !exists(${DESTDIR}/boot/menu.rc) -FILES+= menu.rc -.endif +FILES+= loader.rc menu.rc .endif # XXX crt0.o needs to be first for pxeboot(8) to work diff --git a/sys/boot/mips/beri/loader/Makefile b/sys/boot/mips/beri/loader/Makefile index a134f3d48eb8..7223492068b1 100644 --- a/sys/boot/mips/beri/loader/Makefile +++ b/sys/boot/mips/beri/loader/Makefile @@ -125,13 +125,7 @@ loader.help: help.common help.mips .PATH: ${.CURDIR}/../../../forth .include "${.CURDIR}/../../../forth/Makefile.inc" -.if !exists(${DESTDIR}/boot/loader.rc) -FILES+= loader.rc -.endif - -.if !exists(${DESTDIR}/boot/menu.rc) -FILES+= menu.rc -.endif +FILES+= loader.rc menu.rc .if defined(LOADER_USB_SUPPORT) # Do garbage collection diff --git a/sys/boot/pc98/loader/Makefile b/sys/boot/pc98/loader/Makefile index 9333f3c3756d..319600fd5515 100644 --- a/sys/boot/pc98/loader/Makefile +++ b/sys/boot/pc98/loader/Makefile @@ -90,12 +90,7 @@ FILESMODE_${LOADER}= ${BINMODE} -b .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" -.if !exists(${DESTDIR}/boot/loader.rc) -FILES+= ${.CURDIR}/../../i386/loader/loader.rc -.endif -.if !exists(${DESTDIR}/boot/menu.rc) -FILES+= menu.rc -.endif +FILES+= ${.CURDIR}/../../i386/loader/loader.rc menu.rc # XXX crt0.o needs to be first for pxeboot(8) to work OBJS= ${BTXCRT} diff --git a/sys/boot/powerpc/kboot/Makefile b/sys/boot/powerpc/kboot/Makefile index 4601f29ed16c..a47275c9c89d 100644 --- a/sys/boot/powerpc/kboot/Makefile +++ b/sys/boot/powerpc/kboot/Makefile @@ -117,12 +117,6 @@ loader.help: help.common help.kboot ${.CURDIR}/../../fdt/help.fdt .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" -.if !exists(${DESTDIR}/boot/loader.rc) -FILES+= loader.rc -.endif - -.if !exists(${DESTDIR}/boot/menu.rc) -FILES+= menu.rc -.endif +FILES+= loader.rc menu.rc .include diff --git a/sys/boot/powerpc/ofw/Makefile b/sys/boot/powerpc/ofw/Makefile index 6a2fc700b1ca..ab5720fb1f40 100644 --- a/sys/boot/powerpc/ofw/Makefile +++ b/sys/boot/powerpc/ofw/Makefile @@ -112,12 +112,6 @@ loader.help: help.common help.ofw ${.CURDIR}/../../fdt/help.fdt .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" -.if !exists(${DESTDIR}/boot/loader.rc) -FILES+= loader.rc -.endif - -.if !exists(${DESTDIR}/boot/menu.rc) -FILES+= menu.rc -.endif +FILES+= loader.rc menu.rc .include diff --git a/sys/boot/powerpc/ps3/Makefile b/sys/boot/powerpc/ps3/Makefile index 861872f3852c..baf2507a6b51 100644 --- a/sys/boot/powerpc/ps3/Makefile +++ b/sys/boot/powerpc/ps3/Makefile @@ -114,12 +114,6 @@ loader.help: help.common help.ps3 ${.CURDIR}/../../fdt/help.fdt .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" -.if !exists(${DESTDIR}/boot/loader.rc) -FILES+= loader.rc -.endif - -.if !exists(${DESTDIR}/boot/menu.rc) -FILES+= menu.rc -.endif +FILES+= loader.rc menu.rc .include diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile index 5c9bfbb262ef..05d23ff19265 100644 --- a/sys/boot/sparc64/loader/Makefile +++ b/sys/boot/sparc64/loader/Makefile @@ -99,12 +99,6 @@ loader.help: help.common help.sparc64 .PATH: ${.CURDIR}/../../forth .include "${.CURDIR}/../../forth/Makefile.inc" -.if !exists(${DESTDIR}/boot/loader.rc) -FILES+= loader.rc -.endif - -.if !exists(${DESTDIR}/boot/menu.rc) -FILES+= menu.rc -.endif +FILES+= loader.rc menu.rc .include From 95eee0d40b83e71ef8e2bf9f9f7870e8eb97c567 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 16:12:12 +0000 Subject: [PATCH 274/314] Convert the map_at_zero test case to ATF. In particular, this will facilitate adding more mmap() tests. MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D3268 --- tests/sys/vm/Makefile | 2 +- tests/sys/vm/mmap_test.c | 61 ++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/tests/sys/vm/Makefile b/tests/sys/vm/Makefile index 1795eefa6a52..08fbb2159c63 100644 --- a/tests/sys/vm/Makefile +++ b/tests/sys/vm/Makefile @@ -2,6 +2,6 @@ TESTSDIR= ${TESTSBASE}/sys/vm -TAP_TESTS_C+= mmap_test +ATF_TESTS_C+= mmap_test .include diff --git a/tests/sys/vm/mmap_test.c b/tests/sys/vm/mmap_test.c index 7591a0996971..74e1634950b4 100644 --- a/tests/sys/vm/mmap_test.c +++ b/tests/sys/vm/mmap_test.c @@ -29,16 +29,14 @@ #include #include #include -#include +#include #include -#include -#include static const struct { void *addr; int ok[2]; /* Depending on security.bsd.map_at_zero {0, !=0}. */ -} tests[] = { +} map_at_zero_tests[] = { { (void *)0, { 0, 1 } }, /* Test sysctl. */ { (void *)1, { 0, 0 } }, { (void *)(PAGE_SIZE - 1), { 0, 0 } }, @@ -52,54 +50,43 @@ static const struct { #define MAP_AT_ZERO "security.bsd.map_at_zero" -int -main(void) +ATF_TC_WITHOUT_HEAD(mmap__map_at_zero); +ATF_TC_BODY(mmap__map_at_zero, tc) { void *p; size_t len; - int i, error, mib[3], map_at_zero; - - error = 0; - - /* Get the current sysctl value of security.bsd.map_at_zero. */ - len = sizeof(mib) / sizeof(*mib); - if (sysctlnametomib(MAP_AT_ZERO, mib, &len) == -1) { - printf("1..0 # SKIP: sysctlnametomib(\"%s\") failed: %s\n", - MAP_AT_ZERO, strerror(errno)); - return (0); - } + unsigned int i; + int map_at_zero; len = sizeof(map_at_zero); - if (sysctl(mib, 3, &map_at_zero, &len, NULL, 0) == -1) { - printf("1..0 # SKIP: sysctl for %s failed: %s\n", MAP_AT_ZERO, + if (sysctlbyname(MAP_AT_ZERO, &map_at_zero, &len, NULL, 0) == -1) { + atf_tc_skip("sysctl for %s failed: %s\n", MAP_AT_ZERO, strerror(errno)); - return (0); + return; } /* Normalize to 0 or 1 for array access. */ map_at_zero = !!map_at_zero; - printf("1..%zu\n", nitems(tests)); - for (i = 0; i < (int)nitems(tests); i++) { - p = mmap((void *)tests[i].addr, PAGE_SIZE, + for (i = 0; i < nitems(map_at_zero_tests); i++) { + p = mmap((void *)map_at_zero_tests[i].addr, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_FIXED, -1, 0); if (p == MAP_FAILED) { - if (tests[i].ok[map_at_zero] != 0) - error++; - printf("%sok %d # mmap(%p, ...) failed\n", - tests[i].ok[map_at_zero] == 0 ? "" : "not ", - i + 1, - tests[i].addr); + ATF_CHECK_MSG(map_at_zero_tests[i].ok[map_at_zero] == 0, + "mmap(%p, ...) failed", map_at_zero_tests[i].addr); } else { - if (tests[i].ok[map_at_zero] != 1) - error++; - printf("%sok %d # mmap(%p, ...) succeeded: p=%p\n", - tests[i].ok[map_at_zero] == 1 ? "" : "not ", - i + 1, - tests[i].addr, p); + ATF_CHECK_MSG(map_at_zero_tests[i].ok[map_at_zero] == 1, + "mmap(%p, ...) succeeded: p=%p\n", + map_at_zero_tests[i].addr, p); } } - - return (error != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mmap__map_at_zero); + + return (atf_no_error()); } From 7f43ee0fb73edb41b0d12c4cc6f20b8ca8a9f969 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 16:14:29 +0000 Subject: [PATCH 275/314] Add various tests to ensure that invalid arguments passed to mmap() trigger failures. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D3269 --- tests/sys/vm/mmap_test.c | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/tests/sys/vm/mmap_test.c b/tests/sys/vm/mmap_test.c index 74e1634950b4..00abeb628b6f 100644 --- a/tests/sys/vm/mmap_test.c +++ b/tests/sys/vm/mmap_test.c @@ -32,6 +32,10 @@ #include #include +#include +#include +#include +#include static const struct { void *addr; @@ -83,10 +87,78 @@ ATF_TC_BODY(mmap__map_at_zero, tc) } } +static void +checked_mmap(int prot, int flags, int fd, int error, const char *msg) +{ + void *p; + + p = mmap(NULL, getpagesize(), prot, flags, fd, 0); + if (p == MAP_FAILED) { + if (error == 0) + ATF_CHECK_MSG(0, "%s failed with errno %d", msg, + errno); + else + ATF_CHECK_EQ_MSG(error, errno, + "%s failed with wrong errno %d (expected %d)", msg, + errno, error); + } else { + ATF_CHECK_MSG(error == 0, "%s succeeded", msg); + munmap(p, getpagesize()); + } +} + +ATF_TC_WITHOUT_HEAD(mmap__bad_arguments); +ATF_TC_BODY(mmap__bad_arguments, tc) +{ + int fd; + + ATF_REQUIRE((fd = shm_open(SHM_ANON, O_RDWR, 0644)) >= 0); + ATF_REQUIRE(ftruncate(fd, getpagesize()) == 0); + + /* These should work. */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON, -1, 0, + "simple MAP_ANON"); + checked_mmap(PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0, + "simple shm fd shared"); + checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0, + "simple shm fd private"); + + /* Extra PROT flags. */ + checked_mmap(PROT_READ | PROT_WRITE | 0x100000, MAP_ANON, -1, EINVAL, + "MAP_ANON with extra PROT flags"); + checked_mmap(0xffff, MAP_SHARED, fd, EINVAL, + "shm fd with garbage PROT"); + + /* Undefined flag. */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_RESERVED0080, -1, + EINVAL, "Undefined flag"); + + /* Both MAP_SHARED and MAP_PRIVATE */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | + MAP_SHARED, -1, EINVAL, "MAP_ANON with both SHARED and PRIVATE"); + checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_SHARED, fd, + EINVAL, "shm fd with both SHARED and PRIVATE"); + + /* At least one of MAP_SHARED or MAP_PRIVATE without ANON */ + checked_mmap(PROT_READ | PROT_WRITE, 0, fd, EINVAL, + "shm fd without sharing flag"); + + /* MAP_ANON with either sharing flag (impacts fork). */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0, + "shared MAP_ANON"); + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0, + "private MAP_ANON"); + + /* MAP_ANON should require an fd of -1. */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, EINVAL, + "MAP_ANON with fd != -1"); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, mmap__map_at_zero); + ATF_TP_ADD_TC(tp, mmap__bad_arguments); return (atf_no_error()); } From fada4adf95b0973d035fd474aed580464d51f613 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 16:50:37 +0000 Subject: [PATCH 276/314] The changes that introduced fo_mmap() treated all character device mappings as if MAP_SHARED was always present since in general MAP_PRIVATE is not permitted for character devices. However, there is one exception in that MAP_PRIVATE mappings are permitted for /dev/zero. Only require a writable file descriptor (FWRITE) for shared, writable mappings of character devices. vm_mmap_cdev() will reject any private mappings for other devices. Reviewed by: kib Reported by: sbruno (broke qemu cross-builds), peter Differential Revision: https://reviews.freebsd.org/D3316 --- sys/fs/devfs/devfs_vnops.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index fe8e9ef3f03f..806843769a11 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -1774,13 +1774,24 @@ devfs_mmap_f(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size, return (EACCES); /* - * Character devices always share mappings, so - * require a writable fd for writable mappings. + * If we are sharing potential changes via MAP_SHARED and we + * are trying to get write permission although we opened it + * without asking for it, bail out. + * + * Note that most character devices always share mappings. + * The one exception is that D_MMAP_ANON devices + * (i.e. /dev/zero) permit private writable mappings. + * + * Rely on vm_mmap_cdev() to fail invalid MAP_PRIVATE requests + * as well as updating maxprot to permit writing for + * D_MMAP_ANON devices rather than doing that here. */ - if ((fp->f_flag & FWRITE) != 0) - maxprot |= VM_PROT_WRITE; - else if ((prot & VM_PROT_WRITE) != 0) - return (EACCES); + if ((flags & MAP_SHARED) != 0) { + if ((fp->f_flag & FWRITE) != 0) + maxprot |= VM_PROT_WRITE; + else if ((prot & VM_PROT_WRITE) != 0) + return (EACCES); + } maxprot &= cap_maxprot; fpop = td->td_fpop; From 3c790178c589358099085e42b6f45d3b26461666 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 17:07:21 +0000 Subject: [PATCH 277/314] Remove some more vestiges of the Xen PV domu support. Specifically, use vtophys() directly instead of vtomach() and retire the no-longer-used headers and . Reported by: bde (stale bits in ) Reviewed by: royger (earlier version) Differential Revision: https://reviews.freebsd.org/D3266 --- sys/amd64/include/xen/xenfunc.h | 73 ----------------------------- sys/amd64/include/xen/xenvar.h | 59 ------------------------ sys/dev/xen/balloon/balloon.c | 2 - sys/dev/xen/blkfront/blkfront.c | 5 +- sys/dev/xen/control/control.c | 3 -- sys/dev/xen/netback/netback.c | 4 +- sys/dev/xen/netfront/netfront.c | 6 +-- sys/dev/xen/pcifront/pcifront.c | 2 +- sys/i386/include/xen/xenfunc.h | 81 --------------------------------- sys/i386/include/xen/xenvar.h | 36 --------------- sys/x86/xen/xen_intr.c | 1 - 11 files changed, 6 insertions(+), 266 deletions(-) delete mode 100644 sys/amd64/include/xen/xenfunc.h delete mode 100644 sys/amd64/include/xen/xenvar.h delete mode 100644 sys/i386/include/xen/xenfunc.h delete mode 100644 sys/i386/include/xen/xenvar.h diff --git a/sys/amd64/include/xen/xenfunc.h b/sys/amd64/include/xen/xenfunc.h deleted file mode 100644 index d8a6b5c5c99b..000000000000 --- a/sys/amd64/include/xen/xenfunc.h +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * Copyright (c) 2004, 2005 Kip Macy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 _XEN_XENFUNC_H_ -#define _XEN_XENFUNC_H_ - -#include - -#define BKPT __asm__("int3"); -#define XPQ_CALL_DEPTH 5 -#define XPQ_CALL_COUNT 2 -#define PG_PRIV PG_AVAIL3 -typedef struct { - unsigned long pt_ref; - unsigned long pt_eip[XPQ_CALL_COUNT][XPQ_CALL_DEPTH]; -} pteinfo_t; - -extern pteinfo_t *pteinfo_list; -#ifdef XENDEBUG_LOW -#define __PRINTK(x) printk x -#else -#define __PRINTK(x) -#endif - -char *xen_setbootenv(char *cmd_line); - -int xen_boothowto(char *envp); - -void _xen_machphys_update(vm_paddr_t, vm_paddr_t, char *file, int line); - -#ifdef INVARIANTS -#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), __FILE__, __LINE__) -#else -#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), NULL, 0) -#endif - -extern struct mtx balloon_lock; -#if 0 -#define balloon_lock(__flags) mtx_lock_irqsave(&balloon_lock, __flags) -#define balloon_unlock(__flags) mtx_unlock_irqrestore(&balloon_lock, __flags) -#else -#define balloon_lock(__flags) __flags = 1 -#define balloon_unlock(__flags) __flags = 0 -#endif - - - -#endif /* _XEN_XENFUNC_H_ */ diff --git a/sys/amd64/include/xen/xenvar.h b/sys/amd64/include/xen/xenvar.h deleted file mode 100644 index 110a351bac62..000000000000 --- a/sys/amd64/include/xen/xenvar.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2008 Kip Macy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 XENVAR_H_ -#define XENVAR_H_ -#define XBOOTUP 0x1 -#define XPMAP 0x2 -extern int xendebug_flags; -#ifndef NOXENDEBUG -#define XENPRINTF printk -#else -#define XENPRINTF printf -#endif -#include - -#if 0 -#define TRACE_ENTER XENPRINTF("(file=%s, line=%d) entered %s\n", __FILE__, __LINE__, __FUNCTION__) -#define TRACE_EXIT XENPRINTF("(file=%s, line=%d) exiting %s\n", __FILE__, __LINE__, __FUNCTION__) -#define TRACE_DEBUG(argflags, _f, _a...) \ -if (xendebug_flags & argflags) XENPRINTF("(file=%s, line=%d) " _f "\n", __FILE__, __LINE__, ## _a); -#else -#define TRACE_ENTER -#define TRACE_EXIT -#define TRACE_DEBUG(argflags, _f, _a...) -#endif - -#define vtomach(va) pmap_kextract((vm_offset_t) (va)) - -void xpq_init(void); - -int xen_create_contiguous_region(vm_page_t pages, int npages); - -void xen_destroy_contiguous_region(void * addr, int npages); - -#endif diff --git a/sys/dev/xen/balloon/balloon.c b/sys/dev/xen/balloon/balloon.c index a6036d84961a..773644fda27c 100644 --- a/sys/dev/xen/balloon/balloon.c +++ b/sys/dev/xen/balloon/balloon.c @@ -49,8 +49,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - static MALLOC_DEFINE(M_BALLOON, "Balloon", "Xen Balloon Driver"); /* Convert from KB (as fetched from xenstore) to number of PAGES */ diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c index 312a0771a9e4..5ff9d38a68dc 100644 --- a/sys/dev/xen/blkfront/blkfront.c +++ b/sys/dev/xen/blkfront/blkfront.c @@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include @@ -762,7 +761,7 @@ xbd_alloc_ring(struct xbd_softc *sc) i++, sring_page_addr += PAGE_SIZE) { error = xenbus_grant_ring(sc->xbd_dev, - (vtomach(sring_page_addr) >> PAGE_SHIFT), + (vtophys(sring_page_addr) >> PAGE_SHIFT), &sc->xbd_ring_ref[i]); if (error) { xenbus_dev_fatal(sc->xbd_dev, error, @@ -1305,7 +1304,7 @@ xbd_connect(struct xbd_softc *sc) for (j = 0; j < sc->xbd_max_request_indirectpages; j++) { if (gnttab_grant_foreign_access( xenbus_get_otherend_id(sc->xbd_dev), - (vtomach(indirectpages) >> PAGE_SHIFT) + j, + (vtophys(indirectpages) >> PAGE_SHIFT) + j, 1 /* grant read-only access */, &cm->cm_indirectionrefs[j])) break; diff --git a/sys/dev/xen/control/control.c b/sys/dev/xen/control/control.c index 2a0d459ee621..219a3953a24e 100644 --- a/sys/dev/xen/control/control.c +++ b/sys/dev/xen/control/control.c @@ -145,9 +145,6 @@ __FBSDID("$FreeBSD$"); #include -#include -#include - /*--------------------------- Forward Declarations --------------------------*/ /** Function signature for shutdown event handlers. */ typedef void (xctrl_shutdown_handler_t)(void); diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c index 2233084edb42..c58b324abbfb 100644 --- a/sys/dev/xen/netback/netback.c +++ b/sys/dev/xen/netback/netback.c @@ -87,8 +87,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - /*--------------------------- Compile-time Tunables --------------------------*/ /*---------------------------------- Macros ----------------------------------*/ @@ -132,7 +130,7 @@ static MALLOC_DEFINE(M_XENNETBACK, "xnb", "Xen Net Back Driver Data"); req < rsp ? req : rsp; \ }) -#define virt_to_mfn(x) (vtomach(x) >> PAGE_SHIFT) +#define virt_to_mfn(x) (vtophys(x) >> PAGE_SHIFT) #define virt_to_offset(x) ((x) & (PAGE_SIZE - 1)) /** diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index 3eac25dccd35..2f972b847e39 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -86,8 +86,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include "xenbus_if.h" /* Features supported by all backends. TSO and LRO can be negotiated */ @@ -190,7 +188,7 @@ static int xennet_get_responses(struct netfront_info *np, struct netfront_rx_info *rinfo, RING_IDX rp, RING_IDX *cons, struct mbuf **list, int *pages_flipped_p); -#define virt_to_mfn(x) (vtomach(x) >> PAGE_SHIFT) +#define virt_to_mfn(x) (vtophys(x) >> PAGE_SHIFT) #define INVALID_P2M_ENTRY (~0UL) @@ -901,7 +899,7 @@ network_alloc_rx_buffers(struct netfront_info *sc) req->gref = ref; sc->rx_pfn_array[i] = - vtomach(mtod(m_new,vm_offset_t)) >> PAGE_SHIFT; + vtophys(mtod(m_new,vm_offset_t)) >> PAGE_SHIFT; } KASSERT(i, ("no mbufs processed")); /* should have returned earlier */ diff --git a/sys/dev/xen/pcifront/pcifront.c b/sys/dev/xen/pcifront/pcifront.c index 1613e0ae0ca0..1730bf8fc09f 100644 --- a/sys/dev/xen/pcifront/pcifront.c +++ b/sys/dev/xen/pcifront/pcifront.c @@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$"); #define INVALID_GRANT_REF (0) #define INVALID_EVTCHN (-1) -#define virt_to_mfn(x) (vtomach(x) >> PAGE_SHIFT) +#define virt_to_mfn(x) (vtophys(x) >> PAGE_SHIFT) struct pcifront_device { STAILQ_ENTRY(pcifront_device) next; diff --git a/sys/i386/include/xen/xenfunc.h b/sys/i386/include/xen/xenfunc.h deleted file mode 100644 index f48b1f14719d..000000000000 --- a/sys/i386/include/xen/xenfunc.h +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * Copyright (c) 2004, 2005 Kip Macy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 _XEN_XENFUNC_H_ -#define _XEN_XENFUNC_H_ - -#include -#include - -#include - -#include - -#include -#define BKPT __asm__("int3"); -#define XPQ_CALL_DEPTH 5 -#define XPQ_CALL_COUNT 2 -#define PG_PRIV PG_AVAIL3 -typedef struct { - unsigned long pt_ref; - unsigned long pt_eip[XPQ_CALL_COUNT][XPQ_CALL_DEPTH]; -} pteinfo_t; - -extern pteinfo_t *pteinfo_list; -#ifdef XENDEBUG_LOW -#define __PRINTK(x) printk x -#else -#define __PRINTK(x) -#endif - -char *xen_setbootenv(char *cmd_line); - -int xen_boothowto(char *envp); - -void _xen_machphys_update(vm_paddr_t, vm_paddr_t, char *file, int line); - -#ifdef INVARIANTS -#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), __FILE__, __LINE__) -#else -#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), NULL, 0) -#endif - -void xen_update_descriptor(union descriptor *, union descriptor *); - -extern struct mtx balloon_lock; -#if 0 -#define balloon_lock(__flags) mtx_lock_irqsave(&balloon_lock, __flags) -#define balloon_unlock(__flags) mtx_unlock_irqrestore(&balloon_lock, __flags) -#else -#define balloon_lock(__flags) __flags = 1 -#define balloon_unlock(__flags) __flags = 0 -#endif - - - -#endif /* _XEN_XENFUNC_H_ */ diff --git a/sys/i386/include/xen/xenvar.h b/sys/i386/include/xen/xenvar.h deleted file mode 100644 index 484c279c0ff1..000000000000 --- a/sys/i386/include/xen/xenvar.h +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2008 Kip Macy - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 XENVAR_H_ -#define XENVAR_H_ - -#include - -#define vtomach(va) pmap_kextract((vm_offset_t) (va)) - -#endif diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c index 3bc4b4399f5c..a728ddb22e62 100644 --- a/sys/x86/xen/xen_intr.c +++ b/sys/x86/xen/xen_intr.c @@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include From 5ee9ea19febbed22a5f1173bbc4fa60e6a3a340f Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 6 Aug 2015 17:13:34 +0000 Subject: [PATCH 278/314] After crypto_dispatch() bio might be already delivered and destroyed, so we cannot access it anymore. Setting an error later lead to memory corruption. Assert that crypto_dispatch() was successful. It can fail only if we pass a bogus crypto request, which is a bug in the program, not a runtime condition. PR: 199705 Submitted by: luke.tw Reviewed by: emaste MFC after: 3 days --- sys/geom/eli/g_eli_integrity.c | 11 ++++------- sys/geom/eli/g_eli_privacy.c | 11 ++++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/sys/geom/eli/g_eli_integrity.c b/sys/geom/eli/g_eli_integrity.c index f7bf1fdad713..f68800197eda 100644 --- a/sys/geom/eli/g_eli_integrity.c +++ b/sys/geom/eli/g_eli_integrity.c @@ -408,8 +408,8 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp) struct cryptodesc *crde, *crda; u_int i, lsec, nsec, data_secsize, decr_secsize, encr_secsize; off_t dstoff; - int err, error; u_char *p, *data, *auth, *authkey, *plaindata; + int error; G_ELI_LOGREQ(3, bp, "%s", __func__); @@ -451,7 +451,6 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp) bp->bio_inbed = 0; bp->bio_children = nsec; - error = 0; for (i = 1; i <= nsec; i++, dstoff += encr_secsize) { crp = (struct cryptop *)p; p += sizeof(*crp); crde = (struct cryptodesc *)p; p += sizeof(*crde); @@ -519,10 +518,8 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp) crda->crd_klen = G_ELI_AUTH_SECKEYLEN * 8; crp->crp_etype = 0; - err = crypto_dispatch(crp); - if (err != 0 && error == 0) - error = err; + error = crypto_dispatch(crp); + KASSERT(error == 0, ("crypto_dispatch() failed (error=%d)", + error)); } - if (bp->bio_error == 0) - bp->bio_error = error; } diff --git a/sys/geom/eli/g_eli_privacy.c b/sys/geom/eli/g_eli_privacy.c index a60efe8f1445..d636e1fb0ba0 100644 --- a/sys/geom/eli/g_eli_privacy.c +++ b/sys/geom/eli/g_eli_privacy.c @@ -230,10 +230,10 @@ g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp) struct cryptop *crp; struct cryptodesc *crd; u_int i, nsec, secsize; - int err, error; off_t dstoff; size_t size; u_char *p, *data; + int error; G_ELI_LOGREQ(3, bp, "%s", __func__); @@ -271,7 +271,6 @@ g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp) bcopy(bp->bio_data, data, bp->bio_length); } - error = 0; for (i = 0, dstoff = bp->bio_offset; i < nsec; i++, dstoff += secsize) { crp = (struct cryptop *)p; p += sizeof(*crp); crd = (struct cryptodesc *)p; p += sizeof(*crd); @@ -308,10 +307,8 @@ g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp) crd->crd_next = NULL; crp->crp_etype = 0; - err = crypto_dispatch(crp); - if (error == 0) - error = err; + error = crypto_dispatch(crp); + KASSERT(error == 0, ("crypto_dispatch() failed (error=%d)", + error)); } - if (bp->bio_error == 0) - bp->bio_error = error; } From a8bf83d6188fad9114cd5c3c07e00e7a7755e979 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 6 Aug 2015 18:02:54 +0000 Subject: [PATCH 279/314] Formally pair store_rel(&smp_started) with load_acq(&smp_started). The expected semantic is to have misc. data, e.g. CPU bitmaps, visible in the BSP after smp_started is written by the last started AP, which formally requires acquire barrier on the load. The change is mostly nop due to the ordered behaviour of the x86 CPUs. Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/x86/x86/mp_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c index b4c66a58faa5..c23108cc7ad6 100644 --- a/sys/x86/x86/mp_x86.c +++ b/sys/x86/x86/mp_x86.c @@ -602,7 +602,7 @@ init_secondary_tail(void) mtx_unlock_spin(&ap_boot_mtx); /* Wait until all the AP's are up. */ - while (smp_started == 0) + while (atomic_load_acq_int(&smp_started) == 0) ia32_pause(); /* Start per-CPU event timers. */ From f770ad4a2640e5d8984d5e409c930557b1abd8cb Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 6 Aug 2015 18:15:56 +0000 Subject: [PATCH 280/314] Now that stable/8 is EOL, stop building INDEX-8. MFC after: 1 week --- etc/portsnap.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/etc/portsnap.conf b/etc/portsnap.conf index d30826024355..624ae7e3e200 100644 --- a/etc/portsnap.conf +++ b/etc/portsnap.conf @@ -30,6 +30,5 @@ KEYPRINT=9b5feee6d69f170e3dd0a2c8e469ddbd64f13f978f2f3aede40c98633216c330 # REFUSE korean polish portuguese russian ukrainian vietnamese # List of INDEX files to build and the DESCRIBE file to use for each -INDEX INDEX-8 DESCRIBE.8 INDEX INDEX-9 DESCRIBE.9 INDEX INDEX-10 DESCRIBE.10 From 19d637849ef6d2be522e91fe28542f6045b588ca Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 18:28:15 +0000 Subject: [PATCH 281/314] Don't mark the fcntl flag argument as an output parameter so that it is always decoded. Previously the argument was not decoded if fcntl() failed. --- usr.bin/truss/syscalls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index e8eea832900a..9ee8bb102009 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -93,7 +93,7 @@ static const char rcsid[] = */ static struct syscall syscalls[] = { { .name = "fcntl", .ret_type = 1, .nargs = 3, - .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag | OUT, 2 } } }, + .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } }, { .name = "fork", .ret_type = 1, .nargs = 0 }, { .name = "vfork", .ret_type = 1, .nargs = 0 }, { .name = "rfork", .ret_type = 1, .nargs = 1, From e82ce59c37558b7ac4b3595f6400d48643c0637c Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 18:32:32 +0000 Subject: [PATCH 282/314] Decode the arguments to mkfifo() and fix an off-by-one error in the arguments to mknod(). --- usr.bin/truss/syscalls.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 9ee8bb102009..59b8cf293743 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -141,8 +141,10 @@ static struct syscall syscalls[] = { .args = { { Name, 0 } } }, { .name = "chroot", .ret_type = 0, .nargs = 1, .args = { { Name, 0 } } }, + { .name = "mkfifo", .ret_type = 0, .nargs = 2, + .args = { { Name, 0 }, { Octal, 1 } } }, { .name = "mknod", .ret_type = 0, .nargs = 3, - .args = { { Name, 0 }, { Octal, 1 }, { Int, 3 } } }, + .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } }, { .name = "chmod", .ret_type = 0, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, { .name = "chown", .ret_type = 0, .nargs = 3, From 7d89732757e74ca8e47499fc7f7a87a9080b08c8 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 19:08:33 +0000 Subject: [PATCH 283/314] Decode the arguments passed to the *at() family of system calls. This is especially useful now that libc's open() always calls openat(). While here, fix a few other things: - Decode the mode argument passed to access(), eaccess(), and faccessat(). - Decode the atfd paramete to pretty-print AT_FDCWD. - Decode the special AT_* flags used with some of the *at() system calls. - Decode arguments for fchmod(), lchmod(), fchown(), lchown(), eaccess(), and futimens(). - Decode both of the timeval structures passed to futimes() instead of just the first one. --- usr.bin/truss/syscall.h | 2 +- usr.bin/truss/syscalls.c | 120 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 4 deletions(-) diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h index a57361188c57..a2fa826333c7 100644 --- a/usr.bin/truss/syscall.h +++ b/usr.bin/truss/syscall.h @@ -41,7 +41,7 @@ enum Argtype { None = 1, Hex, Octal, Int, LongHex, Name, Ptr, Stat, Ioctl, Quad, Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open, Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2, Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl, - LinuxSockArgs, Umtxop }; + LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode }; #define ARG_MASK 0xff #define OUT 0x100 diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 59b8cf293743..ec87e470c93c 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -115,6 +115,9 @@ static struct syscall syscalls[] = { { .name = "getuid", .ret_type = 1, .nargs = 0 }, { .name = "readlink", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Readlinkres | OUT, 1 }, { Int, 2 } } }, + { .name = "readlinkat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 }, + { Int, 3 } } }, { .name = "lseek", .ret_type = 2, .nargs = 3, .args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, { .name = "linux_lseek", .ret_type = 2, .nargs = 3, @@ -127,28 +130,55 @@ static struct syscall syscalls[] = { .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } }, { .name = "open", .ret_type = 1, .nargs = 3, .args = { { Name | IN, 0 }, { Open, 1 }, { Octal, 2 } } }, + { .name = "openat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Open, 2 }, + { Octal, 3 } } }, { .name = "mkdir", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "mkdirat", .ret_type = 1, .nargs = 3, + .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } }, { .name = "linux_open", .ret_type = 1, .nargs = 3, .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } }, { .name = "close", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, { .name = "link", .ret_type = 0, .nargs = 2, .args = { { Name, 0 }, { Name, 1 } } }, + { .name = "linkat", .ret_type = 0, .nargs = 5, + .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 }, + { Atflags, 4 } } }, { .name = "unlink", .ret_type = 0, .nargs = 1, .args = { { Name, 0 } } }, + { .name = "unlinkat", .ret_type = 0, .nargs = 3, + .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } }, { .name = "chdir", .ret_type = 0, .nargs = 1, .args = { { Name, 0 } } }, { .name = "chroot", .ret_type = 0, .nargs = 1, .args = { { Name, 0 } } }, { .name = "mkfifo", .ret_type = 0, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "mkfifoat", .ret_type = 0, .nargs = 3, + .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 } } }, { .name = "mknod", .ret_type = 0, .nargs = 3, .args = { { Name, 0 }, { Octal, 1 }, { Int, 2 } } }, + { .name = "mknodat", .ret_type = 0, .nargs = 4, + .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Int, 3 } } }, { .name = "chmod", .ret_type = 0, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "fchmod", .ret_type = 0, .nargs = 2, + .args = { { Int, 0 }, { Octal, 1 } } }, + { .name = "lchmod", .ret_type = 0, .nargs = 2, + .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "fchmodat", .ret_type = 0, .nargs = 4, + .args = { { Atfd, 0 }, { Name, 1 }, { Octal, 2 }, { Atflags, 3 } } }, { .name = "chown", .ret_type = 0, .nargs = 3, .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "fchown", .ret_type = 0, .nargs = 3, + .args = { { Int, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "lchown", .ret_type = 0, .nargs = 3, + .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "fchownat", .ret_type = 0, .nargs = 5, + .args = { { Atfd, 0 }, { Name, 1 }, { Int, 2 }, { Int, 3 }, + { Atflags, 4 } } }, { .name = "linux_stat64", .ret_type = 1, .nargs = 3, .args = { { Name | IN, 0 }, { Ptr | OUT, 1 }, { Ptr | IN, 1 }}}, { .name = "mount", .ret_type = 0, .nargs = 4, @@ -157,6 +187,9 @@ static struct syscall syscalls[] = { .args = { { Name, 0 }, { Int, 2 } } }, { .name = "fstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Stat | OUT, 1 } } }, + { .name = "fstatat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Stat | OUT, 2 }, + { Atflags, 3 } } }, { .name = "stat", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, { .name = "lstat", .ret_type = 1, .nargs = 2, @@ -164,7 +197,7 @@ static struct syscall syscalls[] = { { .name = "linux_newstat", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } }, { .name = "linux_access", .ret_type = 1, .nargs = 2, - .args = { { Name, 0 }, { Int, 1 }}}, + .args = { { Name, 0 }, { Accessmode, 1 }}}, { .name = "linux_newfstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Ptr | OUT, 1 } } }, { .name = "write", .ret_type = 1, .nargs = 3, @@ -176,15 +209,26 @@ static struct syscall syscalls[] = { { .name = "exit", .ret_type = 0, .nargs = 1, .args = { { Hex, 0 } } }, { .name = "access", .ret_type = 1, .nargs = 2, - .args = { { Name | IN, 0 }, { Int, 1 } } }, + .args = { { Name | IN, 0 }, { Accessmode, 1 } } }, + { .name = "eaccess", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Accessmode, 1 } } }, + { .name = "faccessat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Accessmode, 2 }, + { Atflags, 3 } } }, { .name = "sigaction", .ret_type = 1, .nargs = 3, .args = { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 } } }, { .name = "accept", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, { .name = "bind", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, + { .name = "bindat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 }, + { Int, 3 } } }, { .name = "connect", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, + { .name = "connectat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Int, 1 }, { Sockaddr | IN, 2 }, + { Int, 3 } } }, { .name = "getpeername", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, { .name = "getsockname", .ret_type = 1, .nargs = 3, @@ -248,7 +292,14 @@ static struct syscall syscalls[] = { { .name = "lutimes", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, { .name = "futimes", .ret_type = 1, .nargs = 2, - .args = { { Int, 0 }, { Timeval | IN, 1 } } }, + .args = { { Int, 0 }, { Timeval2 | IN, 1 } } }, + { .name = "futimesat", .ret_type = 1, .nargs = 3, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timeval2 | IN, 2 } } }, + { .name = "futimens", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Timespec2 | IN, 1 } } }, + { .name = "utimensat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 }, + { Atflags, 3 } } }, { .name = "chflags", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Hex, 1 } } }, { .name = "lchflags", .ret_type = 1, .nargs = 2, @@ -269,8 +320,12 @@ static struct syscall syscalls[] = { .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } }, { .name = "rename", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Name, 1 } } }, + { .name = "renameat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name, 1 }, { Atfd, 2 }, { Name, 3 } } }, { .name = "symlink", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Name, 1 } } }, + { .name = "symlinkat", .ret_type = 1, .nargs = 3, + .args = { { Name, 0 }, { Atfd, 1 }, { Name, 2 } } }, { .name = "posix_openpt", .ret_type = 1, .nargs = 1, .args = { { Open, 0 } } }, { .name = "wait4", .ret_type = 1, .nargs = 4, @@ -438,6 +493,15 @@ static struct xlat umtx_ops[] = { XEND }; +static struct xlat at_flags[] = { + X(AT_EACCESS) X(AT_SYMLINK_NOFOLLOW) X(AT_SYMLINK_FOLLOW) + X(AT_REMOVEDIR) XEND +}; + +static struct xlat access_modes[] = { + X(R_OK) X(W_OK) X(X_OK) XEND +}; + #undef X #undef XEND @@ -780,6 +844,40 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, asprintf(&tmp, "0x%lx", args[sc->offset]); break; } + case Timespec2: { + struct timespec ts[2]; + FILE *fp; + size_t len; + const char *sep; + unsigned int i; + + if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) + != -1) { + fp = open_memstream(&tmp, &len); + fputc('{', fp); + sep = ""; + for (i = 0; i < nitems(ts); i++) { + fputs(sep, fp); + sep = ", "; + switch (ts[i].tv_nsec) { + case UTIME_NOW: + fprintf(fp, "UTIME_NOW"); + break; + case UTIME_OMIT: + fprintf(fp, "UTIME_OMIT"); + break; + default: + fprintf(fp, "%ld.%09ld", + (long)ts[i].tv_sec, ts[i].tv_nsec); + break; + } + } + fputc('}', fp); + fclose(fp); + } else + asprintf(&tmp, "0x%lx", args[sc->offset]); + break; + } case Timeval: { struct timeval tv; if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) @@ -1319,6 +1417,22 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, case Umtxop: tmp = strdup(xlookup(umtx_ops, args[sc->offset])); break; + case Atfd: + if ((int)args[sc->offset] == AT_FDCWD) + tmp = strdup("AT_FDCWD"); + else + asprintf(&tmp, "%d", (int)args[sc->offset]); + break; + case Atflags: + tmp = strdup(xlookup_bits(at_flags, args[sc->offset])); + break; + case Accessmode: + if (args[sc->offset] == F_OK) + tmp = strdup("F_OK"); + else + tmp = strdup(xlookup_bits(access_modes, + args[sc->offset])); + break; default: errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); } From fc43ff0865d8aa624ad8512e377dc9891197c307 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 6 Aug 2015 19:29:26 +0000 Subject: [PATCH 284/314] Add support to the uftdi driver for reading and writing the serial eeprom that can be attached to the chips, via ioctl() calls. --- sys/dev/usb/serial/uftdi.c | 85 ++++++++++++++++++++++++++++++++++ sys/dev/usb/serial/uftdi_reg.h | 5 +- sys/dev/usb/uftdiio.h | 23 +++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index c0dc79f18b11..cf468044b049 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -1790,6 +1790,82 @@ uftdi_set_error_char(struct ucom_softc *ucom, int echar) return (usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL)); } +static int +uftdi_read_eeprom(struct ucom_softc *ucom, struct uftdi_eeio *eeio) +{ + struct uftdi_softc *sc = ucom->sc_parent; + usb_device_request_t req; + usb_error_t err; + uint16_t widx, wlength, woffset; + + /* Offset and length must both be evenly divisible by two. */ + if ((eeio->offset | eeio->length) & 0x01) + return (EINVAL); + + woffset = eeio->offset / 2U; + wlength = eeio->length / 2U; + for (widx = 0; widx < wlength; widx++) { + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = FTDI_SIO_READ_EEPROM; + USETW(req.wIndex, widx + woffset); + USETW(req.wLength, 2); + USETW(req.wValue, 0); + err = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, + &eeio->data[widx]); + if (err != USB_ERR_NORMAL_COMPLETION) + return (err); + } + return (USB_ERR_NORMAL_COMPLETION); +} + +static int +uftdi_write_eeprom(struct ucom_softc *ucom, struct uftdi_eeio *eeio) +{ + struct uftdi_softc *sc = ucom->sc_parent; + usb_device_request_t req; + usb_error_t err; + uint16_t widx, wlength, woffset; + + /* Offset and length must both be evenly divisible by two. */ + if ((eeio->offset | eeio->length) & 0x01) + return (EINVAL); + + woffset = eeio->offset / 2U; + wlength = eeio->length / 2U; + for (widx = 0; widx < wlength; widx++) { + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = FTDI_SIO_WRITE_EEPROM; + USETW(req.wIndex, widx + woffset); + USETW(req.wLength, 0); + USETW(req.wValue, eeio->data[widx]); + err = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL); + if (err != USB_ERR_NORMAL_COMPLETION) + return (err); + } + return (USB_ERR_NORMAL_COMPLETION); +} + +static int +uftdi_erase_eeprom(struct ucom_softc *ucom, int confirmation) +{ + struct uftdi_softc *sc = ucom->sc_parent; + usb_device_request_t req; + usb_error_t err; + + /* Small effort to prevent accidental erasure. */ + if (confirmation != UFTDI_CONFIRM_ERASE) + return (EINVAL); + + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = FTDI_SIO_ERASE_EEPROM; + USETW(req.wIndex, 0); + USETW(req.wLength, 0); + USETW(req.wValue, 0); + err = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL); + + return (err); +} + static int uftdi_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data, int flag, struct thread *td) @@ -1833,6 +1909,15 @@ uftdi_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data, *(int *)data = sc->sc_bcdDevice; err = 0; break; + case UFTDIIOC_READ_EEPROM: + err = uftdi_read_eeprom(ucom, (struct uftdi_eeio *)data); + break; + case UFTDIIOC_WRITE_EEPROM: + err = uftdi_write_eeprom(ucom, (struct uftdi_eeio *)data); + break; + case UFTDIIOC_ERASE_EEPROM: + err = uftdi_erase_eeprom(ucom, *(int *)data); + break; default: return (ENOIOCTL); } diff --git a/sys/dev/usb/serial/uftdi_reg.h b/sys/dev/usb/serial/uftdi_reg.h index a2d6e3876ae0..a1ea325b89a2 100644 --- a/sys/dev/usb/serial/uftdi_reg.h +++ b/sys/dev/usb/serial/uftdi_reg.h @@ -31,7 +31,10 @@ #define FTDI_SIO_SET_LATENCY 9 /* Set the latency timer */ #define FTDI_SIO_GET_LATENCY 10 /* Read the latency timer */ #define FTDI_SIO_SET_BITMODE 11 /* Set the bit bang I/O mode */ -#define FTDI_SIO_GET_BITMODE 12 /* Read pin states in bit bang mode */ +#define FTDI_SIO_GET_BITMODE 12 /* Read pin states from any mode */ +#define FTDI_SIO_READ_EEPROM 144 /* Read eeprom word */ +#define FTDI_SIO_WRITE_EEPROM 145 /* Write eeprom word */ +#define FTDI_SIO_ERASE_EEPROM 146 /* Erase entire eeprom */ /* Port Identifier Table */ #define FTDI_PIT_DEFAULT 0 /* SIOA */ diff --git a/sys/dev/usb/uftdiio.h b/sys/dev/usb/uftdiio.h index 0db2f3808756..4c6ecbc3f7ba 100644 --- a/sys/dev/usb/uftdiio.h +++ b/sys/dev/usb/uftdiio.h @@ -61,6 +61,26 @@ struct uftdi_bitmode uint8_t iomask; }; +/* + * For UFTDIIOC_READ_EEPROM, UFTDIIOC_WRITE_EEPROM: + * + * IO is done in 16-bit words at the chip level; offset and length are in bytes, + * but must each be evenly divisible by two. + * + * It is not necessary to erase before writing. For the FT232R device (only) + * you must set the latency timer to 0x77 before doing a series of eeprom writes + * (and restore it to the prior value when done). + */ +struct uftdi_eeio +{ + uint16_t offset; + uint16_t length; + uint16_t data[64]; +}; + +/* Pass this value to confirm that eeprom erase request is not accidental. */ +#define UFTDI_CONFIRM_ERASE 0x26139108 + #define UFTDIIOC_RESET_IO _IO('c', 0) /* Reset config, flush fifos.*/ #define UFTDIIOC_RESET_RX _IO('c', 1) /* Flush input fifo. */ #define UFTDIIOC_RESET_TX _IO('c', 2) /* Flush output fifo. */ @@ -71,5 +91,8 @@ struct uftdi_bitmode #define UFTDIIOC_SET_LATENCY _IOW('c', 7, int) /* 1-255 ms */ #define UFTDIIOC_GET_LATENCY _IOR('c', 8, int) #define UFTDIIOC_GET_HWREV _IOR('c', 9, int) +#define UFTDIIOC_READ_EEPROM _IOWR('c', 10, struct uftdi_eeio) +#define UFTDIIOC_WRITE_EEPROM _IOW('c', 11, struct uftdi_eeio) +#define UFTDIIOC_ERASE_EEPROM _IOW('c', 12, int) #endif From 0a46af44bf40eb79832b8ff49bbf64686332338a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 19:36:47 +0000 Subject: [PATCH 285/314] Whitespace fixes to consistently use spaces before }'s and wrap long lines. --- usr.bin/truss/syscalls.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index ec87e470c93c..a627f44f6d38 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -101,9 +101,9 @@ static struct syscall syscalls[] = { { .name = "getegid", .ret_type = 1, .nargs = 0 }, { .name = "geteuid", .ret_type = 1, .nargs = 0 }, { .name = "linux_readlink", .ret_type = 1, .nargs = 3, - .args = { { Name, 0 }, { Name | OUT, 1 }, { Int, 2 }}}, + .args = { { Name, 0 }, { Name | OUT, 1 }, { Int, 2 } } }, { .name = "linux_socketcall", .ret_type = 1, .nargs = 2, - .args = { { Int, 0 }, { LinuxSockArgs, 1 }}}, + .args = { { Int, 0 }, { LinuxSockArgs, 1 } } }, { .name = "getgid", .ret_type = 1, .nargs = 0 }, { .name = "getpid", .ret_type = 1, .nargs = 0 }, { .name = "getpgid", .ret_type = 1, .nargs = 1, @@ -119,13 +119,15 @@ static struct syscall syscalls[] = { .args = { { Atfd, 0 }, { Name, 1 }, { Readlinkres | OUT, 2 }, { Int, 3 } } }, { .name = "lseek", .ret_type = 2, .nargs = 3, - .args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, + .args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, + { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, { .name = "linux_lseek", .ret_type = 2, .nargs = 3, .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } }, { .name = "mmap", .ret_type = 2, .nargs = 6, - .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 }, { Int, 4 }, { Quad, 5 + QUAD_ALIGN } } }, + .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 }, + { Int, 4 }, { Quad, 5 + QUAD_ALIGN } } }, { .name = "linux_mkdir", .ret_type = 1, .nargs = 2, - .args = { { Name | IN, 0}, {Int, 1}}}, + .args = { { Name | IN, 0 }, { Int, 1 } } }, { .name = "mprotect", .ret_type = 1, .nargs = 3, .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } }, { .name = "open", .ret_type = 1, .nargs = 3, @@ -180,7 +182,7 @@ static struct syscall syscalls[] = { .args = { { Atfd, 0 }, { Name, 1 }, { Int, 2 }, { Int, 3 }, { Atflags, 4 } } }, { .name = "linux_stat64", .ret_type = 1, .nargs = 3, - .args = { { Name | IN, 0 }, { Ptr | OUT, 1 }, { Ptr | IN, 1 }}}, + .args = { { Name | IN, 0 }, { Ptr | OUT, 1 }, { Ptr | IN, 1 } } }, { .name = "mount", .ret_type = 0, .nargs = 4, .args = { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } }, { .name = "umount", .ret_type = 0, .nargs = 2, @@ -197,7 +199,7 @@ static struct syscall syscalls[] = { { .name = "linux_newstat", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } }, { .name = "linux_access", .ret_type = 1, .nargs = 2, - .args = { { Name, 0 }, { Accessmode, 1 }}}, + .args = { { Name, 0 }, { Accessmode, 1 } } }, { .name = "linux_newfstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Ptr | OUT, 1 } } }, { .name = "write", .ret_type = 1, .nargs = 3, @@ -216,7 +218,8 @@ static struct syscall syscalls[] = { .args = { { Atfd, 0 }, { Name | IN, 1 }, { Accessmode, 2 }, { Atflags, 3 } } }, { .name = "sigaction", .ret_type = 1, .nargs = 3, - .args = { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 } } }, + .args = { { Signal, 0 }, { Sigaction | IN, 1 }, + { Sigaction | OUT, 2 } } }, { .name = "accept", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, { .name = "bind", .ret_type = 1, .nargs = 3, @@ -234,13 +237,17 @@ static struct syscall syscalls[] = { { .name = "getsockname", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, { .name = "recvfrom", .ret_type = 1, .nargs = 6, - .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 }, { Hex, 3 }, { Sockaddr | OUT, 4 }, { Ptr | OUT, 5 } } }, + .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 }, { Hex, 3 }, + { Sockaddr | OUT, 4 }, { Ptr | OUT, 5 } } }, { .name = "sendto", .ret_type = 1, .nargs = 6, - .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, { Hex, 3 }, { Sockaddr | IN, 4 }, { Ptr | IN, 5 } } }, + .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, { Hex, 3 }, + { Sockaddr | IN, 4 }, { Ptr | IN, 5 } } }, { .name = "execve", .ret_type = 1, .nargs = 3, - .args = { { Name | IN, 0 }, { StringArray | IN, 1 }, { StringArray | IN, 2 } } }, + .args = { { Name | IN, 0 }, { StringArray | IN, 1 }, + { StringArray | IN, 2 } } }, { .name = "linux_execve", .ret_type = 1, .nargs = 3, - .args = { { Name | IN, 0 }, { StringArray | IN, 1 }, { StringArray | IN, 2 } } }, + .args = { { Name | IN, 0 }, { StringArray | IN, 1 }, + { StringArray | IN, 2 } } }, { .name = "kldload", .ret_type = 0, .nargs = 1, .args = { { Name | IN, 0 } } }, { .name = "kldunload", .ret_type = 0, .nargs = 1, @@ -256,7 +263,8 @@ static struct syscall syscalls[] = { { .name = "nanosleep", .ret_type = 0, .nargs = 1, .args = { { Timespec, 0 } } }, { .name = "select", .ret_type = 1, .nargs = 5, - .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 }, { Timeval, 4 } } }, + .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 }, + { Timeval, 4 } } }, { .name = "poll", .ret_type = 1, .nargs = 3, .args = { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } }, { .name = "gettimeofday", .ret_type = 1, .nargs = 2, @@ -270,7 +278,8 @@ static struct syscall syscalls[] = { { .name = "kse_release", .ret_type = 0, .nargs = 1, .args = { { Timespec, 0 } } }, { .name = "kevent", .ret_type = 0, .nargs = 6, - .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } }, + .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, + { Int, 4 }, { Timespec, 5 } } }, { .name = "sigprocmask", .ret_type = 0, .nargs = 3, .args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } }, { .name = "unmount", .ret_type = 1, .nargs = 2, @@ -979,7 +988,8 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, what = buf; break; } - asprintf(&tmp, "(0x%lx)%s, 0x%lx", args[sc->offset], what, (long unsigned int)largs.args); + asprintf(&tmp, "(0x%lx)%s, 0x%lx", args[sc->offset], what, + (long unsigned int)largs.args); break; } case Pollfd: { From a0465416233e9c948e8c8d5d05d7fa89aab5f188 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 6 Aug 2015 19:47:04 +0000 Subject: [PATCH 286/314] Return the current ftdi bitbang mode with the UFTDIIOC_GET_BITMODE ioctl. The ftdi chip itself has a "get bitmode" command that doesn't actually return the current bitmode, just a snapshot of the gpio lines. The chip apparently has no way to provide the current bitmode. This implements the functionality at the driver level. The driver starts out assuming the chip is in UART mode (which it will be, coming out of reset) and keeps track of every successful set-bitmode operation so that it can always return the current mode with UFTDIIOC_GET_BITMODE. --- sys/dev/usb/serial/uftdi.c | 16 ++++++++++++---- sys/dev/usb/uftdiio.h | 7 ++++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index cf468044b049..b33df36d9276 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -161,6 +161,7 @@ struct uftdi_softc { uint8_t sc_hdrlen; uint8_t sc_msr; uint8_t sc_lsr; + uint8_t sc_bitmode; }; struct uftdi_param_config { @@ -196,7 +197,7 @@ static void uftdi_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *); static int uftdi_reset(struct ucom_softc *, int); static int uftdi_set_bitmode(struct ucom_softc *, uint8_t, uint8_t); -static int uftdi_get_bitmode(struct ucom_softc *, uint8_t *); +static int uftdi_get_bitmode(struct ucom_softc *, uint8_t *, uint8_t *); static int uftdi_set_latency(struct ucom_softc *, int); static int uftdi_get_latency(struct ucom_softc *, int *); static int uftdi_set_event_char(struct ucom_softc *, int); @@ -1090,6 +1091,7 @@ uftdi_attach(device_t dev) sc->sc_udev = uaa->device; sc->sc_dev = dev; sc->sc_unit = device_get_unit(dev); + sc->sc_bitmode = UFTDI_BITMODE_NONE; device_set_usb_desc(dev); mtx_init(&sc->sc_mtx, "uftdi", NULL, MTX_DEF); @@ -1681,6 +1683,7 @@ uftdi_set_bitmode(struct ucom_softc *ucom, uint8_t bitmode, uint8_t iomask) { struct uftdi_softc *sc = ucom->sc_parent; usb_device_request_t req; + int rv; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = FTDI_SIO_SET_BITMODE; @@ -1693,11 +1696,15 @@ uftdi_set_bitmode(struct ucom_softc *ucom, uint8_t bitmode, uint8_t iomask) else USETW2(req.wValue, (1 << bitmode), iomask); - return (usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL)); + rv = usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL); + if (rv == USB_ERR_NORMAL_COMPLETION) + sc->sc_bitmode = bitmode; + + return (rv); } static int -uftdi_get_bitmode(struct ucom_softc *ucom, uint8_t *iomask) +uftdi_get_bitmode(struct ucom_softc *ucom, uint8_t *bitmode, uint8_t *iomask) { struct uftdi_softc *sc = ucom->sc_parent; usb_device_request_t req; @@ -1709,6 +1716,7 @@ uftdi_get_bitmode(struct ucom_softc *ucom, uint8_t *iomask) USETW(req.wLength, 1); USETW(req.wValue, 0); + *bitmode = sc->sc_bitmode; return (usbd_do_request(sc->sc_udev, &sc->sc_mtx, &req, iomask)); } @@ -1891,7 +1899,7 @@ uftdi_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data, break; case UFTDIIOC_GET_BITMODE: mode = (struct uftdi_bitmode *)data; - err = uftdi_get_bitmode(ucom, &mode->iomask); + err = uftdi_get_bitmode(ucom, &mode->mode, &mode->iomask); break; case UFTDIIOC_SET_LATENCY: err = uftdi_set_latency(ucom, *((int *)data)); diff --git a/sys/dev/usb/uftdiio.h b/sys/dev/usb/uftdiio.h index 4c6ecbc3f7ba..b6244831de32 100644 --- a/sys/dev/usb/uftdiio.h +++ b/sys/dev/usb/uftdiio.h @@ -43,7 +43,7 @@ enum uftdi_bitmodes UFTDI_BITMODE_CPU_EMUL = 3, UFTDI_BITMODE_FAST_SERIAL = 4, UFTDI_BITMODE_CBUS = 5, - UFTDI_BITMODE_NONE = 0xff, + UFTDI_BITMODE_NONE = 0xff, /* aka UART mode. */ }; /* @@ -52,8 +52,9 @@ enum uftdi_bitmodes * iomask = Mask of bits enabled for bitbang output. * * For UFTDIIOC_GET_BITMODE: - * mode = Unused. - * iomask = Returned snapshot of bitbang pin states at time of call. + * mode = Mode most recently set using UFTDIIOC_SET_BITMODE. + * iomask = Returned snapshot of DBUS0..DBUS7 pin states at time of call. + * Pin states can be read in any mode, not just bitbang modes. */ struct uftdi_bitmode { From 1e2ec671fc497bcf54a6e3dc2ffea46eaa214f13 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 6 Aug 2015 20:05:40 +0000 Subject: [PATCH 287/314] Consistently use both leading and trailing spaces inside of the {}'s when pretty-printing structures. Most structures used both spaces, but some only used a trailing space and some used neither. --- usr.bin/truss/syscalls.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index a627f44f6d38..7ecb38b2ce22 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -847,7 +847,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct timespec ts; if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) != -1) - asprintf(&tmp, "{%ld.%09ld }", (long)ts.tv_sec, + asprintf(&tmp, "{ %ld.%09ld }", (long)ts.tv_sec, ts.tv_nsec); else asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -863,7 +863,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) != -1) { fp = open_memstream(&tmp, &len); - fputc('{', fp); + fputs("{ ", fp); sep = ""; for (i = 0; i < nitems(ts); i++) { fputs(sep, fp); @@ -881,7 +881,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, break; } } - fputc('}', fp); + fputs(" }", fp); fclose(fp); } else asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -891,7 +891,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct timeval tv; if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) - asprintf(&tmp, "{%ld.%06ld }", (long)tv.tv_sec, + asprintf(&tmp, "{ %ld.%06ld }", (long)tv.tv_sec, tv.tv_usec); else asprintf(&tmp, "0x%lx", args[sc->offset]); @@ -901,7 +901,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct timeval tv[2]; if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) - asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }", + asprintf(&tmp, "{ %ld.%06ld, %ld.%06ld }", (long)tv[0].tv_sec, tv[0].tv_usec, (long)tv[1].tv_sec, tv[1].tv_usec); else @@ -912,7 +912,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct itimerval itv; if (get_struct(pid, (void *)args[sc->offset], &itv, sizeof(itv)) != -1) - asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }", + asprintf(&tmp, "{ %ld.%06ld, %ld.%06ld }", (long)itv.it_interval.tv_sec, itv.it_interval.tv_usec, (long)itv.it_value.tv_sec, @@ -1016,6 +1016,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, tmpsize); tmp[used++] = '{'; + tmp[used++] = ' '; for (i = 0; i < numfds; i++) { u = snprintf(tmp + used, per_fd, "%s%d/%s", @@ -1024,6 +1025,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, if (u > 0) used += u < per_fd ? u : per_fd; } + tmp[used++] = ' '; tmp[used++] = '}'; tmp[used++] = '\0'; } else { @@ -1056,6 +1058,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, "output", tmpsize); tmp[used++] = '{'; + tmp[used++] = ' '; for (i = 0; i < numfds; i++) { if (FD_ISSET(i, fds)) { u = snprintf(tmp + used, per_fd, "%d ", @@ -1064,8 +1067,6 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, used += u < per_fd ? u : per_fd; } } - if (tmp[used-1] == ' ') - used--; tmp[used++] = '}'; tmp[used++] = '\0'; } else @@ -1266,8 +1267,9 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, default: sa = (struct sockaddr *)&ss; asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data " - "= {%n%*s } }", (int)sa->sa_len, (int)sa->sa_family, - &i, 6 * (int)(sa->sa_len - ((char *)&sa->sa_data - + "= { %n%*s } }", (int)sa->sa_len, + (int)sa->sa_family, &i, + 6 * (int)(sa->sa_len - ((char *)&sa->sa_data - (char *)sa)), ""); if (tmp != NULL) { p = tmp + i; @@ -1333,6 +1335,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, "output", tmpsize); tmp[used++] = '{'; + tmp[used++] = ' '; for (i = 0; i < numevents; i++) { u = snprintf(tmp + used, per_ke, "%s%p,%s,%s,%d,%p,%p", @@ -1346,6 +1349,7 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, if (u > 0) used += u < per_ke ? u : per_ke; } + tmp[used++] = ' '; tmp[used++] = '}'; tmp[used++] = '\0'; } else { From 374b1ec1eac335ca505754059dac7b2d78880957 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 6 Aug 2015 20:59:03 +0000 Subject: [PATCH 288/314] Document the recently added get-bitmode and eeprom read/write functionality. --- share/man/man4/uftdi.4 | 66 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/share/man/man4/uftdi.4 b/share/man/man4/uftdi.4 index 1045169b7a2d..687d44318f8b 100644 --- a/share/man/man4/uftdi.4 +++ b/share/man/man4/uftdi.4 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 31, 2014 +.Dd August 6, 2015 .Dt UFTDI 4 .Os .Sh NAME @@ -110,6 +110,11 @@ The must be one of the .Va uftdi_bitmodes values. +Setting +.Va mode +to +.Dv UFTDI_BITMODE_NONE +returns the channel to standard UART mode. .Bd -literal enum uftdi_bitmodes { @@ -139,12 +144,15 @@ and data which either reflects pin state or is interpreted as MPSSE commands and parameters, depending on the mode. .It Dv UFTDIIOC_GET_BITMODE Pq Vt "struct uftdi_bitmode" -Return the state of the bitbang pins at the time of the call in the +Return the current bitbang mode in the +.Va mode +member, and the state of the DBUS0..DBUS7 pins at the time +of the call in the .Va iomask member. -The -.Va mode -member is unused. +The pin state can be read while the chip is in any mode, including +.Dv UFTDI_BITMODE_NONE +(UART) mode. .It Dv UFTDIIOC_SET_ERROR_CHAR Pq Vt int Set the character which is inserted into the buffer to mark the point of an error such as FIFO overflow. @@ -164,6 +172,54 @@ This is the .Va bcdDevice value from the .Va usb_device_descriptor . +.It Dv UFTDIIOC_READ_EEPROM Pq Vt "struct uftdi_eeio" +Read one or more words from the configuration eeprom. +The FTDI chip performs eeprom I/O in 16-bit words. +Set +.Va offset +and +.Va length +to values evenly divisible by two before the call, and the +.Va data +array will contain the requested values from eeprom after the call. +.Bd -literal +struct uftdi_eeio +{ + uint16_t offset; + uint16_t length; + uint16_t data[64]; +}; +.Ed +.Pp +The FT232R chip has an internal eeprom. +An external serial eeprom is optional on other FTDI chips. +The eeprom may contain 64, 128, or 256 words, +depending on the part used. +Multiple calls may be needed to read or write the larger parts. +When no eeprom is present, all words in the returned data are 0xffff. +An erased eeprom also reads as all 0xffff. +.It Dv UFTDIIOC_WRITE_EEPROM Pq Vt "struct uftdi_eeio" +Write one or more words to the configuration eeprom. +The +.Va uftdi_eeio +values are as described for +.Dv UFTDIIOC_READ_EEPROM . +.Pp +The FTDI chip does a blind write to the eeprom, and it will appear +to succeed even when no eeprom is present. +To ensure a good write you must read back and verify the data. +It is +.Em not +necessary to erase before writing. +Any position within the eeprom can be overwritten at any time. +.It Dv UFTDIIOC_ERASE_EEPROM Pq Vt int +Erase the entire eeprom. +This is useful primarily for test and debugging, as there is no +need to erase before writing. +To help prevent accidental erasure caused by calling the wrong +ioctl, you must pass the special value +.Dv UFTDI_CONFIRM_ERASE +as the argument to this ioctl. .El .Sh HARDWARE The From e0a63baae4d0f04749ebcdb3014b1127ef8a6860 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 6 Aug 2015 21:27:50 +0000 Subject: [PATCH 289/314] Introduce a sysctl for reporting the number of fully populated reservations. --- sys/vm/vm_reserv.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sys/vm/vm_reserv.c b/sys/vm/vm_reserv.c index 2cfc630026de..34e69e11b832 100644 --- a/sys/vm/vm_reserv.c +++ b/sys/vm/vm_reserv.c @@ -217,6 +217,11 @@ static long vm_reserv_freed; SYSCTL_LONG(_vm_reserv, OID_AUTO, freed, CTLFLAG_RD, &vm_reserv_freed, 0, "Cumulative number of freed reservations"); +static int sysctl_vm_reserv_fullpop(SYSCTL_HANDLER_ARGS); + +SYSCTL_PROC(_vm_reserv, OID_AUTO, fullpop, CTLTYPE_INT | CTLFLAG_RD, NULL, 0, + sysctl_vm_reserv_fullpop, "I", "Current number of full reservations"); + static int sysctl_vm_reserv_partpopq(SYSCTL_HANDLER_ARGS); SYSCTL_OID(_vm_reserv, OID_AUTO, partpopq, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, @@ -234,6 +239,33 @@ static boolean_t vm_reserv_has_pindex(vm_reserv_t rv, static void vm_reserv_populate(vm_reserv_t rv, int index); static void vm_reserv_reclaim(vm_reserv_t rv); +/* + * Returns the current number of full reservations. + * + * Since the number of full reservations is computed without acquiring the + * free page queue lock, the returned value may be inexact. + */ +static int +sysctl_vm_reserv_fullpop(SYSCTL_HANDLER_ARGS) +{ + vm_paddr_t paddr; + struct vm_phys_seg *seg; + vm_reserv_t rv; + int fullpop, segind; + + fullpop = 0; + for (segind = 0; segind < vm_phys_nsegs; segind++) { + seg = &vm_phys_segs[segind]; + paddr = roundup2(seg->start, VM_LEVEL_0_SIZE); + while (paddr + VM_LEVEL_0_SIZE <= seg->end) { + rv = &vm_reserv_array[paddr >> VM_LEVEL_0_SHIFT]; + fullpop += rv->popcnt == VM_LEVEL_0_NPAGES; + paddr += VM_LEVEL_0_SIZE; + } + } + return (sysctl_handle_int(oidp, &fullpop, 0, req)); +} + /* * Describes the current state of the partially-populated reservation queue. */ From 9c354f41b3f42256afdc7e39abb5f36989a2d137 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 6 Aug 2015 23:44:46 +0000 Subject: [PATCH 290/314] Now that the portsnap buildbox is generating the raw bits for INDEX-11, add it to the set of INDEX files built by portsnap. MFC after: 2 weeks --- etc/portsnap.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/portsnap.conf b/etc/portsnap.conf index 624ae7e3e200..f6c18de45d6b 100644 --- a/etc/portsnap.conf +++ b/etc/portsnap.conf @@ -32,3 +32,4 @@ KEYPRINT=9b5feee6d69f170e3dd0a2c8e469ddbd64f13f978f2f3aede40c98633216c330 # List of INDEX files to build and the DESCRIBE file to use for each INDEX INDEX-9 DESCRIBE.9 INDEX INDEX-10 DESCRIBE.10 +INDEX INDEX-11 DESCRIBE.11 From 0fa4d4b57099a9bcb1ac0a71583fcd8a0490cddf Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Fri, 7 Aug 2015 02:05:16 +0000 Subject: [PATCH 291/314] Add support for ASUS WL-100g. --- share/man/man4/bwi.4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/man/man4/bwi.4 b/share/man/man4/bwi.4 index fe1ea65b4e68..7ee9e859229b 100644 --- a/share/man/man4/bwi.4 +++ b/share/man/man4/bwi.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 6, 2011 +.Dd August 7, 2015 .Dt BWI 4 .Os .Sh NAME @@ -76,6 +76,7 @@ driver supports Broadcom BCM43xx based wireless devices, including: .It Em "Card" Ta Em "Chip" Ta Em "Bus" Ta Em "Standard" .It "Apple Airport Extreme BCM4306 PCI b/g" .It "Apple Airport Extreme BCM4318 PCI b/g" +.It "ASUS WL-100g BCM4306 CardBus b/g" .It "ASUS WL-138g BCM4318 PCI b/g" .It "Buffalo WLI-CB-G54S BCM4318 CardBus b/g" .It "Buffalo WLI-PCI-G54S BCM4306 PCI b/g" From e6330ffeeef3f149ddd9a6eb388d2d8ec94698af Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Fri, 7 Aug 2015 02:37:47 +0000 Subject: [PATCH 292/314] Get closest as possible with style(9). No functional change. Differential Revision: D3295 Reviewed by: bapt --- usr.bin/ypmatch/ypmatch.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/usr.bin/ypmatch/ypmatch.c b/usr.bin/ypmatch/ypmatch.c index 66fa84aae100..a57a642a435d 100644 --- a/usr.bin/ypmatch/ypmatch.c +++ b/usr.bin/ypmatch/ypmatch.c @@ -34,20 +34,19 @@ __FBSDID("$FreeBSD$"); #include #include #include + +#include +#include #include #include #include #include -#include -#include #include #include #include #include -void usage(void); - static const struct ypalias { char *alias, *name; } ypaliases[] = { @@ -63,11 +62,11 @@ static const struct ypalias { { "ethers", "ethers.byname" }, }; -void +static void usage(void) { - fprintf(stderr, - "usage: ypmatch [-kt] [-d domain] key ... mapname\n" + fprintf(stderr, "%s\n%s\n", + "usage: ypmatch [-kt] [-d domain] key ... mapname", " ypmatch -x\n"); fprintf(stderr, "where\n" @@ -82,8 +81,6 @@ int main(int argc, char *argv[]) { char *domainname, *inkey, *inmap, *outbuf; - extern char *optarg; - extern int optind; int outbuflen, key, notrans, rval; int c, r; u_int i; @@ -114,12 +111,12 @@ main(int argc, char *argv[]) if ((argc-optind) < 2 ) usage(); - if (!domainname) { + if (domainname == NULL) { yp_get_default_domain(&domainname); } inmap = argv[argc-1]; - if (!notrans) { + if (notrans == 0) { for (i=0; i Date: Fri, 7 Aug 2015 04:27:51 +0000 Subject: [PATCH 293/314] Fix the dynamic VHD format to work with qemu. The size of the disk is taken to match the geometry and only when the geometry is max'd out, is the actual recorded size taken. Note that qemu has the same logic for the fixed VHD format. However that is known to conflict with Microsoft Azure, where the recorded size of the image is what counts. Pointed out by: gjb@ --- usr.bin/mkimg/vhd.c | 92 +++++++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/usr.bin/mkimg/vhd.c b/usr.bin/mkimg/vhd.c index 054f82facd81..c4c1d1d45b8b 100644 --- a/usr.bin/mkimg/vhd.c +++ b/usr.bin/mkimg/vhd.c @@ -159,6 +159,34 @@ vhd_geometry(uint64_t image_size, struct vhd_geom *geom) geom->cylinders = cth / geom->heads; } +static uint64_t +vhd_resize(uint64_t origsz) +{ + struct vhd_geom geom; + uint64_t newsz; + + /* + * Round the image size to the pre-determined geometry that + * matches the image size. This circular dependency implies + * that we need to loop to handle boundary conditions. + * The first time, newsz equals origsz and the geometry will + * typically yield a new size that's smaller. We keep adding + * cylinder's worth of sectors to the new size until its + * larger or equal or origsz. But during those iterations, + * the geometry can change, so we need to account for that. + */ + newsz = origsz; + while (1) { + vhd_geometry(newsz, &geom); + newsz = (int64_t)geom.cylinders * geom.heads * + geom.sectors * VHD_SECTOR_SIZE; + if (newsz >= origsz) + break; + newsz += geom.heads * geom.sectors * VHD_SECTOR_SIZE; + } + return (newsz); +} + static uint32_t vhd_timestamp(void) { @@ -256,8 +284,7 @@ vhd_dyn_resize(lba_t imgsz) { uint64_t imagesz; - imagesz = imgsz * secsz; - imagesz = (imagesz + VHD_BLOCK_SIZE - 1) & ~(VHD_BLOCK_SIZE - 1); + imagesz = vhd_resize(imgsz * secsz); return (image_set_size(imagesz / secsz)); } @@ -266,7 +293,7 @@ vhd_dyn_write(int fd) { struct vhd_footer footer; struct vhd_dyn_header header; - uint64_t imgsz; + uint64_t imgsz, rawsz; lba_t blk, blkcnt, nblks; uint32_t *bat; void *bitmap; @@ -274,13 +301,14 @@ vhd_dyn_write(int fd) uint32_t sector; int bat_entries, error, entry; - imgsz = image_get_size() * secsz; - bat_entries = imgsz / VHD_BLOCK_SIZE; + rawsz = image_get_size() * secsz; + imgsz = (rawsz + VHD_BLOCK_SIZE - 1) & ~(VHD_BLOCK_SIZE - 1); - vhd_make_footer(&footer, imgsz, VHD_DISK_TYPE_DYNAMIC, sizeof(footer)); + vhd_make_footer(&footer, rawsz, VHD_DISK_TYPE_DYNAMIC, sizeof(footer)); if (sparse_write(fd, &footer, sizeof(footer)) < 0) return (errno); + bat_entries = imgsz / VHD_BLOCK_SIZE; memset(&header, 0, sizeof(header)); be64enc(&header.cookie, VHD_HEADER_COOKIE); be64enc(&header.data_offset, ~0ULL); @@ -321,7 +349,7 @@ vhd_dyn_write(int fd) blk = 0; blkcnt = VHD_BLOCK_SIZE / secsz; error = 0; - nblks = image_get_size(); + nblks = rawsz / secsz; while (blk < nblks) { if (!image_data(blk, blkcnt)) { blk += blkcnt; @@ -331,15 +359,20 @@ vhd_dyn_write(int fd) error = errno; break; } + /* Handle partial last block */ + if (blk + blkcnt > nblks) + blkcnt = nblks - blk; error = image_copyout_region(fd, blk, blkcnt); if (error) break; blk += blkcnt; } free(bitmap); - if (blk != nblks) + if (error) + return (error); + error = image_copyout_zeroes(fd, imgsz - rawsz); + if (error) return (error); - if (sparse_write(fd, &footer, sizeof(footer)) < 0) return (errno); @@ -362,24 +395,9 @@ FORMAT_DEFINE(vhd_dyn_format); static int vhd_fix_resize(lba_t imgsz) { - struct vhd_geom geom; - int64_t imagesz; + uint64_t imagesz; - /* - * Round the image size to the pre-determined geometry that - * matches the image size. This circular dependency implies - * that we need to loop to handle boundary conditions. - */ - imgsz *= secsz; - imagesz = imgsz; - while (1) { - vhd_geometry(imagesz, &geom); - imagesz = (int64_t)geom.cylinders * geom.heads * - geom.sectors * VHD_SECTOR_SIZE; - if (imagesz >= imgsz) - break; - imagesz += geom.heads * geom.sectors * VHD_SECTOR_SIZE; - } + imagesz = vhd_resize(imgsz * secsz); /* * Azure demands that images are a whole number of megabytes. */ @@ -391,24 +409,24 @@ static int vhd_fix_write(int fd) { struct vhd_footer footer; - uint64_t imgsz; + uint64_t imagesz; int error; error = image_copyout(fd); - if (!error) { - imgsz = image_get_size() * secsz; - vhd_make_footer(&footer, imgsz, VHD_DISK_TYPE_FIXED, ~0ULL); - if (sparse_write(fd, &footer, sizeof(footer)) < 0) - error = errno; - } + if (error) + return (error); + + imagesz = image_get_size() * secsz; + vhd_make_footer(&footer, imagesz, VHD_DISK_TYPE_FIXED, ~0ULL); + error = (sparse_write(fd, &footer, sizeof(footer)) < 0) ? errno : 0; return (error); } static struct mkimg_format vhd_fix_format = { - .name = "vhdf", - .description = "Fixed Virtual Hard Disk", - .resize = vhd_fix_resize, - .write = vhd_fix_write, + .name = "vhdf", + .description = "Fixed Virtual Hard Disk", + .resize = vhd_fix_resize, + .write = vhd_fix_write, }; FORMAT_DEFINE(vhd_fix_format); From 9286ca0227490e120bb13760e63c468eb814f9fe Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 7 Aug 2015 04:35:43 +0000 Subject: [PATCH 294/314] Rebase after r286395: rounding fix for dynamic VHD --- .../mkimg/tests/img-1x1-4096-apm.vhd.gz.uu | 29 ++++++++------- .../mkimg/tests/img-1x1-4096-bsd.vhd.gz.uu | 26 ++++++------- .../mkimg/tests/img-1x1-4096-ebr.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-1x1-4096-gpt.vhd.gz.uu | 36 +++++++++--------- .../mkimg/tests/img-1x1-4096-mbr.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-1x1-4096-pc98.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-1x1-4096-vtoc8.vhd.gz.uu | 26 ++++++------- usr.bin/mkimg/tests/img-1x1-512-apm.vhd.gz.uu | 29 ++++++++------- usr.bin/mkimg/tests/img-1x1-512-bsd.vhd.gz.uu | 26 ++++++------- usr.bin/mkimg/tests/img-1x1-512-ebr.vhd.gz.uu | 28 +++++++------- usr.bin/mkimg/tests/img-1x1-512-gpt.vhd.gz.uu | 36 +++++++++--------- usr.bin/mkimg/tests/img-1x1-512-mbr.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-1x1-512-pc98.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-1x1-512-vtoc8.vhd.gz.uu | 26 ++++++------- .../mkimg/tests/img-63x255-4096-apm.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-63x255-4096-bsd.vhd.gz.uu | 26 ++++++------- .../mkimg/tests/img-63x255-4096-ebr.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-63x255-4096-gpt.vhd.gz.uu | 36 +++++++++--------- .../mkimg/tests/img-63x255-4096-mbr.vhd.gz.uu | 29 ++++++++------- .../tests/img-63x255-4096-pc98.vhd.gz.uu | 28 +++++++------- .../tests/img-63x255-4096-vtoc8.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-63x255-512-apm.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-63x255-512-bsd.vhd.gz.uu | 26 ++++++------- .../mkimg/tests/img-63x255-512-ebr.vhd.gz.uu | 28 +++++++------- .../mkimg/tests/img-63x255-512-gpt.vhd.gz.uu | 37 ++++++++++--------- .../mkimg/tests/img-63x255-512-mbr.vhd.gz.uu | 29 ++++++++------- .../mkimg/tests/img-63x255-512-pc98.vhd.gz.uu | 28 +++++++------- .../tests/img-63x255-512-vtoc8.vhd.gz.uu | 28 +++++++------- 28 files changed, 407 insertions(+), 402 deletions(-) diff --git a/usr.bin/mkimg/tests/img-1x1-4096-apm.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-4096-apm.vhd.gz.uu index 9b2f1227bf7c..a2be9b15555b 100644 --- a/usr.bin/mkimg/tests/img-1x1-4096-apm.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-4096-apm.vhd.gz.uu @@ -1,18 +1,19 @@ # $FreeBSD$ begin 644 img-1x1-4096-apm.vhd.gz -M'XL("'`EAE4``VEM9RTQ>#$M-#`Y-BUA<&TN=FAD+F]U=`"M5EUOVR`4?<^O -MN-+>*LV":\#=XZ:U;Y.J5=,>6]?!E=6UC9I(ZT-^_+A\Q-C&;I+A$`3"]_AP -M[@R;UQ?=[+KWPC_[E0/C++8: -MFI,]EB#,1RK`FCZBUC2&?8`I/ET]7G3/CP$./1QZ(%F158F@'B;?4>S`CI!^ -M=_AD(>][=N6476]E_@\"F`#.HS?*P.[^P/$`)XQ5V]I6$2/2)[3!9+!`<$]% -M,863;&05T4R)&FTV!:>6K$Z!NUAY7[A0,8%1F=Y(QZ%"&INP"3I,F@F5]^VF -M?MOJ$3^<"15UX,:/3L!AKNTZN'+*3K8^ -MYVS2N1)M>U>Z91O8W9ELVW6[[O7E+L!1H:)2:Q&/9_=<;Y+L9&;?ZB-]>QGE -M"9OX%@(_G3OVM'6'(N'IA)0@$*0YR`3@VA"7M&;F$\#K-ZV_W7[__.OZ-M9/ -MB[S\.#M"/XST'H?"`V1B*/H=S,>1ZT9FG>EEYAIFNNFJ^RIQS -KU26XC%==Y4O6K!4[Z:JK?,G*=-4EN(Q778++>M55MJ"N_@%!NLDU'PT````` +M'XL("`0UQ%4``VEM9RTQ>#$M-#`Y-BUA<&TN=FAD+F]U=`"M5EUOVR`4?<^O +MN%/?*BT"##A[7+7VK5*UJMICY3FXL[JV41.I?[E\%&R#E60X!$'(/3Z< +M^P&$V`=`5B`[D`JDP''-07Z#>@6@%UUCIJ=N"OOVY5FUN_Y]Z9[]PH)1$EL- +MS=&>5<#U2VI@#;Y$KG$,>P^S/+M\..^?'CP<N>@*10,QSKL/$Z3)H. +ME??MIGG=JA$_E@D5^V"0=F-X1*A\E_JR:$= +M=P,M`A%^@9GM#]4+4!#SDY3,:)YW1I9?@_QT:@H6L@TI4:AF];O\B3!?^$B_ +M)N/=D_5K<5EG"%^GHB),QKE[!8J>U: +MN&K*3G0NYTS2V1)M>ENZ1>?9W>MLV_6[_N7YWL-AH<)2:Q`/9_?4;)+L1&'? +MJ@-]NXKRA$Q\"YZ?*AU[RKA#HO!X0@H\-(0^R#BPM28N<$W/)X!7KTI=W/[X +M>G=U&^NG>%E^E!R@'XOTLTD2ZQ?7%IH[Q$_G-ZL?'B9U(C:#?MLW&XB>7VG] +M&J-65KF1EK#$M-#`Y-BUB9LCS$H -M^D@*F/-'])[[4+68Z&5]7)X^CBT.#0X-*$G9*D;0.^\[6G3JF+0YX;E&;GMU -ML:^NMZ+?3H%0(*4U(V[5;3N-'4Z1U>%0/RDKXOBTC_/B###N'$4^+A$#*TOF -M6%`M9\=P>L[J&=QR8=:B215*C)1:"IV$%+E/:=/&P7LH56Z7[_SG4@[TX42J -MZ$Z?],;B:7?1I`JVDXT"Q>D\YR[4E.L0-Y(J_XJ>=NV4Z5`01-(.8.V^&[T> -M!;8^+<5,S*<78U)?SOH4U5D^TDX/5*^1>W?`@H%4KU3NB88,'XW@9OT^MK[% -M1+K\L3H*O(?K!,M'<+&I78L2][BI@08G#$OT.#6GCG.F?,K9)'`R%]G`SEYG -MD`>0>Q"9E=46L%M?Z/6M?!GHN#NC#WQW<\:E[GQIX?".N^#B=K-K.Z].^.J* -MP(NQ'U;&@Y7+$+=R&QR&W0BPWEDH`VF6WTX/5&^1>S=`-%M5L+T/VZTJE$)E -M@,$4$K`,K!#+V61[-@NU41CH(,FX@`=)Q@4\2#(NX$&2<0$/DHP+>)!D7-"# -0I*:_"$(L?@%=YQ4O?0P````` +M'XL("`#$M-#`Y-BUB@4]`YT!3KCME&@[\'D`-1I"S:UM(]0EQ_O57G.G4I4-U9ROZF"T(!5)Z(U*GCC#)=^BL(JO=KBD&1-7$QY7@(>@X.]N+729Z +M5I[,L:"*L[-C.#UG=0UNN;!ST:8*)8:A6H"68)#;E#8N#H-"J7(Z?!9?AZJG +M#R=217?ZY*`OG787;:J@&VP5*$[G.7>AH1S[N)%4^5?T=&BG;(."(#+7@8W[ +M8?3.*/#U:2EF8CX]&9/Z"M9'BT$4(_5T1_V0A'<'+!E(ZY66>Z8AQTLCN%X] +MC#$M-#`Y-BUE8G(N=FAD+F]U=`"METUSI"`0AN_S -M*SJUMQPL:*&=7+D@#V.J'T).^ALEAJB_WS[>7G\\.AQ:'%B0;;54C4!<]A]BB3I,>+O@R -M(Q]7=76L;K52WTX`$\"Y-Z)VZAX7C0M.**MQG,]&*]+Q<6=P$W1HW$M5Q3C) -M-E:>S+V@>L[NX2AG=01W>[)S85)%)4:C6A4Z#@WJ:Y4V+@[1J5+E_?5/^_=U -MV.C#1*K0HH]'?77:7;2I@FZP52!T.N?CY_!X4>X13"_!E?;4NI&^IF1[IC6-#&_#B=RZO02'@XY*POGWG#> -MV/GS#$RMDA[8V?9A"%SF%U9]=[$,#-S-Z(/8W5;CFG`\]W#X@;L0XKKLW.;5 -MW<3J^L*3,6Y7QI4K5T/"E6MP6+80X%Q95`:J47&;[IB^5>%A@&C?',5>16AK -M7S&%P@*+*12NF)936+-LLAW-0K(*"^WK*5WN/[.O)Z_<%]C7DROW*2MV:%]/ ->MMP7VM>3*_=E]O4:5W1?3^H?&V.G?Q5QFYT,#@`` +M'XL("`LUQ%4``VEM9RTQ>#$M-#`Y-BUE8G(N=FAD+F]U=`"M5\%RI"`0O<]7 +M=&IO.5C00F.NJ^#AT,'APY(*N-5(M!Q\1RA?ZTL.X-T?\8_ +M`^3MX\BN7+*;O/1'G8`)X#P847IV&J;X%XL5VJOKAJ:`M4-\?(MN(L,D=A8[ +MR69>``7%0:*YUVO@X+)I.E8^WE_KU +MK9WQPT2JT,B/+VQE6BZZ5$$_V#$0)IVWY,*`\CZ'6TF5;T6/8C_A+G00F/0& +M'.3'T9N@(.1'G&W$/#T927[UIJXO"#X>=P,F&%JX9A1`OSR_QGCIVL3JE3YMZ&^+^!SYM090ET]=?25!A9<*OK_[ +MO38=;6+U[H^?ATN7^*_MZ"LI]AGT]^7*?\F*[ +A]O7DRGVF?3WY#$M-#`Y-BUG<'0N=FAD+F]U=`"MF$UOU#`0AN_] -M%8.X%9'&CNUDA80$4I&X%03JA4/CK%.M$,O']M!#?CP>Q_EP8@>VG5TWVI5W -MGKPS'H^GR?/^!:`*4"TH`TKBYU*`VD%9`=A)/[B[,O\5NN;GT30/A\?,O[J+ -M'L;RN55HCO:\`&%O4@*O\29JCY^A&S#9R^O[R\./^P''/8Y[D"S1JN"@].H^ -M*A_5(>GVP+\[Y-VDKEBKFZSLGQ:0"V!L]HMB4';-D,< -M5L.FRN/I5_WG9!;Z>")5U*B/K>:*M+OY]%KY'H-;G -M`8<(AKC18=U@_%P=,&;RJ$^2*;#%QH+DL_CI/?'ZZO8\H)10URO@UT%?XY9# -M@E`@=I@8MC@(!I*#G-+9^2Z;N;[K#Q_AYMWG+PC[-KG;8+KL.50--#MH]4+= -M>J=MUY:&]]G'VZBS11)W%/.\KW"@PPJNTTJ!^'`K41[L-M36".P.W[* -MCCWL=?;[E==GF,^(V$A/I*)G7%VN4NZ64\%.N`LACKHNFPJC)\FBM_/)$AOI -MB63TZCYZ\2!A]&);=SS5LNQ%B-.TT6/NU+#[P];O]34]T=UDX;L'F%7@;NN$4JV3QN-4'PQ -M*!LA]:]&J#4I9T?.PEG"1DA1-T+*%U*B9QEJ:(36&I[R+$,-C5`^!?`9SS)4 -@O!%ZZK,,Q!$^RT`#$M-#`Y-BUG<'0N=FAD+F]U=`"MF$MOVS`,@._Y +M%0QVZS!#;R>7`2O0`KMUPX9==K$=IRN&=8_VT(/WWT?*4FS9EK&T=%0CB<+/ +M)$61K(3H+P"GP1W!M>`LO2\-N#V4.P"<#$/YNPP?H6M^WK?-X]U3$:YNT\.D +M&$NEXB2O-!A\2`FJHH>X`[V'+F**5U>W%W<_;B-.!9P*(%N2E%;@ZMES#'Z[ +MZ[4CTI<[]=TC+[^=M--S[08I_"L/(`Q(.?J%CMHAIOB;&FM0ZGCTP\&A)=G3 +M2#XD$X.Q$]]9,9$:J;GD5#$8NX1S:U+GX"XV82WZ4,'`*/$NP$DH%;W'L(E^ +MF`T,E:>'7]6?AW:BG\J$BCOI)V=S.F^N"J&BXH^#!H;">@(*Q?DZ*%9_G%R.K7T7ZX680U<(]/]%=%NGK!*SK +M\X#1@RGN9'#=D/]\'FC;P:(^2(*P-J!D=D',=N2_^L"\OO7Q/*"U4%4SX.>H +M7^.7PX)Q8/84&)@"?1W,;2A<&@5-"7L% +MJWGO+3B+O+6Z96-6*8IOB:E[O25\U<']@_I[?\Q/=39&^ +M>J`*98BMKJF02-DT-`'(IJ$)^Y=10]FN+N:YJVQ4J1@S#.$8,PSA&#,,X5@S +M#`$9,PSA&#,,X1@S#.%8,PP"C>!KA`CG&R&LX>A]3=!$C6Q+0_I=$TJGYAJU +MUC[E&Z',8AC&1HAPJXT0_A>=-]9?:F(L8R-$.-9&R(5$RG26X6(C--?A.6<9 +J+C9"8G#@"\XRW'(C]-RS#,(QGF40CO$L@W#,H2*Q=]G\`YT_-4@`$P`` ` end diff --git a/usr.bin/mkimg/tests/img-1x1-4096-mbr.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-4096-mbr.vhd.gz.uu index a3ebac582f05..eee43f3e43bd 100644 --- a/usr.bin/mkimg/tests/img-1x1-4096-mbr.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-4096-mbr.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-1x1-4096-mbr.vhd.gz -M'XL("'\EAE4``VEM9RTQ>#$M-#`Y-BUM8G(N=FAD+F]U=`"MESUOI#`0AOO] -M%1-=EP+9@SV0]J3TUUS2!@A$JRBYTR5%"G[\V6`;&V.R)-YE69`]#^]\>-;+ -MV/P"H!)H`.J!I+ZN!-`-5#6`&C0'3F=N;F'L_KSVW?OYHS"O\33#./.M0G-M -MCR4(]9`*L-$/H4=]#:/%%#]NGZ[/+T\6AP:'!B0K;54B4!L]AYA3ITGW9WR> -MD`^+NC)6MUBI3RN`">#RZ*&"?9 -MRLJ3N154S]DM'.U9'<%=GTPNYE)1A5&ILPH=APKUM2H;&X?H4*7R\?:W^??6 -MK_1AHE3(Z>/16)EV%TVIH)UL%`A=SGONPD1Y7^,V2N5;T:/03I@+%00F[0!. -M[H?16U#@ZR/.=F*>3D927Z/U";7.FHUS>F#\681O!VS;8\":S0I#G'.X[9S# -MC5P\FHMD"2;R=$*NO/BUCYGSVP['@%)"TT3`WU9?ESL=O0:J]JFZKR2H\5*' -M[V_OMI9;GUB]7VQ6/7Z&POTA9V7F -MVNOKE9V?9V!JE73`:J_)>$"77UCTW<0R,'!W1Q_$[C8:5X7SN8?#3]R%$-?N -MYG9?W56LKLNL -CV*%]/9EVGVE?3[;=Y]G7:US6?3VI?VR,G?X#`*JO#$M-#`Y-BUM8G(N=FAD+F]U=`"M5\]SG"`4ON]? +M\3*]Y>#`$Y[FFIG<>VES5E?3G4[;3))##O9_+P@HB)@U15D6%][']W[*,F8N +M`"J!!J`>2.IQ)8#NH*H!U*1M./7X\F`<>9+A>):'DL0 +M:I,*L-&;T%F/870PQ9>'I]O+KR<'AQ8.+9"LM%2)0&VTCU"_UH:=1GJ\X,\) +M\O['S*Z,V2U2ZE.=@0G@W%M1.G8*IO@;*BN4U#!,K0+63_9Q+7@()A9E5[:3 +M;"7ET=PR*EN4W8*C/:DC<+'J*E0>7]];EY> +M^Q4_3(0*S?QX-%>FU44;*N@66P9"A_.>NC"AO*WA-D+EOZQ'H9RP`V4$)MT$ +M3NJ'UEN@P.='G.W8/.V,)+]&\U/)P)J-/CTQWA?A/0.V[3'`FAF&(=RL<-O- +M"C=RT<@$R6),Y&F'W'CV:\^9_=L.QP"EA*:)`+\Y?EUN=_0:4)5/57TE08W7 +M*OSX\'TKW?I$]GZR6/7X$=Q,F%\#5]I2ZE;ZD9&>&)$'ZD(( +MU^[Z=I_=3O)EOM,YWIRY3[/N5[#93W7D_K'QMCI'_LT8,@,#@`` ` end diff --git a/usr.bin/mkimg/tests/img-1x1-4096-pc98.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-4096-pc98.vhd.gz.uu index 3445c958ed66..dbaca2298497 100644 --- a/usr.bin/mkimg/tests/img-1x1-4096-pc98.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-4096-pc98.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-1x1-4096-pc98.vhd.gz -M'XL("(,EAE4``VEM9RTQ>#$M-#`Y-BUP8SDX+G9H9"YO=70`K9=-;X,P#(;O -M_16N=NL!)2:$]CII]UVV74@]Z`ITQOU<@=Y`O@:@0=.PN4IS"W7Y]5F5I\,Y,4>]:&%2N%:^.=MC -M"HI>D@,6_!*]XS[4%I/CG@>X-\ -M[=6EH;K>BGY;!4*!E,X3J57WVFGL<(JL]ONFY:R(XV.;=^,-,.X]24)<)@96 -MCLRQH#K.CN'TG-4MN-7"S$6;*I08.5TI=!)RY#ZEC8U#T"A5SL?OXN=8#?3A -M1*KH3I\,QM)I=]&D"MJ'C0+%Z3SG+C24TQ`WDBK_BI[V[93I4!!$9@>P<=^/ -M7H\"5Y^68B;FTY,QJ:]@?8K663%RG1ZH[Q/_[(#;_6W`+(,B!#Y9ATO6MU%0 -MJK&XNTY>M3K*B>S[\_Q6D>.'C<-4[ZA<9AK6>*W"EX?G$8>G@\(*[X..VLW,[KVX9JBLC3\9NN#*N -M7+D,\5=NB\.XA4`UE9DRD&MD<)T>J!\3_VR!:$I]M&\'FMH<3:$RP&@*E:G. -M$16J:C;9;LU";11&VH@S+N)&G'$1-^*,B[@19US$C3CC(F[$&1=U(Z[I+Y80 -*BU\\?ZUPO0T````` +M'XL("!4UQ%4``VEM9RTQ>#$M-#`Y-BUP8SDX+G9H9"YO=70`K9?!0IE]M8#8PMCDVMG>N]EMV="2#?3V6VGR:$'^NZ5P`8;`TUV#<1#8NOCERP+ +M1XC^`-`YZ"/H!G3!]T:!WH$I`:C37MBUTGZ%MG[]V]27TT=FCW;3PZ3PK4)S +MML<<%#W$`%;\$'W@>V@=)OOQ\'QW^O/L<&AQ:$&%8:L<0>^CYRCZM>S5,>GI +MA"\=\O[WH"Z/U8U6]#$'$`JD]$;D3AUALL_06456QV-W&1!-%Q]W!5^"CM'9 +M2>P*,;'R9,X%58S.SN'TFM4MN+N-G8L^52@Q#+4"M`2#?$]IX^(0790J'^>W +MZOW<3/3A0JKH09^,^O)E=]&F"KK!5H'B=%YS%SK*98J;297_BIX.[92]H2"( +MPG5@YWX8O1$%OCXMQ4K,ER=C45_%^F@QB&JF7>YH[[/P'(#[XVW`HH`J!OYT +M#M>L;Z>@5G-Q]YV\:G74"]GWS_/;)(X?=@Y3O:-R66@H\5J%3P^_9AS&=`[W +M./P.-PB6U^!R6_O<2%*+P]MFL:/';2UK.^+4FCI><\U-SA9IDP7K-U=6) +M)^,P71E7KER&A"NWQV':0J"ZRDP9R#4R:I<[VL#$M-#`Y-BUV=&]C."YV:&0N;W5T`*V636_C(!"& -M[_D5(_76@P4#'B?7JMW;2BOUT&MP3*JHVFW5Y-!#?OPR-O[`F#1M<3#"PO/X -MG6&8($1W`9`"V@-9H)+'E0;:0+4&<).^8=M+_PCGW>L_NSL=/@I_G5<=3(JI -M56C.]JA`NX]4@(8_0@V/X=QCBIN'Y]O#W^<>AQZ''E16;*40J(Z^0V)0QZ2G -M`[ZTR.VH3L7J1BMWUQJ$!BDG;ZA>W7;0.."TL]KOVU:Q(HY/WX*'8()Q+T41 -MXTHQLYK(7`KJQ-DE'%VR^@KN=N77HDL5EQB5ZUWH)%3(8Y]`LWI?,E=:"FG.6XA57X4/0KMM!^X((BR -MG\#6_3!Z(PJF^DB*"S%/+T92GV%]FGA%N0J4H!%*MUDU*'(33 -MT^\P?B:QNM^.GUD'=I_LCC6(#5>-9+J8S6BU^?EF,R:7NQVNOA;'Y:N!QH*U -M,]QV@MME7HPZGK<*.[.#'!`!<5%U8' -MPS:;XIH!-]?XB;-B49W-FBKU_EI<8Z"VH!2H,L*ITN-V;.7^B(19Z-,3YS]% -M^.M2!7U=R5:H,+="[8'9%#J@S:Q0BHN9\=7]2UYAIE,?XS*>^AB7\=3'N(RG -;/L9E//4Q+N.ICW%93WW4YM[J/Q`EJ(,J#``` +M'XL("!@UQ%4``VEM9RTQ>#$M-#`Y-BUV=&]C."YV:&0N;W5T`*V634_#,`R& +M[_L5!FX[3(F;IML5`3^EN8;=\>[7+K\UVYJ[=I(%)T;4* +MS=D>,U#TD@+0\$MTQ6/8>7#=6U5O0M*A`*I.P\D7EUA)E]A\XJLEJMZE:`L'5\?`MN@HG6 +MV5[LAIGSU<2.I\J_HZ=!.N0$% +M0>1^`FOWP^BU*.CJTU(4=X&<"R.G8E604?Q4%7/XYL/: +MR_LK=1O&ST16]\_Q,_/`[DAU4$4O>->(IHM9M%:+_Q>;,:G<;7#EJ3@JB%^CS.)DV5#$M-3$R+6%P;2YV:&0N;W5T`*U6R6[;,!"]^RL& -MZ"U`!7)$CMIC@R:W`D&#HL=$D:E`R&;$!IJ#/[XNEG\*^>GLUU:[YR/RS7[5@4O2MAN9L -MCSDH^Y$"L.2/T)K'L`\PV:>KQXOFY3'`H8=##Z0+MLH1Z&'R'1('=HSTN\$G -M!WG?L495,X -M+496/9ISHO8V.P='2U:GP%VLO"_:4+&!4=C>2B>A0![;L`DZ3)H-E8_MIGS? -MFA$_C(0*'?C)R5H>WR[Z4,'PLF>@.)R7M@L.93>&FPF5_U*/AG;*#ZP(0H<% -M=-L?JM=!09\?2;&@>=P947XE\[.IJ;'+-MOR?VWXZB?#B+$[RHAWS]:OXF6; -M(6H]%Q7=9)R[-S]FPZ5B?DIR&',D5QS#Q_#[MMD\FQDX3+7=%BZ?LM.USSF7 -M=&V)=GU;NG4=V-W9;-LUN^;M]2[`<:'B4NL0CV?W4FYFV>G$OC5'^C8D#7K` -MH6\A\#.I8\\X=Q`+SR>D!H6@[4&F`->6N.8U.Y\`7K\;)L\PT567XE7FG*LN -IPR6\ZI(O65$K<=)5EWS)2G359;B$5UV&2WK5)5=05W\!EOB&R!\-```` +M'XL(".XTQ%4``VEM9RTQ>#$M-3$R+6%P;2YV:&0N;W5T`*U6R6[;,!"]^RNF +MZ"U`#7)$CM)C@R:W`D&#HL=`E:E4:),8L8'FX/Y[.5RBC1)LES)-D*;GZ?'- +M0@KA'P`J@!H@`Z1Y7"J@CU!>`MC%T-#U,DSA4#\_F7K?OJ[#+]O$APF&`PP"D2[8J$.C'Y#W*_GKIV3'2 +M]Q9_.X666MFL:U$H1Q^L0VF`P6 +MNLV.M--B9-6CF1)5=)M-P=&2U2EP%ZO@"Q\J-C!*VPL@"27RV(9-U&'2;*B\ +M[K;5R\Z,^.%,J-`;/SE9*^:WBR%4,/XY,%`R'\,E0N6_U*.AG0H# +M*X+0<0'=]H?J=5#0YT=2+&@^[XQ9?A7SLZFIL#XA-1\:VAYD"G!CB6M>L_,)X,V+,5=WGS]\ +MN[GKZV=47GY2'*$?]O3S2=+7KU];Y-PA?CZ_1?WX,"D3L=GIM_OC`S'RRZT? +M!OU$E>CG%PZWZ^''`V(HIMFJ,W;5+P]#%0"S,51=#N=B*&G1F:=ZF0+#3%== +MFJ\RYUQU&2[C59="R9JU$B===2F4K$Q778;+>-5EN*Q777(%=?4/V&/DOA\- +"```` ` end diff --git a/usr.bin/mkimg/tests/img-1x1-512-bsd.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-512-bsd.vhd.gz.uu index 9949cd1d1c15..04627e2b7de4 100644 --- a/usr.bin/mkimg/tests/img-1x1-512-bsd.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-512-bsd.vhd.gz.uu @@ -1,17 +1,17 @@ # $FreeBSD$ begin 644 img-1x1-512-bsd.vhd.gz -M'XL("%@EAE4``VEM9RTQ>#$M-3$R+6)S9"YV:&0N;W5T`*V738^",!"&[_Z* -M2?;F@;1#*7C=Q/N>UJN(:(S9CZP>//#C=P8*M!10=PO8E+3S\,YTIJE"-!>` -MCD$?0)>@$^ZG"O0*T@R`!LV#=2O-*U3%UV=97$^WR%S5HH%)85NYYFR/,2CZ -M2`J8\T?TGOM0M9CH97UW6Q -MKZZWHM].@5`@I34C;M5M.XT=3I'5X5`_*2OB^+2/\^(,,.X<13XN$0,K2^98 -M4"UGQW!ZSNH9W')AUJ))%4J,E%H*G804N4]IT\;!>RA5;I?O_.=2#O3A1*KH -M3I_TQN)I=]&D"K:3C0+%Z3SG+M24ZQ`WDBK_BIYV[93I4!!$T@Y@[;X;O1X% -MMCXMQ4S,IQ=C4E_.^A3563[23@]4KY%[=\""@52O5.Z)A@P?C>!F_3ZVOL5$ -MNORQ.@J\A^L$RT=PL:E=BQ+WN*F!!B<,2_0X-:>.0 -M!Y![$)F5U1:P6U_H]:U\&>BX.Z,/?'=SQJ7N?&GA\(Z[X.)VLVL[KT[XZHK` -MB[$?5L:#E62@#:9;?3@]4;Y%[-T`T6U6PO0_;K2J40F6` -MP102L`RL$,O99'LV"[51&.@@R;B`!TG&!3Q(,B[@09)Q`0^2C`MXD&1#$M-3$R+6)S9"YV:&0N;W5T`*V736_#(`R&[_T5 +MGG;KI`@<`MEU4N\[K>0`U&D+-K6TCU"7'^]5>=R?$GO5BQ8FA6\5FK,]IJ#H +M)0:PX)?H+;>A=ICD=O6\W+\].QQ:'%I09M@J1=";P7L4_9JWZIBTWN-K@WQX +MZ=2E0W5G*_J8+0@%4GHC4J>.,,EWZ*PBJ]VN*09$U<3'E>`AZ#@[VXM=)GI6 +MGLRQH(JSLV,X/6=U#6ZYL'/1I@HEAJ%:@)9@D-N4-BX.@T*I!C?MA +M],XH\/5I*69B/CT9D_H*UD>+010C]71'_9"$=P]#MU7%4J@L,)I"`E:1%6(UFVS79J&V"B,=)!D7\2#)N(@'2<9%/$@R +;+N)!DG$1#Y*,BWJ0U/0708C%#^STEH1]#``` ` end diff --git a/usr.bin/mkimg/tests/img-1x1-512-ebr.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-512-ebr.vhd.gz.uu index 7bbe238939ff..d8b38b080122 100644 --- a/usr.bin/mkimg/tests/img-1x1-512-ebr.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-512-ebr.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-1x1-512-ebr.vhd.gz -M'XL("%PEAE4``VEM9RTQ>#$M-3$R+65BSF&C6:FDKM1VURR,$?OR"@($+&+*/#:$$_OMTT+<.8 -M^0!0#30"#4!27S<"Z`Z:,X#JM"?.+;>W,/6_?PW]V^6]LI_I9&"<^5:AN;;' -M&H1Z2`/8ZH?0D[Z&R6&J+_?/MY>?SPZ'%H<6)!MM52-0%SV'V*).DQXN^#(C -M'U=U=:QNM5+?3@`3P+DWHG;J'A>-"TXHJW&IKE38N#M&I4N7]]4_[]W78 -MZ,-$JM"BCT=]==I=M*F";K!5('0ZY]R%F?*VQ>VDRG]%CT([82]4$)AT'3B[ -M'T9O18&OCSC+Q#P]&4E];=:O3SC<=8>!"84&UR\.MW+UR"3)&DSD:7TW/NZI -MM+OC,:"4T+81\+O3UVLKHN].F.Z:O57@L^@8-5.5355])<,9K'7ZX_[$W -M'4-B]1Z/G\'A1[A%,+\&5]M2ZD;ZF9'NF-8T,;\.)W+J]!(>#CDK"^?><-[8 -M^?,,3*V2'MC9]F$(7.875GUWL0P,W,WH@]C=5N.:<#SWLI7>X_LZ\GK]P7V->3*_#$M-3$R+65B +M`%0"=4`MD#372@#=@*H`M-$U''KN;J%OGI_:YOW\4;BC/U@PSD*OV-WX8PE" +M/T0!UN8A=#+7T'N8XL?=P_7Y[X.'0P>'#D@JXU4BT''Q'*%_K2P[@W1_QC\# +MY.WCR*Y=@`G@/!A1>G8:IO@7BQ7:J^N&IH"U0WQ\BVXBPR1V%CO) +M9EX!S;6@LDGL&AQM>>V!NSZXN;"IHA-#Z9X!<5!HKG7:^#@LFDZ5C[>7^O6M +MG?'#1*K0R(\O;&5:+KI403_8,1`FG;?DPH#R/H=;295O18]B/^$N=!"8]`8< +MY,?1FZ`@Y$><;<0\/1E)?O6FKB\(/AYW`R886KAF%%S+29%-DBF8R-/\KD*X +M4VZYW3Y`*:&N%X"_/+_&>.G:Q.J5/FWH;XOX'/FU!E"73UU])4&%EPJ^O_N] +M-AUM8O7NCY^%P\_@1L+\$KC2E5(_,LR,M*&?TL1^>SBQQCF*^/"E6M`XI5KX3!O(<"ALN@,U*.6?=K0_RSBTP*B>W-D>Q6A +MJWW9&`H'F(VA\,4T'\.2;2;;WBPDQS#3OI[2Y?XK^WH*RGV&?3WY3*?:9]/?ERGV=?;^"R[NM)_V-C[/`?[N]4)@P.```` ` end diff --git a/usr.bin/mkimg/tests/img-1x1-512-gpt.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-512-gpt.vhd.gz.uu index 9e6e5ae96966..81f18cb6736b 100644 --- a/usr.bin/mkimg/tests/img-1x1-512-gpt.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-512-gpt.vhd.gz.uu @@ -1,22 +1,22 @@ # $FreeBSD$ begin 644 img-1x1-512-gpt.vhd.gz -M'XL("&`EAE4``VEM9RTQ>#$M-3$R+6=P="YV:&0N;W5T`*V82V_4,!"`[_LK -M!G$K(CB.[63%":0B<2L(Q*6'YN%4*V!YM(<>\N/Q.'82;^R4;2?KC;+RSI=Y -M>3PR8^,%H`I0/2@-2N)S*4#MH:P`S*0;W-YS]Q.&]M=1M_>'A\Q=PVZ$Y6PI -M%8JC/"]`F)>4P&M\B>KP&0:/R5Y>WEXS-H5:^UF*?-M!#`!>;[X1^&UNYETG'#"2/6]'244#YW_?=.G^C'$ZFB)OWRU5R1-I>[5.'^STX#@>F\92Y8ROTI+I(JS_*>"N5\ -M=(T3F/03W)H?>F]&P5(_E;,-GZ>#D=2O1OV$66=UY)Z>&-YGX6<"-LUY0._! -M$#<9W+3H/UL'M)XM&I-D=FRQ$1"V\%_3$<>WZ<\#2@EUO0)^]?JU-AP2A`*Q -MQ\0PQ4'D(#G(.9VM[;)=ZG?YX2-A+B&UGNY;1_-^C#U>WU/3PQ76?@9@=QM0V3[ -M&G>%E$Q#X8!D&@JW?@DUS,5F,,^-LG)!(:HPB".L,(@CK#"((ZTP""2L,(@C -MK#"((ZPPB".M,(JV$5*N$6*E#4`!C0[52+8T@P^$;SD\CF^U3QN-4#P8E(V0 -M>JP1ZG726'^=&$O8""GJ1DBY0DITEJ%\([36X2EG&#$M-3$R+6=P="YV:&0N;W5T`*V82W/3,!"`[_T5 +MF^%6!H_>=F[0F3)P*PP,%RY^I62`\&@//9C_CE:6;,NV#&G743U)E/V\+ZVV +M8JR_`(P$K:K7&Q2;Z!6QO0\01.;4D->\E_Q+;':19+ +M%5.I0D-AMY`:FC*)^Q;AJ.MRB].5@;S&+5QSJ-U>WACY']>N[U:[G/B+61GDAYKQ5;&8%*_<-V_=2:C4ZI()NUJ6[6)<1>L][MI'NSYL_5[>TQ/=31:_ +M>J#PVQ#9OB9\(2734'D@F8;*KU]"#;G:#.:Y458B%X05!G&$%09QA!4&<:05 +M!H&$%09QA!4&<805!G&D%<8"73(3-4*(\WVS]7-E_Q6=J9%L:5"_EXB2L;E* +M;+5/Z48H$0Q%V`@A;K,1DNG8^DO,C"5LA!!'V@@97TB)SC),:(26.CSF+,.$ +H1HB-#GS"6899;X0>>Y:!.,*S#,01GF4@CCA5L&^Y^`N^QF[[`!,````` ` end diff --git a/usr.bin/mkimg/tests/img-1x1-512-mbr.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-512-mbr.vhd.gz.uu index 831f819746a0..6aa2b8a05bd3 100644 --- a/usr.bin/mkimg/tests/img-1x1-512-mbr.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-512-mbr.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-1x1-512-mbr.vhd.gz -M'XL("&0EAE4``VEM9RTQ>#$M-3$R+6UBS^O/;=^_FC,*_Q-,,X\ZU"^["1'E?XS9*Y5O1H]!.F`L5!";M`$[N -MA]%;4.#K(\YV8IY.1E)?H_4)M`4D+31,#?5E^7.QV]!JKVJ;JO)*CQ4H?O -M;^^VEEN?6+U?;%8]?H9S@ODEN-*T4CO3KXSTP+B4R?QM<6)/G5["_2%G9>;: -MZ^N5G9]G8&J5=,!JK\EX0)=?6/3=Q#(P<'=''\3N-AI7A?.YA\-/W(40U^[F -M=E_=5:RNRYR,8;TR+ERY&A*NW!F'>1L!3IU%5:":%9_3`^.O(GS/0#2_'-E^ -MBM#TOFP*A0%F4RAL,\VGL&2[Q7:T"LDHS+2OIW2[_\J^GKQVGV%?3[;=IZS8 -BH7T]F7:?:5]/MMWGV==K7-9]/:E_;(R=_@,`JJ]S#`X````` +M'XL("/LTQ%4``VEM9RTQ>#$M-3$R+6UB2Q!J +MDPJPT9O068]A=##%EX>GV\NO)P>'%@XMD*RT5(E`;;2/4+_6AIU&>KS@SPGR +M_L?,KHS9+5+J4YV!">#<6U$Z=@JF^!LJ*Y34,$RM`M9/]G$M>`@F%F57MI-L +M)>71W#(J6Y3=@J,]J2-PMR?K"Q,J*C`JU3,@#A7JL0H;9X>HJ5!Y?WUN7E[[ +M%3],A`K-_'@T5Z;511LJZ!9;!D*'\YZZ,*&\K>$V0N6_K$>AG+`#900FW01. +MZH?66Z#`YT><[=@\[8PDOT;S4\G`FHT^/3'>%^$]`[;M,<":&88AW*QPV\T* +M-W+1R`3)8DSD:8?<>/9KSYG]VP['`*6$IHD`OSE^76YW]!I0E4]5?25!C=N[!X0?J0@C7 +M[OIVG]U-S*[+[(QAG1E79JX&"3/7P&'>0H!395$1J%;%?7IB_%J$MP%$^^;( +M]BI"6_NR,106,!M#X8II/H8EVPVVHU%(EF&FG+E/L^Y7L-E/=>3^L?&V.D?^S1@R`P.```` ` end diff --git a/usr.bin/mkimg/tests/img-1x1-512-pc98.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-512-pc98.vhd.gz.uu index 73e06370351b..fd654d67bab3 100644 --- a/usr.bin/mkimg/tests/img-1x1-512-pc98.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-512-pc98.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-1x1-512-pc98.vhd.gz -M'XL("&DEAE4``VEM9RTQ>#$M-3$R+7!C.3@N=FAD+F]U=`"METUO@S`,AN_] -M%:YVZP$E)H3V.FGW7;9=1RF=JFD?6GOH@1\_&Q)("-!V"Z0H*/CAM>.85(CV -M`-`IZ#WH"G3&_5R!WD"^!J!!T["Y2G,+=?GU696GPSDQ1[UH85*X5KXYVV,* -MBEZ2`Q;\$KWC/M06D]P]O*T.'V\6AP:'!I3E;)4BZ&WP'BTZ=4QZ.>![@WSM -MU:6ANMZ*?EL%0H&4SA.I5??::>QPBJSV^Z;EK(CC8YMWXPTP[CU)0EPF!E:. -MS+&@.LZ.X?2-`L7I/.2*O^*GO;ME.E0$$1F![!QWX]> -MCP)7GY9B)N;3DS&IKV!]BM99,7*='JCO$__L@-O];<`L@R($/EF'2]:W45"J -ML;B[3EZU.LJ)[/OS_%:1XX>-PU3OJ%QF&M9XK<*7A^<1AS&>PRT.+^$ZP?(: -M7&IJGWV2U&+WM9D<:'%+PUKV.#6GCM=<=9.S6=QDP7(]L'/G&03E<`EB[50% -M!]C-+_3Z-J$,]-R=T0>ANP7C#P@KO@X[:S:VAQ-H3+`:`J5J#$M-3$R+7!C.3@N=FAD+F]U=`"ME\%RHS`,AN]Y +M"F7VU@-C"V.3:V=Z[V6W9T)(-]/9;:?)H0?Z[I7`!AL#378-Q$-BZ^.7+`M' +MB/X`T#GH(^@&=,'W1H'>@2D!J-->V+72?H6V?OW;U)?31V:/=M/#I/"M0G.V +MQQP4/<0`5OP0?>![:!TF^_'P?'?Z\^QP:'%H085AJQQ![Z/G*/JU[-4QZ>F$ +M+QWR_O>@+H_5C5;T,0<0"J3T1N1.'6&RS]!915;'8W<9$$T7'W<%7X*.T=E) +M[`HQL?)DS@55C,[.X?2:U2VXNXV=BSY5*#$,M0*T!(-\3VGCXA!=E"H?Y[?J +M_=Q,].%"JNA!GXSZ\F5WT:8*NL%6@>)T7G,7.LIEBIM)E?^*G@[ME+VA((C" +M=6#G?AB]$06^/BW%2LR7)V-17\7Z:#&(:J9=[FCOL_`<@/OC;<"B@"H&_G0. +MUZQOIZ!6MR8N?/,PC* +MX1I$Z54%#SC,+XSZ=K$,#-Q=T0>QNQ7C3#A>>CC\QET(N7(:$*[?'8=I"H+K*3!G(-3)JESO:QRP\>R#:4I_LW8&V-B=3J"PP +MF4)EJW-"A:I93;9;LU!;A8DVXHQ+N!%G7,*-..,2;L09EW`CSKB$&W'&)=V( +/:_J+)<3F"Q0&'5:]#0`` ` end diff --git a/usr.bin/mkimg/tests/img-1x1-512-vtoc8.vhd.gz.uu b/usr.bin/mkimg/tests/img-1x1-512-vtoc8.vhd.gz.uu index a1c781c1c93c..d9a0c6e6aa5f 100644 --- a/usr.bin/mkimg/tests/img-1x1-512-vtoc8.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-1x1-512-vtoc8.vhd.gz.uu @@ -1,17 +1,17 @@ # $FreeBSD$ begin 644 img-1x1-512-vtoc8.vhd.gz -M'XL("&PEAE4``VEM9RTQ>#$M-3$R+79T;V,X+G9H9"YO=70`K99-;^,@$(;O -M^14C]=:#!0,>)]>JW=M**_70:W!,JJC:;=7DT$-^_#(V_L"8-&UQ,,+"\_B= -M89@@1'5!MI`M09PD[YAVTO_".?=ZS^[.QT^"G^=5QU,BJE5 -M:,[VJ$"[CU2`AC]"#8_AW&.*FX?GV\/?YQZ''H<>5%9LI1"HCKY#8E#'I*<# -MOK3([:A.Q>I&*W?7&H0&*2=OJ%[==M`XX+2SVN_;5K$BCD_?@H=@@G$O11'C -M2C&SFLA<"NK$V24<7;+Z"NYVY=>B2Q67&)7K7>@D5,ACES9]'*+F4N7C^&;> -MCW:F#Q.I0H,^&E\R5UH*:$6Y"I2@$4JW634H/=[3 -M[S!^)K&ZWXZ?60=VG^R.-8@-5XUDNIC-:+7Y^68S)I>[':Z^%L?EJX'&@K4S -MW':"VV5>C#IRUW(FJ^N`8NYNS>ZJV?O2]PD<%U(1Z>MPH[LX,<$`%Q475@?# -M-IOBF@$WU_B)LV)1GXC*<^ -:QF4\]3$NXZF/<5E/?=3FWNH_$"6H@RH,```` +M'XL("`(UQ%4``VEM9RTQ>#$M-3$R+79T;V,X+G9H9"YO=70`K99-3\,P#(;O +M^Q4&;CM,B9NFVQ4!-R0D#EQ)UVQ,B`\!AQW&?\=ND[5IFVU`NBQ*E_KI:\?. +M(D1S`>@,]`JT!9WSN%"@%U#,`6C2-:Q[Z6YAMWQ[MCW=O*P]#AT.'2@OV"I#T.7@/8I^G3?JF/2P +MP><:>?FT5Y<-U;56]"TJ$`JD[#R1>76$F7V'SBJR6JWJ5H"P=7Q\"VZ"B=;9 +M7NQRT;/JR!P+JFB='WUR,)?%W467*N@?=@H4I_,A=Z&F?/5Q(ZGRK^CIT$ZY`05! +MY'X":_?#Z+4HZ.K34AR(>7PQHOH,ZU.:5Y1W@9P+(Z=B59!1_%05<_CFP]K+ +M^RMU&\;/1%;WS_$S\\#N2'5012]XUXBFBUFT5HO_%YLQJ=QM<.6I."IR44%E +MP=H>[KR9>C'+@KN5,1EDGRS'@F>JY6[*[C7%_A64,QQMI"PIQK;O8,<$` +M-]A<6!WLRZR+JUI<3^.1Z(7Z/,XF395R=2JN,E!:0!S;1L\];LE6]$.IC7,)3'^,2GOH8E_34I^O!T535JLJL4-:JZ3%P/CJPTR2@S4K/PQY?+(\8/7&?*#,(@ -M?(\/YSZ`,?<#4`6H!I0&)6E<"E"?H#P',(N^H>VYGT)7/S_I^MB^;OVOVS@P -MSF*KH3G98P'"?*0$K.@C:D=CZ`+,]L/E_5G[>!_@T,.A!Y(E614(ZM?D.XJ] -ML2.DGRT^6,B[GETQ9==;N4?30-%$;Q2!W9WM/\>;%<;*O$]-42-]0AM,!@O] -M9D?:23:RBFC.B1IM=@Y.+5F]!^YLXWWA0L4$1FEZ(QV'$FELPB;H,&DF5%X/ -M^^KEH$?\,!$JZHT?GZP5Z>VB#Q4,+WL&@L)Y:;M@48YCN)E0^2_UU-!.^($1 -M@>@<-F$E"`0I#G(!.#.$)>T9N83P*L7K2]NOG[\<743 -MZZ=%7GZ'23D3F[U^AS\N$`._W/I57C]6 -MS?3IA>YZ._P[0/3%-%MUQK[ZY6$H/&`VAJ+/X5P,N5YTYGN]K#S#3%==E:XR -MIUQU"2[C55?YDI6T +M3]]\\Y`8H,R@V`6?0#[V17C-E%*^=@TT#1)%\4@=V[G;^GS@IC9;ZG(>&NM/J$T7OI +M+41G!]I)-K!*:$Z)RJ*S4W!JR>HC<"3-D&'T3"I +M\K;?52][/>"',ZFBDF`,U\2\N^A3!+Q[!ZKW20[F3FV +M^LC8;I(Z8:/80N"G<^>>MN%0)#R=D!($@C0'F0#<&N*2ULS["/#J1>L?-S]/ +M_US=I/IID9PN<.\<_S6]2/#I-R(C>C?OM7EXB!7V[] +M*J\?JR;F^87N>MW_.T#TS31;=\;8_?(P%!XP&T,1:S@70ZX7@_G1*"O<6)DEP.^ -M#M7IL;K>JG6PJD!78H:6ZJ)H+7&&K&@^/Q:V21.?[O%>O`&)\]0E:F`E9$X% -M53@[A;-+5M?@;E4XQ$V4RK^B9WT[XSH4!)5T`]BX[T>O1X'4 -M9V.U$//Y9,SJRUF?H7663[3S`_5#Y-\G8,%`6J^TW!,+&5X:P9?'YZG\%C/E -M\L?54>`Y7"=8[@8^;BUPNDU'3Q'%"T4,NNS?S03NGGZ;'F>6U''-E%,#L\XF -M@8NYR`9V,L\0EQ!K4)FH:@$\Y1=Z?7=C&>BYNZ`/QN[FC$O]^;'`X1EWP<=M -MW;XL)O[Q +MV2)/O3HY5M=;.0=W.Y"[:(8,ZDZVO8F=561%\_DM86-L?,*;?"0#O;.#V)5B +M8!7)G`JJZ)V=PNDEJ]_@+E<^%ZY4J#`,M0)T`0:Y3V43XC!ZJ52.A_?ZX]`. +M].%,J>@H&<,Q->\N^E+!,-DK4"QPR5VPE,,0-U$J_XJ>3NV4[U`01!D&T+J? +M1J]'0:Q/%V(AYO/)F-57LSY%.Z&>:.<'NMMU^GP#&P;2?J7M7FJ_QWX2P<>[ +MAZG\-C/E\L?=T>`Y7!`.GA(5+S0%R-9_Q/T(=^W^`:>6U''- +MM%,#L\Z6F8NYJ09V<9ZA:*&0(*JHJB/@=WZAUW)!F7\2+)N(P72<9EO$@R+NM%DH!4>ZLOT2?4EGT,```` ` end diff --git a/usr.bin/mkimg/tests/img-63x255-4096-ebr.vhd.gz.uu b/usr.bin/mkimg/tests/img-63x255-4096-ebr.vhd.gz.uu index e6addcc9e9d9..9c75099584f2 100644 --- a/usr.bin/mkimg/tests/img-63x255-4096-ebr.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-63x255-4096-ebr.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-63x255-4096-ebr.vhd.gz -M'XL("+`EAE4``VEM9RTV,W@R-34M-#`Y-BUE8G(N=FAD+F]U=`"MESUOXS`, -MAO?\"@*W=3!D6I+=)0$*=+_EFEEV["(H^H'FA@[^\2=:4D+Y*TU/L2/(H/CX -MI431D!#N!Z`+T!WH%K2B?BE!WT-9`5BCOW%H<_\(??/^UC9_CU^9__4;!\L% -M]XK=R1\+D/8E):"AE^@#]:$/F.S7X_/=\?4YX-#CT(-425X%@JXG[ZG$61V1 -M]D=\&:LKINHN7B[`KH.B8R,*KB[+=APGK9<=3[>&6@WS$^[H(3)P7*1.B9$7 -MDSDWJ2S8.9Q>\[H%=[?Q:^%2Q29&:5L!.H<2J6_3)LS#Y+:I\G7Z,)^G=J0/ -M%U)%L\48V^1RN.A3!<-@KT"2P+5P8:"S -M=T$!UZ=SL3+GRXNQJ,^LQO6#@.OZ=N#*[J@;OSL$&$4M[=+<[U7OW]CG=D;? -MSFW;+<<=4H?;W094"HR9`/\$?4WBY:@J,DM;1\U,NVSH'[+X.@.'A+'UV)9S -MI:'"[RKX'<,5;KOQ5+UX\;SC?8;;NG_` -MR35U5!/:.<-BL"IQLIAJY,?7&?(6\@)$Y6T8`\_K"Q=]]U,9&(6[H@^FX1K" -ME?'XG.'P2K@0X^IS99E9PBNSMYVJ:Q(O1CW>&=_7" +MMPK-V1X+D/22$M#P2_03]Z$?,=F/^^>;\Y_G$8<.APZD2K8J$'0=O:>K04BK +MCDF/9_R]5%?$ZF8K^YZN@Z+S9A2^NBP[^3A)5C2?;P6U'M9GO(.'8,#'!>J4 +M6%AY,M<65/ +M=J$/-U)%3_KR:*S:=A==JN`46*M`=?8- +M/;^JX)K1K`YO.JL3)8JJ%G1]GR%O("R[&=@Q#X!1?F/7=QC(P<'=' +M'\3N&L:5X?S'.M3A,6PC, +M4%DH`VE6W&X/]#^S\+)`=)^B9-\V=,4TF4+I@,D4$K!-K-"D_7YH98.2Z*#` +HN(0'!<8E/"@P+N%!@7$)#PJ,2WA08%S2@P(!*?<._P`B"8'870X````` ` end diff --git a/usr.bin/mkimg/tests/img-63x255-4096-gpt.vhd.gz.uu b/usr.bin/mkimg/tests/img-63x255-4096-gpt.vhd.gz.uu index f47328c7e60f..0e9500f82aa5 100644 --- a/usr.bin/mkimg/tests/img-63x255-4096-gpt.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-63x255-4096-gpt.vhd.gz.uu @@ -1,22 +1,22 @@ # $FreeBSD$ begin 644 img-63x255-4096-gpt.vhd.gz -M'XL("+0EAE4``VEM9RTV,W@R-34M-#`Y-BUG<'0N=FAD+F]U=`"M6$UOU#`0 -MO?=7#.)61!H[\21[`8%4)&X%@7KAT"3K5"O$\K$]])`?C\=Q/IS8@6UGUTJS -M.HT[3\`F`&V@!I0T7V1`^Z@*`',I!O27H7["5WS\ZB;A\-CXC[= -M10\FTKF5;T[V,H/3>RR-;O)JO_3MI"ULR>R@=V=O;Z=.YL;*_,\#80&(9L"`ZWK,Z!N[QPL>A3Q21&8:Y&.@&%I'N3-H,. -MJV%2Y?'TJ_IST@M^,I(J./(3J[DL[JYTJ2*'AQV#G-)YRUVP*`]+N$"J/$L] -M].V&Z!H14C5,2.N^K]X$!7-^*-(-S>/!B/*KB%]NUED5N,8GNO>)_QT!Z_H\ -MP$%!'VYTN&Y(/UL'M)X\ZI-D$C;;"$@ZTZ_>,\>W;L\#5`JJ:@7X=>#7V'`H -MR!'R'26&*0ZY`"5!3>EL?5?-G-_UAX]P\^[S%P+[-KG;4+KL)90--#MHZP6[ -M]4K;KBV-[+-/MD%GLRC<51B.%EN[WX`+C3ABZE6]>F&12+W0TAUWM21YXV_G-X3OSGO.MA +M4DRE0G&25REH?$D&JJ27V(;NX3Q@DI?W3W>'[T\#3GF<\B"3D52JP%:+]V0- +MY/U['.[K07USR,NH7;K4;I3J#>PZ2+O)$^F@W<5=WTR-U2B%S],PD&<@]#B" +M'\'$:.S,=T;,I"9JKCE5C,:NX>R6U"VXNYV/19\JF!@97@58"9FB>TR;P0^+ +M@:GR?/I9_CZU,_U4)%7L)!CSN0WO*9\J:GC8:Z!)P2USP5%.<]Q*JOR7]VPH +M-T07G2#,,*$&\W'@^T50&4Y1,>AGI=CP>3P84?U*TD]C)90KU_C$^5T2?J_` +MJKH-.'@PQ%T#4M7D/U>I;3M:U">)%ZXEI&T\(/M)?*N&.;Y5=QO0&"C+!?#+ +MH%_MPF%`6]`%)08V!RW!*##ZBG.VFWJJW_W[#_#P]M-G@CV.YM:NV+#5E5!; +MZGFA=LM*&\V]K!1;3<6&`9EY>\"E4=Q^M79K*K:JW<"MC3A.;TE=UY)_B&V/ +M,R*4RJ=2J'.50E="V41P^QF.NR^W-%UA5&M:PHV$VJWEC04I`7(LD]Q!%"A4 +M$1=V7(4K`IZ/'Y-C#WN=_'KE]6NESXBU$9^(>:]U?3F/F9N-#3MB+H0X[K[< +MYN0]P^:]PB?+VHA/1+U7]MY;=Q)Y;ZUTKZM:DKP(<16O]Z1;-;`^L'\OK_&) +M\T,2?GN@\LL0V[JF?"-ETU![()N&VM2#C&'D@XUAY(0,8>2#C&'D@XQAY(.-8>F#6%2V:FK1KA*/=D`5)# +ME]&&+5`CNND:]=M/S2WZO]"Q#=[&5FTU&(5@W*H1;G.K5G6W&LNX52,)FJPJ!&EF[U%L5$>D -MIQ.^3M55.^8Q>!B3"`@_OI -MZEU0$.N3)=M8\_7-6-6G21^W>:87VO6!_J%(KQ%HS&U`Q5QVI+C18=/X[&"@ -M!;64I:7/5;]^C7UN%S;DZ-+V$*V?>/^PD7?_5P& -M)NYNZ(.YNYIP=3J_C'!XQ5U(<6:L+`M;>&7U#G-U3>;-,-/,^&+F$B3-7(?# -MO(5`#Y7%1J"=-6_7!_H?17HY(/I/4;9O&_IBFDTA]\!L"BVPS:Q0Y_U^2*\P -LTT&!%`@7,:#`N$R'A0(E_&@0+BL!P5ICX",[?X!!W"B9UT.```` +M'XL("$$UQ%4``VEM9RTV,W@R-34M-#`Y-BUM8G(N=FAD+F]U=`"MESUOI#`0 +MAOO]%2-=EP*9P39.LRM%2G_-);5-(%J=+HF2*U+PX\^##=@8V&S."VN!S#R\ +MGB]DQMP/0%8@.Y`M2$'7-0=Y"[4"L)/^Q&$L_2WTS>M+V_P]?Q;^UQ\SH#C#MU +M1'H\X^^ENBI5-UNY]W0=5%WP1!6J*XI3B./6RCY/IP`C!_^,9W03382X2)U@ +M"ZM`YII3V;S8-9S6RX,E-%7%3[>/ZS4K](;[>![W4]IO(0;!8?=/L:=`ESERFVF +M!,TIRKOP.L`=W7_$\3UUU!/:M8G-Q8K,R:+5PBZ,,Y0ME!4U8S9UK0`XQ1=F +M?;>I#(R6NZ,/TN5JPM7Q\V6`PPO+A1AGILZR$L(+WCNFZIK,P3#+ROABY1(D +MKER'P[R-0`^=Q6:@?2H=MR?ZGT5\."#Z3U&V;QOZ9II-(??`;`HML,VL4.?] +M?DCA@I)IHT"XC!L%PF7<*!`NXT:!-5&GOO;1[-A164=5VM>EA#_SX>K`=;`QDTSH09&3/ -MPSL?MF7&W`]`<5`#J!Z4I'8C0!VAT0"VT]\X/6O_"F/W^U??_3F_5_XW'ARL -M9K%5:D[VR$'8CS2`ACZBOE,;QH"I/CV]/)Q_O@0<>AQZD&S(BB.H-ON.9E=U -M1'H^XX^E.IZKFZV<@\,`?(A&\%A=59UBG+!6=CS="EHYQ2?,2=9(M -MK"*9:T&-G%W#J3VK>W`/!Y\+5RJV,!K[9*!J:)#:MFQ"'++;ELK[Y=6\7?J% -M/MPH%14E8]DGMMU%7RH8!GL%@@3NN0L3Y;+$K93*?T5/I7;"-VP0F`P=.+F? -M1F]&0:Q/U6PGYMO)V-1G2)^P\\RL/+<[QL]5>EV![7`?4$HP.?!K<+@C?4T+QP_-KI#[%6I=6*&>%-H5V2[H4H'&CRI\ -M?OJV,H.U*982A\-;N"`X7N]3W"G"<3?A9DI4;-#5P'O_$KK -M0K_6L>FL+%PL1B_LXCQ#W4/-@6G?ARGPFE^8]1US&9BXNZ,/\9&\]&'@".I=.TJ3WO>SVC%:;2=-VL^VA!__XY0DHB#J=+J-C,/`^ +M?M\/(#!F?P"J!-6#ZD!):E<"U!&J&L!TNAO')W>O,+1OKUW[/`X=#AU(5F15(J@F^4[?`!-6 +M'9$>SOB\5%>FZF8K^YV^A[(/1I2ANJ(XA3AAK,QXNB4T:HR/OZ.7J"/$1>HD +M6U@%,M>"RF9GUW!JS^H:W,W!Y<*6BBF,RCP9*`X54MN4C8]#^IH5>C6.C:=E9F+1=<+NS#/P#O@)2W';%JW`N"47YCU'5,9&+F[HP]2=S7A +MJG@\#W!XP5V(<8W;>?W(*(47HG>;JFLS)Z-9SHPOSER"Q#/7XC#O0J#'E<54 +M(*WBR7.[8_A9Q)<%HMN,LNUNZ':/;`J%`V93*-S^D5&A;G>+[=HJ5-(F)=-1 +I@7`9CPJ$RWA4(%S&HP+A,AX5")?QJ$"XK$<%`S2U=_@'6B6GGU\.```` ` end diff --git a/usr.bin/mkimg/tests/img-63x255-4096-vtoc8.vhd.gz.uu b/usr.bin/mkimg/tests/img-63x255-4096-vtoc8.vhd.gz.uu index 995a75abbac5..4b1226c22247 100644 --- a/usr.bin/mkimg/tests/img-63x255-4096-vtoc8.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-63x255-4096-vtoc8.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-63x255-4096-vtoc8.vhd.gz -M'XL(",,EAE4``VEM9RTV,W@R-34M-#`Y-BUV=&]C."YV:&0N;W5T`*V636_; -M,`R&[_D5!';KP9`I6;9/!?;1VX`!.^PZV9:+8-A:M#WTD!\_TI83R5]K5B:" -M8T/BXY<4Q5"I\0-@-=@>K`=;\'UIP-905@`T&08.USP\PJE]^./;E^-K%CZG -MPPC+56R5FK,]:C#TDA+0\4MLQ_=PFC#9AR_W-\??]Q,.`PX#J"C92B/89O:> -M'"IU5L>D'T?\-5>GY^IB*_[1T/>@^VB%CM5EV6V,,V1%ZWE8:/(A/M-('I*) -M&)>H*]3,*E*Z%M3(V36TF:*PV)0JKP^ -M/[JG9S_3AQNI8L_Z\L5*KA(E7=&SZ9V)@U2 -M_#"NH.BH8MM=>XD>3D&C0:I5N;<9V>"O6N!0[5CMX3;<=>RNL9P@7%0*,`@% -MG7W#AQYGA&N%-Z-9N.N'_%=#^;W:W69R5U\6C^>* -M*OL&+JK+MW-"!<[%?4P:JZ[HQK6C`ZM=IU]M,:SHNF2M._%=9K^RI5;N6Y/G+YEZ7<$FJ!0S&4"RBJT -M`2BFT%(3*:JP[&H4W>4J*!3JFQDGV#;]<-S[Y[1S +ML$R$5K$YVZ,$11\I``U_1+?R"%7)0YUR]#)U59$7KN>50YWU\AA8- +MHHG1V4GL`C1%#[E/:3/$8=8H +M58YO+^;US4[TX4JJC)N1S>::=7?1IPH.B[T"-4^5V%WH*0]3W"Q5OAD]'=NI +M.$CAP*V@Z(A\W5T]1@^'H%$CU:+8VHQ][Z^8X5!L6&WA5MPU[*[2G"!<5')0 +M"#F=?<6'%R3UVL7X_7RU]NK/#T'KFY`R=AJT]GK)9Q-FBIU]UE<:Z"F +M/,F@VZC*S::(&]F7,)[,^,2WIL9E_#> +3S+BD]V8"TOG=_0-Y#+@L;`T````` ` end diff --git a/usr.bin/mkimg/tests/img-63x255-512-apm.vhd.gz.uu b/usr.bin/mkimg/tests/img-63x255-512-apm.vhd.gz.uu index da8f61af68f6..5aa8ba1f995c 100644 --- a/usr.bin/mkimg/tests/img-63x255-512-apm.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-63x255-512-apm.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-63x255-512-apm.vhd.gz -M'XL("(HEAE4``VEM9RTV,W@R-34M-3$R+6%P;2YV:&0N;W5T`*U62VO<,!"^ -M[Z\8Z"W0Q1I+X_944IK<"J&A])@X7CF8-,F276@._O'5Z!'+SSI;[0I90I[/ -MG[YY2%GF?@"4`]5`&DCQN)!`GZ'X!&`6?4/;"S^%MGI^TM6Q>=WZ7[MQ8"*+ -MK?KF;(\Y2/.1`K#DC]".Q]`&F.V'B_NSYO$^P*&'0P^D"K;*$>AN]!W*WM@Q -MTJ\&'RSD;<F[`).HR:"977P[Y\ -M.>@!/YP)%7KC)T9K^?QVT8<*AI<]`\GAO+1=L"C'(=Q$J/R7>M2WDWY@1,A4 -M6$"[_;YZ'13$_$AD"YK/.V.67\G\3&HJ[++-M/Q?&[[XP3#9T!WEC'=/UJ_B -M99,A@(.4VW7P>5C=JKV -M.6>3SI5HV[O2K>K`[L9DV[$Y-L]/-P&."Q676HNXGMUCN9]DIQ+[5J_T;4@: -M](!]WT+@IU/'GK;N(!:>3T@%$D&9@TP"[@QQQ6MF/@*\?-'ZZ_6WCS\OKV/] -MM$S+3V0K],-(/Y(@5]J_=#KEY43 -M_?Q">[7M_QT@^F*:K#IC5_W2,)0>,!E#V>5P*H:"%IWY7B^39YCHJDOS5>:4 -KJR[#);SJDB]9LU;NL?:J2[YD);KJ,ES"JR[#);WJDBVHF[_Y8*QC'PT````` +M'XL("!LUQ%4``VEM9RTV,W@R-34M-3$R+6%P;2YV:&0N;W5T`*U62VO<,!"^ +M[Z\8Z"V011I+\N:2DM+D5@@-I.5@FL>274@.SG^O1@\D/]DDVA7"1IY/ +MWWSSD!AS/P!5@&I`:5"2GDL!Z@S*#8!9]`/MS/TK=/7SDZX/[=O:_[J5`^,L +MM>J;DST6(,PF)6!%FZ@M/4,78-;?+N]/VL?[`(<>#CV0+,FJ0%!WHWW*+6S< +M/A;N;XO_+.1[9%>,V44KYV#30-$D7Q2!W;N=OZ?."F-EOJ^DM +M1&<'VDDVL$IH3HG*HK-3<&K)ZB-P)RL?"Y>@2""2^Z"1=D/X292Y4OJJ;Z=\`]& +M!";#`EKW^^I%*$CY*]`3<)C+70=7 +MC-G)QM><+3K7HNWL6K=L`KM;4VV']M`^/]T&.&I4U&HMXO'L'JO=)#N9.;;Z +MR-B&HD$/V(\M!'XZ=^YI&PY%PM,)*4$@2'.0"<"M(2YIS;R/`*]>M/YQ\_/T +MS]5-JI\6>?EQ=H1^F.CGBB35+^TM?.X0_SR_1?WH,"DG,!L#$6LX5P,N5H,YD>CK'!C7:#AWX\+T#$\Z\DK0&8AG9]^-_#UN. -M4NT%8#78"FP)-N%^:L#>09H!T*![L&EC]PIU\?%>%M^'G\A=]:J%Q4I:^>9L -MCQH,?20%S/DC=L=]J#M,=/.XOSV\[3L<.APZ4)*RE4:PV]%W,G52QZ27`[X. -MU>FQNMZJ=;"J0%=BAI;JHF@M<8:L:#X_%K9)$Y_N\5Z\`8GSU"5J8"5D3@55 -M.#N%LTM6U^!N5RX7;:E08:34*K`QI,A]*ILN#J.'2N7G^)E_'?IL>9Y;4<)!D7-"#I*6_"$JM?@%SQ_>F?0P````` +M'XL("!XUQ%4``VEM9RTV,W@R-34M-3$R+6)S9"YV:&0N;W5T`*V6R4[#,!"& +M[WV*D;AQJ)RQ8X<+2$C<.<$Y35-4(191#CVD[\Z,%V)G*XN;U')DS^=_%EL6 +MPOT`M`2]`]V"+KEO%.@K,!4`#?H7;5OX3^B:M]>V^=P?U_[7K1RL$+%5:L[V +M*$'1(@:PYD7TEOO0!A!I6$KB:`WHW7,%BJWCL4][O'9 +M(D^].CE6UULY!W<[D+MHA@SJ3K:]B9U59$7S^2UA8VQ\PIM\)`.]LX/8E6)@ +M%S/D4[H9YHYP>ZVW7Z?`,;!M)^I>U>:K_'?A+!Q[N' +MJ?PV,^7RQ]W1X#E<$!R?!BGN)L))EXZ>$A4O-`7(UG_$_0AW[?X!IY;4<_3A\'1']493O[,!Q5N10J#\RFD(!M9H78+A;;;ZM08V5=SG219%S&BR3C +B,EXD&9?Q(LFXC!=)QF6\2#(NZT62@%1[JR_1)]26?0P````` ` end diff --git a/usr.bin/mkimg/tests/img-63x255-512-ebr.vhd.gz.uu b/usr.bin/mkimg/tests/img-63x255-512-ebr.vhd.gz.uu index 5865a83838f7..bf1b6b684a1b 100644 --- a/usr.bin/mkimg/tests/img-63x255-512-ebr.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-63x255-512-ebr.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-63x255-512-ebr.vhd.gz -M'XL(")(EAE4``VEM9RTV,W@R-34M-3$R+65B:&#O[Q)UI20ODK34^Q(\B@^/BE -M1-&0$.X'H`O0'>@6M*)^*4'?0UD!6*._<6AS_PA]\_[6-G^/7YG_]1L'RP7W -MBMW)'PN0]B4EH*&7Z`/UH0^8[-?C\]WQ]3G@T./0@U1)7@6"KB?OJ<19'9'V -M1WP9JRNFZBY>+L"N@Z)C(PJN+LMV'">MEQU/MX9:#?,3[N@A,G!3 -M.3>I+-@YG%[SN@5WM_%KX5+%)D9I6P$ZAQ*I;],FS,/DMJGR=?HPGZ=VI`\7 -M4D6SQ1C;Y'*XZ%,%PV"O0)+`M7!AH)S&N)E4^:_9T[&?]!T["4(%`P[AQ[-W -M00'7IW.Q,N?+B[&HSZS&]8.`Z_IVX,KNJ!N_.P0812WMTMSO5>_?V.=V1M_. -M;=LMQQU2A]O=!E0*C)D`_P1]3>+EJ"HR2UM'S4R[;.@?LO@Z`X>$L?78EG.E -MH<+O*MP_/LVL;V46RL'M`3L<7L,%P;S:Q[@=PQ5NN_%4O7CQO.-]AMNZ?\#) -M-754$]HYPV*P*G&RF&KDQ]<9\A;R`D3E;1@#S^L+%WWW4QD8A;NB#Z;A&L*5 -M\?BX2^>7UIF[_GS\S]^H.%Y<*W +M"LW9'@N0])(2T/!+]!/WH1\QV8_[YYOSG^<1APZ'#J1*MBH0=!V]IZM!2*N. +M28]G_+U45\3J9BO[GJZ#HO-F%+ZZ+#OY.$E6-)]O!;4>UF>\@X=@P,<%ZI18 +M6'DRUQ95S,ZNX?2>U36XFX.+A4T52HR26@$ZAQ*Y3VDSKD-T4ZI\?KR9]X]V +MH0\W4D5/^O)HK-IV%UVJX!18JT!R:N^Y"P/E=8E;297_6CT=VDG7H440:AS` +MP?UP]684^/IT+G;6?#L8F_K,KE_?<+BNKP?N[(ZZ<;M#@%'<\B[-W5YU]@T] +MMROZ3G;;'GW<4VIWN^N`2H$Q$?#7J*])'(ZJXF%)==2LM-L#_5T67A-P2!BJ +MQU3.E88*OZKP\?YA);Z5V2@'USML<7@)-PKVJWV(.WFXPFXW/U5G*S_O_+Z' +M.]K_B)-[ZK@FM&L#F\ZJQ,EBJH6='V?(6\@++L9V#$/@%%^8]=W&,C!P=T&%U3O&ZIK$P:B7.^.+.Y%!@7-*#`@$I]P[_`"()@=A=#@`` ` end diff --git a/usr.bin/mkimg/tests/img-63x255-512-gpt.vhd.gz.uu b/usr.bin/mkimg/tests/img-63x255-512-gpt.vhd.gz.uu index 438b398df848..b496241a9260 100644 --- a/usr.bin/mkimg/tests/img-63x255-512-gpt.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-63x255-512-gpt.vhd.gz.uu @@ -1,22 +1,23 @@ # $FreeBSD$ begin 644 img-63x255-512-gpt.vhd.gz -M'XL(")8EAE4``VEM9RTV,W@R-34M-3$R+6=P="YV:&0N;W5T`*U82V^<,!"^ -M[Z^8JK=4I6#L@3U5K91*O:55JUYR"+`F6K7=/I)##OSX>L`&##;I)@.6EY69 -MCV^>'CE-APL`<\`64`,J>BXDX!Z*$L`LVB'Z.;-_H6M^G71S?WQ([-7M!K`L -MG4OYXB0OOV4U2PT_;0M[.WL@=NYM^?CM75AHI\SX-A`8AE=/P_G@+ -MD[(+VZET(36C&3+J3-D0'&Y)G0-WL;.^&$+%!$9A9F.Z#`I!SR9LG!U6PX3* -MP]WOZN^=7O`3D5#!D5^V6LOCZ@H;*L*];!E("NY_X]PA8U^EIL1021>D1=\.&XZ[(NR7J*S7I[&RRA -M$5^(6J\:K!ZXJR7)"Q^NYK5>UK>/)C],_5[/\87N*O'O`5#8;8AM -M7Q.VD+(QE!:0C:&T^<9:!KA-+)@,\XR\!P(_34 -0;"WB0'7N%-5(V?H1LPR=.;^^OCU_L!QSV.>Y#,T2KCH/3J +M/GD-17\?A[L[\L\.^3BIR];J)JO>P;:%K)W](AO4/;KKR[FSPEK9W^.04.3` +MQ#2"+\'$Y.PB=I(MK&8RMX+*)F>W<&K/ZA+<]97/15\JMC!R>V6@4L@Y?K9E +M,\1A-6RI/)R_5S_/S4(?CY2*FB5C.;<3/>Y+A0\_]@H$"MQS%QSEO,1ME,I_ +M14^%=D-V;1"8'";XX+X=]OXL6!E.*!OTJ93MQ#R>C*B^"O4)NQ*JC6M\HGN= +MA.\1J/5EP"&"(6Y,B#88/[=2FV;RJ"\2;VQ2R)IX0@ZS_.J:.+^ZO0PH)535 +M"OAQT&=<.B0(!:+$PK#-0:0@.4@QXISOTLSUW;QY"[>OWG]`V*?)78/E8MNF +MK36E(-<+=>N5YG$\:7]O+#:#B\TF9!'M`9=%HW?87+L&%YMN=G!;(XX3>U;C +M7O(/N>UQDH56Q=RJD+A_*`-U%<5]"7#4?;G!:6VS:G`+ERD8MY?7"M+4ZK/+ +MI'`0#KP&9C=VNPMK!':G=\FIA[U(?CSW^IK45\36B$_$HM?PO8I`47]Q%T(< +M=5]N"HR>)(M>Z8ME:\0GHM&K^NAM!PE%;2W=<5=+DB +M7^,3W6T2OGL@]]L0V;[&?2,E4R@\D$RA\.N74&$J=I-Y:9:55TCFLO)E0Z8P +MKPO*'H@XPAZ(.,(>B#C2'HA`PAZ(.,(>B#C"'H@XTAZ8UZ4K9J*C&N*P]KB" +M4N._W<*$,J*'KNY9MI:(3```` ` end diff --git a/usr.bin/mkimg/tests/img-63x255-512-mbr.vhd.gz.uu b/usr.bin/mkimg/tests/img-63x255-512-mbr.vhd.gz.uu index 16d286a648bd..27e7455f2046 100644 --- a/usr.bin/mkimg/tests/img-63x255-512-mbr.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-63x255-512-mbr.vhd.gz.uu @@ -1,18 +1,19 @@ # $FreeBSD$ begin 644 img-63x255-512-mbr.vhd.gz -M'XL(")LEAE4``VEM9RTV,W@R-34M-3$R+6UB?O3-G]/GX7_]3L'*UEL -ME9J3/5;`[4MJ0$TOD<_4ASY@BKO'E_WI]TO`H<>A!XF:K"H$:6;O46Q41Z2G -M$[Y.U55S=1C*UX[YC%X&),("#^^GJ -M75`0ZY,EVUCS]CD@^D]1MF\;^F*:32'WP&P*+;#-K%#G_7Y(KS#3 -K08%P&0\*A,MX4"!%`B7\:!`N*P'!6F/@(SM_@$'<*)G70X````` +M'XL(""DUQ%4``VEM9RTV,W@R-34M-3$R+6UB +M+V3&W`]`5B`[D"U(0=CSC[Z6Z*E4W6[GW=!U47?!$%:HKBE.(X];*/D^G`",'_XQG=!--A+A(G6`+ +MJT#FFE/9O-@UG-RSN@9W<_"Q<*EB$Z.V(P-90HUT;=-F]$-RVE3Y_'C3[Q_M +M0A]NI(J<])7)G-I>+OI4P2FP3@&GU-Y;+@R4UR5N)57^RWLRMN/^PCJ!B7$" +MA^7'WIM1$.J3)=OQ^78P-O5ITL=MG>F5<7NBOROB8P(:`_^9I\SQ-=UU0"%`ZP3X:]37[,JX7I]2 +MF>.KAH2Q_=BVFSK(2P@O>.Z;JFLS!,,O*^&+E$B2N +M7(?#O(U`#YW%9J!]*AVW)_J?17PX(/I/4;9O&_IFFDTA]\!L"BVPS:Q0Y_U^ +M2.&"DFFC0+B,&P7"9=PH$"[C1H%P&3<*A,NX42!^]M'LV%%91U7:UZ6$/_/AZL!UL#&33.A!D9,_# -M.Q^V9<;<#T!Q4`.H'I2D=B-`':'1`+;3WS@]:_\*8_?[5]_].;]7_C<>'*QF -ML55J3O;(0=B/-("&/J*^4QO&@*D^/;T\G'^^!!QZ''J0;,B*(Z@V^XYF5W5$ -M>C[CCZ4ZGJN;K9R#PP!\B$;P6%U5G6*VW45?*A@&>P6"!.ZY"Q/ELL2ME,I_14^E=L(W;!"8#!TXN9]& -M;T9!K$_5;"?FV\G8U&=(G[#SS*P\MSO&SU5Z78'M[U/<*<)Q-^%F2E1LT-7`>_\2MR/'P -MAKN0XEJ_\X:120IO1.\Q5]<53D:[G!D?G+D$26>NPV'9AQ10*#RRF4/C]HZ!"T^T6V[U5J+S"0D<%PA4\*A"N -CX%&!<`6/"H0K>%0@7,&C`N&*'A64/00R=O@+OHS"'5\.```` +M'XL(""TUQ%4``VEM9RTV,W@R-34M-3$R+7!C.3@N=FAD+F]U=`"ME\]OI"`4 +MQ^_S5[QD;ST8>`(ZET[2I/>][/:,5IM)TW:S[:$'__CE"2B(.ITNHV,P\#Y^ +MWP\@,&9_`*H$U8/J0$EJ5P+4$:H:P'2Z&\A +M56Q.]EB",!^I`#5]1#U2&P:/*7[H(\1%ZB1; +M6`4RUX+*9F?7<&K/ZAK3OGK;772E@E-BK0)!I;WG+HR4MR5NI53^*WHJMA.N88+`I._` +MT?TX>C,*0GV*LYV8;R=C4Y\F?<+,,[WRW.X8[HKXFH!-?QU02M`I\)=WN"5] +M1P&M6(N[F[))Q'#_>^5&5SK;"FQ.+R$\X+#]3[&G0)<:2?<3`F*#5H.9>=>PG:`N[5_CQ-[ +MZFA5Z-8Z-IV5F8M%UPN[,,_`.^`E+<=L6K<"X)1?F/4=4QD8N;NC#U)W->&J +M>#P/<'C!78AQC=MY_<@HA1>B=YNJ:S,GHUG.C"_.7(+$,]?B,.]"H,>5Q50@ +MK>+)<[MC^%G$EP6BVXRR[6[H=H]L"H4#9E,HW/Z14:%N=XOMVBI4TB8ETU&! +H%0@7,:C`N$R'A4(E_&H0+BL1P4#-+5W^`=:):>?7PX````` ` end diff --git a/usr.bin/mkimg/tests/img-63x255-512-vtoc8.vhd.gz.uu b/usr.bin/mkimg/tests/img-63x255-512-vtoc8.vhd.gz.uu index a38fd79a5827..03552762de0b 100644 --- a/usr.bin/mkimg/tests/img-63x255-512-vtoc8.vhd.gz.uu +++ b/usr.bin/mkimg/tests/img-63x255-512-vtoc8.vhd.gz.uu @@ -1,18 +1,18 @@ # $FreeBSD$ begin 644 img-63x255-512-vtoc8.vhd.gz -M'XL("*4EAE4``VEM9RTV,W@R-34M-3$R+79T;V,X+G9H9"YO=70`K99-;]LP -M#(;O^14$=NO!D"E9MD\%]M';@`$[[#K9EHM@V%JT/?20'S_2EA/)7VM6)H)C -M0^+CEQ3%4*GQ`V`UV!ZL!UOP?6G`UE!6`#09!@[7/#S"J7WXX]N7XVL6/J?# -M",M5;)6:LSUJ,/22$M#Q2VS']W":,-F'+_5AH\B$^TT@>DHD8 -MEZ@KU,PJ4KH6U,C9-9S=L[H&=W,(>S&F"B5&25<%-H<2^9[29HK#8E"JO#X_ -MNJ=G/].'&ZEBS_KRQ5R[[2Z&5,%I<5!@EJF2N@L#99XJN$B5=T;/IG8F#5+\ -M,*Z@Z*ABVUU[B1Y.0:-!JE6YMQG9X*]:X%#M6.WA-MQU[*ZQG"!<5`HP"`6= -M?<.'%S3==:OQNWOR_N/WSZB_)OK<1K+\]W:X*K'[QV&K0-5$:X4WHUFXZX?\5T/YO=K=9G)77Q:/YXHJ -M^P8NJLNWJ5YFO[*E5NY;D^QMI97VL->2A%2CJ@^U/.27\/^-`CCZ,Z.5476O%80M>![((5NYY5#G?7R&%@VB +MB='92>QR,;$*E"X%58S.+N'TEM4YN(N=WPN7*A2Q@MX"-$4/N4]I,\1AUBA5 +MCF\OYO7-3O3A2JJ,FY'-YIIU=]&G"@Z+O0(U3Y787>@I#U/<+%6^&3T=VZDX +M2.'`K:#HB'S=73U&#X>@42/5HMC:C'WOKYCA4&Q8;>%6W#7LKM*<(%Q4#E-&=O\Y;"6(BHO0ZG:8:K2J +MOG]VC4GEKL/5G\51S1`MM!:LG>#N`ER3>#/JF;NVSW_1E]^SW:T'=^6XV)TK +MJNPKN*`N7TYQ3734PH8PVB^H@T5U[0>N;D#)V&K3V>LEG$V:*G7W65QKH*8\ +MR:#;J,K-IHAS4P5]74E6J#"U0MF6EJ?IKUR8A??ZQ.GW/OXYH/(*D[E,P+0* +MM0_-C$MX;V9FQF7\-[, +2N*3W9@+2^=W]`WD,N"QL#0`` ` end From 1caaaaf09ec77e245c31c1f6a6b5c6be20922418 Mon Sep 17 00:00:00 2001 From: Gregory Neil Shapiro Date: Fri, 7 Aug 2015 04:58:35 +0000 Subject: [PATCH 295/314] Reminder to check tools/build/mk/OptionalObsoleteFiles.inc on new version imports. Obtained from: garga@ --- contrib/sendmail/FREEBSD-upgrade | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/sendmail/FREEBSD-upgrade b/contrib/sendmail/FREEBSD-upgrade index 64adce45b37f..451a2a0c9daf 100644 --- a/contrib/sendmail/FREEBSD-upgrade +++ b/contrib/sendmail/FREEBSD-upgrade @@ -86,6 +86,7 @@ infrastructure in FreeBSD: share/man/man8/rc.sendmail.8 share/mk/bsd.libnames.mk share/sendmail/Makefile + tools/build/mk/OptionalObsoleteFiles.inc usr.bin/Makefile usr.bin/vacation/Makefile usr.sbin/Makefile From c3f62b5352bacf285e1ad383e8ac0e5127c4bddf Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 7 Aug 2015 05:59:58 +0000 Subject: [PATCH 296/314] Remove unused i386 header privatespace.h. For the native kernel, its use was removed in r173592 (Nov 2007), yet Xen PV bits continued referencing the privatespace structure, and were removed in r282274 (Apr 2015). Discussed with: jhb Sponsored by: The FreeBSD Foundation --- sys/i386/include/privatespace.h | 49 --------------------------------- sys/pc98/include/privatespace.h | 6 ---- 2 files changed, 55 deletions(-) delete mode 100644 sys/i386/include/privatespace.h delete mode 100644 sys/pc98/include/privatespace.h diff --git a/sys/i386/include/privatespace.h b/sys/i386/include/privatespace.h deleted file mode 100644 index 5eb54c224f9a..000000000000 --- a/sys/i386/include/privatespace.h +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright (c) Peter Wemm - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 _MACHINE_PRIVATESPACE_H_ -#define _MACHINE_PRIVATESPACE_H_ - -/* - * This is the upper (0xff800000) address space layout that is per-cpu. - * It is setup in locore.s and pmap.c for the BSP and in mp_machdep.c for - * each AP. This is only applicable to the x86 SMP kernel. - */ -struct privatespace { - /* page 0 - data page */ - struct pcpu pcpu; - char __filler0[PAGE_SIZE - sizeof(struct pcpu)]; - - /* page 1 - idle stack (KSTACK_PAGES pages) */ - char idlekstack[KSTACK_PAGES * PAGE_SIZE]; - /* page 1+KSTACK_PAGES... */ -}; - -extern struct privatespace SMP_prvspace[]; - -#endif /* ! _MACHINE_PRIVATESPACE_H_ */ diff --git a/sys/pc98/include/privatespace.h b/sys/pc98/include/privatespace.h deleted file mode 100644 index 5db57c3230e9..000000000000 --- a/sys/pc98/include/privatespace.h +++ /dev/null @@ -1,6 +0,0 @@ -/*- - * This file is in the public domain. - */ -/* $FreeBSD$ */ - -#include From fa77157916eb487f074541fd8a62c39bffbc7e99 Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Fri, 7 Aug 2015 06:15:01 +0000 Subject: [PATCH 297/314] Fix variable 'old' is used uninitialized whenever '&&' condition is false. Spotted by clang. Differential Revision: D2721 Reviewed by: rodrigc, bapt --- contrib/bsnmp/snmp_mibII/mibII_ip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/bsnmp/snmp_mibII/mibII_ip.c b/contrib/bsnmp/snmp_mibII/mibII_ip.c index 11efe8274dd8..1e33dc974903 100644 --- a/contrib/bsnmp/snmp_mibII/mibII_ip.c +++ b/contrib/bsnmp/snmp_mibII/mibII_ip.c @@ -151,7 +151,7 @@ int op_ip(struct snmp_context *ctx, struct snmp_value *value, u_int sub, u_int idx __unused, enum snmp_op op) { - int old; + int old = 0; switch (op) { From b47f904d8f130280ddd0eb5c5dd55a151ced0246 Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Fri, 7 Aug 2015 07:05:47 +0000 Subject: [PATCH 298/314] Remove an extra new line on usage(). Rename domain to domainname to be identical to the man page. Reported by: bde --- usr.bin/ypmatch/ypmatch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.bin/ypmatch/ypmatch.c b/usr.bin/ypmatch/ypmatch.c index a57a642a435d..ff5365be25ab 100644 --- a/usr.bin/ypmatch/ypmatch.c +++ b/usr.bin/ypmatch/ypmatch.c @@ -66,8 +66,8 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n", - "usage: ypmatch [-kt] [-d domain] key ... mapname", - " ypmatch -x\n"); + "usage: ypmatch [-kt] [-d domainname] key ... mapname", + " ypmatch -x"); fprintf(stderr, "where\n" "\tmapname may be either a mapname or a nickname for a map.\n" From 9b34965019a89e0c95c39ac20c81e3ebae4f5143 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 7 Aug 2015 08:13:34 +0000 Subject: [PATCH 299/314] The condition to use direct processing for the unmapped bio is reverted. We can do direct processing when g_io_check() does not need to perform transient remapping of the bio, otherwise the thread has to sleep. Reviewed by: mav (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/geom/geom_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index 0b8e118a6944..97a7eef7e23e 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -520,8 +520,8 @@ g_io_request(struct bio *bp, struct g_consumer *cp) direct = (cp->flags & G_CF_DIRECT_SEND) && (pp->flags & G_PF_DIRECT_RECEIVE) && !g_is_geom_thread(curthread) && - (((pp->flags & G_PF_ACCEPT_UNMAPPED) == 0 && - (bp->bio_flags & BIO_UNMAPPED) != 0) || THREAD_CAN_SLEEP()); + ((pp->flags & G_PF_ACCEPT_UNMAPPED) != 0 || + (bp->bio_flags & BIO_UNMAPPED) == 0 || THREAD_CAN_SLEEP()); if (direct) { /* Block direct execution if less then half of stack left. */ size_t st, su; From 347e9d54952e4cfcb7ecee25addde6c447d237a7 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 7 Aug 2015 08:24:12 +0000 Subject: [PATCH 300/314] Minor style cleanup of the code surrounding r286404. Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/geom/geom_io.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index 97a7eef7e23e..e72e709a25ae 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -517,11 +517,11 @@ g_io_request(struct bio *bp, struct g_consumer *cp) getbinuptime(&bp->bio_t0); #ifdef GET_STACK_USAGE - direct = (cp->flags & G_CF_DIRECT_SEND) && - (pp->flags & G_PF_DIRECT_RECEIVE) && - !g_is_geom_thread(curthread) && - ((pp->flags & G_PF_ACCEPT_UNMAPPED) != 0 || - (bp->bio_flags & BIO_UNMAPPED) == 0 || THREAD_CAN_SLEEP()); + direct = (cp->flags & G_CF_DIRECT_SEND) != 0 && + (pp->flags & G_PF_DIRECT_RECEIVE) != 0 && + !g_is_geom_thread(curthread) && + ((pp->flags & G_PF_ACCEPT_UNMAPPED) != 0 || + (bp->bio_flags & BIO_UNMAPPED) == 0 || THREAD_CAN_SLEEP()); if (direct) { /* Block direct execution if less then half of stack left. */ size_t st, su; From 8b3ae99560e967df6d7ccf963ca57427e4e0f500 Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Fri, 7 Aug 2015 08:30:43 +0000 Subject: [PATCH 301/314] Wrap some unused functions with notyet, it is necessary to be able to build the modules/ctl directly. Remove a dead MALLOC_DEFINE. Differential Revision: D3329 Reviewed by: mav Sponsored by: gandi.net --- sys/cam/ctl/ctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 3889ca8eb642..0c27d90f2413 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -511,7 +511,6 @@ static struct cdevsw ctl_cdevsw = { MALLOC_DEFINE(M_CTL, "ctlmem", "Memory used for CTL"); -MALLOC_DEFINE(M_CTLIO, "ctlio", "Memory used for CTL requests"); static int ctl_module_event_handler(module_t, int /*modeventtype_t*/, void *); @@ -14274,6 +14273,7 @@ ctl_init_isc_msg(void) printf("CTL: Still calling this thing\n"); } +#ifdef notyet /* * Init component * Initializes component into configuration defined by bootMode @@ -14365,6 +14365,7 @@ struct ctl_ha_component ctl_ha_component_ctlisc = .start = ctl_isc_start, .quiesce = ctl_isc_quiesce }; +#endif /* * vim: ts=8 From a336c37514276db2d293c5e861c496d5d5da7194 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 7 Aug 2015 08:54:50 +0000 Subject: [PATCH 302/314] Stop including machine/fdt.h, it's unneeded, and purposefully unimplemented on arm64. Sponsored by: ABT Systems Ltd --- sys/dev/mmc/host/dwmmc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c index 81e3083a33cf..6801d6cbe80f 100644 --- a/sys/dev/mmc/host/dwmmc.c +++ b/sys/dev/mmc/host/dwmmc.c @@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include From d1b2133d032c01fd364b8558f7a5f466f82a87c1 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 7 Aug 2015 08:57:58 +0000 Subject: [PATCH 303/314] Attach dwmmc to the ofwbus, som devicetrees place it here. Sponsored by: ABT Systems Ltd --- sys/dev/mmc/host/dwmmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c index 6801d6cbe80f..162cd94f396b 100644 --- a/sys/dev/mmc/host/dwmmc.c +++ b/sys/dev/mmc/host/dwmmc.c @@ -1208,4 +1208,5 @@ static driver_t dwmmc_driver = { static devclass_t dwmmc_devclass; DRIVER_MODULE(dwmmc, simplebus, dwmmc_driver, dwmmc_devclass, 0, 0); +DRIVER_MODULE(dwmmc, ofwbus, dwmmc_driver, dwmmc_devclass, 0, 0); From 84fe889c6328a22456ff8138019b536242fc3328 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Fri, 7 Aug 2015 10:48:52 +0000 Subject: [PATCH 304/314] Manpage cleanup. - new sentence -> new line - fix manpage references - fix macro usage - fix a typo MFC after: 1 week --- usr.sbin/bhyve/bhyve.8 | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index c5de82a74f36..4f0115f6346d 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 17, 2014 +.Dd August 7, 2015 .Dt BHYVE 8 .Os .Sh NAME @@ -50,7 +50,7 @@ Parameters such as the number of virtual CPUs, amount of guest memory, and I/O connectivity can be specified with command-line parameters. .Pp The guest operating system must be loaded with -.Xr bhyveload 4 +.Xr bhyveload 8 or a similar boot loader before running .Nm . .Pp @@ -61,8 +61,8 @@ exit is detected. .Bl -tag -width 10n .It Fl a The guest's local APIC is configured in xAPIC mode. -The xAPIC mode is the default setting so this option is redundant. It will be -deprecated in a future version. +The xAPIC mode is the default setting so this option is redundant. +It will be deprecated in a future version. .It Fl A Generate ACPI tables. Required for @@ -124,7 +124,7 @@ Force the guest virtual CPU to exit when a PAUSE instruction is detected. .It Fl s Ar slot,emulation Ns Op , Ns Ar conf Configure a virtual PCI slot and function. .Pp -.Nm bhyve +.Nm provides PCI bus emulation and virtual devices that can be attached to slots on the bus. There are 32 available slots, with the option of providing up to 8 functions @@ -136,11 +136,19 @@ per slot. .Pp The .Ar pcislot -value is 0 to 31. The optional function value is 0 to 7. The optional +value is 0 to 31. +The optional +.Ar function +value is 0 to 7. +The optional .Ar bus value is 0 to 255. -If not specified, the function value defaults to 0. -If not specified, the bus value defaults to 0. +If not specified, the +.Ar function +value defaults to 0. +If not specified, the +.Ar bus +value defaults to 0. .It Ar emulation .Bl -tag -width 10n .It Li hostbridge | Li amd_hostbridge @@ -221,7 +229,9 @@ TTY devices: .Bl -tag -width 10n .It Li stdio Connect the serial port to the standard input and output of -the bhyve process. +the +.Nm +process. .It Pa /dev/xxx Use the host TTY device for serial port I/O. .El @@ -265,7 +275,8 @@ in the guest's System Management BIOS System Information structure. By default a UUID is generated from the host's hostname and .Ar vmname . .It Fl w -Ignore accesses to unimplemented Model Specific Registers (MSRs). This is intended for debug purposes. +Ignore accesses to unimplemented Model Specific Registers (MSRs). +This is intended for debug purposes. .It Fl W Force virtio PCI device emulations to use MSI interrupts instead of MSI-X interrupts. @@ -280,7 +291,7 @@ This should be the same as that created by .El .Sh EXAMPLES The guest operating system must have been loaded with -.Xr bhyveload 4 +.Xr bhyveload 8 or a similar boot loader before .Xr bhyve 4 can be run. @@ -308,7 +319,7 @@ Run an 8GB quad-CPU virtual machine with 8 AHCI SATA disks, an AHCI ATAPI CD-ROM, a single virtio network port, an AMD hostbridge, and the console port connected to an .Xr nmdm 4 -null-model device. +null-modem device. .Bd -literal -offset indent bhyve -c 4 \e\ -s 0,amd_hostbridge -s 1,lpc \\ From 79d2c5e8574c155e3e247a52eddeda3521c7d46b Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 7 Aug 2015 11:43:14 +0000 Subject: [PATCH 305/314] Change KPI of how device drivers that provide wireless connectivity interact with the net80211 stack. Historical background: originally wireless devices created an interface, just like Ethernet devices do. Name of an interface matched the name of the driver that created. Later, wlan(4) layer was introduced, and the wlanX interfaces become the actual interface, leaving original ones as "a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer and a driver became a mix of methods that pass a pointer to struct ifnet as identifier and methods that pass pointer to struct ieee80211com. From user point of view, the parent interface just hangs on in the ifconfig list, and user can't do anything useful with it. Now, the struct ifnet goes away. The struct ieee80211com is the only KPI between a device driver and net80211. Details: - The struct ieee80211com is embedded into drivers softc. - Packets are sent via new ic_transmit method, which is very much like the previous if_transmit. - Bringing parent up/down is done via new ic_parent method, which notifies driver about any changes: number of wlan(4) interfaces, number of them in promisc or allmulti state. - Device specific ioctls (if any) are received on new ic_ioctl method. - Packets/errors accounting are done by the stack. In certain cases, when driver experiences errors and can not attribute them to any specific interface, driver updates ic_oerrors or ic_ierrors counters. Details on interface configuration with new world order: - A sequence of commands needed to bring up wireless DOESN"T change. - /etc/rc.conf parameters DON'T change. - List of devices that can be used to create wlan(4) interfaces is now provided by net.wlan.devices sysctl. Most drivers in this change were converted by me, except of wpi(4), that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing changes to at least 8 drivers. Thanks to Olivier Cochard, gjb@, mmoll@, op@ and lev@, who also participated in testing. Details here: https://wiki.freebsd.org/projects/ifnet/net80211 Still, drivers: ndis, wtap, mwl, ipw, bwn, wi, upgt, uath were not tested. Changes to mwl, ipw, bwn, wi, upgt are trivial and chances of problems are low. The wtap wasn't compilable even before this change. But the ndis driver is complex, and it is likely to be broken with this commit. Help with testing and debugging it is appreciated. Differential Revision: D2655, D2740 Sponsored by: Nginx, Inc. Sponsored by: Netflix --- etc/network.subr | 67 ++ etc/rc.d/netif | 12 + sys/dev/ath/ath_rate/sample/sample.c | 9 +- sys/dev/ath/ath_rate/sample/sample.h | 3 +- sys/dev/ath/if_ath.c | 496 +++++--------- sys/dev/ath/if_ath_beacon.c | 6 +- sys/dev/ath/if_ath_debug.h | 7 +- sys/dev/ath/if_ath_keycache.c | 6 +- sys/dev/ath/if_ath_misc.h | 2 +- sys/dev/ath/if_ath_rx.c | 46 +- sys/dev/ath/if_ath_rx_edma.c | 10 +- sys/dev/ath/if_ath_sysctl.c | 12 +- sys/dev/ath/if_ath_tdma.c | 2 +- sys/dev/ath/if_ath_tx.c | 31 +- sys/dev/ath/if_ath_tx_edma.c | 10 - sys/dev/ath/if_athvar.h | 7 +- sys/dev/bwi/bwimac.c | 73 +- sys/dev/bwi/bwiphy.c | 2 +- sys/dev/bwi/bwirf.c | 9 +- sys/dev/bwi/if_bwi.c | 420 +++++------- sys/dev/bwi/if_bwivar.h | 4 +- sys/dev/bwn/if_bwn.c | 448 ++++-------- sys/dev/bwn/if_bwnvar.h | 6 +- sys/dev/if_ndis/if_ndis.c | 988 ++++++++++++++------------- sys/dev/if_ndis/if_ndisvar.h | 27 +- sys/dev/ipw/if_ipw.c | 254 +++---- sys/dev/ipw/if_ipwvar.h | 4 +- sys/dev/iwi/if_iwi.c | 310 ++++----- sys/dev/iwi/if_iwivar.h | 11 +- sys/dev/iwn/if_iwn.c | 363 ++++------ sys/dev/iwn/if_iwnvar.h | 8 +- sys/dev/malo/if_malo.c | 441 +++++------- sys/dev/malo/if_malo.h | 10 +- sys/dev/mwl/if_mwl.c | 511 ++++++-------- sys/dev/mwl/if_mwl_pci.c | 1 + sys/dev/mwl/if_mwlvar.h | 6 +- sys/dev/ral/if_ral_pci.c | 1 + sys/dev/ral/rt2560.c | 315 ++++----- sys/dev/ral/rt2560var.h | 9 +- sys/dev/ral/rt2661.c | 291 ++++---- sys/dev/ral/rt2661var.h | 7 +- sys/dev/ral/rt2860.c | 274 +++----- sys/dev/ral/rt2860var.h | 7 +- sys/dev/usb/wlan/if_rsu.c | 295 +++----- sys/dev/usb/wlan/if_rsureg.h | 9 +- sys/dev/usb/wlan/if_rum.c | 304 +++------ sys/dev/usb/wlan/if_rumvar.h | 7 +- sys/dev/usb/wlan/if_run.c | 387 ++++------- sys/dev/usb/wlan/if_runvar.h | 9 +- sys/dev/usb/wlan/if_uath.c | 308 +++------ sys/dev/usb/wlan/if_uathvar.h | 3 +- sys/dev/usb/wlan/if_upgt.c | 329 ++++----- sys/dev/usb/wlan/if_upgtvar.h | 6 +- sys/dev/usb/wlan/if_ural.c | 286 +++----- sys/dev/usb/wlan/if_uralvar.h | 7 +- sys/dev/usb/wlan/if_urtw.c | 344 ++++------ sys/dev/usb/wlan/if_urtwn.c | 284 +++----- sys/dev/usb/wlan/if_urtwnreg.h | 5 +- sys/dev/usb/wlan/if_urtwvar.h | 6 +- sys/dev/usb/wlan/if_zyd.c | 301 ++++---- sys/dev/usb/wlan/if_zydreg.h | 5 +- sys/dev/wi/if_wi.c | 384 ++++------- sys/dev/wi/if_wi_pccard.c | 1 + sys/dev/wi/if_wi_pci.c | 17 +- sys/dev/wi/if_wivar.h | 8 +- sys/dev/wpi/if_wpi.c | 493 +++++++------ sys/dev/wpi/if_wpivar.h | 7 +- sys/dev/wtap/if_wtap.c | 231 +------ sys/dev/wtap/if_wtapvar.h | 6 +- sys/net80211/ieee80211.c | 282 +++----- sys/net80211/ieee80211_ddb.c | 3 +- sys/net80211/ieee80211_freebsd.c | 90 +-- sys/net80211/ieee80211_ioctl.c | 71 +- sys/net80211/ieee80211_output.c | 30 +- sys/net80211/ieee80211_power.c | 55 +- sys/net80211/ieee80211_proto.c | 36 +- sys/net80211/ieee80211_proto.h | 3 +- sys/net80211/ieee80211_regdomain.c | 3 +- sys/net80211/ieee80211_scan_sta.c | 26 +- sys/net80211/ieee80211_var.h | 27 +- tools/tools/iwn/iwnstats/main.c | 15 +- 81 files changed, 4045 insertions(+), 6164 deletions(-) diff --git a/etc/network.subr b/etc/network.subr index 73ed57536317..5087a93d18fc 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -1249,6 +1249,70 @@ ifscript_down() fi } +# wlan_up +# Create IEEE802.3 interfaces. +# +wlan_up() +{ + local _list _iflist wlan parent ifn + _list= + _iflist=$* + + for wlan in `set | egrep ^wlans_[a-z]+[0-9]+=[a-z]+[0-9]+`; do + # Parse wlans_$parent=$ifn + wlan=`echo $wlan | sed -E 's/wlans_([a-z]+[0-9]+)=([a-z]+[0-9]+)/\1:\2/'` + OIFS=$IFS; IFS=:; set -- $wlan; parent=$1; ifn=$2; IFS=$OIFS + case $_iflist in + ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;; + *) continue ;; + esac + # Skip if ${ifn} already exists. + if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then + continue + fi + ${IFCONFIG_CMD} ${ifn} create wlandev ${parent} + if [ $? -eq 0 ]; then + _list="$_list $ifn" + fi + done + if [ -n "${_list# }" ]; then + echo "Created wlan(4) interfaces: ${_list# }." + fi + debug "Created wlan(4)s: ${_list# }" +} + +# wlan_down +# Destroy IEEE802.3 interfaces. +# +wlan_down() +{ + local _list _iflist wlan parent ifn + _list= + _iflist=$* + + for wlan in `set | egrep ^wlans_[a-z]+[0-9]+=[a-z]+[0-9]+`; do + # Parse wlans_$parent=$ifn + wlan=`echo $wlan | sed -E 's/wlans_([a-z]+[0-9]+)=([a-z]+[0-9]+)/\1:\2/'` + OIFS=$IFS; IFS=:; set -- $wlan; parent=$1; ifn=$2; IFS=$OIFS + case $_iflist in + ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;; + *) continue ;; + esac + # Skip if ${ifn} doesn't exists. + if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then + continue + fi + ${IFCONFIG_CMD} -n ${ifn} destroy + if [ $? -eq 0 ]; then + _list="$_list $ifn" + fi + done + if [ -n "${_list# }" ]; then + echo "Destroyed wlan(4) interfaces: ${_list# }." + fi + debug "Destroyed wlan(4)s: ${_list# }" +} + # clone_up # Create cloneable interfaces. # @@ -1398,6 +1462,9 @@ clone_down() # Create and configure child interfaces. Return 0 if child # interfaces are created. # +# XXXGL: the wlan code in this functions is superseded by wlan_up(), +# and will go away soon. +# childif_create() { local cfg child child_vlans child_wlans create_args debug_flags ifn i diff --git a/etc/rc.d/netif b/etc/rc.d/netif index 0915b28e29ed..c7b84b9b449a 100755 --- a/etc/rc.d/netif +++ b/etc/rc.d/netif @@ -37,6 +37,8 @@ name="netif" rcvar="${name}_enable" start_cmd="netif_start" stop_cmd="netif_stop" +wlanup_cmd="wlan_up" +wlandown_cmd="wlan_down" cloneup_cmd="clone_up" clonedown_cmd="clone_down" clear_cmd="doclear" @@ -65,6 +67,9 @@ netif_start() trap : 2 fi + # Create IEEE802.3 interface + wlan_up $cmdifn + # Create cloned interfaces clone_up $cmdifn @@ -91,12 +96,14 @@ netif_start() netif_stop() { _clone_down=1 + _wlan_down=1 netif_stop0 $* } doclear() { _clone_down= + _wlan_down= netif_stop0 $* } @@ -111,6 +118,11 @@ netif_stop0() # Deconfigure the interface(s) netif_common ifn_stop $cmdifn + # Destroy wlan interfaces + if [ -n "$_wlan_down" ]; then + wlan_down $cmdifn + fi + # Destroy cloned interfaces if [ -n "$_clone_down" ]; then clone_down $cmdifn diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c index 3606e14c28c3..815c68b7a245 100644 --- a/sys/dev/ath/ath_rate/sample/sample.c +++ b/sys/dev/ath/ath_rate/sample/sample.c @@ -488,8 +488,7 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, #define RATE(ix) (DOT11RATE(ix) / 2) struct sample_node *sn = ATH_NODE_SAMPLE(an); struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const HAL_RATE_TABLE *rt = sc->sc_currates; const int size_bin = size_to_bin(frameLen); int rix, mrr, best_rix, change_rates; @@ -856,8 +855,7 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, const struct ath_rc_series *rc, const struct ath_tx_status *ts, int frame_size, int nframes, int nbad) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct sample_node *sn = ATH_NODE_SAMPLE(an); int final_rix, short_tries, long_tries; const HAL_RATE_TABLE *rt = sc->sc_currates; @@ -1303,8 +1301,7 @@ static int ath_rate_sysctl_stats(SYSCTL_HANDLER_ARGS) { struct ath_softc *sc = arg1; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int error, v; v = 0; diff --git a/sys/dev/ath/ath_rate/sample/sample.h b/sys/dev/ath/ath_rate/sample/sample.h index 1c57dee88c45..5495141c60be 100644 --- a/sys/dev/ath/ath_rate/sample/sample.h +++ b/sys/dev/ath/ath_rate/sample/sample.h @@ -134,8 +134,7 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc, int long_retries, int is_ht40) { const HAL_RATE_TABLE *rt = sc->sc_currates; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int rts, cts; unsigned t_slot = 20; diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 2c935a2b857d..f40f4fa77eac 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -151,15 +151,15 @@ static struct ieee80211vap *ath_vap_create(struct ieee80211com *, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void ath_vap_delete(struct ieee80211vap *); -static void ath_init(void *); -static void ath_stop_locked(struct ifnet *); -static void ath_stop(struct ifnet *); +static void ath_init(struct ath_softc *); +static void ath_stop_locked(struct ath_softc *); +static void ath_stop(struct ath_softc *); static int ath_reset_vap(struct ieee80211vap *, u_long); -static int ath_transmit(struct ifnet *ifp, struct mbuf *m); -static void ath_qflush(struct ifnet *ifp); +static int ath_transmit(struct ieee80211com *, struct mbuf *); static int ath_media_change(struct ifnet *); static void ath_watchdog(void *); -static int ath_ioctl(struct ifnet *, u_long, caddr_t); +static int ath_ioctl(struct ieee80211com *, u_long, void *); +static void ath_parent(struct ieee80211com *); static void ath_fatal_proc(void *, int); static void ath_bmiss_vap(struct ieee80211vap *); static void ath_bmiss_proc(void *, int); @@ -571,34 +571,19 @@ ath_fetch_mac_kenv(struct ath_softc *sc, uint8_t *macaddr) int ath_attach(u_int16_t devid, struct ath_softc *sc) { - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = NULL; HAL_STATUS status; int error = 0, i; u_int wmodes; - uint8_t macaddr[IEEE80211_ADDR_LEN]; int rx_chainmask, tx_chainmask; HAL_OPS_CONFIG ah_config; DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid); - CURVNET_SET(vnet0); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - error = ENOSPC; - CURVNET_RESTORE(); - goto bad; - } - ic = ifp->if_l2com; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(sc->sc_dev); - if_initname(ifp, device_get_name(sc->sc_dev), - device_get_unit(sc->sc_dev)); - CURVNET_RESTORE(); - /* * Configure the initial configuration data. * @@ -732,8 +717,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) sc->sc_tq = taskqueue_create("ath_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->sc_tq); - taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, - "%s taskq", ifp->if_xname); + taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", + device_get_nameunit(sc->sc_dev)); TASK_INIT(&sc->sc_rxtask, 0, sc->sc_rx.recv_tasklet, sc); TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc); @@ -876,17 +861,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) ath_led_config(sc); ath_hal_setledstate(ah, HAL_LED_INIT); - ifp->if_softc = sc; - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; - ifp->if_transmit = ath_transmit; - ifp->if_qflush = ath_qflush; - ifp->if_ioctl = ath_ioctl; - ifp->if_init = ath_init; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; /* XXX not right but it's not used anywhere important */ ic->ic_phytype = IEEE80211_T_OFDM; ic->ic_opmode = IEEE80211_M_STA; @@ -1208,11 +1182,11 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) sc->sc_hasveol = ath_hal_hasveol(ah); /* get mac address from kenv first, then hardware */ - if (ath_fetch_mac_kenv(sc, macaddr) == 0) { + if (ath_fetch_mac_kenv(sc, ic->ic_macaddr) == 0) { /* Tell the HAL now about the new MAC */ - ath_hal_setmac(ah, macaddr); + ath_hal_setmac(ah, ic->ic_macaddr); } else { - ath_hal_getmac(ah, macaddr); + ath_hal_getmac(ah, ic->ic_macaddr); } if (sc->sc_hasbmask) @@ -1221,12 +1195,15 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) /* NB: used to size node table key mapping array */ ic->ic_max_keyix = sc->sc_keymax; /* call MI attach routine. */ - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_setregdomain = ath_setregdomain; ic->ic_getradiocaps = ath_getradiocaps; sc->sc_opmode = HAL_M_STA; /* override default methods */ + ic->ic_ioctl = ath_ioctl; + ic->ic_parent = ath_parent; + ic->ic_transmit = ath_transmit; ic->ic_newassoc = ath_newassoc; ic->ic_updateslot = ath_updateslot; ic->ic_wme.wme_update = ath_wme_update; @@ -1322,16 +1299,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) bad: if (ah) ath_hal_detach(ah); - - /* - * To work around scoping issues with CURVNET_SET/CURVNET_RESTORE.. - */ - if (ifp != NULL && ifp->if_vnet) { - CURVNET_SET(ifp->if_vnet); - if_free(ifp); - CURVNET_RESTORE(); - } else if (ifp != NULL) - if_free(ifp); sc->sc_invalid = 1; return error; } @@ -1339,10 +1306,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) int ath_detach(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - - DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); /* * NB: the order of these is important: @@ -1367,14 +1330,14 @@ ath_detach(struct ath_softc *sc) ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); ath_power_setpower(sc, HAL_PM_AWAKE); - ATH_UNLOCK(sc); /* * Stop things cleanly. */ - ath_stop(ifp); + ath_stop_locked(sc); + ATH_UNLOCK(sc); - ieee80211_ifdetach(ifp->if_l2com); + ieee80211_ifdetach(&sc->sc_ic); taskqueue_free(sc->sc_tq); #ifdef ATH_TX99_DIAG if (sc->sc_tx99 != NULL) @@ -1394,10 +1357,6 @@ ath_detach(struct ath_softc *sc) ath_tx_cleanup(sc); ath_hal_detach(sc->sc_ah); /* NB: sets chip in full sleep */ - CURVNET_SET(ifp->if_vnet); - if_free(ifp); - CURVNET_RESTORE(); - return 0; } @@ -1473,7 +1432,7 @@ ath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac0[IEEE80211_ADDR_LEN]) { - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_vap *avp; struct ieee80211vap *vap; uint8_t mac[IEEE80211_ADDR_LEN]; @@ -1581,8 +1540,7 @@ ath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, vap = &avp->av_vap; /* XXX can't hold mutex across if_alloc */ ATH_UNLOCK(sc); - error = ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, - bssid, mac); + error = ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); ATH_LOCK(sc); if (error != 0) { device_printf(sc->sc_dev, "%s: error %d creating vap\n", @@ -1716,7 +1674,8 @@ ath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ATH_UNLOCK(sc); /* complete setup */ - ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status, + mac); return vap; bad2: reclaim_address(sc, mac); @@ -1731,8 +1690,7 @@ static void ath_vap_delete(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_hal *ah = sc->sc_ah; struct ath_vap *avp = ATH_VAP(vap); @@ -1741,7 +1699,7 @@ ath_vap_delete(struct ieee80211vap *vap) ATH_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_running) { /* * Quiesce the hardware while we remove the vap. In * particular we need to reclaim all references to @@ -1824,7 +1782,7 @@ ath_vap_delete(struct ieee80211vap *vap) #endif free(avp, M_80211_VAP); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_running) { /* * Restart rx+tx machines if still running (RUNNING will * be reset if we just destroyed the last vap). @@ -1851,13 +1809,9 @@ ath_vap_delete(struct ieee80211vap *vap) void ath_suspend(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; - DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); - - sc->sc_resume_up = (ifp->if_flags & IFF_UP) != 0; + sc->sc_resume_up = ic->ic_nrunning != 0; ieee80211_suspend_all(ic); /* @@ -1898,8 +1852,7 @@ ath_suspend(struct ath_softc *sc) static void ath_reset_keycache(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; int i; @@ -1941,8 +1894,7 @@ ath_update_chainmasks(struct ath_softc *sc, struct ieee80211_channel *chan) void ath_resume(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; @@ -2015,12 +1967,8 @@ ath_resume(struct ath_softc *sc) void ath_shutdown(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); - - ath_stop(ifp); + ath_stop(sc); /* NB: no point powering down chip as we're about to reboot */ } @@ -2031,7 +1979,6 @@ void ath_intr(void *arg) { struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; struct ath_hal *ah = sc->sc_ah; HAL_INT status = 0; uint32_t txqs; @@ -2070,12 +2017,11 @@ ath_intr(void *arg) ath_power_set_power_state(sc, HAL_PM_AWAKE); ATH_UNLOCK(sc); - if ((ifp->if_flags & IFF_UP) == 0 || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if (sc->sc_ic.ic_nrunning == 0 && sc->sc_running == 0) { HAL_INT status; - DPRINTF(sc, ATH_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); + DPRINTF(sc, ATH_DEBUG_ANY, "%s: ic_nrunning %d sc_running %d\n", + __func__, sc->sc_ic.ic_nrunning, sc->sc_running); ath_hal_getisr(ah, &status); /* clear ISR */ ath_hal_intrset(ah, 0); /* disable further intr's */ ATH_PCU_UNLOCK(sc); @@ -2313,7 +2259,6 @@ static void ath_fatal_proc(void *arg, int pending) { struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; u_int32_t *state; u_int32_t len; void *sp; @@ -2334,13 +2279,13 @@ ath_fatal_proc(void *arg, int pending) "0x%08x 0x%08x 0x%08x, 0x%08x 0x%08x 0x%08x\n", state[0], state[1] , state[2], state[3], state[4], state[5]); } - ath_reset(ifp, ATH_RESET_NOLOSS); + ath_reset(sc, ATH_RESET_NOLOSS); } static void ath_bmiss_vap(struct ieee80211vap *vap) { - struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; /* * Workaround phantom bmiss interrupts by sanity-checking @@ -2361,8 +2306,6 @@ ath_bmiss_vap(struct ieee80211vap *vap) ATH_UNLOCK(sc); if ((vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) == 0) { - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; u_int64_t lastrx = sc->sc_lastrx; u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah); /* XXX should take a locked ref to iv_bss */ @@ -2420,7 +2363,6 @@ static void ath_bmiss_proc(void *arg, int pending) { struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t hangs; DPRINTF(sc, ATH_DEBUG_ANY, "%s: pending %u\n", __func__, pending); @@ -2438,12 +2380,12 @@ ath_bmiss_proc(void *arg, int pending) * to clear. */ if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) { - ath_reset(ifp, ATH_RESET_NOLOSS); + ath_reset(sc, ATH_RESET_NOLOSS); device_printf(sc->sc_dev, "bb hang detected (0x%x), resetting\n", hangs); } else { - ath_reset(ifp, ATH_RESET_NOLOSS); - ieee80211_beacon_miss(ifp->if_l2com); + ath_reset(sc, ATH_RESET_NOLOSS); + ieee80211_beacon_miss(&sc->sc_ic); } /* Force a beacon resync, in case they've drifted */ @@ -2463,8 +2405,7 @@ ath_bmiss_proc(void *arg, int pending) static void ath_settkipmic(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; if ((ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP) && !sc->sc_wmetkipmic) { if (ic->ic_flags & IEEE80211_F_WME) { @@ -2478,11 +2419,9 @@ ath_settkipmic(struct ath_softc *sc) } static void -ath_init(void *arg) +ath_init(struct ath_softc *sc) { - struct ath_softc *sc = (struct ath_softc *) arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; @@ -2501,7 +2440,7 @@ ath_init(void *arg) * Stop anything previously setup. This is safe * whether this is the first time through or not. */ - ath_stop_locked(ifp); + ath_stop_locked(sc); /* * The basic interface to setting the hardware in a good @@ -2627,7 +2566,7 @@ ath_init(void *arg) DPRINTF(sc, ATH_DEBUG_RESET, "%s: imask=0x%x\n", __func__, sc->sc_imask); - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_running = 1; callout_reset(&sc->sc_wd_ch, hz, ath_watchdog, sc); ath_hal_intrset(ah, sc->sc_imask); @@ -2643,14 +2582,10 @@ ath_init(void *arg) } static void -ath_stop_locked(struct ifnet *ifp) +ath_stop_locked(struct ath_softc *sc) { - struct ath_softc *sc = ifp->if_softc; struct ath_hal *ah = sc->sc_ah; - DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", - __func__, sc->sc_invalid, ifp->if_flags); - ATH_LOCK_ASSERT(sc); /* @@ -2658,7 +2593,7 @@ ath_stop_locked(struct ifnet *ifp) */ ath_power_set_power_state(sc, HAL_PM_AWAKE); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_running) { /* * Shutdown the hardware and driver: * reset 802.11 state machine @@ -2680,7 +2615,7 @@ ath_stop_locked(struct ifnet *ifp) #endif callout_stop(&sc->sc_wd_ch); sc->sc_wd_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->sc_running = 0; if (!sc->sc_invalid) { if (sc->sc_softled) { callout_stop(&sc->sc_ledtimer); @@ -2832,12 +2767,11 @@ ath_reset_grablock(struct ath_softc *sc, int dowait) */ static void -ath_stop(struct ifnet *ifp) +ath_stop(struct ath_softc *sc) { - struct ath_softc *sc = ifp->if_softc; - + ATH_LOCK(sc); - ath_stop_locked(ifp); + ath_stop_locked(sc); ATH_UNLOCK(sc); } @@ -2849,10 +2783,9 @@ ath_stop(struct ifnet *ifp) * to reset or reload hardware state. */ int -ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type) +ath_reset(struct ath_softc *sc, ATH_RESET_TYPE reset_type) { - struct ath_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; int i; @@ -3014,15 +2947,6 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type) } } - /* - * This may have been set during an ath_start() call which - * set this once it detected a concurrent TX was going on. - * So, clear it. - */ - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); - ATH_LOCK(sc); ath_power_restore_power_state(sc); ATH_UNLOCK(sc); @@ -3044,8 +2968,7 @@ static int ath_reset_vap(struct ieee80211vap *vap, u_long cmd) { struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_hal *ah = sc->sc_ah; switch (cmd) { @@ -3060,7 +2983,7 @@ ath_reset_vap(struct ieee80211vap *vap, u_long cmd) return 0; } /* XXX? Full or NOLOSS? */ - return ath_reset(ifp, ATH_RESET_FULL); + return ath_reset(sc, ATH_RESET_FULL); } struct ath_buf * @@ -3220,24 +3143,12 @@ ath_getbuf(struct ath_softc *sc, ath_buf_type_t btype) bf = _ath_getbuf_locked(sc, ATH_BUFTYPE_NORMAL); ATH_TXBUF_UNLOCK(sc); if (bf == NULL) { - struct ifnet *ifp = sc->sc_ifp; - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: stop queue\n", __func__); sc->sc_stats.ast_tx_qstop++; - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); } return bf; } -static void -ath_qflush(struct ifnet *ifp) -{ - - /* XXX TODO */ -} - /* * Transmit a single frame. * @@ -3245,10 +3156,9 @@ ath_qflush(struct ifnet *ifp) * fails, so don't free the node reference here. */ static int -ath_transmit(struct ifnet *ifp, struct mbuf *m) +ath_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct ieee80211com *ic = ifp->if_l2com; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ieee80211_node *ni; struct mbuf *next; struct ath_buf *bf; @@ -3263,10 +3173,7 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m) DPRINTF(sc, ATH_DEBUG_XMIT, "%s: sc_inreset_cnt > 0; bailing\n", __func__); ATH_PCU_UNLOCK(sc); - IF_LOCK(&ifp->if_snd); sc->sc_stats.ast_tx_qstop++; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); ATH_KTR(sc, ATH_KTR_TX, 0, "ath_start_task: OACTIVE, finish"); return (ENOBUFS); /* XXX should be EINVAL or? */ } @@ -3306,8 +3213,6 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m) if ((!(m->m_flags & M_EAPOL)) && (ATH_NODE(ni)->an_swq_depth > sc->sc_txq_node_maxdepth)) { sc->sc_stats.ast_tx_nodeq_overflow++; - m_freem(m); - m = NULL; retval = ENOBUFS; goto finish; } @@ -3331,8 +3236,6 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m) if ((!(m->m_flags & M_EAPOL)) && (sc->sc_txbuf_cnt <= sc->sc_txq_data_minfree)) { sc->sc_stats.ast_tx_nobuf++; - m_freem(m); - m = NULL; retval = ENOBUFS; goto finish; } @@ -3360,11 +3263,6 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m) * above. */ sc->sc_stats.ast_tx_nobuf++; - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); - m_freem(m); - m = NULL; retval = ENOBUFS; goto finish; } @@ -3386,8 +3284,13 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m) DPRINTF(sc, ATH_DEBUG_XMIT, "%s: out of txfrag buffers\n", __func__); sc->sc_stats.ast_tx_nofrag++; - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + /* + * XXXGL: is mbuf valid after ath_txfrag_setup? If yes, + * we shouldn't free it but return back. + */ ath_freetx(m); + m = NULL; goto bad; } @@ -3429,12 +3332,6 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m) } } - /* - * Bump the ifp output counter. - * - * XXX should use atomics? - */ - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); nextfrag: /* * Pass the frame to the h/w for transmission. @@ -3454,7 +3351,7 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m) next = m->m_nextpkt; if (ath_tx_start(sc, ni, bf, m)) { bad: - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); reclaim: bf->bf_m = NULL; bf->bf_node = NULL; @@ -3538,8 +3435,7 @@ ath_media_change(struct ifnet *ifp) static void ath_key_update_begin(struct ieee80211vap *vap) { - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__); taskqueue_block(sc->sc_tq); @@ -3548,8 +3444,7 @@ ath_key_update_begin(struct ieee80211vap *vap) static void ath_key_update_end(struct ieee80211vap *vap) { - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__); taskqueue_unblock(sc->sc_tq); @@ -3580,32 +3475,41 @@ ath_update_promisc(struct ieee80211com *ic) static void ath_update_mcast_hw(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; u_int32_t mfilt[2]; /* calculate and install multicast filter */ - if ((ifp->if_flags & IFF_ALLMULTI) == 0) { + if (ic->ic_allmulti == 0) { + struct ieee80211vap *vap; + struct ifnet *ifp; struct ifmultiaddr *ifma; + /* * Merge multicast addresses to form the hardware filter. */ mfilt[0] = mfilt[1] = 0; - if_maddr_rlock(ifp); /* XXX need some fiddling to remove? */ - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - caddr_t dl; - u_int32_t val; - u_int8_t pos; + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + ifp = vap->iv_ifp; + if_maddr_rlock(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + caddr_t dl; + uint32_t val; + uint8_t pos; - /* calculate XOR of eight 6bit values */ - dl = LLADDR((struct sockaddr_dl *) ifma->ifma_addr); - val = LE_READ_4(dl + 0); - pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; - val = LE_READ_4(dl + 3); - pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; - pos &= 0x3f; - mfilt[pos / 32] |= (1 << (pos % 32)); + /* calculate XOR of eight 6bit values */ + dl = LLADDR((struct sockaddr_dl *) + ifma->ifma_addr); + val = LE_READ_4(dl + 0); + pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ + val; + val = LE_READ_4(dl + 3); + pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ + val; + pos &= 0x3f; + mfilt[pos / 32] |= (1 << (pos % 32)); + } + if_maddr_runlock(ifp); } - if_maddr_runlock(ifp); } else mfilt[0] = mfilt[1] = ~0; @@ -3638,7 +3542,7 @@ ath_update_mcast(struct ieee80211com *ic) void ath_mode_init(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; u_int32_t rfilt; @@ -3649,15 +3553,8 @@ ath_mode_init(struct ath_softc *sc) /* configure operational mode */ ath_hal_setopmode(ah); - DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_MODE, - "%s: ah=%p, ifp=%p, if_addr=%p\n", - __func__, - ah, - ifp, - (ifp == NULL) ? NULL : ifp->if_addr); - /* handle any link-level address change */ - ath_hal_setmac(ah, IF_LLADDR(ifp)); + ath_hal_setmac(ah, ic->ic_macaddr); /* calculate and install multicast filter */ ath_update_mcast_hw(sc); @@ -3669,7 +3566,7 @@ ath_mode_init(struct ath_softc *sc) void ath_setslottime(struct ath_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; u_int usec; @@ -3753,12 +3650,11 @@ static void ath_reset_proc(void *arg, int pending) { struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; #if 0 device_printf(sc->sc_dev, "%s: resetting\n", __func__); #endif - ath_reset(ifp, ATH_RESET_NOLOSS); + ath_reset(sc, ATH_RESET_NOLOSS); } /* @@ -3768,7 +3664,6 @@ static void ath_bstuck_proc(void *arg, int pending) { struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t hangs = 0; if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) @@ -3786,7 +3681,7 @@ ath_bstuck_proc(void *arg, int pending) * This assumes that there's no simultaneous channel mode change * occuring. */ - ath_reset(ifp, ATH_RESET_NOLOSS); + ath_reset(sc, ATH_RESET_NOLOSS); } static void @@ -4156,7 +4051,7 @@ static struct ieee80211_node * ath_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ieee80211com *ic = vap->iv_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; const size_t space = sizeof(struct ath_node) + sc->sc_rc->arc_space; struct ath_node *an; @@ -4183,7 +4078,7 @@ static void ath_node_cleanup(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; DPRINTF(sc, ATH_DEBUG_NODE, "%s: %6D: an %p\n", __func__, ni->ni_macaddr, ":", ATH_NODE(ni)); @@ -4198,7 +4093,7 @@ static void ath_node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; DPRINTF(sc, ATH_DEBUG_NODE, "%s: %6D: an %p\n", __func__, ni->ni_macaddr, ":", ATH_NODE(ni)); @@ -4210,7 +4105,7 @@ static void ath_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise) { struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_hal *ah = sc->sc_ah; *rssi = ic->ic_node_getrssi(ni); @@ -4348,8 +4243,7 @@ ath_txq_update(struct ath_softc *sc, int ac) { #define ATH_EXPONENT_TO_VALUE(v) ((1<sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_txq *txq = sc->sc_ac2q[ac]; struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; struct ath_hal *ah = sc->sc_ah; @@ -4422,7 +4316,7 @@ ath_txq_update(struct ath_softc *sc, int ac) int ath_wme_update(struct ieee80211com *ic) { - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; return !ath_txq_update(sc, WME_AC_BE) || !ath_txq_update(sc, WME_AC_BK) || @@ -4473,8 +4367,7 @@ ath_tx_update_stats(struct ath_softc *sc, struct ath_tx_status *ts, struct ath_buf *bf) { struct ieee80211_node *ni = bf->bf_node; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int sr, lr, pri; if (ts->ts_status == 0) { @@ -4829,7 +4722,6 @@ static void ath_tx_proc_q0(void *arg, int npending) { struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t txqs; ATH_PCU_LOCK(sc); @@ -4850,9 +4742,6 @@ ath_tx_proc_q0(void *arg, int npending) sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum)) ath_tx_processq(sc, sc->sc_cabq, 1); - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; if (sc->sc_softled) @@ -4877,7 +4766,6 @@ static void ath_tx_proc_q0123(void *arg, int npending) { struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; int nacked; uint32_t txqs; @@ -4911,9 +4799,6 @@ ath_tx_proc_q0123(void *arg, int npending) if (nacked) sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; if (sc->sc_softled) @@ -4937,7 +4822,6 @@ static void ath_tx_proc(void *arg, int npending) { struct ath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; int i, nacked; uint32_t txqs; @@ -4963,10 +4847,6 @@ ath_tx_proc(void *arg, int npending) if (nacked) sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); - /* XXX check this inside of IF_LOCK? */ - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; if (sc->sc_softled) @@ -5277,7 +5157,7 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) txq->axq_aggr_depth--; #ifdef ATH_DEBUG if (sc->sc_debug & ATH_DEBUG_RESET) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int status = 0; /* @@ -5422,9 +5302,8 @@ void ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type) { struct ath_hal *ah = sc->sc_ah; - struct ifnet *ifp = sc->sc_ifp; - int i; struct ath_buf *bf_last; + int i; (void) ath_stoptxdma(sc); @@ -5476,15 +5355,12 @@ ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type) ath_printtxbuf(sc, bf, sc->sc_bhalq, 0, ath_hal_txprocdesc(ah, bf->bf_lastds, &bf->bf_status.ds_txstat) == HAL_OK); - ieee80211_dump_pkt(ifp->if_l2com, + ieee80211_dump_pkt(&sc->sc_ic, mtod(bf->bf_m, const uint8_t *), bf->bf_m->m_len, 0, -1); } } #endif /* ATH_DEBUG */ - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; } @@ -5515,8 +5391,7 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan) static int ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; int ret = 0; @@ -5651,9 +5526,6 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) ath_hal_intrset(ah, sc->sc_imask); ATH_PCU_UNLOCK(sc); - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); ath_txrx_start(sc); /* XXX ath_start? */ @@ -5669,8 +5541,7 @@ ath_calibrate(void *arg) { struct ath_softc *sc = arg; struct ath_hal *ah = sc->sc_ah; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; HAL_BOOL longCal, isCalDone = AH_TRUE; HAL_BOOL aniCal, shortCal = AH_FALSE; int nextcal; @@ -5796,12 +5667,12 @@ ath_calibrate(void *arg) static void ath_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_hal *ah = sc->sc_ah; u_int32_t rfilt; /* XXX calibration timer? */ + /* XXXGL: is constant ieee80211broadcastaddr a correct choice? */ ATH_LOCK(sc); sc->sc_scanning = 1; @@ -5811,18 +5682,17 @@ ath_scan_start(struct ieee80211com *ic) ATH_PCU_LOCK(sc); ath_hal_setrxfilter(ah, rfilt); - ath_hal_setassocid(ah, ifp->if_broadcastaddr, 0); + ath_hal_setassocid(ah, ieee80211broadcastaddr, 0); ATH_PCU_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0\n", - __func__, rfilt, ether_sprintf(ifp->if_broadcastaddr)); + __func__, rfilt, ether_sprintf(ieee80211broadcastaddr)); } static void ath_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_hal *ah = sc->sc_ah; u_int32_t rfilt; @@ -5862,8 +5732,7 @@ ath_scan_end(struct ieee80211com *ic) static void ath_update_chw(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; DPRINTF(sc, ATH_DEBUG_STATE, "%s: called\n", __func__); ath_set_channel(ic); @@ -5873,8 +5742,7 @@ ath_update_chw(struct ieee80211com *ic) static void ath_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); @@ -5916,7 +5784,7 @@ static int ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_vap *avp = ATH_VAP(vap); struct ath_hal *ah = sc->sc_ah; struct ieee80211_node *ni = NULL; @@ -6252,7 +6120,7 @@ static void ath_setup_stationkey(struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; ieee80211_keyix keyix, rxkeyix; /* XXX should take a locked ref to vap->iv_bss */ @@ -6285,7 +6153,7 @@ ath_newassoc(struct ieee80211_node *ni, int isnew) { struct ath_node *an = ATH_NODE(ni); struct ieee80211vap *vap = ni->ni_vap; - struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; const struct ieee80211_txparam *tp = ni->ni_txparms; an->an_mcastrix = ath_tx_findrix(sc, tp->mcastrate); @@ -6337,7 +6205,7 @@ static int ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *reg, int nchans, struct ieee80211_channel chans[]) { - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; @@ -6361,7 +6229,7 @@ static void ath_getradiocaps(struct ieee80211com *ic, int maxchans, int *nchans, struct ieee80211_channel chans[]) { - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_hal *ah = sc->sc_ah; DPRINTF(sc, ATH_DEBUG_REGDOMAIN, "%s: use rd %u cc %d\n", @@ -6376,8 +6244,7 @@ ath_getradiocaps(struct ieee80211com *ic, static int ath_getchannels(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; @@ -6539,12 +6406,12 @@ static void ath_watchdog(void *arg) { struct ath_softc *sc = arg; + struct ieee80211com *ic = &sc->sc_ic; int do_reset = 0; ATH_LOCK_ASSERT(sc); if (sc->sc_wd_timer != 0 && --sc->sc_wd_timer == 0) { - struct ifnet *ifp = sc->sc_ifp; uint32_t hangs; ath_power_set_power_state(sc, HAL_PM_AWAKE); @@ -6556,7 +6423,7 @@ ath_watchdog(void *arg) } else device_printf(sc->sc_dev, "device timeout\n"); do_reset = 1; - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(ic->ic_oerrors, 1); sc->sc_stats.ast_watchdog++; ath_power_restore_power_state(sc); @@ -6582,7 +6449,7 @@ static int ath_ioctl_ratestats(struct ath_softc *sc, struct ath_rateioctl *rs) { struct ath_node *an; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; int error = 0; @@ -6688,31 +6555,23 @@ ath_ioctl_diag(struct ath_softc *sc, struct ath_diag *ad) } #endif /* ATH_DIAGAPI */ -static int -ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +ath_parent(struct ieee80211com *ic) { -#define IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct ath_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *)data; - const HAL_RATE_TABLE *rt; - int error = 0; + struct ath_softc *sc = ic->ic_softc; - switch (cmd) { - case SIOCSIFFLAGS: - if (IS_RUNNING(ifp)) { - /* - * To avoid rescanning another access point, - * do not call ath_init() here. Instead, - * only reflect promisc mode settings. - */ - ATH_LOCK(sc); + ATH_LOCK(sc); + if (ic->ic_nrunning > 0) { + /* + * To avoid rescanning another access point, + * do not call ath_init() here. Instead, + * only reflect promisc mode settings. + */ + if (sc->sc_running) { ath_power_set_power_state(sc, HAL_PM_AWAKE); ath_mode_init(sc); ath_power_restore_power_state(sc); - ATH_UNLOCK(sc); - } else if (ifp->if_flags & IFF_UP) { + } else if (!sc->sc_invalid) { /* * Beware of being called during attach/detach * to reset promiscuous mode. In that case we @@ -6722,26 +6581,40 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * torn down much of our state. There's * probably a better way to deal with this. */ - if (!sc->sc_invalid) - ath_init(sc); /* XXX lose error */ - } else { - ATH_LOCK(sc); - ath_stop_locked(ifp); - if (!sc->sc_invalid) - ath_power_setpower(sc, HAL_PM_FULL_SLEEP); ATH_UNLOCK(sc); + ath_init(sc); /* XXX lose error */ + return; } - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGATHSTATS: + } else { + ath_stop_locked(sc); + if (!sc->sc_invalid) + ath_power_setpower(sc, HAL_PM_FULL_SLEEP); + } + ATH_UNLOCK(sc); +} + +static int +ath_ioctl(struct ieee80211com *ic, u_long cmd, void *data) +{ + struct ifreq *ifr = data; + struct ath_softc *sc = ic->ic_softc; + + switch (cmd) { + case SIOCGATHSTATS: { + struct ieee80211vap *vap; + struct ifnet *ifp; + const HAL_RATE_TABLE *rt; + /* NB: embed these numbers to get a consistent view */ - sc->sc_stats.ast_tx_packets = ifp->if_get_counter(ifp, - IFCOUNTER_OPACKETS); - sc->sc_stats.ast_rx_packets = ifp->if_get_counter(ifp, - IFCOUNTER_IPACKETS); + sc->sc_stats.ast_tx_packets = 0; + sc->sc_stats.ast_rx_packets = 0; + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + ifp = vap->iv_ifp; + sc->sc_stats.ast_tx_packets += ifp->if_get_counter(ifp, + IFCOUNTER_OPACKETS); + sc->sc_stats.ast_rx_packets += ifp->if_get_counter(ifp, + IFCOUNTER_IPACKETS); + } sc->sc_stats.ast_tx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgtxrssi); sc->sc_stats.ast_rx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgrssi); #ifdef IEEE80211_SUPPORT_TDMA @@ -6755,10 +6628,13 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sc->sc_stats.ast_tx_rate |= IEEE80211_RATE_MCS; return copyout(&sc->sc_stats, ifr->ifr_data, sizeof (sc->sc_stats)); + } case SIOCGATHAGSTATS: return copyout(&sc->sc_aggr_stats, ifr->ifr_data, sizeof (sc->sc_aggr_stats)); - case SIOCZATHSTATS: + case SIOCZATHSTATS: { + int error; + error = priv_check(curthread, PRIV_DRIVER); if (error == 0) { memset(&sc->sc_stats, 0, sizeof(sc->sc_stats)); @@ -6767,30 +6643,21 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) memset(&sc->sc_intr_stats, 0, sizeof(sc->sc_intr_stats)); } - break; + return (error); + } #ifdef ATH_DIAGAPI case SIOCGATHDIAG: - error = ath_ioctl_diag(sc, (struct ath_diag *) ifr); - break; + return (ath_ioctl_diag(sc, data)); case SIOCGATHPHYERR: - error = ath_ioctl_phyerr(sc,(struct ath_diag*) ifr); - break; + return (ath_ioctl_phyerr(sc, data)); #endif case SIOCGATHSPECTRAL: - error = ath_ioctl_spectral(sc,(struct ath_diag*) ifr); - break; + return (ath_ioctl_spectral(sc, data)); case SIOCGATHNODERATESTATS: - error = ath_ioctl_ratestats(sc, (struct ath_rateioctl *) ifr); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; + return (ath_ioctl_ratestats(sc, data)); default: - error = EINVAL; - break; + return (ENOTTY); } - return error; -#undef IS_RUNNING } /* @@ -6831,8 +6698,7 @@ static void ath_dfs_tasklet(void *p, int npending) { struct ath_softc *sc = (struct ath_softc *) p; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* * If previous processing has found a radar event, @@ -6864,7 +6730,7 @@ ath_node_powersave(struct ieee80211_node *ni, int enable) #ifdef ATH_SW_PSQ struct ath_node *an = ATH_NODE(ni); struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_vap *avp = ATH_VAP(ni->ni_vap); /* XXX and no TXQ locks should be held here */ @@ -6931,7 +6797,7 @@ ath_node_set_tim(struct ieee80211_node *ni, int enable) { #ifdef ATH_SW_PSQ struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_node *an = ATH_NODE(ni); struct ath_vap *avp = ATH_VAP(ni->ni_vap); int changed = 0; @@ -7136,7 +7002,7 @@ ath_node_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m) struct ath_node *an; struct ath_vap *avp; struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; int tid; /* Just paranoia */ diff --git a/sys/dev/ath/if_ath_beacon.c b/sys/dev/ath/if_ath_beacon.c index a672c71336f5..41267b31f885 100644 --- a/sys/dev/ath/if_ath_beacon.c +++ b/sys/dev/ath/if_ath_beacon.c @@ -134,7 +134,7 @@ int ath_beaconq_config(struct ath_softc *sc) { #define ATH_EXPONENT_TO_VALUE(v) ((1<<(v))-1) - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; HAL_TXQ_INFO qi; @@ -464,7 +464,7 @@ ath_beacon_proc(void *arg, int pending) } if (sc->sc_stagbeacons) { /* staggered beacons */ - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tsftu; tsftu = ath_hal_gettsf32(ah) >> 10; @@ -917,7 +917,7 @@ ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap) ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10)) #define FUDGE 2 struct ath_hal *ah = sc->sc_ah; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; u_int32_t nexttbtt, intval, tsftu; u_int32_t nexttbtt_u8, intval_u8; diff --git a/sys/dev/ath/if_ath_debug.h b/sys/dev/ath/if_ath_debug.h index 40c0b9a5ac74..05d3cf5b12ed 100644 --- a/sys/dev/ath/if_ath_debug.h +++ b/sys/dev/ath/if_ath_debug.h @@ -91,9 +91,7 @@ enum { extern uint64_t ath_debug; -#define IFF_DUMPPKTS(sc, m) \ - ((sc->sc_debug & (m)) || \ - (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) +#define IFF_DUMPPKTS(sc, m) ((sc->sc_debug & (m)) #define DPRINTF(sc, m, fmt, ...) do { \ if (sc->sc_debug & (m)) \ device_printf(sc->sc_dev, fmt, __VA_ARGS__); \ @@ -112,8 +110,7 @@ extern void ath_printtxstatbuf(struct ath_softc *sc, const struct ath_buf *bf, #else /* ATH_DEBUG */ #define ATH_KTR(_sc, _km, _kf, ...) do { } while (0) -#define IFF_DUMPPKTS(sc, m) \ - ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) +#define IFF_DUMPPKTS(sc, m) (0) #define DPRINTF(sc, m, fmt, ...) do { \ (void) sc; \ } while (0) diff --git a/sys/dev/ath/if_ath_keycache.c b/sys/dev/ath/if_ath_keycache.c index fe99f106ac50..b8a77e89343a 100644 --- a/sys/dev/ath/if_ath_keycache.c +++ b/sys/dev/ath/if_ath_keycache.c @@ -425,7 +425,7 @@ int ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { - struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; /* * Group key allocation must be handled specially for @@ -493,7 +493,7 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, int ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) { - struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; struct ath_hal *ah = sc->sc_ah; const struct ieee80211_cipher *cip = k->wk_cipher; u_int keyix = k->wk_keyix; @@ -538,7 +538,7 @@ int ath_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, const u_int8_t mac[IEEE80211_ADDR_LEN]) { - struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; return ath_keyset(sc, vap, k, vap->iv_bss); } diff --git a/sys/dev/ath/if_ath_misc.h b/sys/dev/ath/if_ath_misc.h index 711e69e87ba5..ff9a4db0eb7d 100644 --- a/sys/dev/ath/if_ath_misc.h +++ b/sys/dev/ath/if_ath_misc.h @@ -65,7 +65,7 @@ extern void ath_freebuf(struct ath_softc *sc, struct ath_buf *bf); extern void ath_returnbuf_head(struct ath_softc *sc, struct ath_buf *bf); extern void ath_returnbuf_tail(struct ath_softc *sc, struct ath_buf *bf); -extern int ath_reset(struct ifnet *, ATH_RESET_TYPE); +extern int ath_reset(struct ath_softc *, ATH_RESET_TYPE); extern void ath_tx_default_comp(struct ath_softc *sc, struct ath_buf *bf, int fail); extern void ath_tx_update_ratectrl(struct ath_softc *sc, diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c index 2779b7a59053..600d0a58d1da 100644 --- a/sys/dev/ath/if_ath_rx.c +++ b/sys/dev/ath/if_ath_rx.c @@ -154,8 +154,7 @@ __FBSDID("$FreeBSD$"); u_int32_t ath_calcrxfilter(struct ath_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; u_int32_t rfilt; rfilt = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST; @@ -164,7 +163,7 @@ ath_calcrxfilter(struct ath_softc *sc) if (ic->ic_opmode != IEEE80211_M_STA) rfilt |= HAL_RX_FILTER_PROBEREQ; /* XXX ic->ic_monvaps != 0? */ - if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC)) + if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_promisc > 0) rfilt |= HAL_RX_FILTER_PROM; /* @@ -330,7 +329,7 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; - struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_softc; uint64_t tsf_beacon_old, tsf_beacon; uint64_t nexttbtt; int64_t tsf_delta; @@ -463,10 +462,9 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, #ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT static void -ath_rx_tap_vendor(struct ifnet *ifp, struct mbuf *m, +ath_rx_tap_vendor(struct ath_softc *sc, struct mbuf *m, const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf) { - struct ath_softc *sc = ifp->if_softc; /* Fill in the extension bitmap */ sc->sc_rx_th.wr_ext_bitmap = htole32(1 << ATH_RADIOTAP_VENDOR_HEADER); @@ -529,14 +527,13 @@ ath_rx_tap_vendor(struct ifnet *ifp, struct mbuf *m, #endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */ static void -ath_rx_tap(struct ifnet *ifp, struct mbuf *m, +ath_rx_tap(struct ath_softc *sc, struct mbuf *m, const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf) { #define CHAN_HT20 htole32(IEEE80211_CHAN_HT20) #define CHAN_HT40U htole32(IEEE80211_CHAN_HT40U) #define CHAN_HT40D htole32(IEEE80211_CHAN_HT40D) #define CHAN_HT (CHAN_HT20|CHAN_HT40U|CHAN_HT40D) - struct ath_softc *sc = ifp->if_softc; const HAL_RATE_TABLE *rt; uint8_t rix; @@ -560,7 +557,7 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m, else if (IEEE80211_IS_CHAN_HT20(sc->sc_curchan)) sc->sc_rx_th.wr_chan_flags |= CHAN_HT20; } else if (sc->sc_rx_th.wr_rate & IEEE80211_RATE_MCS) { /* HT rate */ - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; if ((rs->rs_flags & HAL_RX_2040) == 0) sc->sc_rx_th.wr_chan_flags |= CHAN_HT20; @@ -617,8 +614,7 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, { uint64_t rstamp; int len, type; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; int is_good = 0; struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; @@ -704,7 +700,7 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, rs->rs_keyix-32 : rs->rs_keyix); } } - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); rx_error: /* * Cleanup any pending partial frame. @@ -724,9 +720,9 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, /* NB: bpf needs the mbuf length setup */ len = rs->rs_datalen; m->m_pkthdr.len = m->m_len = len; - ath_rx_tap(ifp, m, rs, rstamp, nf); + ath_rx_tap(sc, m, rs, rstamp, nf); #ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT - ath_rx_tap_vendor(ifp, m, rs, rstamp, nf); + ath_rx_tap_vendor(sc, m, rs, rstamp, nf); #endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */ ieee80211_radiotap_rx_all(ic, m); } @@ -749,7 +745,6 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, sc->sc_stats.ast_rx_toobig++; m_freem(re->m_rxpending); } - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = len; re->m_rxpending = m; m = NULL; @@ -766,10 +761,8 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, re->m_rxpending = NULL; } else { /* - * Normal single-descriptor receive; setup - * the rcvif and packet length. + * Normal single-descriptor receive; setup packet length. */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = len; } @@ -830,7 +823,6 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, rs->rs_antenna |= 0x4; } - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); sc->sc_stats.ast_ant_rx[rs->rs_antenna]++; /* @@ -841,9 +833,9 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, * noise setting is filled in above. */ if (ieee80211_radiotap_active(ic)) { - ath_rx_tap(ifp, m, rs, rstamp, nf); + ath_rx_tap(sc, m, rs, rstamp, nf); #ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT - ath_rx_tap_vendor(ifp, m, rs, rstamp, nf); + ath_rx_tap_vendor(sc, m, rs, rstamp, nf); #endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */ } @@ -991,10 +983,9 @@ ath_rx_proc(struct ath_softc *sc, int resched) ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) struct ath_buf *bf; - struct ifnet *ifp = sc->sc_ifp; struct ath_hal *ah = sc->sc_ah; #ifdef IEEE80211_SUPPORT_SUPERG - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; #endif struct ath_desc *ds; struct ath_rx_status *rs; @@ -1189,15 +1180,10 @@ ath_rx_proc(struct ath_softc *sc, int resched) ATH_PCU_UNLOCK(sc); } - /* XXX check this inside of IF_LOCK? */ - if (resched && (ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { #ifdef IEEE80211_SUPPORT_SUPERG + if (resched) ieee80211_ff_age_all(ic, 100); #endif - if (!IFQ_IS_EMPTY(&ifp->if_snd)) - ath_tx_kick(sc); - } -#undef PA2DESC /* * Put the hardware to sleep again if we're done with it. @@ -1219,7 +1205,7 @@ ath_rx_proc(struct ath_softc *sc, int resched) sc->sc_rxproc_cnt--; ATH_PCU_UNLOCK(sc); } - +#undef PA2DESC #undef ATH_RX_MAX /* diff --git a/sys/dev/ath/if_ath_rx_edma.c b/sys/dev/ath/if_ath_rx_edma.c index 7aa818fe02aa..c3e8d3ab9492 100644 --- a/sys/dev/ath/if_ath_rx_edma.c +++ b/sys/dev/ath/if_ath_rx_edma.c @@ -579,9 +579,8 @@ static void ath_edma_recv_tasklet(void *arg, int npending) { struct ath_softc *sc = (struct ath_softc *) arg; - struct ifnet *ifp = sc->sc_ifp; #ifdef IEEE80211_SUPPORT_SUPERG - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; #endif DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called; npending=%d\n", @@ -617,14 +616,9 @@ ath_edma_recv_tasklet(void *arg, int npending) ath_power_restore_power_state(sc); ATH_UNLOCK(sc); - /* XXX inside IF_LOCK ? */ - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { #ifdef IEEE80211_SUPPORT_SUPERG - ieee80211_ff_age_all(ic, 100); + ieee80211_ff_age_all(ic, 100); #endif - if (! IFQ_IS_EMPTY(&ifp->if_snd)) - ath_tx_kick(sc); - } if (ath_dfs_tasklet_needed(sc, sc->sc_curchan)) taskqueue_enqueue(sc->sc_tq, &sc->sc_dfstask); diff --git a/sys/dev/ath/if_ath_sysctl.c b/sys/dev/ath/if_ath_sysctl.c index eeb8d4b8400a..d8c6bac78e92 100644 --- a/sys/dev/ath/if_ath_sysctl.c +++ b/sys/dev/ath/if_ath_sysctl.c @@ -367,7 +367,6 @@ static int ath_sysctl_tpscale(SYSCTL_HANDLER_ARGS) { struct ath_softc *sc = arg1; - struct ifnet *ifp = sc->sc_ifp; u_int32_t scale; int error; @@ -381,8 +380,7 @@ ath_sysctl_tpscale(SYSCTL_HANDLER_ARGS) goto finish; error = !ath_hal_settpscale(sc->sc_ah, scale) ? EINVAL : - (ifp->if_drv_flags & IFF_DRV_RUNNING) ? - ath_reset(ifp, ATH_RESET_NOLOSS) : 0; + (sc->sc_running) ? ath_reset(sc, ATH_RESET_NOLOSS) : 0; finish: ATH_LOCK(sc); @@ -422,7 +420,6 @@ static int ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS) { struct ath_softc *sc = arg1; - struct ifnet *ifp = sc->sc_ifp; struct ath_hal *ah = sc->sc_ah; u_int rfkill; int error; @@ -444,8 +441,7 @@ ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS) error = EINVAL; goto finish; } - error = (ifp->if_drv_flags & IFF_DRV_RUNNING) ? - ath_reset(ifp, ATH_RESET_FULL) : 0; + error = sc->sc_running ? ath_reset(sc, ATH_RESET_FULL) : 0; finish: ATH_LOCK(sc); @@ -671,8 +667,8 @@ ath_sysctl_intmit(SYSCTL_HANDLER_ARGS) * doesn't reset ANI related registers, so it'll leave * things in an inconsistent state. */ - if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) - ath_reset(sc->sc_ifp, ATH_RESET_NOLOSS); + if (sc->sc_running) + ath_reset(sc, ATH_RESET_NOLOSS); error = 0; diff --git a/sys/dev/ath/if_ath_tdma.c b/sys/dev/ath/if_ath_tdma.c index fd23db1977da..d4c9ccd20aad 100644 --- a/sys/dev/ath/if_ath_tdma.c +++ b/sys/dev/ath/if_ath_tdma.c @@ -359,7 +359,7 @@ ath_tdma_update(struct ieee80211_node *ni, #define TU_TO_TSF(_tu) (((u_int64_t)(_tu)) << 10) struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_hal *ah = sc->sc_ah; const HAL_RATE_TABLE *rt = sc->sc_currates; u_int64_t tsf, rstamp, nextslot, nexttbtt, nexttbtt_full; diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c index c15b1583761a..bee632001480 100644 --- a/sys/dev/ath/if_ath_tx.c +++ b/sys/dev/ath/if_ath_tx.c @@ -1051,8 +1051,7 @@ ath_tx_calc_protection(struct ath_softc *sc, struct ath_buf *bf) uint16_t flags; int shortPreamble; const HAL_RATE_TABLE *rt = sc->sc_currates; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; flags = bf->bf_state.bfs_txflags; rix = bf->bf_state.bfs_rc[0].rix; @@ -1545,8 +1544,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni, { struct ieee80211vap *vap = ni->ni_vap; struct ath_hal *ah = sc->sc_ah; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams; int error, iswep, ismcast, isfrag, ismrr; int keyix, hdrlen, pktlen, try0 = 0; @@ -2074,8 +2072,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; struct ieee80211vap *vap = ni->ni_vap; int error, ismcast, ismrr; @@ -2340,8 +2337,7 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ath_softc *sc = ic->ic_softc; struct ath_buf *bf; struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); int error = 0; @@ -2364,10 +2360,9 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, ATH_TX_LOCK(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) { - DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, %s", __func__, - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ? - "!running" : "invalid"); + if (!sc->sc_running || sc->sc_invalid) { + DPRINTF(sc, ATH_DEBUG_XMIT, "%s: discard frame, r/i: %d/%d", + __func__, sc->sc_running, sc->sc_invalid); m_freem(m); error = ENETDOWN; goto bad; @@ -2424,7 +2419,6 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, } } sc->sc_wd_timer = 5; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); sc->sc_stats.ast_tx_raw++; /* @@ -2473,7 +2467,6 @@ ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, badbad: ATH_KTR(sc, ATH_KTR_TX, 2, "ath_raw_xmit: bad0: m=%p, params=%p", m, params); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); sc->sc_stats.ast_tx_raw_fail++; ieee80211_free_node(ni); @@ -5731,7 +5724,7 @@ int ath_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int dialogtoken, int baparamset, int batimeout) { - struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct ath_softc *sc = ni->ni_ic->ic_softc; int tid = tap->txa_tid; struct ath_node *an = ATH_NODE(ni); struct ath_tid *atid = &an->an_tid[tid]; @@ -5809,7 +5802,7 @@ int ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int status, int code, int batimeout) { - struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct ath_softc *sc = ni->ni_ic->ic_softc; int tid = tap->txa_tid; struct ath_node *an = ATH_NODE(ni); struct ath_tid *atid = &an->an_tid[tid]; @@ -5856,7 +5849,7 @@ ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, void ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) { - struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct ath_softc *sc = ni->ni_ic->ic_softc; int tid = tap->txa_tid; struct ath_node *an = ATH_NODE(ni); struct ath_tid *atid = &an->an_tid[tid]; @@ -5991,7 +5984,7 @@ void ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int status) { - struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct ath_softc *sc = ni->ni_ic->ic_softc; int tid = tap->txa_tid; struct ath_node *an = ATH_NODE(ni); struct ath_tid *atid = &an->an_tid[tid]; @@ -6064,7 +6057,7 @@ void ath_addba_response_timeout(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) { - struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct ath_softc *sc = ni->ni_ic->ic_softc; int tid = tap->txa_tid; struct ath_node *an = ATH_NODE(ni); struct ath_tid *atid = &an->an_tid[tid]; diff --git a/sys/dev/ath/if_ath_tx_edma.c b/sys/dev/ath/if_ath_tx_edma.c index 7d149203d3ed..fdc2b4beb3c8 100644 --- a/sys/dev/ath/if_ath_tx_edma.c +++ b/sys/dev/ath/if_ath_tx_edma.c @@ -537,7 +537,6 @@ ath_edma_dma_txteardown(struct ath_softc *sc) static void ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type) { - struct ifnet *ifp = sc->sc_ifp; int i; DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__); @@ -579,9 +578,6 @@ ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type) /* XXX dump out the frames */ - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); sc->sc_wd_timer = 0; } @@ -834,12 +830,6 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched) sc->sc_wd_timer = 0; - if (idx > 0) { - IF_LOCK(&sc->sc_ifp->if_snd); - sc->sc_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&sc->sc_ifp->if_snd); - } - /* Kick software scheduler */ /* * XXX It's inefficient to do this if the FIFO queue is full, diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 5c5e6cd3d287..2e71ff6374d4 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -555,8 +555,8 @@ struct ath_tx_methods { }; struct ath_softc { - struct ifnet *sc_ifp; /* interface common */ - struct ath_stats sc_stats; /* interface statistics */ + struct ieee80211com sc_ic; + struct ath_stats sc_stats; /* device statistics */ struct ath_tx_aggr_stats sc_aggr_stats; struct ath_intr_stats sc_intr_stats; uint64_t sc_debug; @@ -650,7 +650,8 @@ struct ath_softc { /* * Second set of flags. */ - u_int32_t sc_use_ent : 1, + u_int32_t sc_running : 1, /* initialized */ + sc_use_ent : 1, sc_rx_stbc : 1, sc_tx_stbc : 1, sc_hasenforcetxop : 1, /* support enforce TxOP */ diff --git a/sys/dev/bwi/bwimac.c b/sys/dev/bwi/bwimac.c index f39ef44d4174..baad7fef550f 100644 --- a/sys/dev/bwi/bwimac.c +++ b/sys/dev/bwi/bwimac.c @@ -832,11 +832,11 @@ bwi_fwimage_is_valid(struct bwi_softc *sc, const struct firmware *fw, uint8_t fw_type) { const struct bwi_fwhdr *hdr; - struct ifnet *ifp = sc->sc_ifp; if (fw->datasize < sizeof(*hdr)) { - if_printf(ifp, "invalid firmware (%s): invalid size %zu\n", - fw->name, fw->datasize); + device_printf(sc->sc_dev, + "invalid firmware (%s): invalid size %zu\n", + fw->name, fw->datasize); return 0; } @@ -847,25 +847,26 @@ bwi_fwimage_is_valid(struct bwi_softc *sc, const struct firmware *fw, * Don't verify IV's size, it has different meaning */ if (be32toh(hdr->fw_size) != fw->datasize - sizeof(*hdr)) { - if_printf(ifp, "invalid firmware (%s): size mismatch, " - "fw %u, real %zu\n", fw->name, - be32toh(hdr->fw_size), - fw->datasize - sizeof(*hdr)); + device_printf(sc->sc_dev, + "invalid firmware (%s): size mismatch, " + "fw %u, real %zu\n", fw->name, + be32toh(hdr->fw_size), fw->datasize - sizeof(*hdr)); return 0; } } if (hdr->fw_type != fw_type) { - if_printf(ifp, "invalid firmware (%s): type mismatch, " - "fw \'%c\', target \'%c\'\n", fw->name, - hdr->fw_type, fw_type); + device_printf(sc->sc_dev, + "invalid firmware (%s): type mismatch, " + "fw \'%c\', target \'%c\'\n", fw->name, + hdr->fw_type, fw_type); return 0; } if (hdr->fw_gen != BWI_FW_GEN_1) { - if_printf(ifp, "invalid firmware (%s): wrong generation, " - "fw %d, target %d\n", fw->name, - hdr->fw_gen, BWI_FW_GEN_1); + device_printf(sc->sc_dev, + "invalid firmware (%s): wrong generation, " + "fw %d, target %d\n", fw->name, hdr->fw_gen, BWI_FW_GEN_1); return 0; } return 1; @@ -1002,7 +1003,6 @@ static int bwi_mac_fw_load(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; const uint32_t *fw; uint16_t fw_rev; int fw_len, i; @@ -1057,7 +1057,8 @@ bwi_mac_fw_load(struct bwi_mac *mac) DELAY(10); } if (i == NRETRY) { - if_printf(ifp, "firmware (ucode&pcm) loading timed out\n"); + device_printf(sc->sc_dev, + "firmware (ucode&pcm) loading timed out\n"); return ETIMEDOUT; } @@ -1067,12 +1068,14 @@ bwi_mac_fw_load(struct bwi_mac *mac) fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV); if (fw_rev > BWI_FW_VERSION3_REVMAX) { - if_printf(ifp, "firmware version 4 is not supported yet\n"); + device_printf(sc->sc_dev, + "firmware version 4 is not supported yet\n"); return ENODEV; } - if_printf(ifp, "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev, - MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV)); + device_printf(sc->sc_dev, + "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev, + MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV)); return 0; } @@ -1132,7 +1135,6 @@ static int bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; const struct bwi_fwhdr *hdr; const struct bwi_fw_iv *iv; int n, i, iv_img_size; @@ -1155,7 +1157,7 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) int sz = 0; if (iv_img_size < sizeof(iv->iv_ofs)) { - if_printf(ifp, "invalid IV image, ofs\n"); + device_printf(sc->sc_dev, "invalid IV image, ofs\n"); return EINVAL; } iv_img_size -= sizeof(iv->iv_ofs); @@ -1165,7 +1167,7 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK); if (ofs >= 0x1000) { - if_printf(ifp, "invalid ofs (0x%04x) " + device_printf(sc->sc_dev, "invalid ofs (0x%04x) " "for %dth iv\n", ofs, i); return EINVAL; } @@ -1174,7 +1176,8 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) uint32_t val32; if (iv_img_size < sizeof(iv->iv_val.val32)) { - if_printf(ifp, "invalid IV image, val32\n"); + device_printf(sc->sc_dev, + "invalid IV image, val32\n"); return EINVAL; } iv_img_size -= sizeof(iv->iv_val.val32); @@ -1186,7 +1189,8 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) uint16_t val16; if (iv_img_size < sizeof(iv->iv_val.val16)) { - if_printf(ifp, "invalid IV image, val16\n"); + device_printf(sc->sc_dev, + "invalid IV image, val16\n"); return EINVAL; } iv_img_size -= sizeof(iv->iv_val.val16); @@ -1200,7 +1204,8 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) } if (iv_img_size != 0) { - if_printf(ifp, "invalid IV image, size left %d\n", iv_img_size); + device_printf(sc->sc_dev, "invalid IV image, size left %d\n", + iv_img_size); return EINVAL; } return 0; @@ -1209,19 +1214,19 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) static int bwi_mac_fw_init(struct bwi_mac *mac) { - struct ifnet *ifp = mac->mac_sc->sc_ifp; + device_t dev = mac->mac_sc->sc_dev; int error; error = bwi_mac_fw_load_iv(mac, mac->mac_iv); if (error) { - if_printf(ifp, "load IV failed\n"); + device_printf(dev, "load IV failed\n"); return error; } if (mac->mac_iv_ext != NULL) { error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext); if (error) - if_printf(ifp, "load ExtIV failed\n"); + device_printf(dev, "load ExtIV failed\n"); } return error; } @@ -1230,8 +1235,7 @@ static void bwi_mac_opmode_init(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t mac_status; uint16_t pre_tbtt; @@ -1280,7 +1284,7 @@ bwi_mac_opmode_init(struct bwi_mac *mac) break; } - if (ic->ic_ifp->if_flags & IFF_PROMISC) + if (ic->ic_promisc > 0) mac_status |= BWI_MAC_STATUS_PROMISC; CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status); @@ -1331,8 +1335,7 @@ bwi_mac_bss_param_init(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; struct bwi_phy *phy = &mac->mac_phy; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct ieee80211_rate_table *rt; struct bwi_retry_lim lim; uint16_t cw_min; @@ -1915,8 +1918,7 @@ static void bwi_mac_lock(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0, ("mac_flags 0x%x", mac->mac_flags)); @@ -1939,8 +1941,7 @@ static void bwi_mac_unlock(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED, ("mac_flags 0x%x", mac->mac_flags)); diff --git a/sys/dev/bwi/bwiphy.c b/sys/dev/bwi/bwiphy.c index 1057a83dcb9a..60d6bf569baf 100644 --- a/sys/dev/bwi/bwiphy.c +++ b/sys/dev/bwi/bwiphy.c @@ -429,7 +429,7 @@ static void bwi_phy_init_11b_rev2(struct bwi_mac *mac) { /* TODO:11B */ - if_printf(mac->mac_sc->sc_ifp, + device_printf(mac->mac_sc->sc_dev, "%s is not implemented yet\n", __func__); } diff --git a/sys/dev/bwi/bwirf.c b/sys/dev/bwi/bwirf.c index cd0723a6a3d8..615e6dff6902 100644 --- a/sys/dev/bwi/bwirf.c +++ b/sys/dev/bwi/bwirf.c @@ -1260,7 +1260,6 @@ static void bwi_rf_lo_update_11g(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; struct bwi_rf *rf = &mac->mac_rf; struct bwi_phy *phy = &mac->mac_phy; struct bwi_tpctl *tpctl = &mac->mac_tpctl; @@ -1329,7 +1328,7 @@ bwi_rf_lo_update_11g(struct bwi_mac *mac) PHY_WRITE(mac, 0x812, 0xb2); } - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & BWI_F_RUNNING) == 0) tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac); PHY_WRITE(mac, 0x80f, 0x8078); @@ -1352,7 +1351,7 @@ bwi_rf_lo_update_11g(struct bwi_mac *mac) PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0); } - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & BWI_F_RUNNING) == 0) tpctl = NULL; bwi_rf_lo_adjust(mac, tpctl); @@ -1462,7 +1461,7 @@ _bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a) static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 }; - struct ifnet *ifp = mac->mac_sc->sc_ifp; + struct bwi_softc *sc = mac->mac_sc; struct bwi_rf_lo lo_save, *lo; uint8_t devi_ctrl = 0; int idx, adj_rf7a = 0; @@ -1476,7 +1475,7 @@ _bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a) for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) { uint16_t tp_ctrl2, rf7a; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((sc->sc_flags & BWI_F_RUNNING) == 0) { if (idx == 0) { bzero(&lo_save, sizeof(lo_save)); } else if (init_rf_atten < 0) { diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c index ad41bc675447..741f5f1d922b 100644 --- a/sys/dev/bwi/if_bwi.c +++ b/sys/dev/bwi/if_bwi.c @@ -102,10 +102,10 @@ static struct ieee80211vap *bwi_vap_create(struct ieee80211com *, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void bwi_vap_delete(struct ieee80211vap *); -static void bwi_init(void *); -static int bwi_ioctl(struct ifnet *, u_long, caddr_t); -static void bwi_start(struct ifnet *); -static void bwi_start_locked(struct ifnet *); +static void bwi_init(struct bwi_softc *); +static void bwi_parent(struct ieee80211com *); +static int bwi_transmit(struct ieee80211com *, struct mbuf *); +static void bwi_start_locked(struct bwi_softc *); static int bwi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void bwi_watchdog(void *); @@ -352,14 +352,12 @@ bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array, int bwi_attach(struct bwi_softc *sc) { - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; device_t dev = sc->sc_dev; - struct ifnet *ifp; struct bwi_mac *mac; struct bwi_phy *phy; int i, error; uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; BWI_LOCK_INIT(sc); @@ -371,8 +369,8 @@ bwi_attach(struct bwi_softc *sc) taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", device_get_nameunit(dev)); TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc); - callout_init_mtx(&sc->sc_calib_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* * Initialize sysctl variables @@ -450,25 +448,6 @@ bwi_attach(struct bwi_softc *sc) if (error) goto fail; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - error = ENOSPC; - goto fail; - } - ic = ifp->if_l2com; - - /* set these up early for if_printf use */ - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - - ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = bwi_init; - ifp->if_ioctl = bwi_ioctl; - ifp->if_start = bwi_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0); /* @@ -485,13 +464,13 @@ bwi_attach(struct bwi_softc *sc) setbit(&bands, IEEE80211_MODE_11G); } - bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, macaddr); - if (IEEE80211_IS_MULTICAST(macaddr)) { - bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, macaddr); - if (IEEE80211_IS_MULTICAST(macaddr)) { + bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_macaddr); + if (IEEE80211_IS_MULTICAST(ic->ic_macaddr)) { + bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_macaddr); + if (IEEE80211_IS_MULTICAST(ic->ic_macaddr)) { device_printf(dev, "invalid MAC address: %6D\n", - macaddr, ":"); + ic->ic_macaddr, ":"); } } } else if (phy->phy_mode == IEEE80211_MODE_11A) { @@ -510,7 +489,6 @@ bwi_attach(struct bwi_softc *sc) /* XXX use locale */ ieee80211_init_channels(ic, NULL, &bands); - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_caps = IEEE80211_C_STA | @@ -520,7 +498,7 @@ bwi_attach(struct bwi_softc *sc) IEEE80211_C_BGSCAN | IEEE80211_C_MONITOR; ic->ic_opmode = IEEE80211_M_STA; - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_headroom = sizeof(struct bwi_txbuf_hdr); @@ -532,6 +510,8 @@ bwi_attach(struct bwi_softc *sc) ic->ic_scan_start = bwi_scan_start; ic->ic_scan_end = bwi_scan_end; ic->ic_set_channel = bwi_set_channel; + ic->ic_transmit = bwi_transmit; + ic->ic_parent = bwi_parent; sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); @@ -577,8 +557,7 @@ bwi_attach(struct bwi_softc *sc) int bwi_detach(struct bwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int i; bwi_stop(sc, 1); @@ -590,8 +569,8 @@ bwi_detach(struct bwi_softc *sc) for (i = 0; i < sc->sc_nmac; ++i) bwi_mac_detach(&sc->sc_mac[i]); bwi_dma_free(sc); - if_free(ifp); taskqueue_free(sc->sc_tq); + mbufq_drain(&sc->sc_snd); BWI_LOCK_DESTROY(sc); @@ -609,14 +588,11 @@ bwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - bvp = (struct bwi_vap *) malloc(sizeof(struct bwi_vap), - M_80211_VAP, M_WAITOK | M_ZERO); - if (bvp == NULL) - return NULL; + bvp = malloc(sizeof(struct bwi_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &bvp->bv_vap; /* enable s/w bmiss handling for sta mode */ ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + flags | IEEE80211_CLONE_NOBEACONS, bssid); /* override default methods */ bvp->bv_newstate = vap->iv_newstate; @@ -627,7 +603,8 @@ bwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status, + mac); ic->ic_opmode = opmode; return vap; } @@ -651,9 +628,8 @@ bwi_suspend(struct bwi_softc *sc) void bwi_resume(struct bwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) + if (sc->sc_ic.ic_nrunning > 0) bwi_init(sc); } @@ -1217,27 +1193,26 @@ bwi_set_clock_delay(struct bwi_softc *sc) } static void -bwi_init(void *xsc) +bwi_init(struct bwi_softc *sc) { - struct bwi_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; BWI_LOCK(sc); bwi_init_statechg(sc, 1); BWI_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & BWI_F_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } static void bwi_init_statechg(struct bwi_softc *sc, int statechg) { - struct ifnet *ifp = sc->sc_ifp; struct bwi_mac *mac; int error; + BWI_ASSERT_LOCKED(sc); + bwi_stop_locked(sc, statechg); bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); @@ -1247,20 +1222,21 @@ bwi_init_statechg(struct bwi_softc *sc, int statechg) mac = &sc->sc_mac[0]; error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL); if (error) { - if_printf(ifp, "%s: error %d on regwin switch\n", + device_printf(sc->sc_dev, "%s: error %d on regwin switch\n", __func__, error); goto bad; } error = bwi_mac_init(mac); if (error) { - if_printf(ifp, "%s: error %d on MAC init\n", __func__, error); + device_printf(sc->sc_dev, "%s: error %d on MAC init\n", + __func__, error); goto bad; } bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN); bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */ - bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, IF_LLADDR(ifp)); + bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, sc->sc_ic.ic_macaddr); bwi_mac_reset_hwkeys(mac); @@ -1278,7 +1254,8 @@ bwi_init_statechg(struct bwi_softc *sc, int statechg) CSR_READ_4(sc, BWI_TXSTATUS1); } if (i == NRETRY) - if_printf(ifp, "%s: can't drain TX status\n", __func__); + device_printf(sc->sc_dev, + "%s: can't drain TX status\n", __func__); #undef NRETRY } @@ -1288,14 +1265,14 @@ bwi_init_statechg(struct bwi_softc *sc, int statechg) /* Start MAC */ error = bwi_mac_start(mac); if (error) { - if_printf(ifp, "%s: error %d starting MAC\n", __func__, error); + device_printf(sc->sc_dev, "%s: error %d starting MAC\n", + __func__, error); goto bad; } /* Clear stop flag before enabling interrupt */ sc->sc_flags &= ~BWI_F_STOP; - - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= BWI_F_RUNNING; callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc); /* Enable intrs */ @@ -1305,135 +1282,110 @@ bwi_init_statechg(struct bwi_softc *sc, int statechg) bwi_stop_locked(sc, 1); } -static int -bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ -#define IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct bwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; - - switch (cmd) { - case SIOCSIFFLAGS: - BWI_LOCK(sc); - if (IS_RUNNING(ifp)) { - struct bwi_mac *mac; - int promisc = -1; - - KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, - ("current regwin type %d", - sc->sc_cur_regwin->rw_type)); - mac = (struct bwi_mac *)sc->sc_cur_regwin; - - if ((ifp->if_flags & IFF_PROMISC) && - (sc->sc_flags & BWI_F_PROMISC) == 0) { - promisc = 1; - sc->sc_flags |= BWI_F_PROMISC; - } else if ((ifp->if_flags & IFF_PROMISC) == 0 && - (sc->sc_flags & BWI_F_PROMISC)) { - promisc = 0; - sc->sc_flags &= ~BWI_F_PROMISC; - } - - if (promisc >= 0) - bwi_mac_set_promisc(mac, promisc); - } - - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - bwi_init_statechg(sc, 1); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - bwi_stop_locked(sc, 1); - } - BWI_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; -#undef IS_RUNNING -} - static void -bwi_start(struct ifnet *ifp) +bwi_parent(struct ieee80211com *ic) { - struct bwi_softc *sc = ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; + int startall = 0; BWI_LOCK(sc); - bwi_start_locked(ifp); + if (ic->ic_nrunning > 0) { + struct bwi_mac *mac; + int promisc = -1; + + KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, + ("current regwin type %d", + sc->sc_cur_regwin->rw_type)); + mac = (struct bwi_mac *)sc->sc_cur_regwin; + + if (ic->ic_promisc > 0 && (sc->sc_flags & BWI_F_PROMISC) == 0) { + promisc = 1; + sc->sc_flags |= BWI_F_PROMISC; + } else if (ic->ic_promisc == 0 && + (sc->sc_flags & BWI_F_PROMISC) != 0) { + promisc = 0; + sc->sc_flags &= ~BWI_F_PROMISC; + } + + if (promisc >= 0) + bwi_mac_set_promisc(mac, promisc); + } + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & BWI_F_RUNNING) == 0) { + bwi_init_statechg(sc, 1); + startall = 1; + } + } else if (sc->sc_flags & BWI_F_RUNNING) + bwi_stop_locked(sc, 1); BWI_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); +} + +static int +bwi_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct bwi_softc *sc = ic->ic_softc; + int error; + + BWI_LOCK(sc); + if ((sc->sc_flags & BWI_F_RUNNING) == 0) { + BWI_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + BWI_UNLOCK(sc); + return (error); + } + bwi_start_locked(sc); + BWI_UNLOCK(sc); + return (0); } static void -bwi_start_locked(struct ifnet *ifp) +bwi_start_locked(struct bwi_softc *sc) { - struct bwi_softc *sc = ifp->if_softc; struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; struct ieee80211_frame *wh; struct ieee80211_node *ni; - struct ieee80211_key *k; struct mbuf *m; int trans, idx; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; + BWI_ASSERT_LOCKED(sc); trans = 0; idx = tbd->tbd_idx; - while (tbd->tbd_buf[idx].tb_mbuf == NULL) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ - if (m == NULL) - break; - + while (tbd->tbd_buf[idx].tb_mbuf == NULL && + tbd->tbd_used + BWI_TX_NSPRDESC < BWI_TX_NDESC && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; wh = mtod(m, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { - k = ieee80211_crypto_encap(ni, m); - if (k == NULL) { - ieee80211_free_node(ni); - m_freem(m); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - continue; - } - } - wh = NULL; /* Catch any invalid use */ - - if (bwi_encap(sc, idx, m, ni) != 0) { - /* 'm' is freed in bwi_encap() if we reach here */ - if (ni != NULL) - ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) != 0 && + ieee80211_crypto_encap(ni, m) == NULL) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); + ieee80211_free_node(ni); + m_freem(m); + continue; + } + if (bwi_encap(sc, idx, m, ni) != 0) { + /* 'm' is freed in bwi_encap() if we reach here */ + if (ni != NULL) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); + ieee80211_free_node(ni); + } else + counter_u64_add(sc->sc_ic.ic_oerrors, 1); continue; } - trans = 1; tbd->tbd_used++; idx = (idx + 1) % BWI_TX_NDESC; - - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - - if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } } - tbd->tbd_idx = idx; + tbd->tbd_idx = idx; if (trans) sc->sc_tx_timer = 5; } @@ -1443,13 +1395,12 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct bwi_softc *sc = ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; /* XXX wme? */ struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; int idx, error; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((sc->sc_flags & BWI_F_RUNNING) == 0) { ieee80211_free_node(ni); m_freem(m); return ENETDOWN; @@ -1472,16 +1423,12 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, error = bwi_encap_raw(sc, idx, m, ni, params); } if (error == 0) { - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - if (++tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + tbd->tbd_used++; tbd->tbd_idx = (idx + 1) % BWI_TX_NDESC; sc->sc_tx_timer = 5; - } else { + } else /* NB: m is reclaimed on encap failure */ ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - } BWI_UNLOCK(sc); return error; } @@ -1490,14 +1437,12 @@ static void bwi_watchdog(void *arg) { struct bwi_softc *sc; - struct ifnet *ifp; sc = arg; - ifp = sc->sc_ifp; BWI_ASSERT_LOCKED(sc); if (sc->sc_tx_timer != 0 && --sc->sc_tx_timer == 0) { - if_printf(ifp, "watchdog timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, "watchdog timeout\n"); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task); } callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc); @@ -1514,7 +1459,6 @@ bwi_stop(struct bwi_softc *sc, int statechg) static void bwi_stop_locked(struct bwi_softc *sc, int statechg) { - struct ifnet *ifp = sc->sc_ifp; struct bwi_mac *mac; int i, error, pwr_off = 0; @@ -1525,7 +1469,7 @@ bwi_stop_locked(struct bwi_softc *sc, int statechg) sc->sc_led_blinking = 0; sc->sc_flags |= BWI_F_STOP; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_flags & BWI_F_RUNNING) { KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, ("current regwin type %d", sc->sc_cur_regwin->rw_type)); mac = (struct bwi_mac *)sc->sc_cur_regwin; @@ -1557,14 +1501,13 @@ bwi_stop_locked(struct bwi_softc *sc, int statechg) sc->sc_tx_timer = 0; callout_stop(&sc->sc_watchdog_timer); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~BWI_F_RUNNING; } void bwi_intr(void *xsc) { struct bwi_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; struct bwi_mac *mac; uint32_t intr_status; uint32_t txrx_intr_status[BWI_TXRX_NRING]; @@ -1572,7 +1515,7 @@ bwi_intr(void *xsc) BWI_LOCK(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || + if ((sc->sc_flags & BWI_F_RUNNING) == 0 || (sc->sc_flags & BWI_F_STOP)) { BWI_UNLOCK(sc); return; @@ -1615,7 +1558,7 @@ bwi_intr(void *xsc) i, txrx_intr_status[i]); if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) { - if_printf(ifp, + device_printf(sc->sc_dev, "%s: intr fatal TX/RX (%d) error 0x%08x\n", __func__, i, txrx_intr_status[i]); txrx_error = 1; @@ -1653,7 +1596,8 @@ bwi_intr(void *xsc) */ if (intr_status & BWI_INTR_PHY_TXERR) { if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) { - if_printf(ifp, "%s: intr PHY TX error\n", __func__); + device_printf(sc->sc_dev, "%s: intr PHY TX error\n", + __func__); taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task); BWI_UNLOCK(sc); return; @@ -1668,7 +1612,7 @@ bwi_intr(void *xsc) bwi_mac_config_ps(mac); if (intr_status & BWI_INTR_EO_ATIM) - if_printf(ifp, "EO_ATIM\n"); + device_printf(sc->sc_dev, "EO_ATIM\n"); if (intr_status & BWI_INTR_PMQ) { for (;;) { @@ -1679,7 +1623,7 @@ bwi_intr(void *xsc) } if (intr_status & BWI_INTR_NOISE) - if_printf(ifp, "intr noise\n"); + device_printf(sc->sc_dev, "intr noise\n"); if (txrx_intr_status[0] & BWI_TXRX_INTR_RX) { rx_data = sc->sc_rxeof(sc); @@ -1728,7 +1672,7 @@ bwi_intr(void *xsc) static void bwi_scan_start(struct ieee80211com *ic) { - struct bwi_softc *sc = ic->ic_ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; BWI_LOCK(sc); /* Enable MAC beacon promiscuity */ @@ -1739,7 +1683,7 @@ bwi_scan_start(struct ieee80211com *ic) static void bwi_set_channel(struct ieee80211com *ic) { - struct bwi_softc *sc = ic->ic_ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; struct ieee80211_channel *c = ic->ic_curchan; struct bwi_mac *mac; @@ -1765,7 +1709,7 @@ bwi_set_channel(struct ieee80211com *ic) static void bwi_scan_end(struct ieee80211com *ic) { - struct bwi_softc *sc = ic->ic_ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; BWI_LOCK(sc); CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN); @@ -1777,9 +1721,8 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct bwi_vap *bvp = BWI_VAP(vap); struct ieee80211com *ic= vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; + struct bwi_softc *sc = ic->ic_softc; enum ieee80211_state ostate = vap->iv_state; - struct bwi_softc *sc = ifp->if_softc; struct bwi_mac *mac; int error; @@ -2625,8 +2568,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) { struct bwi_ring_data *rd = &sc->sc_rx_rdata; struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int idx, rx_data = 0; idx = rbd->rbd_idx; @@ -2645,7 +2587,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) BUS_DMASYNC_POSTREAD); if (bwi_newbuf(sc, idx, 0)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto next; } @@ -2659,9 +2601,10 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) buflen = le16toh(hdr->rxh_buflen); if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) { - if_printf(ifp, "%s: zero length data, hdr_extra %d\n", - __func__, hdr_extra); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + device_printf(sc->sc_dev, + "%s: zero length data, hdr_extra %d\n", + __func__, hdr_extra); + counter_u64_add(ic->ic_ierrors, 1); m_freem(m); goto next; } @@ -2670,7 +2613,6 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) rssi = bwi_calc_rssi(sc, hdr); noise = bwi_calc_noise(sc); - m->m_pkthdr.rcvif = ifp; m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); m_adj(m, sizeof(*hdr) + wh_ofs); @@ -2804,7 +2746,6 @@ bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx) { struct bwi_ring_data *rd; struct bwi_txbuf_data *tbd; - struct ifnet *ifp = sc->sc_ifp; uint32_t state, val; int i; @@ -2825,8 +2766,9 @@ bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx) DELAY(1000); } if (i == NRETRY) { - if_printf(ifp, "%s: wait for TX ring(%d) stable timed out\n", - __func__, ring_idx); + device_printf(sc->sc_dev, + "%s: wait for TX ring(%d) stable timed out\n", + __func__, ring_idx); } CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0); @@ -2839,7 +2781,7 @@ bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx) DELAY(1000); } if (i == NRETRY) - if_printf(ifp, "%s: reset TX ring (%d) timed out\n", + device_printf(sc->sc_dev, "%s: reset TX ring (%d) timed out\n", __func__, ring_idx); #undef NRETRY @@ -2947,8 +2889,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; @@ -3024,7 +2965,8 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, */ M_PREPEND(m, sizeof(*hdr), M_NOWAIT); if (m == NULL) { - if_printf(ifp, "%s: prepend TX header failed\n", __func__); + device_printf(sc->sc_dev, "%s: prepend TX header failed\n", + __func__); return ENOBUFS; } hdr = mtod(m, struct bwi_txbuf_hdr *); @@ -3073,7 +3015,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m, bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); if (error && error != EFBIG) { - if_printf(ifp, "%s: can't load TX buffer (1) %d\n", + device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", __func__, error); goto back; } @@ -3083,8 +3025,8 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, m_new = m_defrag(m, M_NOWAIT); if (m_new == NULL) { - if_printf(ifp, "%s: can't defrag TX buffer\n", - __func__); + device_printf(sc->sc_dev, + "%s: can't defrag TX buffer\n", __func__); error = ENOBUFS; goto back; } else { @@ -3095,7 +3037,8 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); if (error) { - if_printf(ifp, "%s: can't load TX buffer (2) %d\n", + device_printf(sc->sc_dev, + "%s: can't load TX buffer (2) %d\n", __func__, error); goto back; } @@ -3137,7 +3080,6 @@ static int bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; @@ -3204,7 +3146,8 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m, */ M_PREPEND(m, sizeof(*hdr), M_NOWAIT); if (m == NULL) { - if_printf(ifp, "%s: prepend TX header failed\n", __func__); + device_printf(sc->sc_dev, "%s: prepend TX header failed\n", + __func__); return ENOBUFS; } hdr = mtod(m, struct bwi_txbuf_hdr *); @@ -3252,14 +3195,15 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m, struct mbuf *m_new; if (error != EFBIG) { - if_printf(ifp, "%s: can't load TX buffer (1) %d\n", + device_printf(sc->sc_dev, + "%s: can't load TX buffer (1) %d\n", __func__, error); goto back; } m_new = m_defrag(m, M_NOWAIT); if (m_new == NULL) { - if_printf(ifp, "%s: can't defrag TX buffer\n", - __func__); + device_printf(sc->sc_dev, + "%s: can't defrag TX buffer\n", __func__); error = ENOBUFS; goto back; } @@ -3268,7 +3212,8 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m, bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); if (error) { - if_printf(ifp, "%s: can't load TX buffer (2) %d\n", + device_printf(sc->sc_dev, + "%s: can't load TX buffer (2) %d\n", __func__, error); goto back; } @@ -3312,7 +3257,6 @@ bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx) static void bwi_txeof_status32(struct bwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; uint32_t val, ctrl_base; int end_idx; @@ -3327,8 +3271,7 @@ bwi_txeof_status32(struct bwi_softc *sc) CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, end_idx * sizeof(struct bwi_desc32)); - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) - ifp->if_start(ifp); + bwi_start_locked(sc); } static void @@ -3340,7 +3283,6 @@ bwi_txeof_status64(struct bwi_softc *sc) static void _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt) { - struct ifnet *ifp = sc->sc_ifp; struct bwi_txbuf_data *tbd; struct bwi_txbuf *tb; int ring_idx, buf_idx; @@ -3348,7 +3290,7 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt) struct ieee80211vap *vap; if (tx_id == 0) { - if_printf(ifp, "%s: zero tx id\n", __func__); + device_printf(sc->sc_dev, "%s: zero tx id\n", __func__); return; } @@ -3369,8 +3311,7 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt) bus_dmamap_unload(sc->sc_buf_dtag, tb->tb_dmap); - ni = tb->tb_ni; - if (tb->tb_ni != NULL) { + if ((ni = tb->tb_ni) != NULL) { const struct bwi_txbuf_hdr *hdr = mtod(tb->tb_mbuf, const struct bwi_txbuf_hdr *); vap = ni->ni_vap; @@ -3388,24 +3329,14 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt) (data_txcnt > 1) ? IEEE80211_RATECTL_TX_SUCCESS : IEEE80211_RATECTL_TX_FAILURE, &acked, NULL); } - - /* - * Do any tx complete callback. Note this must - * be done before releasing the node reference. - */ - if (tb->tb_mbuf->m_flags & M_TXCB) - ieee80211_process_callback(ni, tb->tb_mbuf, !acked); - - ieee80211_free_node(tb->tb_ni); + ieee80211_tx_complete(ni, tb->tb_mbuf, !acked); tb->tb_ni = NULL; - } - m_freem(tb->tb_mbuf); + } else + m_freem(tb->tb_mbuf); tb->tb_mbuf = NULL; if (tbd->tbd_used == 0) sc->sc_tx_timer = 0; - - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void @@ -3437,7 +3368,6 @@ bwi_txeof_status(struct bwi_softc *sc, int end_idx) static void bwi_txeof(struct bwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; for (;;) { uint32_t tx_status0, tx_status1; @@ -3460,8 +3390,7 @@ bwi_txeof(struct bwi_softc *sc) data_txcnt); } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) - ifp->if_start(ifp); + bwi_start_locked(sc); } static int @@ -3709,7 +3638,6 @@ bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags) static void bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid) { - struct ifnet *ifp = sc->sc_ifp; struct bwi_mac *mac; struct bwi_myaddr_bssid buf; const uint8_t *p; @@ -3722,7 +3650,7 @@ bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid) bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid); - bcopy(IF_LLADDR(ifp), buf.myaddr, sizeof(buf.myaddr)); + bcopy(sc->sc_ic.ic_macaddr, buf.myaddr, sizeof(buf.myaddr)); bcopy(bssid, buf.bssid, sizeof(buf.bssid)); n = sizeof(buf) / sizeof(val); @@ -3745,7 +3673,7 @@ bwi_updateslot(struct ieee80211com *ic) struct bwi_mac *mac; BWI_LOCK(sc); - if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_flags & BWI_F_RUNNING) { DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__); KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, @@ -3761,16 +3689,12 @@ static void bwi_calibrate(void *xsc) { struct bwi_softc *sc = xsc; -#ifdef INVARIANTS - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; -#endif struct bwi_mac *mac; BWI_ASSERT_LOCKED(sc); - KASSERT(ic->ic_opmode != IEEE80211_M_MONITOR, - ("opmode %d", ic->ic_opmode)); + KASSERT(sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR, + ("opmode %d", sc->sc_ic.ic_opmode)); KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, ("current regwin type %d", sc->sc_cur_regwin->rw_type)); @@ -3912,8 +3836,7 @@ bwi_led_onoff(const struct bwi_led *led, uint16_t val, int on) static void bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t val; int i; @@ -3922,7 +3845,7 @@ bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate) sc->sc_led_blinking = 0; } - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & BWI_F_RUNNING) == 0) return; val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL); @@ -4050,13 +3973,12 @@ static void bwi_restart(void *xsc, int pending) { struct bwi_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - if_printf(ifp, "%s begin, help!\n", __func__); + device_printf(sc->sc_dev, "%s begin, help!\n", __func__); BWI_LOCK(sc); - bwi_init_statechg(xsc, 0); + bwi_init_statechg(sc, 0); #if 0 - bwi_start_locked(ifp); + bwi_start_locked(sc); #endif BWI_UNLOCK(sc); } diff --git a/sys/dev/bwi/if_bwivar.h b/sys/dev/bwi/if_bwivar.h index d5f09da6eb2f..07c20fef2b0c 100644 --- a/sys/dev/bwi/if_bwivar.h +++ b/sys/dev/bwi/if_bwivar.h @@ -541,10 +541,11 @@ struct bwi_vap { #define BWI_VAP(vap) ((struct bwi_vap *)(vap)) struct bwi_softc { - struct ifnet *sc_ifp; uint32_t sc_flags; /* BWI_F_ */ device_t sc_dev; struct mtx sc_mtx; + struct ieee80211com sc_ic; + struct mbufq sc_snd; int sc_invalid; uint32_t sc_cap; /* BWI_CAP_ */ @@ -647,6 +648,7 @@ struct bwi_softc { #define BWI_F_BUS_INITED 0x1 #define BWI_F_PROMISC 0x2 #define BWI_F_STOP 0x4 +#define BWI_F_RUNNING 0x8 #define BWI_DBG_MAC 0x00000001 #define BWI_DBG_RF 0x00000002 diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c index 39bd06fadae4..15f6f27a0a5a 100644 --- a/sys/dev/bwn/if_bwn.c +++ b/sys/dev/bwn/if_bwn.c @@ -133,13 +133,13 @@ static int bwn_wme = 1; SYSCTL_INT(_hw_bwn, OID_AUTO, wme, CTLFLAG_RW, &bwn_wme, 0, "uses WME support"); -static int bwn_attach_pre(struct bwn_softc *); +static void bwn_attach_pre(struct bwn_softc *); static int bwn_attach_post(struct bwn_softc *); static void bwn_sprom_bugfixes(device_t); -static void bwn_init(void *); -static int bwn_init_locked(struct bwn_softc *); -static int bwn_ioctl(struct ifnet *, u_long, caddr_t); -static void bwn_start(struct ifnet *); +static int bwn_init(struct bwn_softc *); +static void bwn_parent(struct ieee80211com *); +static void bwn_start(struct bwn_softc *); +static int bwn_transmit(struct ieee80211com *, struct mbuf *); static int bwn_attach_core(struct bwn_mac *); static void bwn_reset_core(struct bwn_mac *, uint32_t); static int bwn_phy_getinfo(struct bwn_mac *, int); @@ -197,8 +197,7 @@ static struct ieee80211vap *bwn_vap_create(struct ieee80211com *, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void bwn_vap_delete(struct ieee80211vap *); -static void bwn_stop(struct bwn_softc *, int); -static void bwn_stop_locked(struct bwn_softc *, int); +static void bwn_stop(struct bwn_softc *); static int bwn_core_init(struct bwn_mac *); static void bwn_core_start(struct bwn_mac *); static void bwn_core_exit(struct bwn_mac *); @@ -409,7 +408,6 @@ static void bwn_handle_txeof(struct bwn_mac *, const struct bwn_txstatus *); static void bwn_rxeof(struct bwn_mac *, struct mbuf *, const void *); static void bwn_phy_txpower_check(struct bwn_mac *, uint32_t); -static void bwn_start_locked(struct ifnet *); static int bwn_tx_start(struct bwn_softc *, struct ieee80211_node *, struct mbuf *); static int bwn_tx_isfull(struct bwn_softc *, struct mbuf *); @@ -930,9 +928,7 @@ bwn_attach(device_t dev) #endif if ((sc->sc_flags & BWN_FLAG_ATTACHED) == 0) { - error = bwn_attach_pre(sc); - if (error != 0) - return (error); + bwn_attach_pre(sc); bwn_sprom_bugfixes(dev); sc->sc_flags |= BWN_FLAG_ATTACHED; } @@ -947,10 +943,7 @@ bwn_attach(device_t dev) } } - mac = (struct bwn_mac *)malloc(sizeof(*mac), M_DEVBUF, - M_NOWAIT | M_ZERO); - if (mac == NULL) - return (ENOMEM); + mac = malloc(sizeof(*mac), M_DEVBUF, M_WAITOK | M_ZERO); mac->mac_sc = sc; mac->mac_status = BWN_MAC_STATUS_UNINIT; if (bwn_bfp != 0) @@ -1053,11 +1046,8 @@ bwn_is_valid_ether_addr(uint8_t *addr) static int bwn_attach_post(struct bwn_softc *sc) { - struct ieee80211com *ic; - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; - ic = ifp->if_l2com; - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(sc->sc_dev); /* XXX not right but it's not used anywhere important */ @@ -1077,12 +1067,14 @@ bwn_attach_post(struct bwn_softc *sc) ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ - /* call MI attach routine. */ - ieee80211_ifattach(ic, + IEEE80211_ADDR_COPY(ic->ic_macaddr, bwn_is_valid_ether_addr(siba_sprom_get_mac_80211a(sc->sc_dev)) ? siba_sprom_get_mac_80211a(sc->sc_dev) : siba_sprom_get_mac_80211bg(sc->sc_dev)); + /* call MI attach routine. */ + ieee80211_ifattach(ic); + ic->ic_headroom = sizeof(struct bwn_txhdr); /* override default methods */ @@ -1090,13 +1082,13 @@ bwn_attach_post(struct bwn_softc *sc) ic->ic_updateslot = bwn_updateslot; ic->ic_update_promisc = bwn_update_promisc; ic->ic_wme.wme_update = bwn_wme_update; - ic->ic_scan_start = bwn_scan_start; ic->ic_scan_end = bwn_scan_end; ic->ic_set_channel = bwn_set_channel; - ic->ic_vap_create = bwn_vap_create; ic->ic_vap_delete = bwn_vap_delete; + ic->ic_transmit = bwn_transmit; + ic->ic_parent = bwn_parent; ieee80211_radiotap_attach(ic, &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), @@ -1124,26 +1116,24 @@ bwn_detach(device_t dev) { struct bwn_softc *sc = device_get_softc(dev); struct bwn_mac *mac = sc->sc_curmac; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int i; sc->sc_flags |= BWN_FLAG_INVALID; if (device_is_attached(sc->sc_dev)) { - bwn_stop(sc, 1); + BWN_LOCK(sc); + bwn_stop(sc); + BWN_UNLOCK(sc); bwn_dma_free(mac); callout_drain(&sc->sc_led_blink_ch); callout_drain(&sc->sc_rfswitch_ch); callout_drain(&sc->sc_task_ch); callout_drain(&sc->sc_watchdog_ch); bwn_phy_detach(mac); - if (ifp != NULL) { - ieee80211_draintask(ic, &mac->mac_hwreset); - ieee80211_draintask(ic, &mac->mac_txpower); - ieee80211_ifdetach(ic); - if_free(ifp); - } + ieee80211_draintask(ic, &mac->mac_hwreset); + ieee80211_draintask(ic, &mac->mac_txpower); + ieee80211_ifdetach(ic); } taskqueue_drain(sc->sc_tq, &mac->mac_intrtask); taskqueue_free(sc->sc_tq); @@ -1158,52 +1148,25 @@ bwn_detach(device_t dev) bus_release_resources(dev, mac->mac_intr_spec, mac->mac_res_irq); if (mac->mac_msi != 0) pci_release_msi(dev); - + mbufq_drain(&sc->sc_snd); BWN_LOCK_DESTROY(sc); return (0); } -static int +static void bwn_attach_pre(struct bwn_softc *sc) { - struct ifnet *ifp; - int error = 0; BWN_LOCK_INIT(sc); TAILQ_INIT(&sc->sc_maclist); callout_init_mtx(&sc->sc_rfswitch_ch, &sc->sc_mtx, 0); callout_init_mtx(&sc->sc_task_ch, &sc->sc_mtx, 0); callout_init_mtx(&sc->sc_watchdog_ch, &sc->sc_mtx, 0); - + mbufq_init(&sc->sc_snd, ifqmaxlen); sc->sc_tq = taskqueue_create_fast("bwn_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->sc_tq); taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->sc_dev)); - - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - error = ENOSPC; - goto fail; - } - - /* set these up early for if_printf use */ - if_initname(ifp, device_get_name(sc->sc_dev), - device_get_unit(sc->sc_dev)); - - ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = bwn_init; - ifp->if_ioctl = bwn_ioctl; - ifp->if_start = bwn_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - return (0); - -fail: BWN_LOCK_DESTROY(sc); - return (error); } static void @@ -1238,58 +1201,51 @@ bwn_sprom_bugfixes(device_t dev) #undef BWN_ISDEV } -static int -bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ -#define IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct bwn_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0, startall; - - switch (cmd) { - case SIOCSIFFLAGS: - startall = 0; - if (IS_RUNNING(ifp)) { - bwn_update_promisc(ic); - } else if (ifp->if_flags & IFF_UP) { - if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) { - bwn_init(sc); - startall = 1; - } - } else - bwn_stop(sc, 1); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return (error); -} - static void -bwn_start(struct ifnet *ifp) +bwn_parent(struct ieee80211com *ic) { - struct bwn_softc *sc = ifp->if_softc; + struct bwn_softc *sc = ic->ic_softc; + int startall = 0; BWN_LOCK(sc); - bwn_start_locked(ifp); + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { + bwn_init(sc); + startall = 1; + } else + bwn_update_promisc(ic); + } else if (sc->sc_flags & BWN_FLAG_RUNNING) + bwn_stop(sc); BWN_UNLOCK(sc); + + if (startall) + ieee80211_start_all(ic); +} + +static int +bwn_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct bwn_softc *sc = ic->ic_softc; + int error; + + BWN_LOCK(sc); + if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) { + BWN_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + BWN_UNLOCK(sc); + return (error); + } + bwn_start(sc); + BWN_UNLOCK(sc); + return (0); } static void -bwn_start_locked(struct ifnet *ifp) +bwn_start(struct bwn_softc *sc) { - struct bwn_softc *sc = ifp->if_softc; struct bwn_mac *mac = sc->sc_curmac; struct ieee80211_frame *wh; struct ieee80211_node *ni; @@ -1298,44 +1254,40 @@ bwn_start_locked(struct ifnet *ifp) BWN_ASSERT_LOCKED(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || mac == NULL || + if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac == NULL || mac->mac_status < BWN_MAC_STATUS_STARTED) return; - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ - if (m == NULL) - break; - + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { if (bwn_tx_isfull(sc, m)) break; ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (ni == NULL) { device_printf(sc->sc_dev, "unexpected NULL ni\n"); m_freem(m); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); continue; } - KASSERT(ni != NULL, ("%s:%d: fail", __func__, __LINE__)); wh = mtod(m, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m); if (k == NULL) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); m_freem(m); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); continue; } } wh = NULL; /* Catch any invalid use */ - if (bwn_tx_start(sc, ni, m) != 0) { - if (ni != NULL) + if (ni != NULL) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + } continue; } - sc->sc_watchdog_timer = 5; } } @@ -1346,7 +1298,6 @@ bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) struct bwn_dma_ring *dr; struct bwn_mac *mac = sc->sc_curmac; struct bwn_pio_txqueue *tq; - struct ifnet *ifp = sc->sc_ifp; int pktlen = roundup(m->m_pkthdr.len + BWN_HDRSIZE(mac), 4); BWN_ASSERT_LOCKED(sc); @@ -1361,15 +1312,12 @@ bwn_tx_isfull(struct bwn_softc *sc, struct mbuf *m) } else { tq = bwn_pio_select(mac, M_WME_GETAC(m)); if (tq->tq_free == 0 || pktlen > tq->tq_size || - pktlen > (tq->tq_size - tq->tq_used)) { - tq->tq_stop = 1; + pktlen > (tq->tq_size - tq->tq_used)) goto full; - } } return (0); full: - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + mbufq_prepend(&sc->sc_snd, m); return (1); } @@ -1496,7 +1444,6 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) struct bwn_dmadesc_generic *desc; struct bwn_dmadesc_meta *mt; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; uint8_t *txhdr_cache = (uint8_t *)dr->dr_txhdr_cache; int error, slot, backup[2] = { dr->dr_curslot, dr->dr_usedslot }; @@ -1519,7 +1466,7 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) BWN_GET_TXHDRCACHE(slot), BWN_HDRSIZE(mac), bwn_dma_ring_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); if (error) { - if_printf(ifp, "%s: can't load TX buffer (1) %d\n", + device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", __func__, error); goto fail; } @@ -1539,7 +1486,7 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); if (error && error != EFBIG) { - if_printf(ifp, "%s: can't load TX buffer (1) %d\n", + device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", __func__, error); goto fail; } @@ -1548,7 +1495,8 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) m_new = m_defrag(m, M_NOWAIT); if (m_new == NULL) { - if_printf(ifp, "%s: can't defrag TX buffer\n", + device_printf(sc->sc_dev, + "%s: can't defrag TX buffer\n", __func__); error = ENOBUFS; goto fail; @@ -1560,7 +1508,8 @@ bwn_dma_tx_start(struct bwn_mac *mac, struct ieee80211_node *ni, struct mbuf *m) error = bus_dmamap_load_mbuf(dma->txbuf_dtag, mt->mt_dmap, m, bwn_dma_buf_addr, &mt->mt_paddr, BUS_DMA_NOWAIT); if (error) { - if_printf(ifp, "%s: can't load TX buffer (2) %d\n", + device_printf(sc->sc_dev, + "%s: can't load TX buffer (2) %d\n", __func__, error); goto fail; } @@ -1585,11 +1534,10 @@ static void bwn_watchdog(void *arg) { struct bwn_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; if (sc->sc_watchdog_timer != 0 && --sc->sc_watchdog_timer == 0) { - if_printf(ifp, "device timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, "device timeout\n"); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); } callout_schedule(&sc->sc_watchdog_ch, hz); } @@ -1860,8 +1808,7 @@ static int bwn_setup_channels(struct bwn_mac *mac, int have_bg, int have_a) { struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); ic->ic_nchans = 0; @@ -2735,11 +2682,10 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct bwn_softc *sc = ifp->if_softc; + struct bwn_softc *sc = ic->ic_softc; struct bwn_mac *mac = sc->sc_curmac; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || + if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 || mac->mac_status < BWN_MAC_STATUS_STARTED) { ieee80211_free_node(ni); m_freem(m); @@ -2750,7 +2696,6 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, if (bwn_tx_isfull(sc, m)) { ieee80211_free_node(ni); m_freem(m); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); BWN_UNLOCK(sc); return (ENOBUFS); } @@ -2758,7 +2703,6 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, if (bwn_tx_start(sc, ni, m) != 0) { if (ni != NULL) ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } sc->sc_watchdog_timer = 5; BWN_UNLOCK(sc); @@ -2778,7 +2722,7 @@ bwn_updateslot(struct ieee80211com *ic) struct bwn_mac *mac; BWN_LOCK(sc); - if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_flags & BWN_FLAG_RUNNING) { mac = (struct bwn_mac *)sc->sc_curmac; bwn_set_slot_time(mac, (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20); @@ -2802,7 +2746,7 @@ bwn_update_promisc(struct ieee80211com *ic) BWN_LOCK(sc); mac = sc->sc_curmac; if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) { - if (ic->ic_ifp->if_flags & IFF_PROMISC) + if (ic->ic_promisc > 0) sc->sc_filters |= BWN_MACCTL_PROMISC; else sc->sc_filters &= ~BWN_MACCTL_PROMISC; @@ -2817,7 +2761,7 @@ bwn_update_promisc(struct ieee80211com *ic) static int bwn_wme_update(struct ieee80211com *ic) { - struct bwn_softc *sc = ic->ic_ifp->if_softc; + struct bwn_softc *sc = ic->ic_softc; struct bwn_mac *mac = sc->sc_curmac; struct wmeParams *wmep; int i; @@ -2839,8 +2783,7 @@ bwn_wme_update(struct ieee80211com *ic) static void bwn_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct bwn_softc *sc = ifp->if_softc; + struct bwn_softc *sc = ic->ic_softc; struct bwn_mac *mac; BWN_LOCK(sc); @@ -2857,8 +2800,7 @@ bwn_scan_start(struct ieee80211com *ic) static void bwn_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct bwn_softc *sc = ifp->if_softc; + struct bwn_softc *sc = ic->ic_softc; struct bwn_mac *mac; BWN_LOCK(sc); @@ -2874,8 +2816,7 @@ bwn_scan_end(struct ieee80211com *ic) static void bwn_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct bwn_softc *sc = ifp->if_softc; + struct bwn_softc *sc = ic->ic_softc; struct bwn_mac *mac = sc->sc_curmac; struct bwn_phy *phy = &mac->mac_phy; int chan, error; @@ -2931,15 +2872,11 @@ static struct ieee80211vap * bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac0[IEEE80211_ADDR_LEN]) + const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; - struct bwn_softc *sc = ifp->if_softc; struct ieee80211vap *vap; struct bwn_vap *bvp; - uint8_t mac[IEEE80211_ADDR_LEN]; - IEEE80211_ADDR_COPY(mac, mac0); switch (opmode) { case IEEE80211_M_HOSTAP: case IEEE80211_M_MBSS: @@ -2953,17 +2890,9 @@ bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, return (NULL); } - IEEE80211_ADDR_COPY(sc->sc_macaddr, mac0); - - bvp = (struct bwn_vap *) malloc(sizeof(struct bwn_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (bvp == NULL) { - device_printf(sc->sc_dev, "failed to allocate a buffer\n"); - return (NULL); - } + bvp = malloc(sizeof(struct bwn_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &bvp->bv_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); - IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override with driver methods */ bvp->bv_newstate = vap->iv_newstate; vap->iv_newstate = bwn_newstate; @@ -2975,7 +2904,7 @@ bwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); return (vap); } @@ -2989,30 +2918,10 @@ bwn_vap_delete(struct ieee80211vap *vap) free(bvp, M_80211_VAP); } -static void -bwn_init(void *arg) -{ - struct bwn_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - int error = 0; - - DPRINTF(sc, BWN_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); - - BWN_LOCK(sc); - error = bwn_init_locked(sc); - BWN_UNLOCK(sc); - - if (error == 0) - ieee80211_start_all(ic); /* start all vap's */ -} - static int -bwn_init_locked(struct bwn_softc *sc) +bwn_init(struct bwn_softc *sc) { struct bwn_mac *mac; - struct ifnet *ifp = sc->sc_ifp; int error; BWN_ASSERT_LOCKED(sc); @@ -3038,7 +2947,7 @@ bwn_init_locked(struct bwn_softc *sc) bwn_spu_setdelay(mac, 0); bwn_set_macaddr(mac); - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= BWN_FLAG_RUNNING; callout_reset(&sc->sc_rfswitch_ch, hz, bwn_rfswitch, sc); callout_reset(&sc->sc_watchdog_ch, hz, bwn_watchdog, sc); @@ -3046,19 +2955,9 @@ bwn_init_locked(struct bwn_softc *sc) } static void -bwn_stop(struct bwn_softc *sc, int statechg) -{ - - BWN_LOCK(sc); - bwn_stop_locked(sc, statechg); - BWN_UNLOCK(sc); -} - -static void -bwn_stop_locked(struct bwn_softc *sc, int statechg) +bwn_stop(struct bwn_softc *sc) { struct bwn_mac *mac = sc->sc_curmac; - struct ifnet *ifp = sc->sc_ifp; BWN_ASSERT_LOCKED(sc); @@ -3077,7 +2976,7 @@ bwn_stop_locked(struct bwn_softc *sc, int statechg) bwn_core_exit(mac); sc->sc_rf_enabled = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~BWN_FLAG_RUNNING; } static void @@ -4441,7 +4340,7 @@ static void bwn_spu_setdelay(struct bwn_mac *mac, int idle) { struct bwn_softc *sc = mac->mac_sc; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t delay; /* microsec */ delay = (mac->mac_phy.type == BWN_PHYTYPE_A) ? 3700 : 1050; @@ -4479,7 +4378,8 @@ bwn_set_macaddr(struct bwn_mac *mac) { bwn_mac_write_bssid(mac); - bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, mac->mac_sc->sc_macaddr); + bwn_mac_setfilter(mac, BWN_MACFILTER_SELF, + mac->mac_sc->sc_ic.ic_macaddr); } static void @@ -4649,8 +4549,7 @@ static void bwn_set_opmode(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t ctl; uint16_t cfp_pretbtt; @@ -7943,8 +7842,7 @@ bwn_switch_channel(struct bwn_mac *mac, int chan) { struct bwn_phy *phy = &(mac->mac_phy); struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t channelcookie, savedcookie; int error; @@ -8055,7 +7953,7 @@ bwn_mac_write_bssid(struct bwn_mac *mac) uint8_t mac_bssid[IEEE80211_ADDR_LEN * 2]; bwn_mac_setfilter(mac, BWN_MACFILTER_BSSID, sc->sc_bssid); - memcpy(mac_bssid, sc->sc_macaddr, IEEE80211_ADDR_LEN); + memcpy(mac_bssid, sc->sc_ic.ic_macaddr, IEEE80211_ADDR_LEN); memcpy(mac_bssid + IEEE80211_ADDR_LEN, sc->sc_bssid, IEEE80211_ADDR_LEN); @@ -8329,9 +8227,8 @@ bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct bwn_vap *bvp = BWN_VAP(vap); struct ieee80211com *ic= vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; enum ieee80211_state ostate = vap->iv_state; - struct bwn_softc *sc = ifp->if_softc; + struct bwn_softc *sc = ic->ic_softc; struct bwn_mac *mac = sc->sc_curmac; int error; @@ -8370,7 +8267,6 @@ bwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) /* XXX nothing to do? */ } else if (nstate == IEEE80211_S_RUN) { memcpy(sc->sc_bssid, vap->iv_bss->ni_bssid, IEEE80211_ADDR_LEN); - memcpy(sc->sc_macaddr, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); bwn_set_opmode(mac); bwn_set_pretbtt(mac); bwn_spu_setdelay(mac, 0); @@ -8386,7 +8282,7 @@ static void bwn_set_pretbtt(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t pretbtt; if (ic->ic_opmode == IEEE80211_M_IBSS) @@ -8444,7 +8340,6 @@ bwn_intrtask(void *arg, int npending) { struct bwn_mac *mac = arg; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; uint32_t merged = 0; int i, tx = 0, rx = 0; @@ -8544,10 +8439,8 @@ bwn_intrtask(void *arg, int npending) bwn_led_event(mac, evt); } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { - if (!IFQ_IS_EMPTY(&ifp->if_snd)) - bwn_start_locked(ifp); - } + if (mbufq_first(&sc->sc_snd) != NULL) + bwn_start(sc); BWN_BARRIER(mac, BUS_SPACE_BARRIER_READ); BWN_BARRIER(mac, BUS_SPACE_BARRIER_WRITE); @@ -8559,8 +8452,7 @@ static void bwn_restart(struct bwn_mac *mac, const char *msg) { struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; if (mac->mac_status < BWN_MAC_STATUS_INITED) return; @@ -8605,7 +8497,7 @@ static void bwn_intr_tbtt_indication(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; if (ic->ic_opmode != IEEE80211_M_HOSTAP) bwn_psctl(mac, 0); @@ -8628,7 +8520,7 @@ static void bwn_intr_beacon(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t cmd, beacon0, beacon1; if (ic->ic_opmode == IEEE80211_M_HOSTAP || @@ -8917,7 +8809,6 @@ bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) struct bwn_dmadesc_generic *desc; struct bwn_dmadesc_meta *meta; struct bwn_rxhdr4 *rxhdr; - struct ifnet *ifp = sc->sc_ifp; struct mbuf *m; uint32_t macstat; int32_t tmp; @@ -8930,14 +8821,14 @@ bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) m = meta->mt_m; if (bwn_dma_newbuf(dr, desc, meta, 0)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(sc->sc_ic.ic_ierrors, 1); return; } rxhdr = mtod(m, struct bwn_rxhdr4 *); len = le16toh(rxhdr->frame_len); if (len <= 0) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(sc->sc_ic.ic_ierrors, 1); return; } if (bwn_dma_check_redzone(dr, m)) { @@ -8973,7 +8864,6 @@ bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot) } } - m->m_pkthdr.rcvif = ifp; m->m_len = m->m_pkthdr.len = len + dr->dr_frameoffset; m_adj(m, dr->dr_frameoffset); @@ -9060,7 +8950,6 @@ bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) struct bwn_mac *mac = prq->prq_mac; struct bwn_softc *sc = mac->mac_sc; struct bwn_rxhdr4 rxhdr; - struct ifnet *ifp = sc->sc_ifp; struct mbuf *m; uint32_t ctl32, macstat, v32; unsigned int i, padding; @@ -9157,7 +9046,6 @@ bwn_pio_rxeof(struct bwn_pio_rxqueue *prq) } } - m->m_pkthdr.rcvif = ifp; m->m_len = m->m_pkthdr.len = totlen; bwn_rxeof(prq->prq_mac, m, &rxhdr); @@ -9302,8 +9190,7 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) struct bwn_softc *sc = mac->mac_sc; struct ieee80211_frame_min *wh; struct ieee80211_node *ni; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t macstat; int padding, rate, rssi = 0, noise = 0, type; uint16_t phytype, phystat0, phystat3, chanstat; @@ -9367,8 +9254,6 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr) rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */ noise = mac->mac_stats.link_noise; - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - BWN_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, wh); @@ -9393,9 +9278,6 @@ bwn_dma_handle_txeof(struct bwn_mac *mac, struct bwn_dmadesc_generic *desc; struct bwn_dmadesc_meta *meta; struct bwn_softc *sc = mac->mac_sc; - struct ieee80211_node *ni; - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; int slot; BWN_ASSERT_LOCKED(sc); @@ -9421,37 +9303,22 @@ bwn_dma_handle_txeof(struct bwn_mac *mac, KASSERT(meta->mt_m != NULL, ("%s:%d: fail", __func__, __LINE__)); - ni = meta->mt_ni; - m = meta->mt_m; - if (ni != NULL) { - /* - * Do any tx complete callback. Note this must - * be done before releasing the node reference. - */ - if (m->m_flags & M_TXCB) - ieee80211_process_callback(ni, m, 0); - ieee80211_free_node(ni); - meta->mt_ni = NULL; - } - m_freem(m); + ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0); + meta->mt_ni = NULL; meta->mt_m = NULL; - } else { + } else KASSERT(meta->mt_m == NULL, ("%s:%d: fail", __func__, __LINE__)); - } dr->dr_usedslot--; - if (meta->mt_islast) { - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + if (meta->mt_islast) break; - } slot = bwn_dma_nextslot(dr, slot); } sc->sc_watchdog_timer = 0; if (dr->dr_stop) { KASSERT(bwn_dma_freeslot(dr) >= BWN_TX_SLOTS_PER_FRAME, ("%s:%d: fail", __func__, __LINE__)); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; dr->dr_stop = 0; } } @@ -9463,7 +9330,6 @@ bwn_pio_handle_txeof(struct bwn_mac *mac, struct bwn_pio_txqueue *tq; struct bwn_pio_txpkt *tp = NULL; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; BWN_ASSERT_LOCKED(sc); @@ -9488,13 +9354,7 @@ bwn_pio_handle_txeof(struct bwn_mac *mac, tp->tp_m = NULL; TAILQ_INSERT_TAIL(&tq->tq_pktlist, tp, tp_list); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - sc->sc_watchdog_timer = 0; - if (tq->tq_stop) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - tq->tq_stop = 0; - } } static void @@ -9502,8 +9362,7 @@ bwn_phy_txpower_check(struct bwn_mac *mac, uint32_t flags) { struct bwn_softc *sc = mac->mac_sc; struct bwn_phy *phy = &mac->mac_phy; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; unsigned long now; int result; @@ -9607,8 +9466,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni, struct ieee80211_frame_rts *rts; const struct ieee80211_txparam *tp; struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mbuf *mprot; unsigned int len; uint32_t macctl = 0; @@ -10106,7 +9964,7 @@ static void bwn_phy_lock(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; KASSERT(siba_get_revid(sc->sc_dev) >= 3, ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); @@ -10119,7 +9977,7 @@ static void bwn_phy_unlock(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; KASSERT(siba_get_revid(sc->sc_dev) >= 3, ("%s: unsupported rev %d", __func__, siba_get_revid(sc->sc_dev))); @@ -10635,8 +10493,7 @@ static void bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) { struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t val; int i; @@ -10645,7 +10502,7 @@ bwn_led_newstate(struct bwn_mac *mac, enum ieee80211_state nstate) sc->sc_led_blinking = 0; } - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0) return; val = BWN_READ_2(mac, BWN_GPIO_CONTROL); @@ -10780,7 +10637,9 @@ bwn_suspend(device_t dev) { struct bwn_softc *sc = device_get_softc(dev); - bwn_stop(sc, 1); + BWN_LOCK(sc); + bwn_stop(sc); + BWN_UNLOCK(sc); return (0); } @@ -10788,10 +10647,14 @@ static int bwn_resume(device_t dev) { struct bwn_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; + int error = EDOOFUS; - if (ifp->if_flags & IFF_UP) - bwn_init(sc); + BWN_LOCK(sc); + if (sc->sc_ic.ic_nrunning > 0) + error = bwn_init(sc); + BWN_UNLOCK(sc); + if (error == 0) + ieee80211_start_all(&sc->sc_ic); return (0); } @@ -10870,8 +10733,7 @@ bwn_phy_lp_init(struct bwn_mac *mac) struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; struct bwn_softc *sc = mac->mac_sc; const struct bwn_stxtable *st; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int i, error; uint16_t tmp; @@ -11024,8 +10886,7 @@ static uint32_t bwn_phy_lp_get_default_chan(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36); } @@ -11058,8 +10919,7 @@ bwn_phy_lp_readsprom(struct bwn_mac *mac) { struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev); @@ -11098,8 +10958,7 @@ bwn_phy_lp_txpctl_init(struct bwn_mac *mac) struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 }; struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 }; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; bwn_phy_lp_set_txgain(mac, IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz); @@ -11111,8 +10970,7 @@ bwn_phy_lp_calib(struct bwn_mac *mac) { struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct bwn_rxcompco *rc = NULL; struct bwn_txgain ogain; int i, omode, oafeovr, orf, obbmult; @@ -11458,8 +11316,7 @@ bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq) { struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t iso, tmp[3]; KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__)); @@ -11730,8 +11587,7 @@ bwn_phy_lp_bbinit_r2(struct bwn_mac *mac) { struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; static const struct bwn_wpair v1[] = { { BWN_PHY_AFE_DAC_CTL, 0x50 }, { BWN_PHY_AFE_CTL, 0x8800 }, @@ -11841,8 +11697,7 @@ bwn_phy_lp_bbinit_r01(struct bwn_mac *mac) { struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; static const struct bwn_smpair v1[] = { { BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 }, { BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 }, @@ -12027,8 +11882,7 @@ bwn_phy_lp_b2062_init(struct bwn_mac *mac) ((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff) struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; static const struct bwn_b2062_freq freqdata_tab[] = { { 12000, { 6, 6, 6, 6, 10, 6 } }, { 13000, { 4, 4, 4, 4, 11, 7 } }, @@ -12374,8 +12228,7 @@ bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac) #define FLAG_A 0x01 #define FLAG_G 0x02 struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = { { BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, }, { BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, }, @@ -12448,8 +12301,7 @@ bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac) #define FLAG_A 0x01 #define FLAG_G 0x02 struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = { { BWN_B2063_COM1, 0x0, 0x0, FLAG_G, }, { BWN_B2063_COM10, 0x1, 0x0, FLAG_A, }, @@ -12667,8 +12519,7 @@ static void bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain) { struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp; if (mac->mac_phy.rev < 2) { @@ -12736,8 +12587,7 @@ bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user) { struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp; struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; if (user) plp->plp_crsusr_off = 0; @@ -13280,8 +13130,7 @@ static void bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; static struct bwn_txgain_entry txgain_r2[] = { { 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 }, { 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 }, @@ -14158,8 +14007,7 @@ bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset, struct bwn_txgain_entry te) { struct bwn_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__)); diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h index f6647b0f4f5f..b8295ece9b1c 100644 --- a/sys/dev/bwn/if_bwnvar.h +++ b/sys/dev/bwn/if_bwnvar.h @@ -656,7 +656,6 @@ struct bwn_pio_txqueue { uint16_t tq_size; uint16_t tq_used; uint16_t tq_free; - uint8_t tq_stop; uint8_t tq_index; struct bwn_pio_txpkt tq_pkts[BWN_PIO_MAX_TXPACKETS]; TAILQ_HEAD(, bwn_pio_txpkt) tq_pktlist; @@ -897,17 +896,18 @@ struct bwn_vap { struct bwn_softc { device_t sc_dev; struct mtx sc_mtx; - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; unsigned sc_flags; #define BWN_FLAG_ATTACHED (1 << 0) #define BWN_FLAG_INVALID (1 << 1) #define BWN_FLAG_NEED_BEACON_TP (1 << 2) +#define BWN_FLAG_RUNNING (1 << 3) unsigned sc_debug; struct bwn_mac *sc_curmac; TAILQ_HEAD(, bwn_mac) sc_maclist; - uint8_t sc_macaddr[IEEE80211_ADDR_LEN]; uint8_t sc_bssid[IEEE80211_ADDR_LEN]; unsigned int sc_filters; uint8_t sc_beacons[2]; diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 9c57aedd3a55..c30f31c4807c 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -166,7 +167,6 @@ static void ndis_starttask (device_object *, void *); static void ndis_resettask (device_object *, void *); static void ndis_inputtask (device_object *, void *); static int ndis_ioctl (struct ifnet *, u_long, caddr_t); -static int ndis_ioctl_80211 (struct ifnet *, u_long, caddr_t); static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state, int); static int ndis_nettype_chan (uint32_t); @@ -197,10 +197,15 @@ static int ndis_add_key (struct ieee80211vap *, const struct ieee80211_key *, const u_int8_t []); static int ndis_del_key (struct ieee80211vap *, const struct ieee80211_key *); - static void ndis_setmulti (struct ndis_softc *); static void ndis_map_sclist (void *, bus_dma_segment_t *, int, bus_size_t, int); +static int ndis_ifattach(struct ndis_softc *); + +static int ndis_80211attach(struct ndis_softc *); +static int ndis_80211ioctl(struct ieee80211com *, u_long , void *); +static int ndis_80211transmit(struct ieee80211com *, struct mbuf *); +static void ndis_80211parent(struct ieee80211com *); static int ndisdrv_loaded = 0; @@ -536,16 +541,12 @@ ndis_nettype_mode(uint32_t type) * setup and ethernet/BPF attach. */ int -ndis_attach(dev) - device_t dev; +ndis_attach(device_t dev) { - u_char eaddr[ETHER_ADDR_LEN]; struct ndis_softc *sc; driver_object *pdrv; device_object *pdo; - struct ifnet *ifp = NULL; - int error = 0, len, mode; - uint8_t bands = 0; + int error = 0, len; int i; sc = device_get_softc(dev); @@ -559,6 +560,7 @@ ndis_attach(dev) InitializeListHead(&sc->ndisusb_tasklist); InitializeListHead(&sc->ndisusb_xferdonelist); callout_init(&sc->ndis_stat_callout, 1); + mbufq_init(&sc->ndis_rxqueue, INT_MAX); /* XXXGL: sane maximum */ if (sc->ndis_iftype == PCMCIABus) { error = ndis_alloc_amem(sc); @@ -634,16 +636,9 @@ ndis_attach(dev) goto fail; } - /* - * Get station address from the driver. - */ - len = sizeof(eaddr); - ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &eaddr, &len); - /* * Figure out how big to make the TX buffer pool. */ - len = sizeof(sc->ndis_maxpkts); if (ndis_get_info(sc, OID_GEN_MAXIMUM_SEND_PACKETS, &sc->ndis_maxpkts, &len)) { @@ -696,95 +691,89 @@ ndis_attach(dev) */ for (i = 0; i < sc->ndis_oidcnt; i++) if (sc->ndis_oids[i] == OID_802_11_CONFIGURATION) { - sc->ndis_80211++; + sc->ndis_80211 = 1; break; } if (sc->ndis_80211) - ifp = if_alloc(IFT_IEEE80211); + error = ndis_80211attach(sc); else - ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - error = ENOSPC; - goto fail; + error = ndis_ifattach(sc); + +fail: + if (error) { + ndis_detach(dev); + return (error); } - sc->ifp = ifp; - ifp->if_softc = sc; - /* Check for task offload support. */ - ndis_probe_offload(sc); + if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0) + return (error); - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = ndis_ioctl; - ifp->if_start = ndis_start; - ifp->if_init = ndis_init; - ifp->if_baudrate = 10000000; - IFQ_SET_MAXLEN(&ifp->if_snd, 50); - ifp->if_snd.ifq_drv_maxlen = 25; - IFQ_SET_READY(&ifp->if_snd); - ifp->if_capenable = ifp->if_capabilities; - ifp->if_hwassist = sc->ndis_hwassist; + DPRINTF(("attach done.\n")); + /* We're done talking to the NIC for now; halt it. */ + ndis_halt_nic(sc); + DPRINTF(("halting done.\n")); - /* Do media setup */ - if (sc->ndis_80211) { - struct ieee80211com *ic = ifp->if_l2com; - ndis_80211_rates_ex rates; - struct ndis_80211_nettype_list *ntl; - uint32_t arg; - int r; + return (error); +} - callout_init(&sc->ndis_scan_callout, 1); +static int +ndis_80211attach(struct ndis_softc *sc) +{ + struct ieee80211com *ic = &sc->ndis_ic; + ndis_80211_rates_ex rates; + struct ndis_80211_nettype_list *ntl; + uint32_t arg; + int mode, i, r, len; + uint8_t bands = 0; - ifp->if_ioctl = ndis_ioctl_80211; - ic->ic_ifp = ifp; - ic->ic_softc = sc; - ic->ic_name = device_get_nameunit(dev); - ic->ic_opmode = IEEE80211_M_STA; - ic->ic_phytype = IEEE80211_T_DS; - ic->ic_caps = IEEE80211_C_8023ENCAP | - IEEE80211_C_STA | IEEE80211_C_IBSS; - setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO); - len = 0; - r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, - NULL, &len); - if (r != ENOSPC) - goto nonettypes; - ntl = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO); - r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, - ntl, &len); - if (r != 0) { - free(ntl, M_DEVBUF); - goto nonettypes; - } + callout_init(&sc->ndis_scan_callout, 1); - for (i = 0; i < ntl->ntl_items; i++) { - mode = ndis_nettype_mode(ntl->ntl_type[i]); - if (mode) { - setbit(ic->ic_modecaps, mode); - setbit(&bands, mode); - } else - device_printf(dev, "Unknown nettype %d\n", - ntl->ntl_type[i]); - } + ic->ic_softc = sc; + ic->ic_ioctl = ndis_80211ioctl; + ic->ic_name = device_get_nameunit(sc->ndis_dev); + ic->ic_opmode = IEEE80211_M_STA; + ic->ic_phytype = IEEE80211_T_DS; + ic->ic_caps = IEEE80211_C_8023ENCAP | + IEEE80211_C_STA | IEEE80211_C_IBSS; + setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO); + len = 0; + r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, NULL, &len); + if (r != ENOSPC) + goto nonettypes; + ntl = malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, ntl, &len); + if (r != 0) { free(ntl, M_DEVBUF); + goto nonettypes; + } + + for (i = 0; i < ntl->ntl_items; i++) { + mode = ndis_nettype_mode(ntl->ntl_type[i]); + if (mode) { + setbit(ic->ic_modecaps, mode); + setbit(&bands, mode); + } else + device_printf(sc->ndis_dev, "Unknown nettype %d\n", + ntl->ntl_type[i]); + } + free(ntl, M_DEVBUF); nonettypes: - /* Default to 11b channels if the card did not supply any */ - if (bands == 0) { - setbit(ic->ic_modecaps, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11B); - } - len = sizeof(rates); - bzero((char *)&rates, len); - r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES, - (void *)rates, &len); - if (r) - device_printf(dev, "get rates failed: 0x%x\n", r); - /* - * Since the supported rates only up to 8 can be supported, - * if this is not 802.11b we're just going to be faking it - * all up to heck. - */ + /* Default to 11b channels if the card did not supply any */ + if (bands == 0) { + setbit(ic->ic_modecaps, IEEE80211_MODE_11B); + setbit(&bands, IEEE80211_MODE_11B); + } + len = sizeof(rates); + bzero((char *)&rates, len); + r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES, (void *)rates, &len); + if (r != 0) + device_printf(sc->ndis_dev, "get rates failed: 0x%x\n", r); + /* + * Since the supported rates only up to 8 can be supported, + * if this is not 802.11b we're just going to be faking it + * all up to heck. + */ #define TESTSETRATE(x, y) \ do { \ @@ -804,174 +793,198 @@ ndis_attach(dev) #define INCRATE(x) \ ic->ic_sup_rates[x].rs_nrates++ - ic->ic_curmode = IEEE80211_MODE_AUTO; - if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) - ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0; - if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) - ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0; - if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) - ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0; - for (i = 0; i < len; i++) { - switch (rates[i] & IEEE80211_RATE_VAL) { - case 2: - case 4: - case 11: - case 10: - case 22: - if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) { - /* Lazy-init 802.11b. */ - setbit(ic->ic_modecaps, - IEEE80211_MODE_11B); - ic->ic_sup_rates[IEEE80211_MODE_11B]. - rs_nrates = 0; - } - SETRATE(IEEE80211_MODE_11B, rates[i]); - INCRATE(IEEE80211_MODE_11B); - break; - default: - if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { - SETRATE(IEEE80211_MODE_11A, rates[i]); - INCRATE(IEEE80211_MODE_11A); - } - if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { - SETRATE(IEEE80211_MODE_11G, rates[i]); - INCRATE(IEEE80211_MODE_11G); - } - break; + ic->ic_curmode = IEEE80211_MODE_AUTO; + if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) + ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0; + if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) + ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0; + if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) + ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0; + for (i = 0; i < len; i++) { + switch (rates[i] & IEEE80211_RATE_VAL) { + case 2: + case 4: + case 11: + case 10: + case 22: + if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) { + /* Lazy-init 802.11b. */ + setbit(ic->ic_modecaps, IEEE80211_MODE_11B); + ic->ic_sup_rates[IEEE80211_MODE_11B]. + rs_nrates = 0; } + SETRATE(IEEE80211_MODE_11B, rates[i]); + INCRATE(IEEE80211_MODE_11B); + break; + default: + if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { + SETRATE(IEEE80211_MODE_11A, rates[i]); + INCRATE(IEEE80211_MODE_11A); + } + if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { + SETRATE(IEEE80211_MODE_11G, rates[i]); + INCRATE(IEEE80211_MODE_11G); + } + break; } + } + + /* + * If the hardware supports 802.11g, it most + * likely supports 802.11b and all of the + * 802.11b and 802.11g speeds, so maybe we can + * just cheat here. Just how in the heck do + * we detect turbo modes, though? + */ + if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) { + TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|2); + TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|4); + TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|11); + TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|22); + } + if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { + TESTSETRATE(IEEE80211_MODE_11G, 48); + TESTSETRATE(IEEE80211_MODE_11G, 72); + TESTSETRATE(IEEE80211_MODE_11G, 96); + TESTSETRATE(IEEE80211_MODE_11G, 108); + } + if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { + TESTSETRATE(IEEE80211_MODE_11A, 48); + TESTSETRATE(IEEE80211_MODE_11A, 72); + TESTSETRATE(IEEE80211_MODE_11A, 96); + TESTSETRATE(IEEE80211_MODE_11A, 108); + } - /* - * If the hardware supports 802.11g, it most - * likely supports 802.11b and all of the - * 802.11b and 802.11g speeds, so maybe we can - * just cheat here. Just how in the heck do - * we detect turbo modes, though? - */ - if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) { - TESTSETRATE(IEEE80211_MODE_11B, - IEEE80211_RATE_BASIC|2); - TESTSETRATE(IEEE80211_MODE_11B, - IEEE80211_RATE_BASIC|4); - TESTSETRATE(IEEE80211_MODE_11B, - IEEE80211_RATE_BASIC|11); - TESTSETRATE(IEEE80211_MODE_11B, - IEEE80211_RATE_BASIC|22); - } - if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { - TESTSETRATE(IEEE80211_MODE_11G, 48); - TESTSETRATE(IEEE80211_MODE_11G, 72); - TESTSETRATE(IEEE80211_MODE_11G, 96); - TESTSETRATE(IEEE80211_MODE_11G, 108); - } - if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { - TESTSETRATE(IEEE80211_MODE_11A, 48); - TESTSETRATE(IEEE80211_MODE_11A, 72); - TESTSETRATE(IEEE80211_MODE_11A, 96); - TESTSETRATE(IEEE80211_MODE_11A, 108); - } #undef SETRATE #undef INCRATE - ieee80211_init_channels(ic, NULL, &bands); +#undef TESTSETRATE - /* - * To test for WPA support, we need to see if we can - * set AUTHENTICATION_MODE to WPA and read it back - * successfully. - */ - i = sizeof(arg); - arg = NDIS_80211_AUTHMODE_WPA; - r = ndis_set_info(sc, - OID_802_11_AUTHENTICATION_MODE, &arg, &i); - if (r == 0) { - r = ndis_get_info(sc, - OID_802_11_AUTHENTICATION_MODE, &arg, &i); - if (r == 0 && arg == NDIS_80211_AUTHMODE_WPA) - ic->ic_caps |= IEEE80211_C_WPA; - } + ieee80211_init_channels(ic, NULL, &bands); - /* - * To test for supported ciphers, we set each - * available encryption type in descending order. - * If ENC3 works, then we have WEP, TKIP and AES. - * If only ENC2 works, then we have WEP and TKIP. - * If only ENC1 works, then we have just WEP. - */ - i = sizeof(arg); - arg = NDIS_80211_WEPSTAT_ENC3ENABLED; - r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); - if (r == 0) { - ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP - | IEEE80211_CRYPTO_TKIP - | IEEE80211_CRYPTO_AES_CCM; - goto got_crypto; - } - arg = NDIS_80211_WEPSTAT_ENC2ENABLED; - r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); - if (r == 0) { - ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP - | IEEE80211_CRYPTO_TKIP; - goto got_crypto; - } - arg = NDIS_80211_WEPSTAT_ENC1ENABLED; - r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); - if (r == 0) - ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP; + /* + * To test for WPA support, we need to see if we can + * set AUTHENTICATION_MODE to WPA and read it back + * successfully. + */ + i = sizeof(arg); + arg = NDIS_80211_AUTHMODE_WPA; + r = ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i); + if (r == 0) { + r = ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i); + if (r == 0 && arg == NDIS_80211_AUTHMODE_WPA) + ic->ic_caps |= IEEE80211_C_WPA; + } + + /* + * To test for supported ciphers, we set each + * available encryption type in descending order. + * If ENC3 works, then we have WEP, TKIP and AES. + * If only ENC2 works, then we have WEP and TKIP. + * If only ENC1 works, then we have just WEP. + */ + i = sizeof(arg); + arg = NDIS_80211_WEPSTAT_ENC3ENABLED; + r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); + if (r == 0) { + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP + | IEEE80211_CRYPTO_TKIP + | IEEE80211_CRYPTO_AES_CCM; + goto got_crypto; + } + arg = NDIS_80211_WEPSTAT_ENC2ENABLED; + r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); + if (r == 0) { + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP + | IEEE80211_CRYPTO_TKIP; + goto got_crypto; + } + arg = NDIS_80211_WEPSTAT_ENC1ENABLED; + r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); + if (r == 0) + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP; got_crypto: - i = sizeof(arg); - r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i); - if (r == 0) - ic->ic_caps |= IEEE80211_C_PMGT; + i = sizeof(arg); + r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i); + if (r == 0) + ic->ic_caps |= IEEE80211_C_PMGT; - r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i); - if (r == 0) - ic->ic_caps |= IEEE80211_C_TXPMGT; + r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i); + if (r == 0) + ic->ic_caps |= IEEE80211_C_TXPMGT; - ieee80211_ifattach(ic, eaddr); - ic->ic_raw_xmit = ndis_raw_xmit; - ic->ic_scan_start = ndis_scan_start; - ic->ic_scan_end = ndis_scan_end; - ic->ic_set_channel = ndis_set_channel; - ic->ic_scan_curchan = ndis_scan_curchan; - ic->ic_scan_mindwell = ndis_scan_mindwell; - ic->ic_bsschan = IEEE80211_CHAN_ANYC; - //ic->ic_bss->ni_chan = ic->ic_bsschan; - ic->ic_vap_create = ndis_vap_create; - ic->ic_vap_delete = ndis_vap_delete; - ic->ic_update_mcast = ndis_update_mcast; - ic->ic_update_promisc = ndis_update_promisc; + /* + * Get station address from the driver. + */ + len = sizeof(ic->ic_macaddr); + ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &ic->ic_macaddr, &len); - if (bootverbose) - ieee80211_announce(ic); + ieee80211_ifattach(ic); + ic->ic_raw_xmit = ndis_raw_xmit; + ic->ic_scan_start = ndis_scan_start; + ic->ic_scan_end = ndis_scan_end; + ic->ic_set_channel = ndis_set_channel; + ic->ic_scan_curchan = ndis_scan_curchan; + ic->ic_scan_mindwell = ndis_scan_mindwell; + ic->ic_bsschan = IEEE80211_CHAN_ANYC; + ic->ic_vap_create = ndis_vap_create; + ic->ic_vap_delete = ndis_vap_delete; + ic->ic_update_mcast = ndis_update_mcast; + ic->ic_update_promisc = ndis_update_promisc; + ic->ic_transmit = ndis_80211transmit; + ic->ic_parent = ndis_80211parent; - } else { - ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd, - ndis_ifmedia_sts); - ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); - ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); - ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); - ifmedia_add(&sc->ifmedia, - IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); - ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); - ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO); - ether_ifattach(ifp, eaddr); - } + if (bootverbose) + ieee80211_announce(ic); -fail: - if (error) { - ndis_detach(dev); - return (error); - } + return (0); +} - if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0) - return (error); +static int +ndis_ifattach(struct ndis_softc *sc) +{ + struct ifnet *ifp; + u_char eaddr[ETHER_ADDR_LEN]; + int len; - DPRINTF(("attach done.\n")); - /* We're done talking to the NIC for now; halt it. */ - ndis_halt_nic(sc); - DPRINTF(("halting done.\n")); + ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) + return (ENOSPC); + sc->ifp = ifp; + ifp->if_softc = sc; - return (error); + /* Check for task offload support. */ + ndis_probe_offload(sc); + + /* + * Get station address from the driver. + */ + len = sizeof(eaddr); + ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, eaddr, &len); + + if_initname(ifp, device_get_name(sc->ndis_dev), + device_get_unit(sc->ndis_dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = ndis_ioctl; + ifp->if_start = ndis_start; + ifp->if_init = ndis_init; + ifp->if_baudrate = 10000000; + IFQ_SET_MAXLEN(&ifp->if_snd, 50); + ifp->if_snd.ifq_drv_maxlen = 25; + IFQ_SET_READY(&ifp->if_snd); + ifp->if_capenable = ifp->if_capabilities; + ifp->if_hwassist = sc->ndis_hwassist; + + ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd, + ndis_ifmedia_sts); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); + ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO); + ether_ifattach(ifp, eaddr); + + return (0); } static struct ieee80211vap * @@ -985,18 +998,16 @@ ndis_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - nvp = (struct ndis_vap *) malloc(sizeof(struct ndis_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (nvp == NULL) - return NULL; + nvp = malloc(sizeof(struct ndis_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &nvp->vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override with driver methods */ nvp->newstate = vap->iv_newstate; vap->iv_newstate = ndis_newstate; /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ndis_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, ndis_media_status, + mac); ic->ic_opmode = opmode; /* install key handing routines */ vap->iv_key_set = ndis_add_key; @@ -1009,8 +1020,7 @@ ndis_vap_delete(struct ieee80211vap *vap) { struct ndis_vap *nvp = NDIS_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ndis_softc *sc = ifp->if_softc; + struct ndis_softc *sc = ic->ic_softc; ndis_stop(sc); callout_drain(&sc->ndis_scan_callout); @@ -1026,28 +1036,27 @@ ndis_vap_delete(struct ieee80211vap *vap) * allocated. */ int -ndis_detach(dev) - device_t dev; +ndis_detach(device_t dev) { - struct ndis_softc *sc; struct ifnet *ifp; + struct ndis_softc *sc; driver_object *drv; sc = device_get_softc(dev); NDIS_LOCK(sc); - ifp = sc->ifp; + if (!sc->ndis_80211) + ifp = sc->ifp; + else + ifp = NULL; if (ifp != NULL) ifp->if_flags &= ~IFF_UP; - if (device_is_attached(dev)) { NDIS_UNLOCK(sc); ndis_stop(sc); - if (ifp != NULL) { - if (sc->ndis_80211) - ieee80211_ifdetach(ifp->if_l2com); - else - ether_ifdetach(ifp); - } + if (sc->ndis_80211) + ieee80211_ifdetach(&sc->ndis_ic); + else if (ifp != NULL) + ether_ifdetach(ifp); } else NDIS_UNLOCK(sc); @@ -1302,11 +1311,11 @@ ndis_rxeof_xfr(dpc, adapter, sysarg1, sysarg2) IoFreeMdl(p->np_private.npp_head); NdisFreePacket(p); KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock); - _IF_ENQUEUE(&sc->ndis_rxqueue, m); + mbufq_enqueue(&sc->ndis_rxqueue, m); KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock); IoQueueWorkItem(sc->ndis_inputitem, (io_workitem_func)ndis_inputtask_wrap, - WORKQUEUE_CRITICAL, ifp); + WORKQUEUE_CRITICAL, sc); } if (status == NDIS_STATUS_FAILURE) @@ -1350,11 +1359,11 @@ ndis_rxeof_xfr_done(adapter, packet, status, len) m->m_len = m->m_pkthdr.len; m->m_pkthdr.rcvif = ifp; KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock); - _IF_ENQUEUE(&sc->ndis_rxqueue, m); + mbufq_enqueue(&sc->ndis_rxqueue, m); KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock); IoQueueWorkItem(sc->ndis_inputitem, (io_workitem_func)ndis_inputtask_wrap, - WORKQUEUE_CRITICAL, ifp); + WORKQUEUE_CRITICAL, sc); } /* * A frame has been uploaded: pass the resulting mbuf chain up to @@ -1399,7 +1408,7 @@ ndis_rxeof(adapter, packets, pktcnt) * before we're completely ready to handle them. If we detect this, * we need to return them to the miniport and ignore them. */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!sc->ndis_running) { for (i = 0; i < pktcnt; i++) { p = packets[i]; if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) { @@ -1473,11 +1482,11 @@ ndis_rxeof(adapter, packets, pktcnt) } KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock); - _IF_ENQUEUE(&sc->ndis_rxqueue, m0); + mbufq_enqueue(&sc->ndis_rxqueue, m0); KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock); IoQueueWorkItem(sc->ndis_inputitem, (io_workitem_func)ndis_inputtask_wrap, - WORKQUEUE_CRITICAL, ifp); + WORKQUEUE_CRITICAL, sc); } } } @@ -1489,34 +1498,29 @@ ndis_rxeof(adapter, packets, pktcnt) * 'dispatch level' per-cpu sleep lock). */ static void -ndis_inputtask(dobj, arg) - device_object *dobj; - void *arg; +ndis_inputtask(device_object *dobj, void *arg) { ndis_miniport_block *block; - struct ifnet *ifp; - struct ndis_softc *sc; + struct ndis_softc *sc = arg; struct mbuf *m; - struct ieee80211com *ic; - struct ieee80211vap *vap; uint8_t irql; - ifp = arg; - sc = ifp->if_softc; - ic = ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); block = dobj->do_devext; KeAcquireSpinLock(&sc->ndis_rxlock, &irql); - while(1) { - _IF_DEQUEUE(&sc->ndis_rxqueue, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->ndis_rxqueue)) != NULL) { KeReleaseSpinLock(&sc->ndis_rxlock, irql); - if ((sc->ndis_80211 != 0) && (vap != NULL)) - vap->iv_deliver_data(vap, vap->iv_bss, m); - else + if ((sc->ndis_80211 != 0)) { + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + if (vap != NULL) + vap->iv_deliver_data(vap, vap->iv_bss, m); + } else { + struct ifnet *ifp = sc->ifp; + (*ifp->if_input)(ifp, m); + } KeAcquireSpinLock(&sc->ndis_rxlock, &irql); } KeReleaseSpinLock(&sc->ndis_rxlock, irql); @@ -1676,20 +1680,12 @@ ndis_tick(xsc) } static void -ndis_ticktask(d, xsc) - device_object *d; - void *xsc; +ndis_ticktask(device_object *d, void *xsc) { - struct ndis_softc *sc; - struct ieee80211com *ic; - struct ieee80211vap *vap; + struct ndis_softc *sc = xsc; ndis_checkforhang_handler hangfunc; uint8_t rval; - sc = xsc; - ic = sc->ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); - NDIS_LOCK(sc); if (!NDIS_INITIALIZED(sc)) { NDIS_UNLOCK(sc); @@ -1712,12 +1708,18 @@ ndis_ticktask(d, xsc) if (sc->ndis_link == 0 && sc->ndis_sts == NDIS_STATUS_MEDIA_CONNECT) { sc->ndis_link = 1; - if ((sc->ndis_80211 != 0) && (vap != NULL)) { - NDIS_UNLOCK(sc); - ndis_getstate_80211(sc); - ieee80211_new_state(vap, IEEE80211_S_RUN, -1); - NDIS_LOCK(sc); - if_link_state_change(vap->iv_ifp, LINK_STATE_UP); + if (sc->ndis_80211 != 0) { + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + if (vap != NULL) { + NDIS_UNLOCK(sc); + ndis_getstate_80211(sc); + ieee80211_new_state(vap, IEEE80211_S_RUN, -1); + NDIS_LOCK(sc); + if_link_state_change(vap->iv_ifp, + LINK_STATE_UP); + } } else if_link_state_change(sc->ifp, LINK_STATE_UP); } @@ -1725,11 +1727,17 @@ ndis_ticktask(d, xsc) if (sc->ndis_link == 1 && sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) { sc->ndis_link = 0; - if ((sc->ndis_80211 != 0) && (vap != NULL)) { - NDIS_UNLOCK(sc); - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); - NDIS_LOCK(sc); - if_link_state_change(vap->iv_ifp, LINK_STATE_DOWN); + if (sc->ndis_80211 != 0) { + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + if (vap != NULL) { + NDIS_UNLOCK(sc); + ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); + NDIS_LOCK(sc); + if_link_state_change(vap->iv_ifp, + LINK_STATE_DOWN); + } } else if_link_state_change(sc->ifp, LINK_STATE_DOWN); } @@ -1939,13 +1947,103 @@ ndis_start(ifp) return; } +static int +ndis_80211transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct ndis_softc *sc = ic->ic_softc; + ndis_packet **p0 = NULL, *p = NULL; + int status; + + NDIS_LOCK(sc); + if (!sc->ndis_link || !sc->ndis_running) { + NDIS_UNLOCK(sc); + return (ENXIO); + } + + if (sc->ndis_txpending == 0) { + NDIS_UNLOCK(sc); + return (ENOBUFS); + } + + p0 = &sc->ndis_txarray[sc->ndis_txidx]; + + NdisAllocatePacket(&status, + &sc->ndis_txarray[sc->ndis_txidx], sc->ndis_txpool); + + if (status != NDIS_STATUS_SUCCESS) { + NDIS_UNLOCK(sc); + return (ENOBUFS); + } + + if (ndis_mtop(m, &sc->ndis_txarray[sc->ndis_txidx])) { + NDIS_UNLOCK(sc); + return (ENOBUFS); + } + + /* + * Save pointer to original mbuf + * so we can free it later. + */ + + p = sc->ndis_txarray[sc->ndis_txidx]; + p->np_txidx = sc->ndis_txidx; + p->np_m0 = m; + p->np_oob.npo_status = NDIS_STATUS_PENDING; + + /* + * Do scatter/gather processing, if driver requested it. + */ + if (sc->ndis_sc) { + bus_dmamap_load_mbuf(sc->ndis_ttag, + sc->ndis_tmaps[sc->ndis_txidx], m, + ndis_map_sclist, &p->np_sclist, BUS_DMA_NOWAIT); + bus_dmamap_sync(sc->ndis_ttag, + sc->ndis_tmaps[sc->ndis_txidx], + BUS_DMASYNC_PREREAD); + p->np_ext.npe_info[ndis_sclist_info] = &p->np_sclist; + } + + NDIS_INC(sc); + sc->ndis_txpending--; + + /* + * Set a timeout in case the chip goes out to lunch. + */ + sc->ndis_tx_timer = 5; + NDIS_UNLOCK(sc); + + /* + * According to NDIS documentation, if a driver exports + * a MiniportSendPackets() routine, we prefer that over + * a MiniportSend() routine (which sends just a single + * packet). + */ + if (sc->ndis_chars->nmc_sendmulti_func != NULL) + ndis_send_packets(sc, p0, 1); + else + ndis_send_packet(sc, p); + + return (0); +} + static void -ndis_init(xsc) - void *xsc; +ndis_80211parent(struct ieee80211com *ic) +{ + struct ndis_softc *sc = ic->ic_softc; + + /*NDIS_LOCK(sc);*/ + if (ic->ic_nrunning > 0) { + if (!sc->ndis_running) + ndis_init(sc); + } else if (sc->ndis_running) + ndis_stop(sc); + /*NDIS_UNLOCK(sc);*/ +} + +static void +ndis_init(void *xsc) { struct ndis_softc *sc = xsc; - struct ifnet *ifp = sc->ifp; - struct ieee80211com *ic = ifp->if_l2com; int i, len, error; /* @@ -1971,17 +2069,21 @@ ndis_init(xsc) } } - /* Init our MAC address */ - /* Program the packet filter */ + sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED | + NDIS_PACKET_TYPE_BROADCAST; - sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED; + if (sc->ndis_80211) { + struct ieee80211com *ic = &sc->ndis_ic; - if (ifp->if_flags & IFF_BROADCAST) - sc->ndis_filter |= NDIS_PACKET_TYPE_BROADCAST; + if (ic->ic_promisc > 0) + sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS; + } else { + struct ifnet *ifp = sc->ifp; - if (ifp->if_flags & IFF_PROMISC) - sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS; + if (ifp->if_flags & IFF_PROMISC) + sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS; + } len = sizeof(sc->ndis_filter); @@ -1994,7 +2096,10 @@ ndis_init(xsc) /* * Set lookahead. */ - i = ifp->if_mtu; + if (sc->ndis_80211) + i = ETHERMTU; + else + i = sc->ifp->if_mtu; len = sizeof(i); ndis_set_info(sc, OID_GEN_CURRENT_LOOKAHEAD, &i, &len); @@ -2012,10 +2117,12 @@ ndis_init(xsc) sc->ndis_txpending = sc->ndis_maxpkts; sc->ndis_link = 0; - if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN); + if (!sc->ndis_80211) { + if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN); + sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + } - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->ndis_tx_timer = 0; /* @@ -2029,11 +2136,12 @@ ndis_init(xsc) sc->ndis_hang_timer = sc->ndis_block->nmb_checkforhangsecs; callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc); + sc->ndis_running = 1; NDIS_UNLOCK(sc); /* XXX force handling */ if (sc->ndis_80211) - ieee80211_start_all(ic); /* start all vap's */ + ieee80211_start_all(&sc->ndis_ic); /* start all vap's */ } /* @@ -2101,16 +2209,12 @@ ndis_ifmedia_sts(ifp, ifmr) } static int -ndis_set_cipher(sc, cipher) - struct ndis_softc *sc; - int cipher; +ndis_set_cipher(struct ndis_softc *sc, int cipher) { - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->ndis_ic; int rval = 0, len; uint32_t arg, save; - ic = sc->ifp->if_l2com; - len = sizeof(arg); if (cipher == WPA_CSE_WEP40 || cipher == WPA_CSE_WEP104) { @@ -2239,7 +2343,7 @@ static void ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr) { struct ieee80211vap *vap = ifp->if_softc; - struct ndis_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ndis_softc *sc = vap->iv_ic->ic_softc; uint32_t txrate; int len; @@ -2253,20 +2357,14 @@ ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr) } static void -ndis_setstate_80211(sc) - struct ndis_softc *sc; +ndis_setstate_80211(struct ndis_softc *sc) { - struct ieee80211com *ic; - struct ieee80211vap *vap; + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); ndis_80211_macaddr bssid; ndis_80211_config config; int rval = 0, len; uint32_t arg; - struct ifnet *ifp; - - ifp = sc->ifp; - ic = ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); if (!NDIS_INITIALIZED(sc)) { DPRINTF(("%s: NDIS not initialized\n", __func__)); @@ -2371,7 +2469,7 @@ ndis_setstate_80211(sc) /* Set the BSSID to our value so the driver doesn't associate */ len = IEEE80211_ADDR_LEN; - bcopy(IF_LLADDR(ifp), bssid, len); + bcopy(vap->iv_myaddr, bssid, len); DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":")); rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len); if (rval) @@ -2380,22 +2478,14 @@ ndis_setstate_80211(sc) } static void -ndis_auth_and_assoc(sc, vap) - struct ndis_softc *sc; - struct ieee80211vap *vap; +ndis_auth_and_assoc(struct ndis_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic; - struct ieee80211_node *ni; + struct ieee80211_node *ni = vap->iv_bss; ndis_80211_ssid ssid; ndis_80211_macaddr bssid; ndis_80211_wep wep; int i, rval = 0, len, error; uint32_t arg; - struct ifnet *ifp; - - ifp = sc->ifp; - ic = ifp->if_l2com; - ni = vap->iv_bss; if (!NDIS_INITIALIZED(sc)) { DPRINTF(("%s: NDIS not initialized\n", __func__)); @@ -2562,7 +2652,7 @@ ndis_auth_and_assoc(sc, vap) vap->iv_opmode != IEEE80211_M_IBSS) bcopy(ni->ni_bssid, bssid, len); else - bcopy(ifp->if_broadcastaddr, bssid, len); + bcopy(ieee80211broadcastaddr, bssid, len); DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":")); rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len); @@ -2627,12 +2717,9 @@ ndis_get_bssid_list(sc, bl) } static int -ndis_get_assoc(sc, assoc) - struct ndis_softc *sc; - ndis_wlan_bssid_ex **assoc; +ndis_get_assoc(struct ndis_softc *sc, ndis_wlan_bssid_ex **assoc) { - struct ifnet *ifp = sc->ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->ndis_ic; struct ieee80211vap *vap; struct ieee80211_node *ni; ndis_80211_bssid_list_ex *bl; @@ -2679,22 +2766,15 @@ ndis_get_assoc(sc, assoc) } static void -ndis_getstate_80211(sc) - struct ndis_softc *sc; +ndis_getstate_80211(struct ndis_softc *sc) { - struct ieee80211com *ic; - struct ieee80211vap *vap; - struct ieee80211_node *ni; + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211_node *ni = vap->iv_bss; ndis_wlan_bssid_ex *bs; int rval, len, i = 0; int chanflag; uint32_t arg; - struct ifnet *ifp; - - ifp = sc->ifp; - ic = ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); - ni = vap->iv_bss; if (!NDIS_INITIALIZED(sc)) return; @@ -2813,7 +2893,7 @@ ndis_ioctl(ifp, command, data) switch (command) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && + if (sc->ndis_running && ifp->if_flags & IFF_PROMISC && !(sc->ndis_if_flags & IFF_PROMISC)) { sc->ndis_filter |= @@ -2822,7 +2902,7 @@ ndis_ioctl(ifp, command, data) error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER, &sc->ndis_filter, &i); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && + } else if (sc->ndis_running && !(ifp->if_flags & IFF_PROMISC) && sc->ndis_if_flags & IFF_PROMISC) { sc->ndis_filter &= @@ -2834,7 +2914,7 @@ ndis_ioctl(ifp, command, data) } else ndis_init(sc); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->ndis_running) ndis_stop(sc); } sc->ndis_if_flags = ifp->if_flags; @@ -2868,101 +2948,48 @@ ndis_ioctl(ifp, command, data) } static int -ndis_ioctl_80211(ifp, command, data) - struct ifnet *ifp; - u_long command; - caddr_t data; +ndis_80211ioctl(struct ieee80211com *ic, u_long cmd, void *data) { - struct ndis_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - struct ndis_oid_data oid; - struct ndis_evt evt; - void *oidbuf; - int error = 0; + struct ndis_softc *sc = ic->ic_softc; + struct ifreq *ifr = data; + struct ndis_oid_data oid; + struct ndis_evt evt; + void *oidbuf = NULL; + int error = 0; - switch (command) { - case SIOCSIFFLAGS: - /*NDIS_LOCK(sc);*/ - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - ndis_init(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ndis_stop(sc); - } - sc->ndis_if_flags = ifp->if_flags; - error = 0; - /*NDIS_UNLOCK(sc);*/ - break; + if ((error = priv_check(curthread, PRIV_DRIVER)) != 0) + return (error); + + switch (cmd) { case SIOCGDRVSPEC: - if ((error = priv_check(curthread, PRIV_DRIVER))) - break; - error = copyin(ifr->ifr_data, &oid, sizeof(oid)); + case SIOCSDRVSPEC: + error = copyin(ifr->ifr_data, &oid, sizeof(oid)); if (error) break; - oidbuf = malloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO); - if (oidbuf == NULL) { - error = ENOMEM; - break; - } - error = copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len); - if (error) { - free(oidbuf, M_TEMP); - break; - } - error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len); - if (error) { - free(oidbuf, M_TEMP); - break; - } - error = copyout(&oid, ifr->ifr_data, sizeof(oid)); - if (error) { - free(oidbuf, M_TEMP); - break; - } - error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len); + oidbuf = malloc(oid.len, M_TEMP, M_WAITOK | M_ZERO); + error = copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len); + } + + if (error) { free(oidbuf, M_TEMP); + return (error); + } + + switch (cmd) { + case SIOCGDRVSPEC: + error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len); break; case SIOCSDRVSPEC: - if ((error = priv_check(curthread, PRIV_DRIVER))) - break; - error = copyin(ifr->ifr_data, &oid, sizeof(oid)); - if (error) - break; - oidbuf = malloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO); - if (oidbuf == NULL) { - error = ENOMEM; - break; - } - error = copyin(ifr->ifr_data + sizeof(oid), oidbuf, oid.len); - if (error) { - free(oidbuf, M_TEMP); - break; - } error = ndis_set_info(sc, oid.oid, oidbuf, &oid.len); - if (error) { - free(oidbuf, M_TEMP); - break; - } - error = copyout(&oid, ifr->ifr_data, sizeof(oid)); - if (error) { - free(oidbuf, M_TEMP); - break; - } - error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len); - free(oidbuf, M_TEMP); break; case SIOCGPRIVATE_0: - if ((error = priv_check(curthread, PRIV_DRIVER))) - break; NDIS_LOCK(sc); if (sc->ndis_evt[sc->ndis_evtcidx].ne_sts == 0) { error = ENOENT; NDIS_UNLOCK(sc); break; } - error = copyin(ifr->ifr_data, &evt, sizeof(evt)); + error = copyin(ifr->ifr_data, &evt, sizeof(evt)); if (error) { NDIS_UNLOCK(sc); break; @@ -2994,30 +3021,32 @@ ndis_ioctl_80211(ifp, command, data) NDIS_EVTINC(sc->ndis_evtcidx); NDIS_UNLOCK(sc); break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, command, data); - break; default: - error = EINVAL; + error = ENOTTY; break; } + + switch (cmd) { + case SIOCGDRVSPEC: + case SIOCSDRVSPEC: + error = copyout(&oid, ifr->ifr_data, sizeof(oid)); + if (error) + break; + error = copyout(oidbuf, ifr->ifr_data + sizeof(oid), oid.len); + } + + free(oidbuf, M_TEMP); + return (error); } int -ndis_del_key(vap, key) - struct ieee80211vap *vap; - const struct ieee80211_key *key; +ndis_del_key(struct ieee80211vap *vap, const struct ieee80211_key *key) { - struct ndis_softc *sc; + struct ndis_softc *sc = vap->iv_ic->ic_softc; ndis_80211_key rkey; int len, error = 0; - sc = vap->iv_ic->ic_ifp->if_softc; - bzero((char *)&rkey, sizeof(rkey)); len = sizeof(rkey); @@ -3041,19 +3070,13 @@ ndis_del_key(vap, key) * set after initial authentication with the AP. */ static int -ndis_add_key(vap, key, mac) - struct ieee80211vap *vap; - const struct ieee80211_key *key; - const uint8_t mac[IEEE80211_ADDR_LEN]; +ndis_add_key(struct ieee80211vap *vap, const struct ieee80211_key *key, + const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ndis_softc *sc; - struct ifnet *ifp; + struct ndis_softc *sc = vap->iv_ic->ic_softc; ndis_80211_key rkey; int len, error = 0; - ifp = vap->iv_ic->ic_ifp; - sc = ifp->if_softc; - switch (key->wk_cipher->ic_cipher) { case IEEE80211_CIPHER_TKIP: @@ -3077,7 +3100,7 @@ ndis_add_key(vap, key, mac) rkey.nk_keyidx |= 1 << 31; if (key->wk_flags & IEEE80211_KEY_GROUP) { - bcopy(ifp->if_broadcastaddr, + bcopy(ieee80211broadcastaddr, rkey.nk_bssid, IEEE80211_ADDR_LEN); } else { bcopy(vap->iv_bss->ni_bssid, @@ -3138,19 +3161,18 @@ ndis_resettask(d, arg) * RX and TX lists. */ static void -ndis_stop(sc) - struct ndis_softc *sc; +ndis_stop(struct ndis_softc *sc) { - struct ifnet *ifp; int i; - ifp = sc->ifp; callout_drain(&sc->ndis_stat_callout); NDIS_LOCK(sc); sc->ndis_tx_timer = 0; sc->ndis_link = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + if (!sc->ndis_80211) + sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->ndis_running = 0; NDIS_UNLOCK(sc); if (sc->ndis_iftype != PNPBus || @@ -3192,8 +3214,7 @@ ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ndis_vap *nvp = NDIS_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ndis_softc *sc = ifp->if_softc; + struct ndis_softc *sc = ic->ic_softc; enum ieee80211_state ostate; DPRINTF(("%s: %s -> %s\n", __func__, @@ -3239,8 +3260,8 @@ ndis_scan(void *arg) static void ndis_scan_results(struct ndis_softc *sc) { - struct ieee80211com *ic; - struct ieee80211vap *vap; + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); ndis_80211_bssid_list_ex *bl; ndis_wlan_bssid_ex *wb; struct ieee80211_scanparams sp; @@ -3252,8 +3273,6 @@ ndis_scan_results(struct ndis_softc *sc) uint8_t rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t *frm, *efrm; - ic = sc->ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); saved_chan = ic->ic_curchan; noise = -96; @@ -3329,8 +3348,7 @@ ndis_scan_results(struct ndis_softc *sc) static void ndis_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ndis_softc *sc = ifp->if_softc; + struct ndis_softc *sc = ic->ic_softc; struct ieee80211vap *vap; struct ieee80211_scan_state *ss; ndis_80211_ssid ssid; @@ -3391,7 +3409,7 @@ ndis_scan_mindwell(struct ieee80211_scan_state *ss) static void ndis_scan_end(struct ieee80211com *ic) { - struct ndis_softc *sc = ic->ic_ifp->if_softc; + struct ndis_softc *sc = ic->ic_softc; ndis_scan_results(sc); } diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h index f98db0a203cd..e3b1a39c35c5 100644 --- a/sys/dev/if_ndis/if_ndisvar.h +++ b/sys/dev/if_ndis/if_ndisvar.h @@ -152,8 +152,22 @@ struct ndisusb_task { }; struct ndis_softc { - struct ifnet *ifp; - struct ifmedia ifmedia; /* media info */ + u_int ndis_80211:1, + ndis_link:1, + ndis_running:1; + union { + struct { /* Ethernet */ + struct ifnet *ifp; + struct ifmedia ifmedia; + int ndis_if_flags; + }; + struct { /* Wireless */ + struct ieee80211com ndis_ic; + struct callout ndis_scan_callout; + int (*ndis_newstate)(struct ieee80211com *, + enum ieee80211_state, int); + }; + }; u_long ndis_hwassist; uint32_t ndis_v4tx; uint32_t ndis_v4rx; @@ -180,7 +194,6 @@ struct ndis_softc { ndis_miniport_block *ndis_block; ndis_miniport_characteristics *ndis_chars; interface_type ndis_type; - struct callout ndis_scan_callout; struct callout ndis_stat_callout; int ndis_maxpkts; ndis_oid *ndis_oids; @@ -192,13 +205,9 @@ struct ndis_softc { int ndis_sc; ndis_cfg *ndis_regvals; struct nch ndis_cfglist_head; - int ndis_80211; - int ndis_link; uint32_t ndis_sts; uint32_t ndis_filter; - int ndis_if_flags; int ndis_skip; - int ndis_devidx; interface_type ndis_iftype; driver_object *ndis_dobj; @@ -217,11 +226,9 @@ struct ndis_softc { struct ndis_evt ndis_evt[NDIS_EVENTS]; int ndis_evtpidx; int ndis_evtcidx; - struct ifqueue ndis_rxqueue; + struct mbufq ndis_rxqueue; kspin_lock ndis_rxlock; - int (*ndis_newstate)(struct ieee80211com *, - enum ieee80211_state, int); int ndis_tx_timer; int ndis_hang_timer; diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index d3eb85e8f188..1ffd24c5243d 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -127,14 +127,14 @@ static void ipw_intr(void *); static void ipw_dma_map_addr(void *, bus_dma_segment_t *, int, int); static const char * ipw_cmdname(int); static int ipw_cmd(struct ipw_softc *, uint32_t, void *, uint32_t); -static int ipw_tx_start(struct ifnet *, struct mbuf *, +static int ipw_tx_start(struct ipw_softc *, struct mbuf *, struct ieee80211_node *); static int ipw_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void ipw_start(struct ifnet *); -static void ipw_start_locked(struct ifnet *); +static int ipw_transmit(struct ieee80211com *, struct mbuf *); +static void ipw_start(struct ipw_softc *); static void ipw_watchdog(void *); -static int ipw_ioctl(struct ifnet *, u_long, caddr_t); +static void ipw_parent(struct ieee80211com *); static void ipw_stop_master(struct ipw_softc *); static int ipw_enable(struct ipw_softc *); static int ipw_disable(struct ipw_softc *); @@ -220,18 +220,16 @@ static int ipw_attach(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_channel *c; uint16_t val; int error, i; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); - + mbufq_init(&sc->sc_snd, ifqmaxlen); TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc); callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); @@ -268,24 +266,6 @@ ipw_attach(device_t dev) goto fail2; } - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - goto fail3; - } - ic = ifp->if_l2com; - - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = ipw_init; - ifp->if_ioctl = ipw_ioctl; - ifp->if_start = ipw_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_opmode = IEEE80211_M_STA; @@ -303,14 +283,14 @@ ipw_attach(device_t dev) /* read MAC address from EEPROM */ val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0); - macaddr[0] = val >> 8; - macaddr[1] = val & 0xff; + ic->ic_macaddr[0] = val >> 8; + ic->ic_macaddr[1] = val & 0xff; val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 1); - macaddr[2] = val >> 8; - macaddr[3] = val & 0xff; + ic->ic_macaddr[2] = val >> 8; + ic->ic_macaddr[3] = val & 0xff; val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 2); - macaddr[4] = val >> 8; - macaddr[5] = val & 0xff; + ic->ic_macaddr[4] = val >> 8; + ic->ic_macaddr[5] = val & 0xff; /* set supported .11b channels (read from EEPROM) */ if ((val = ipw_read_prom_word(sc, IPW_EEPROM_CHANNEL_LIST)) == 0) @@ -329,16 +309,17 @@ ipw_attach(device_t dev) if (!(ipw_read_prom_word(sc, IPW_EEPROM_RADIO) & 8)) sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH; - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_scan_start = ipw_scan_start; ic->ic_scan_end = ipw_scan_end; ic->ic_set_channel = ipw_set_channel; ic->ic_scan_curchan = ipw_scan_curchan; ic->ic_scan_mindwell = ipw_scan_mindwell; ic->ic_raw_xmit = ipw_raw_xmit; - ic->ic_vap_create = ipw_vap_create; ic->ic_vap_delete = ipw_vap_delete; + ic->ic_transmit = ipw_transmit; + ic->ic_parent = ipw_parent; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -366,15 +347,13 @@ ipw_attach(device_t dev) NULL, ipw_intr, sc, &sc->sc_ih); if (error != 0) { device_printf(dev, "could not set up interrupt\n"); - goto fail4; + goto fail3; } if (bootverbose) ieee80211_announce(ic); return 0; -fail4: - if_free(ifp); fail3: ipw_release(sc); fail2: @@ -391,8 +370,7 @@ static int ipw_detach(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; bus_teardown_intr(dev, sc->irq, sc->sc_ih); @@ -402,6 +380,7 @@ ipw_detach(device_t dev) ieee80211_ifdetach(ic); callout_drain(&sc->sc_wdtimer); + mbufq_drain(&sc->sc_snd); ipw_release(sc); @@ -410,8 +389,6 @@ ipw_detach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem), sc->mem); - if_free(ifp); - if (sc->sc_firmware != NULL) { firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD); sc->sc_firmware = NULL; @@ -428,8 +405,7 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; struct ipw_vap *ivp; struct ieee80211vap *vap; const struct firmware *fp; @@ -487,19 +463,17 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, return NULL; } - ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (ivp == NULL) - return NULL; + ivp = malloc(sizeof(struct ipw_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &ivp->vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override with driver methods */ ivp->newstate = vap->iv_newstate; vap->iv_newstate = ipw_newstate; /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status, + mac); ic->ic_opmode = opmode; return vap; } @@ -827,7 +801,7 @@ static int ipw_suspend(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; ieee80211_suspend_all(ic); return 0; @@ -837,7 +811,7 @@ static int ipw_resume(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; pci_write_config(dev, 0x41, 0, 1); @@ -866,7 +840,7 @@ ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr) { struct ieee80211vap *vap = ifp->if_softc; struct ieee80211com *ic = vap->iv_ic; - struct ipw_softc *sc = ic->ic_ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; /* read current transmission rate from adapter */ vap->iv_bss->ni_txrate = ipw_cvtrate( @@ -879,8 +853,7 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ipw_vap *ivp = IPW_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; enum ieee80211_state ostate; DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, @@ -1015,8 +988,7 @@ static void ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) { #define IEEESTATE(vap) ieee80211_state_name[vap->iv_state] - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t state; @@ -1118,8 +1090,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) static void ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; ic->ic_curchan = chan; ieee80211_radiotap_chan_change(ic); @@ -1132,8 +1103,7 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan) static void ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_channel *c; struct ieee80211_frame *wh; uint8_t subtype; @@ -1178,8 +1148,7 @@ static void ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mbuf *mnew, *m; struct ieee80211_node *ni; bus_addr_t physaddr; @@ -1201,7 +1170,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -1222,7 +1191,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -1233,9 +1202,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, m = sbuf->m; sbuf->m = mnew; sbd->bd->physaddr = htole32(physaddr); - - /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = le32toh(status->len); rssi = status->rssi + IPW_RSSI_TO_DBM; @@ -1364,7 +1330,6 @@ ipw_release_sbd(struct ipw_softc *sc, struct ipw_soft_bd *sbd) static void ipw_tx_intr(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct ipw_soft_bd *sbd; uint32_t r, i; @@ -1375,10 +1340,6 @@ ipw_tx_intr(struct ipw_softc *sc) for (i = (sc->txold + 1) % IPW_NTBD; i != r; i = (i + 1) % IPW_NTBD) { sbd = &sc->stbd_list[i]; - - if (sbd->type == IPW_SBD_TYPE_DATA) - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ipw_release_sbd(sc, sbd); sc->txfree++; } @@ -1386,15 +1347,13 @@ ipw_tx_intr(struct ipw_softc *sc) /* remember what the firmware has processed */ sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ipw_start_locked(ifp); + ipw_start(sc); } static void ipw_fatal_error_intr(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "firmware error\n"); @@ -1579,10 +1538,9 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len) } static int -ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) +ipw_tx_start(struct ipw_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_frame *wh; struct ipw_soft_bd *sbd; @@ -1736,38 +1694,42 @@ ipw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; } -static void -ipw_start(struct ifnet *ifp) +static int +ipw_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; + int error; IPW_LOCK(sc); - ipw_start_locked(ifp); + if ((sc->flags & IPW_FLAG_RUNNING) == 0) { + IPW_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + IPW_UNLOCK(sc); + return (error); + } + ipw_start(sc); IPW_UNLOCK(sc); + return (0); } static void -ipw_start_locked(struct ifnet *ifp) +ipw_start(struct ipw_softc *sc) { - struct ipw_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; IPW_LOCK_ASSERT(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->txfree < 1 + IPW_MAX_NSEG) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } + while (sc->txfree < 1 + IPW_MAX_NSEG && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - if (ipw_tx_start(ifp, m, ni) != 0) { + if (ipw_tx_start(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); break; } /* start watchdog timer */ @@ -1779,15 +1741,14 @@ static void ipw_watchdog(void *arg) { struct ipw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; IPW_LOCK_ASSERT(sc); if (sc->sc_tx_timer > 0) { if (--sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, "device timeout\n"); + counter_u64_add(ic->ic_oerrors, 1); taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task); } } @@ -1803,45 +1764,27 @@ ipw_watchdog(void *arg) } } } - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->flags & IPW_FLAG_RUNNING) callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc); } -static int -ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +ipw_parent(struct ieee80211com *ic) { - struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct ipw_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - IPW_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - ipw_init_locked(sc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ipw_stop_locked(sc); + IPW_LOCK(sc); + if (ic->ic_nrunning > 0) { + if (!(sc->flags & IPW_FLAG_RUNNING)) { + ipw_init_locked(sc); + startall = 1; } - IPW_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; + } else if (sc->flags & IPW_FLAG_RUNNING) + ipw_stop_locked(sc); + IPW_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -2057,8 +2000,7 @@ ipw_load_firmware(struct ipw_softc *sc, const char *fw, int size) static int ipw_setwepkeys(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ipw_wep_key wepkey; struct ieee80211_key *wk; @@ -2201,8 +2143,7 @@ ipw_scan(struct ipw_softc *sc) static int ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t data; int error; @@ -2217,8 +2158,7 @@ ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan) static void ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap) { - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; struct ieee80211_node *ni = vap->iv_bss; struct ipw_security security; uint32_t data; @@ -2309,9 +2249,8 @@ ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap) static void ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap) { - struct ifnet *ifp = vap->iv_ic->ic_ifp; struct ieee80211_node *ni = vap->iv_bss; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; IPW_LOCK(sc); DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":")); @@ -2345,22 +2284,20 @@ static void ipw_init(void *priv) { struct ipw_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; IPW_LOCK(sc); ipw_init_locked(sc); IPW_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->flags & IPW_FLAG_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } static void ipw_init_locked(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); const struct firmware *fp; const struct ipw_firmware_hdr *hdr; @@ -2444,22 +2381,19 @@ ipw_init_locked(struct ipw_softc *sc) } callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - - sc->flags &=~ IPW_FLAG_INIT_LOCKED; + sc->flags |= IPW_FLAG_RUNNING; + sc->flags &= ~IPW_FLAG_INIT_LOCKED; return; fail: ipw_stop_locked(sc); - sc->flags &=~ IPW_FLAG_INIT_LOCKED; + sc->flags &= ~IPW_FLAG_INIT_LOCKED; } static int ipw_config(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ipw_configuration config; uint32_t data; int error; @@ -2504,7 +2438,7 @@ ipw_config(struct ipw_softc *sc) IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE); if (ic->ic_opmode == IEEE80211_M_IBSS) config.flags |= htole32(IPW_CFG_IBSS_AUTO_START); - if (ifp->if_flags & IFF_PROMISC) + if (ic->ic_promisc > 0) config.flags |= htole32(IPW_CFG_PROMISCUOUS); config.bss_chan = htole32(0x3fff); /* channels 1-14 */ config.ibss_chan = htole32(0x7ff); /* channels 1-11 */ @@ -2562,7 +2496,6 @@ ipw_stop(void *priv) static void ipw_stop_locked(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int i; IPW_LOCK_ASSERT(sc); @@ -2579,7 +2512,7 @@ ipw_stop_locked(struct ipw_softc *sc) ipw_release_sbd(sc, &sc->stbd_list[i]); sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->flags &= ~IPW_FLAG_RUNNING; } static int @@ -2677,8 +2610,7 @@ ipw_write_mem_1(struct ipw_softc *sc, bus_size_t offset, const uint8_t *datap, static void ipw_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; IPW_LOCK(sc); ipw_scan(sc); @@ -2688,8 +2620,7 @@ ipw_scan_start(struct ieee80211com *ic) static void ipw_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; IPW_LOCK(sc); if (ic->ic_opmode == IEEE80211_M_MONITOR) { @@ -2715,8 +2646,7 @@ ipw_scan_mindwell(struct ieee80211_scan_state *ss) static void ipw_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; IPW_LOCK(sc); sc->flags &= ~IPW_FLAG_SCANNING; diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h index cca050f3e469..aa3ba5bb4944 100644 --- a/sys/dev/ipw/if_ipwvar.h +++ b/sys/dev/ipw/if_ipwvar.h @@ -87,7 +87,8 @@ struct ipw_vap { #define IPW_VAP(vap) ((struct ipw_vap *)(vap)) struct ipw_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct mtx sc_mtx; @@ -104,6 +105,7 @@ struct ipw_softc { #define IPW_FLAG_BUSY 0x0040 #define IPW_FLAG_ASSOCIATING 0x0080 #define IPW_FLAG_ASSOCIATED 0x0100 +#define IPW_FLAG_RUNNING 0x0200 struct resource *irq; struct resource *mem; diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index fecbe89c4562..73631eaa1e5f 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -166,14 +166,15 @@ static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *); static void iwi_intr(void *); static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t); static void iwi_write_ibssnode(struct iwi_softc *, const u_int8_t [], int); -static int iwi_tx_start(struct ifnet *, struct mbuf *, +static int iwi_tx_start(struct iwi_softc *, struct mbuf *, struct ieee80211_node *, int); static int iwi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void iwi_start_locked(struct ifnet *); -static void iwi_start(struct ifnet *); +static void iwi_start(struct iwi_softc *); +static int iwi_transmit(struct ieee80211com *, struct mbuf *); static void iwi_watchdog(void *); -static int iwi_ioctl(struct ifnet *, u_long, caddr_t); +static int iwi_ioctl(struct ieee80211com *, u_long, void *); +static void iwi_parent(struct ieee80211com *); static void iwi_stop_master(struct iwi_softc *); static int iwi_reset(struct iwi_softc *); static int iwi_load_ucode(struct iwi_softc *, const struct iwi_fw *); @@ -269,23 +270,15 @@ static int iwi_attach(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; uint16_t val; int i, error; uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - return ENXIO; - } - ic = ifp->if_l2com; - IWI_LOCK_INIT(sc); + mbufq_init(&sc->sc_snd, ifqmaxlen); sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx); @@ -353,17 +346,6 @@ iwi_attach(device_t dev) iwi_wme_init(sc); - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = iwi_init; - ifp->if_ioctl = iwi_ioctl; - ifp->if_start = iwi_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_opmode = IEEE80211_M_STA; @@ -385,14 +367,14 @@ iwi_attach(device_t dev) /* read MAC address from EEPROM */ val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0); - macaddr[0] = val & 0xff; - macaddr[1] = val >> 8; + ic->ic_macaddr[0] = val & 0xff; + ic->ic_macaddr[1] = val >> 8; val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 1); - macaddr[2] = val & 0xff; - macaddr[3] = val >> 8; + ic->ic_macaddr[2] = val & 0xff; + ic->ic_macaddr[3] = val >> 8; val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 2); - macaddr[4] = val & 0xff; - macaddr[5] = val >> 8; + ic->ic_macaddr[4] = val & 0xff; + ic->ic_macaddr[5] = val >> 8; bands = 0; setbit(&bands, IEEE80211_MODE_11B); @@ -401,7 +383,7 @@ iwi_attach(device_t dev) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); /* override default methods */ ic->ic_node_alloc = iwi_node_alloc; sc->sc_node_free = ic->ic_node_free; @@ -416,6 +398,9 @@ iwi_attach(device_t dev) ic->ic_vap_create = iwi_vap_create; ic->ic_vap_delete = iwi_vap_delete; + ic->ic_ioctl = iwi_ioctl; + ic->ic_transmit = iwi_transmit; + ic->ic_parent = iwi_parent; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -450,8 +435,7 @@ static int iwi_detach(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; bus_teardown_intr(dev, sc->irq, sc->sc_ih); @@ -482,11 +466,10 @@ iwi_detach(device_t dev) sc->mem); delete_unrhdr(sc->sc_unr); + mbufq_drain(&sc->sc_snd); IWI_LOCK_DESTROY(sc); - if_free(ifp); - return 0; } @@ -496,8 +479,7 @@ iwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; - struct iwi_softc *sc = ifp->if_softc; + struct iwi_softc *sc = ic->ic_softc; struct iwi_vap *ivp; struct ieee80211vap *vap; int i; @@ -519,12 +501,9 @@ iwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (iwi_init_fw_dma(sc, i)) return NULL; - ivp = (struct iwi_vap *) malloc(sizeof(struct iwi_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (ivp == NULL) - return NULL; + ivp = malloc(sizeof(struct iwi_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &ivp->iwi_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override the default, the setting comes from the linux driver */ vap->iv_bmissthreshold = 24; /* override with driver methods */ @@ -532,7 +511,8 @@ iwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, vap->iv_newstate = iwi_newstate; /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, iwi_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, iwi_media_status, + mac); ic->ic_opmode = opmode; return vap; } @@ -859,7 +839,7 @@ static int iwi_suspend(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; ieee80211_suspend_all(ic); return 0; @@ -869,7 +849,7 @@ static int iwi_resume(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; pci_write_config(dev, 0x41, 0, 1); @@ -895,7 +875,7 @@ static void iwi_node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct iwi_softc *sc = ic->ic_ifp->if_softc; + struct iwi_softc *sc = ic->ic_softc; struct iwi_node *in = (struct iwi_node *)ni; if (in->in_station != -1) { @@ -939,7 +919,7 @@ iwi_media_status(struct ifnet *ifp, struct ifmediareq *imr) { struct ieee80211vap *vap = ifp->if_softc; struct ieee80211com *ic = vap->iv_ic; - struct iwi_softc *sc = ic->ic_ifp->if_softc; + struct iwi_softc *sc = ic->ic_softc; struct ieee80211_node *ni; /* read current transmission rate from adapter */ @@ -955,8 +935,7 @@ iwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct iwi_vap *ivp = IWI_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct iwi_softc *sc = ifp->if_softc; + struct iwi_softc *sc = ic->ic_softc; IWI_LOCK_DECL; DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, @@ -1061,7 +1040,7 @@ iwi_wme_init(struct iwi_softc *sc) static int iwi_wme_setparams(struct iwi_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct wmeParams *wmep; int ac; @@ -1095,7 +1074,7 @@ iwi_update_wme(void *arg, int npending) static int iwi_wme_update(struct ieee80211com *ic) { - struct iwi_softc *sc = ic->ic_ifp->if_softc; + struct iwi_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); /* @@ -1189,8 +1168,7 @@ iwi_read_prom_word(struct iwi_softc *sc, uint8_t addr) static void iwi_setcurchan(struct iwi_softc *sc, int chan) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; sc->curchan = chan; ieee80211_radiotap_chan_change(ic); @@ -1200,8 +1178,7 @@ static void iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, struct iwi_frame *frame) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mbuf *mnew, *m; struct ieee80211_node *ni; int type, error, framelen; @@ -1237,7 +1214,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -1258,7 +1235,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -1271,7 +1248,6 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, CSR_WRITE_4(sc, data->reg, data->physaddr); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = sizeof (struct iwi_hdr) + sizeof (struct iwi_frame) + framelen; @@ -1410,8 +1386,7 @@ iwi_notif_link_quality(struct iwi_softc *sc, struct iwi_notif *notif) static void iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct iwi_notif_scan_channel *chan; struct iwi_notif_scan_complete *scan; @@ -1632,47 +1607,33 @@ iwi_rx_intr(struct iwi_softc *sc) static void iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq) { - struct ifnet *ifp = sc->sc_ifp; struct iwi_tx_data *data; uint32_t hw; hw = CSR_READ_4(sc, txq->csr_ridx); - for (; txq->next != hw;) { + while (txq->next != hw) { data = &txq->data[txq->next]; - + DPRINTFN(15, ("tx done idx=%u\n", txq->next)); bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(txq->data_dmat, data->map); - if (data->m->m_flags & M_TXCB) - ieee80211_process_callback(data->ni, data->m, 0/*XXX*/); - m_freem(data->m); - data->m = NULL; - ieee80211_free_node(data->ni); + ieee80211_tx_complete(data->ni, data->m, 0); data->ni = NULL; - - DPRINTFN(15, ("tx done idx=%u\n", txq->next)); - - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - + data->m = NULL; txq->queued--; txq->next = (txq->next + 1) % IWI_TX_RING_COUNT; } - sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if (sc->sc_softled) iwi_led_event(sc, IWI_LED_TX); - - iwi_start_locked(ifp); + iwi_start(sc); } static void iwi_fatal_error_intr(struct iwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "firmware error\n"); @@ -1688,10 +1649,8 @@ iwi_fatal_error_intr(struct iwi_softc *sc) static void iwi_radio_off_intr(struct iwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - ieee80211_runtask(ic, &sc->sc_radiofftask); + ieee80211_runtask(&sc->sc_ic, &sc->sc_radiofftask); } static void @@ -1806,10 +1765,9 @@ iwi_write_ibssnode(struct iwi_softc *sc, } static int -iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, +iwi_tx_start(struct iwi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, int ac) { - struct iwi_softc *sc = ifp->if_softc; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct iwi_node *in = (struct iwi_node *)ni; @@ -1852,9 +1810,10 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, in->in_station = alloc_unr(sc->sc_unr); if (in->in_station == -1) { /* h/w table is full */ + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); m_freem(m0); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); return 0; } iwi_write_ibssnode(sc, @@ -1980,141 +1939,139 @@ iwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; } -static void -iwi_start_locked(struct ifnet *ifp) +static int +iwi_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct iwi_softc *sc = ic->ic_softc; + int error; + IWI_LOCK_DECL; + + IWI_LOCK(sc); + if (!sc->sc_running) { + IWI_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + IWI_UNLOCK(sc); + return (error); + } + iwi_start(sc); + IWI_UNLOCK(sc); + return (0); +} + +static void +iwi_start(struct iwi_softc *sc) { - struct iwi_softc *sc = ifp->if_softc; struct mbuf *m; struct ieee80211_node *ni; int ac; IWI_LOCK_ASSERT(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; - - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ac = M_WME_GETAC(m); if (sc->txq[ac].queued > IWI_TX_RING_COUNT - 8) { /* there is no place left in this ring; tail drop */ /* XXX tail drop */ - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + mbufq_prepend(&sc->sc_snd, m); break; } - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - if (iwi_tx_start(ifp, m, ni, ac) != 0) { + if (iwi_tx_start(sc, m, ni, ac) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); break; } - sc->sc_tx_timer = 5; } } -static void -iwi_start(struct ifnet *ifp) -{ - struct iwi_softc *sc = ifp->if_softc; - IWI_LOCK_DECL; - - IWI_LOCK(sc); - iwi_start_locked(ifp); - IWI_UNLOCK(sc); -} - static void iwi_watchdog(void *arg) { struct iwi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; IWI_LOCK_ASSERT(sc); if (sc->sc_tx_timer > 0) { if (--sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, "device timeout\n"); + counter_u64_add(ic->ic_oerrors, 1); ieee80211_runtask(ic, &sc->sc_restarttask); } } if (sc->sc_state_timer > 0) { if (--sc->sc_state_timer == 0) { - if_printf(ifp, "firmware stuck in state %d, resetting\n", + device_printf(sc->sc_dev, + "firmware stuck in state %d, resetting\n", sc->fw_state); - if (sc->fw_state == IWI_FW_SCANNING) { - struct ieee80211com *ic = ifp->if_l2com; + if (sc->fw_state == IWI_FW_SCANNING) ieee80211_cancel_scan(TAILQ_FIRST(&ic->ic_vaps)); - } ieee80211_runtask(ic, &sc->sc_restarttask); sc->sc_state_timer = 3; } } if (sc->sc_busy_timer > 0) { if (--sc->sc_busy_timer == 0) { - if_printf(ifp, "firmware command timeout, resetting\n"); + device_printf(sc->sc_dev, + "firmware command timeout, resetting\n"); ieee80211_runtask(ic, &sc->sc_restarttask); } } callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc); } -static int -iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +iwi_parent(struct ieee80211com *ic) { - struct iwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct iwi_softc *sc = ic->ic_softc; + int startall = 0; IWI_LOCK_DECL; - switch (cmd) { - case SIOCSIFFLAGS: - IWI_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - iwi_init_locked(sc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - iwi_stop_locked(sc); + IWI_LOCK(sc); + if (ic->ic_nrunning > 0) { + if (!sc->sc_running) { + iwi_init_locked(sc); + startall = 1; } - IWI_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; + } else if (sc->sc_running) + iwi_stop_locked(sc); + IWI_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); +} + +static int +iwi_ioctl(struct ieee80211com *ic, u_long cmd, void *data) +{ + struct ifreq *ifr = data; + struct iwi_softc *sc = ic->ic_softc; + int error; + IWI_LOCK_DECL; + + IWI_LOCK(sc); + switch (cmd) { case SIOCGIWISTATS: - IWI_LOCK(sc); /* XXX validate permissions/memory/etc? */ error = copyout(&sc->sc_linkqual, ifr->ifr_data, sizeof(struct iwi_notif_link_quality)); - IWI_UNLOCK(sc); break; case SIOCZIWISTATS: - IWI_LOCK(sc); memset(&sc->sc_linkqual, 0, sizeof(struct iwi_notif_link_quality)); - IWI_UNLOCK(sc); error = 0; break; default: - error = EINVAL; + error = ENOTTY; break; } - return error; + IWI_UNLOCK(sc); + + return (error); } static void @@ -2593,8 +2550,7 @@ iwi_setwepkeys(struct iwi_softc *sc, struct ieee80211vap *vap) static int iwi_config(struct iwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct iwi_configuration config; struct iwi_rateset rs; struct iwi_txpower power; @@ -2603,8 +2559,8 @@ iwi_config(struct iwi_softc *sc) IWI_LOCK_ASSERT(sc); - DPRINTF(("Setting MAC address to %6D\n", IF_LLADDR(ifp), ":")); - error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp), + DPRINTF(("Setting MAC address to %6D\n", ic->ic_macaddr, ":")); + error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, ic->ic_macaddr, IEEE80211_ADDR_LEN); if (error != 0) return error; @@ -2724,7 +2680,7 @@ iwi_monitor_scan(void *arg, int npending) static int iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int allchan) { - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_channel *chan; struct ieee80211_scan_state *ss; struct iwi_scan_ext scan; @@ -2741,7 +2697,6 @@ iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int allchan) } IWI_STATE_BEGIN(sc, IWI_FW_SCANNING); - ic = sc->sc_ifp->if_l2com; ss = ic->ic_scan; memset(&scan, 0, sizeof scan); @@ -3128,7 +3083,6 @@ iwi_init_fw_dma(struct iwi_softc *sc, int size) static void iwi_init_locked(struct iwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct iwi_rx_data *data; int i; @@ -3202,8 +3156,7 @@ iwi_init_locked(struct iwi_softc *sc) } callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_running = 1; return; fail: IWI_STATE_END(sc, IWI_FW_LOADING); @@ -3215,15 +3168,14 @@ static void iwi_init(void *priv) { struct iwi_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; IWI_LOCK_DECL; IWI_LOCK(sc); iwi_init_locked(sc); IWI_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_running) ieee80211_start_all(ic); } @@ -3231,11 +3183,10 @@ static void iwi_stop_locked(void *priv) { struct iwi_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; IWI_LOCK_ASSERT(sc); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_running = 0; if (sc->sc_softled) { callout_stop(&sc->sc_ledtimer); @@ -3296,7 +3247,7 @@ static void iwi_radio_on(void *arg, int pending) { struct iwi_softc *sc = arg; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; device_printf(sc->sc_dev, "radio turned on\n"); @@ -3317,10 +3268,7 @@ iwi_rfkill_poll(void *arg) * it is enabled so we must poll for the latter. */ if (!iwi_getrfkill(sc)) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - ieee80211_runtask(ic, &sc->sc_radiontask); + ieee80211_runtask(&sc->sc_ic, &sc->sc_radiontask); return; } callout_reset(&sc->sc_rftimer, 2*hz, iwi_rfkill_poll, sc); @@ -3330,7 +3278,7 @@ static void iwi_radio_off(void *arg, int pending) { struct iwi_softc *sc = arg; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; IWI_LOCK_DECL; device_printf(sc->sc_dev, "radio turned off\n"); @@ -3594,8 +3542,8 @@ iwi_scan_start(struct ieee80211com *ic) static void iwi_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct iwi_softc *sc = ifp->if_softc; + struct iwi_softc *sc = ic->ic_softc; + if (sc->fw_state == IWI_FW_IDLE) iwi_setcurchan(sc, ic->ic_curchan->ic_ieee); } @@ -3604,8 +3552,7 @@ static void iwi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) { struct ieee80211vap *vap = ss->ss_vap; - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct iwi_softc *sc = ifp->if_softc; + struct iwi_softc *sc = vap->iv_ic->ic_softc; IWI_LOCK_DECL; IWI_LOCK(sc); @@ -3623,8 +3570,7 @@ iwi_scan_mindwell(struct ieee80211_scan_state *ss) static void iwi_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct iwi_softc *sc = ifp->if_softc; + struct iwi_softc *sc = ic->ic_softc; IWI_LOCK_DECL; IWI_LOCK(sc); diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h index b38bbd91d2c0..47848e16c822 100644 --- a/sys/dev/iwi/if_iwivar.h +++ b/sys/dev/iwi/if_iwivar.h @@ -125,11 +125,13 @@ struct iwi_vap { #define IWI_VAP(vap) ((struct iwi_vap *)(vap)) struct iwi_softc { - struct ifnet *sc_ifp; - void (*sc_node_free)(struct ieee80211_node *); + struct mtx sc_mtx; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; - struct mtx sc_mtx; + void (*sc_node_free)(struct ieee80211_node *); + uint8_t sc_mcast[IEEE80211_ADDR_LEN]; struct unrhdr *sc_unr; @@ -193,7 +195,8 @@ struct iwi_softc { struct task sc_wmetask; /* set wme parameters */ struct task sc_monitortask; - unsigned int sc_softled : 1, /* enable LED gpio status */ + unsigned int sc_running : 1, /* initialized */ + sc_softled : 1, /* enable LED gpio status */ sc_ledstate: 1, /* LED on/off state */ sc_blinking: 1; /* LED blink operation active */ u_int sc_nictype; /* NIC type from EEPROM */ diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 3cd5d7b066dd..cfed420ce8dd 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -235,10 +235,11 @@ static int iwn_tx_data_raw(struct iwn_softc *, struct mbuf *, static void iwn_xmit_task(void *arg0, int pending); static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void iwn_start(struct ifnet *); -static void iwn_start_locked(struct ifnet *); +static int iwn_transmit(struct ieee80211com *, struct mbuf *); +static void iwn_start_locked(struct iwn_softc *); static void iwn_watchdog(void *); -static int iwn_ioctl(struct ifnet *, u_long, caddr_t); +static int iwn_ioctl(struct ieee80211com *, u_long , void *); +static void iwn_parent(struct ieee80211com *); static int iwn_cmd(struct iwn_softc *, int, const void *, int, int); static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *, int); @@ -336,7 +337,7 @@ static void iwn_radio_on(void *, int); static void iwn_radio_off(void *, int); static void iwn_panicked(void *, int); static void iwn_init_locked(struct iwn_softc *); -static void iwn_init(void *); +static void iwn_init(struct iwn_softc *); static void iwn_stop_locked(struct iwn_softc *); static void iwn_stop(struct iwn_softc *); static void iwn_scan_start(struct ieee80211com *); @@ -406,9 +407,7 @@ iwn_attach(device_t dev) { struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev); struct ieee80211com *ic; - struct ifnet *ifp; int i, error, rid; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; @@ -464,6 +463,7 @@ iwn_attach(device_t dev) } IWN_LOCK_INIT(sc); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* Read hardware revision and attach. */ sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> IWN_HW_REV_TYPE_SHIFT) @@ -549,14 +549,7 @@ iwn_attach(device_t dev) /* Clear pending interrupts. */ IWN_WRITE(sc, IWN_INT, 0xffffffff); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not allocate ifnet structure\n"); - goto fail; - } - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; + ic = &sc->sc_ic; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -581,7 +574,7 @@ iwn_attach(device_t dev) ; /* Read MAC address, channels, etc from EEPROM. */ - if ((error = iwn_read_eeprom(sc, macaddr)) != 0) { + if ((error = iwn_read_eeprom(sc, ic->ic_macaddr)) != 0) { device_printf(dev, "could not read EEPROM, error %d\n", error); goto fail; @@ -599,7 +592,7 @@ iwn_attach(device_t dev) if (bootverbose) { device_printf(dev, "MIMO %dT%dR, %.4s, address %6D\n", sc->ntxchains, sc->nrxchains, sc->eeprom_domain, - macaddr, ":"); + ic->ic_macaddr, ":"); } if (sc->sc_flags & IWN_FLAG_HAS_11N) { @@ -640,19 +633,12 @@ iwn_attach(device_t dev) ; } - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = iwn_init; - ifp->if_ioctl = iwn_ioctl; - ifp->if_start = iwn_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_vap_create = iwn_vap_create; + ic->ic_ioctl = iwn_ioctl; + ic->ic_parent = iwn_parent; ic->ic_vap_delete = iwn_vap_delete; + ic->ic_transmit = iwn_transmit; ic->ic_raw_xmit = iwn_raw_xmit; ic->ic_node_alloc = iwn_node_alloc; sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start; @@ -1293,10 +1279,9 @@ iwn5000_attach(struct iwn_softc *sc, uint16_t pid) static void iwn_radiotap_attach(struct iwn_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); - ieee80211_radiotap_attach(ic, + ieee80211_radiotap_attach(&sc->sc_ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), IWN_TX_RADIOTAP_PRESENT, &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), @@ -1326,21 +1311,14 @@ iwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, struct iwn_softc *sc = ic->ic_softc; struct iwn_vap *ivp; struct ieee80211vap *vap; - uint8_t mac1[IEEE80211_ADDR_LEN]; if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - IEEE80211_ADDR_COPY(mac1, mac); - - ivp = (struct iwn_vap *) malloc(sizeof(struct iwn_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (ivp == NULL) - return NULL; + ivp = malloc(sizeof(struct iwn_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &ivp->iv_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac1); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); ivp->ctx = IWN_RXON_BSS_CTX; - IEEE80211_ADDR_COPY(ivp->macaddr, mac1); vap->iv_bmissthreshold = 10; /* override default */ /* Override with driver methods. */ ivp->iv_newstate = vap->iv_newstate; @@ -1349,7 +1327,8 @@ iwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* Complete setup. */ - ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status, + mac); ic->ic_opmode = opmode; return vap; } @@ -1390,24 +1369,19 @@ static int iwn_detach(device_t dev) { struct iwn_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic; int qid; DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); - if (ifp != NULL) { - ic = ifp->if_l2com; - + if (sc->sc_ic.ic_softc != NULL) { /* Free the mbuf queue and node references */ IWN_LOCK(sc); iwn_xmit_queue_drain(sc); IWN_UNLOCK(sc); - ieee80211_draintask(ic, &sc->sc_reinit_task); - ieee80211_draintask(ic, &sc->sc_radioon_task); - ieee80211_draintask(ic, &sc->sc_radiooff_task); - + ieee80211_draintask(&sc->sc_ic, &sc->sc_reinit_task); + ieee80211_draintask(&sc->sc_ic, &sc->sc_radioon_task); + ieee80211_draintask(&sc->sc_ic, &sc->sc_radiooff_task); iwn_stop(sc); taskqueue_drain_all(sc->sc_tq); @@ -1415,9 +1389,11 @@ iwn_detach(device_t dev) callout_drain(&sc->watchdog_to); callout_drain(&sc->calib_to); - ieee80211_ifdetach(ic); + ieee80211_ifdetach(&sc->sc_ic); } + mbufq_drain(&sc->sc_snd); + /* Uninstall interrupt handler. */ if (sc->irq != NULL) { bus_teardown_intr(dev, sc->irq, sc->sc_ih); @@ -1440,9 +1416,6 @@ iwn_detach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem), sc->mem); - if (ifp != NULL) - if_free(ifp); - DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n", __func__); IWN_LOCK_DESTROY(sc); return 0; @@ -1461,9 +1434,8 @@ static int iwn_suspend(device_t dev) { struct iwn_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; - ieee80211_suspend_all(ic); + ieee80211_suspend_all(&sc->sc_ic); return 0; } @@ -1471,12 +1443,11 @@ static int iwn_resume(device_t dev) { struct iwn_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; /* Clear device-specific "PCI retry timeout" register (41h). */ pci_write_config(dev, 0x41, 0, 1); - ieee80211_resume_all(ic); + ieee80211_resume_all(&sc->sc_ic); return 0; } @@ -2385,8 +2356,7 @@ iwn_eeprom_channel_flags(struct iwn_eeprom_chan *channel) static void iwn_read_eeprom_band(struct iwn_softc *sc, int n) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct iwn_eeprom_chan *channels = sc->eeprom_channels[n]; const struct iwn_chan_band *band = &iwn_bands[n]; struct ieee80211_channel *c; @@ -2445,8 +2415,7 @@ iwn_read_eeprom_band(struct iwn_softc *sc, int n) static void iwn_read_eeprom_ht40(struct iwn_softc *sc, int n) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct iwn_eeprom_chan *channels = sc->eeprom_channels[n]; const struct iwn_chan_band *band = &iwn_bands[n]; struct ieee80211_channel *c, *cent, *extc; @@ -2514,8 +2483,7 @@ iwn_read_eeprom_ht40(struct iwn_softc *sc, int n) static void iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n], iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan)); @@ -2583,8 +2551,7 @@ static void iwn_read_eeprom_enhinfo(struct iwn_softc *sc) { struct iwn_eeprom_enhinfo enhinfo[35]; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_channel *c; uint16_t val, base; int8_t maxpwr; @@ -2967,8 +2934,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, struct iwn_rx_data *data) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct iwn_rx_ring *ring = &sc->rxq; struct ieee80211_frame *wh; struct ieee80211_node *ni; @@ -3015,14 +2981,14 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) { DPRINTF(sc, IWN_DEBUG_RECV, "%s: RX flags error %x\n", __func__, flags); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } /* Discard frames that are too short. */ if (len < sizeof (struct ieee80211_frame_ack)) { DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n", __func__, len); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -3030,7 +2996,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, if (m1 == NULL) { DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n", __func__); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } bus_dmamap_unload(ring->data_dmat, data->map); @@ -3053,7 +3019,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, ring->desc[ring->cur] = htole32(paddr >> 8); bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map, BUS_DMASYNC_PREWRITE); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -3065,7 +3031,6 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, BUS_DMASYNC_PREWRITE); /* Finalize mbuf. */ - m->m_pkthdr.rcvif = ifp; m->m_data = head; m->m_pkthdr.len = m->m_len = len; @@ -3159,7 +3124,6 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc, struct iwn_rx_data *data) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; struct iwn_node *wn; struct ieee80211_node *ni; struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1); @@ -3240,12 +3204,10 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc, bitmap = (le64toh(ba->bitmap) >> shift) & wn->agg[tid].bitmap; for (i = 0; bitmap; i++) { if ((bitmap & 1) == 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); tx_err ++; ieee80211_ratectl_tx_complete(ni->ni_vap, ni, IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); } else { - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); tx_ok ++; ieee80211_ratectl_tx_complete(ni->ni_vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); @@ -3391,8 +3353,7 @@ iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc, struct iwn_rx_data *data) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct iwn_calib_state *calib = &sc->calib; struct iwn_stats *stats = (struct iwn_stats *)(desc + 1); @@ -3565,7 +3526,6 @@ static void iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt, uint8_t status) { - struct ifnet *ifp = sc->sc_ifp; struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf]; struct iwn_tx_data *data = &ring->data[desc->idx]; struct mbuf *m; @@ -3586,15 +3546,12 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt, /* * Update rate control statistics for the node. */ - if (status & IWN_TX_FAIL) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if (status & IWN_TX_FAIL) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); - } else { - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + else ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); - } /* * Channels marked for "radar" require traffic to be received @@ -3620,11 +3577,8 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt, sc->sc_tx_timer = 0; if (--ring->queued < IWN_TX_RING_LOMARK) { sc->qfullmsk &= ~(1 << ring->qid); - if (sc->qfullmsk == 0 && - (ifp->if_drv_flags & IFF_DRV_OACTIVE)) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - iwn_start_locked(ifp); - } + if (sc->qfullmsk == 0) + iwn_start_locked(sc); } DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); @@ -3669,7 +3623,6 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, int ackfailcnt, void *stat) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; struct iwn_tx_ring *ring = &sc->txq[qid]; struct iwn_tx_data *data; struct mbuf *m; @@ -3808,11 +3761,8 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, sc->sc_tx_timer = 0; if (ring->queued < IWN_TX_RING_LOMARK) { sc->qfullmsk &= ~(1 << ring->qid); - if (sc->qfullmsk == 0 && - (ifp->if_drv_flags & IFF_DRV_OACTIVE)) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - iwn_start_locked(ifp); - } + if (sc->qfullmsk == 0) + iwn_start_locked(sc); } DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); @@ -3826,8 +3776,7 @@ static void iwn_notif_intr(struct iwn_softc *sc) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t hw; @@ -4021,8 +3970,7 @@ iwn_wakeup_intr(struct iwn_softc *sc) static void iwn_rftoggle_intr(struct iwn_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL); IWN_LOCK_ASSERT(sc); @@ -4101,7 +4049,6 @@ static void iwn_intr(void *arg) { struct iwn_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t r1, r2, tmp; IWN_LOCK(sc); @@ -4194,7 +4141,7 @@ iwn_intr(void *arg) done: /* Re-enable interrupts. */ - if (ifp->if_flags & IFF_UP) + if (sc->sc_flags & IWN_FLAG_RUNNING) IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask); IWN_UNLOCK(sc); @@ -4678,9 +4625,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { struct iwn_ops *ops = &sc->ops; -// struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap = ni->ni_vap; -// struct ieee80211com *ic = ifp->if_l2com; struct iwn_tx_cmd *cmd; struct iwn_cmd_data *tx; struct ieee80211_frame *wh; @@ -4875,7 +4820,6 @@ static void iwn_xmit_task(void *arg0, int pending) { struct iwn_softc *sc = arg0; - struct ifnet *ifp = sc->sc_ifp; struct ieee80211_node *ni; struct mbuf *m; int error; @@ -4907,8 +4851,9 @@ iwn_xmit_task(void *arg0, int pending) error = iwn_tx_data(sc, m, ni); if (error != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } } @@ -4921,13 +4866,12 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct iwn_softc *sc = ifp->if_softc; + struct iwn_softc *sc = ic->ic_softc; int error = 0; DPRINTF(sc, IWN_DEBUG_XMIT | IWN_DEBUG_TRACE, "->%s begin\n", __func__); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) { ieee80211_free_node(ni); m_freem(m); return ENETDOWN; @@ -4942,8 +4886,9 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, if (sc->sc_beacon_wait) { if (iwn_xmit_queue_enqueue(sc, m) != 0) { m_freem(m); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); IWN_UNLOCK(sc); return (ENOBUFS); } @@ -4968,7 +4913,6 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, if (error != 0) { /* NB: m is reclaimed on tx failure */ ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } else sc->sc_tx_timer = 5; @@ -4979,20 +4923,32 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return error; } -static void -iwn_start(struct ifnet *ifp) +static int +iwn_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct iwn_softc *sc = ifp->if_softc; + struct iwn_softc *sc; + int error; + + sc = ic->ic_softc; IWN_LOCK(sc); - iwn_start_locked(ifp); + if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) { + IWN_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + IWN_UNLOCK(sc); + return (error); + } + iwn_start_locked(sc); IWN_UNLOCK(sc); + return (0); } static void -iwn_start_locked(struct ifnet *ifp) +iwn_start_locked(struct iwn_softc *sc) { - struct iwn_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; @@ -5007,27 +4963,16 @@ iwn_start_locked(struct ifnet *ifp) } DPRINTF(sc, IWN_DEBUG_XMIT, "%s: called\n", __func__); - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - (ifp->if_drv_flags & IFF_DRV_OACTIVE)) - return; - - for (;;) { - if (sc->qfullmsk != 0) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while (sc->qfullmsk == 0 && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; if (iwn_tx_data(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } else sc->sc_tx_timer = 5; } - DPRINTF(sc, IWN_DEBUG_XMIT, "%s: done\n", __func__); } @@ -5035,12 +4980,11 @@ static void iwn_watchdog(void *arg) { struct iwn_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; IWN_LOCK_ASSERT(sc); - KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + KASSERT(sc->sc_flags & IWN_FLAG_RUNNING, ("not running")); DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); @@ -5055,41 +4999,13 @@ iwn_watchdog(void *arg) } static int -iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +iwn_ioctl(struct ieee80211com *ic, u_long cmd, void *data) { - struct iwn_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0, stop = 0; - + struct ifreq *ifr = data; + struct iwn_softc *sc = ic->ic_softc; + int error = 0; + switch (cmd) { - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - case SIOCSIFFLAGS: - IWN_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - iwn_init_locked(sc); - if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL) - startall = 1; - else - stop = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - iwn_stop_locked(sc); - } - IWN_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - else if (vap != NULL && stop) - ieee80211_stop(vap); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; case SIOCGIWNSTATS: IWN_LOCK(sc); /* XXX validate permissions/memory/etc? */ @@ -5103,10 +5019,35 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) IWN_UNLOCK(sc); break; default: - error = EINVAL; + error = ENOTTY; break; } - return error; + return (error); +} + +static void +iwn_parent(struct ieee80211com *ic) +{ + struct iwn_softc *sc = ic->ic_softc; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + int startall = 0, stop = 0; + + IWN_LOCK(sc); + if (ic->ic_nrunning > 0) { + if (!(sc->sc_flags & IWN_FLAG_RUNNING)) { + iwn_init_locked(sc); + if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL) + startall = 1; + else + stop = 1; + } + } else if (sc->sc_flags & IWN_FLAG_RUNNING) + iwn_stop_locked(sc); + IWN_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); + else if (vap != NULL && stop) + ieee80211_stop(vap); } /* @@ -5340,8 +5281,7 @@ static int iwn_add_broadcast_node(struct iwn_softc *sc, int async) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct iwn_node_info node; struct iwn_cmd_link_quality linkq; uint8_t txant; @@ -5352,7 +5292,7 @@ iwn_add_broadcast_node(struct iwn_softc *sc, int async) sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX]; memset(&node, 0, sizeof node); - IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr); + IEEE80211_ADDR_COPY(node.macaddr, ieee80211broadcastaddr); node.id = sc->broadcast_id; DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__); if ((error = ops->add_node(sc, &node, async)) != 0) @@ -5501,8 +5441,7 @@ iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni) static void iwn4965_power_calibration(struct iwn_softc *sc, int temp) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); @@ -5872,8 +5811,7 @@ iwn_collect_noise(struct iwn_softc *sc, { struct iwn_ops *ops = &sc->ops; struct iwn_calib_state *calib = &sc->calib; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t val; int i; @@ -6506,9 +6444,8 @@ iwn5000_runtime_calib(struct iwn_softc *sc) static uint32_t iwn_get_rxon_ht_flags(struct iwn_softc *sc, struct ieee80211_channel *c) { + struct ieee80211com *ic = &sc->sc_ic; uint32_t htflags = 0; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; if (! IEEE80211_IS_CHAN_HT(c)) return (0); @@ -6535,8 +6472,9 @@ static int iwn_config(struct iwn_softc *sc) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + const uint8_t *macaddr; uint32_t txmask; uint16_t rxchain; int error; @@ -6618,8 +6556,9 @@ iwn_config(struct iwn_softc *sc) /* Set mode, channel, RX filter and enable RX. */ sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX]; memset(sc->rxon, 0, sizeof (struct iwn_rxon)); - IEEE80211_ADDR_COPY(sc->rxon->myaddr, IF_LLADDR(ifp)); - IEEE80211_ADDR_COPY(sc->rxon->wlap, IF_LLADDR(ifp)); + macaddr = vap ? vap->iv_myaddr : ic->ic_macaddr; + IEEE80211_ADDR_COPY(sc->rxon->myaddr, macaddr); + IEEE80211_ADDR_COPY(sc->rxon->wlap, macaddr); sc->rxon->chan = ieee80211_chan2ieee(ic, ic->ic_curchan); sc->rxon->flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF); if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) @@ -6732,7 +6671,7 @@ iwn_get_active_dwell_time(struct iwn_softc *sc, static uint16_t iwn_limit_dwell(struct iwn_softc *sc, uint16_t dwell_time) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = NULL; int bintval = 0; @@ -6780,8 +6719,7 @@ static int iwn_scan(struct iwn_softc *sc, struct ieee80211vap *vap, struct ieee80211_scan_state *ss, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni = vap->iv_bss; struct iwn_scan_hdr *hdr; struct iwn_cmd_data *tx; @@ -6919,9 +6857,9 @@ iwn_scan(struct iwn_softc *sc, struct ieee80211vap *vap, 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, ifp->if_broadcastaddr); - IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp)); - IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr); + IEEE80211_ADDR_COPY(wh->i_addr1, vap->iv_ifp->if_broadcastaddr); + IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(vap->iv_ifp)); + IEEE80211_ADDR_COPY(wh->i_addr3, vap->iv_ifp->if_broadcastaddr); *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */ *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */ @@ -7040,8 +6978,7 @@ static int iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni = vap->iv_bss; int error; @@ -7113,8 +7050,7 @@ static int iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap) { struct iwn_ops *ops = &sc->ops; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni = vap->iv_bss; struct iwn_node_info node; int error; @@ -8685,8 +8621,7 @@ static void iwn_radio_on(void *arg0, int pending) { struct iwn_softc *sc = arg0; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); @@ -8701,8 +8636,7 @@ static void iwn_radio_off(void *arg0, int pending) { struct iwn_softc *sc = arg0; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); @@ -8722,8 +8656,7 @@ static void iwn_panicked(void *arg0, int pending) { struct iwn_softc *sc = arg0; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); int error; @@ -8751,7 +8684,7 @@ iwn_panicked(void *arg0, int pending) } /* Only run start once the NIC is in a useful state, like associated */ - iwn_start_locked(sc->sc_ifp); + iwn_start_locked(sc); IWN_UNLOCK(sc); } @@ -8759,13 +8692,14 @@ iwn_panicked(void *arg0, int pending) static void iwn_init_locked(struct iwn_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int error; DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__); IWN_LOCK_ASSERT(sc); + sc->sc_flags |= IWN_FLAG_RUNNING; + if ((error = iwn_hw_prepare(sc)) != 0) { device_printf(sc->sc_dev, "%s: hardware not ready, error %d\n", __func__, error); @@ -8813,38 +8747,33 @@ iwn_init_locked(struct iwn_softc *sc) goto fail; } - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc); DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__); return; -fail: iwn_stop_locked(sc); +fail: + sc->sc_flags &= ~IWN_FLAG_RUNNING; + iwn_stop_locked(sc); DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end in error\n",__func__); } static void -iwn_init(void *arg) +iwn_init(struct iwn_softc *sc) { - struct iwn_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; IWN_LOCK(sc); iwn_init_locked(sc); IWN_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); + if (sc->sc_flags & IWN_FLAG_RUNNING) + ieee80211_start_all(&sc->sc_ic); } static void iwn_stop_locked(struct iwn_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; IWN_LOCK_ASSERT(sc); @@ -8852,7 +8781,7 @@ iwn_stop_locked(struct iwn_softc *sc) sc->sc_tx_timer = 0; callout_stop(&sc->watchdog_to); callout_stop(&sc->calib_to); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~IWN_FLAG_RUNNING; /* Power OFF hardware. */ iwn_hw_stop(sc); @@ -8872,8 +8801,7 @@ iwn_stop(struct iwn_softc *sc) static void iwn_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct iwn_softc *sc = ifp->if_softc; + struct iwn_softc *sc = ic->ic_softc; IWN_LOCK(sc); /* make the link LED blink while we're scanning */ @@ -8887,8 +8815,7 @@ iwn_scan_start(struct ieee80211com *ic) static void iwn_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct iwn_softc *sc = ifp->if_softc; + struct iwn_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); IWN_LOCK(sc); @@ -8906,8 +8833,7 @@ static void iwn_set_channel(struct ieee80211com *ic) { const struct ieee80211_channel *c = ic->ic_curchan; - struct ifnet *ifp = ic->ic_ifp; - struct iwn_softc *sc = ifp->if_softc; + struct iwn_softc *sc = ic->ic_softc; int error; DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); @@ -8964,8 +8890,7 @@ static void iwn_hw_reset(void *arg0, int pending) { struct iwn_softc *sc = arg0; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h index 9366fc2bf7fb..ed275bf7c4f4 100644 --- a/sys/dev/iwn/if_iwnvar.h +++ b/sys/dev/iwn/if_iwnvar.h @@ -228,18 +228,16 @@ struct iwn_vap { enum ieee80211_state, int); int ctx; int beacon_int; - uint8_t macaddr[IEEE80211_ADDR_LEN]; }; #define IWN_VAP(_vap) ((struct iwn_vap *)(_vap)) struct iwn_softc { device_t sc_dev; - - struct ifnet *sc_ifp; int sc_debug; - struct mtx sc_mtx; + struct ieee80211com sc_ic; + struct mbufq sc_snd; u_int sc_flags; #define IWN_FLAG_HAS_OTPROM (1 << 1) @@ -251,6 +249,7 @@ struct iwn_softc { #define IWN_FLAG_ADV_BTCOEX (1 << 8) #define IWN_FLAG_PAN_SUPPORT (1 << 9) #define IWN_FLAG_BTCOEX (1 << 10) +#define IWN_FLAG_RUNNING (1 << 11) uint8_t hw_type; /* subdevice_id used to adjust configuration */ @@ -320,7 +319,6 @@ struct iwn_softc { struct iwn_calib_state calib; int last_calib_ticks; struct callout watchdog_to; - struct callout ct_kill_exit_to; struct iwn_fw_info fw; struct iwn_calib_info calibcmd[IWN5000_PHY_CALIB_MAX_RESULT]; uint32_t errptr; diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c index 741837949909..2790fdc8400c 100644 --- a/sys/dev/malo/if_malo.c +++ b/sys/dev/malo/if_malo.c @@ -102,13 +102,9 @@ enum { (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON)) #define IFF_DUMPPKTS_RECV(sc, wh) \ (((sc->malo_debug & MALO_DEBUG_RECV) && \ - ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \ - (sc->malo_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == \ - (IFF_DEBUG|IFF_LINK2)) + ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh)))) #define IFF_DUMPPKTS_XMIT(sc) \ - ((sc->malo_debug & MALO_DEBUG_XMIT) || \ - (sc->malo_ifp->if_flags & (IFF_DEBUG | IFF_LINK2)) == \ - (IFF_DEBUG | IFF_LINK2)) + (sc->malo_debug & MALO_DEBUG_XMIT) #define DPRINTF(sc, m, fmt, ...) do { \ if (sc->malo_debug & (m)) \ printf(fmt, __VA_ARGS__); \ @@ -130,9 +126,10 @@ static int malo_dma_setup(struct malo_softc *); static int malo_setup_hwdma(struct malo_softc *); static void malo_txq_init(struct malo_softc *, struct malo_txq *, int); static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *); -static void malo_start(struct ifnet *); +static void malo_parent(struct ieee80211com *); +static int malo_transmit(struct ieee80211com *, struct mbuf *); +static void malo_start(struct malo_softc *); static void malo_watchdog(void *); -static int malo_ioctl(struct ifnet *, u_long, caddr_t); static void malo_updateslot(struct ieee80211com *); static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void malo_scan_start(struct ieee80211com *); @@ -143,7 +140,7 @@ static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *, static void malo_sysctlattach(struct malo_softc *); static void malo_announce(struct malo_softc *); static void malo_dma_cleanup(struct malo_softc *); -static void malo_stop_locked(struct ifnet *, int); +static void malo_stop(struct malo_softc *); static int malo_chan_set(struct malo_softc *, struct ieee80211_channel *); static int malo_mode_init(struct malo_softc *); static void malo_tx_proc(void *, int); @@ -173,30 +170,19 @@ malo_bar0_write4(struct malo_softc *sc, bus_size_t off, uint32_t val) int malo_attach(uint16_t devid, struct malo_softc *sc) { - int error; - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->malo_ic; struct malo_hal *mh; + int error; uint8_t bands; - ifp = sc->malo_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->malo_dev, "can not if_alloc()\n"); - return ENOSPC; - } - ic = ifp->if_l2com; - MALO_LOCK_INIT(sc); callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0); - - /* set these up early for if_printf use */ - if_initname(ifp, device_get_name(sc->malo_dev), - device_get_unit(sc->malo_dev)); + mbufq_init(&sc->malo_snd, ifqmaxlen); mh = malo_hal_attach(sc->malo_dev, devid, sc->malo_io1h, sc->malo_io1t, sc->malo_dmat); if (mh == NULL) { - if_printf(ifp, "unable to attach HAL\n"); + device_printf(sc->malo_dev, "unable to attach HAL\n"); error = EIO; goto bad; } @@ -209,13 +195,13 @@ malo_attach(uint16_t devid, struct malo_softc *sc) */ error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m"); if (error != 0) { - if_printf(ifp, "unable to setup firmware\n"); + device_printf(sc->malo_dev, "unable to setup firmware\n"); goto bad1; } /* XXX gethwspecs() extracts correct informations? not maybe! */ error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs); if (error != 0) { - if_printf(ifp, "unable to fetch h/w specs\n"); + device_printf(sc->malo_dev, "unable to fetch h/w specs\n"); goto bad1; } @@ -251,7 +237,8 @@ malo_attach(uint16_t devid, struct malo_softc *sc) */ error = malo_dma_setup(sc); if (error != 0) { - if_printf(ifp, "failed to setup descriptors: %d\n", error); + device_printf(sc->malo_dev, + "failed to setup descriptors: %d\n", error); goto bad1; } error = malo_setup_hwdma(sc); /* push to firmware */ @@ -261,21 +248,11 @@ malo_attach(uint16_t devid, struct malo_softc *sc) sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->malo_tq); taskqueue_start_threads(&sc->malo_tq, 1, PI_NET, - "%s taskq", ifp->if_xname); + "%s taskq", device_get_nameunit(sc->malo_dev)); TASK_INIT(&sc->malo_rxtask, 0, malo_rx_proc, sc); TASK_INIT(&sc->malo_txtask, 0, malo_tx_proc, sc); - ifp->if_softc = sc; - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; - ifp->if_start = malo_start; - ifp->if_ioctl = malo_ioctl; - ifp->if_init = malo_init; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(sc->malo_dev); /* XXX not right but it's not used anywhere important */ @@ -290,6 +267,7 @@ malo_attach(uint16_t devid, struct malo_softc *sc) | IEEE80211_C_TXPMGT /* capable of txpow mgt */ | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ ; + IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->malo_hwspecs.macaddr); /* * Transmit requires space in the packet for a special format transmit @@ -301,16 +279,17 @@ malo_attach(uint16_t devid, struct malo_softc *sc) sizeof(struct ieee80211_frame); /* call MI attach routine. */ - ieee80211_ifattach(ic, sc->malo_hwspecs.macaddr); + ieee80211_ifattach(ic); /* override default methods */ ic->ic_vap_create = malo_vap_create; ic->ic_vap_delete = malo_vap_delete; ic->ic_raw_xmit = malo_raw_xmit; ic->ic_updateslot = malo_updateslot; - ic->ic_scan_start = malo_scan_start; ic->ic_scan_end = malo_scan_end; ic->ic_set_channel = malo_set_channel; + ic->ic_parent = malo_parent; + ic->ic_transmit = malo_transmit; sc->malo_invalid = 0; /* ready to go, enable int handling */ @@ -335,7 +314,6 @@ malo_attach(uint16_t devid, struct malo_softc *sc) bad1: malo_hal_detach(mh); bad: - if_free(ifp); sc->malo_invalid = 1; return error; @@ -347,12 +325,12 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; + struct malo_softc *sc = ic->ic_softc; struct malo_vap *mvp; struct ieee80211vap *vap; if (!TAILQ_EMPTY(&ic->ic_vaps)) { - if_printf(ifp, "multiple vaps not supported\n"); + device_printf(sc->malo_dev, "multiple vaps not supported\n"); return NULL; } switch (opmode) { @@ -363,18 +341,13 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MONITOR: break; default: - if_printf(ifp, "%s mode not supported\n", + device_printf(sc->malo_dev, "%s mode not supported\n", ieee80211_opmode_name[opmode]); return NULL; /* unsupported */ } - mvp = (struct malo_vap *) malloc(sizeof(struct malo_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (mvp == NULL) { - if_printf(ifp, "cannot allocate vap state block\n"); - return NULL; - } + mvp = malloc(sizeof(struct malo_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &mvp->malo_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override state transition machine */ mvp->malo_newstate = vap->iv_newstate; @@ -382,7 +355,7 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, - ieee80211_media_change, ieee80211_media_status); + ieee80211_media_change, ieee80211_media_status, mac); ic->ic_opmode = opmode; return vap; } @@ -461,7 +434,6 @@ malo_desc_setup(struct malo_softc *sc, const char *name, int nbuf, size_t bufsize, int ndesc, size_t descsize) { int error; - struct ifnet *ifp = sc->malo_ifp; uint8_t *ds; DPRINTF(sc, MALO_DEBUG_RESET, @@ -488,7 +460,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name, NULL, /* lockarg */ &dd->dd_dmat); if (error != 0) { - if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name); + device_printf(sc->malo_dev, "cannot allocate %s DMA tag\n", + dd->dd_name); return error; } @@ -496,7 +469,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name, error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc, BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap); if (error != 0) { - if_printf(ifp, "unable to alloc memory for %u %s descriptors, " + device_printf(sc->malo_dev, + "unable to alloc memory for %u %s descriptors, " "error %u\n", nbuf * ndesc, dd->dd_name, error); goto fail1; } @@ -505,7 +479,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name, dd->dd_desc, dd->dd_desc_len, malo_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT); if (error != 0) { - if_printf(ifp, "unable to map %s descriptors, error %u\n", + device_printf(sc->malo_dev, + "unable to map %s descriptors, error %u\n", dd->dd_name, error); goto fail2; } @@ -532,7 +507,6 @@ malo_desc_setup(struct malo_softc *sc, const char *name, static int malo_rxdma_setup(struct malo_softc *sc) { - struct ifnet *ifp = sc->malo_ifp; int error, bsize, i; struct malo_rxbuf *bf; struct malo_rxdesc *ds; @@ -549,7 +523,8 @@ malo_rxdma_setup(struct malo_softc *sc) bsize = malo_rxbuf * sizeof(struct malo_rxbuf); bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO); if (bf == NULL) { - if_printf(ifp, "malloc of %u rx buffers failed\n", bsize); + device_printf(sc->malo_dev, + "malloc of %u rx buffers failed\n", bsize); return error; } sc->malo_rxdma.dd_bufptr = bf; @@ -562,8 +537,9 @@ malo_rxdma_setup(struct malo_softc *sc) error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT, &bf->bf_dmamap); if (error != 0) { - if_printf(ifp, "%s: unable to dmamap for rx buffer, " - "error %d\n", __func__, error); + device_printf(sc->malo_dev, + "%s: unable to dmamap for rx buffer, error %d\n", + __func__, error); return error; } /* NB: tail is intentional to preserve descriptor order */ @@ -575,7 +551,6 @@ malo_rxdma_setup(struct malo_softc *sc) static int malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq) { - struct ifnet *ifp = sc->malo_ifp; int error, bsize, i; struct malo_txbuf *bf; struct malo_txdesc *ds; @@ -590,7 +565,7 @@ malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq) bsize = malo_txbuf * sizeof(struct malo_txbuf); bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO); if (bf == NULL) { - if_printf(ifp, "malloc of %u tx buffers failed\n", + device_printf(sc->malo_dev, "malloc of %u tx buffers failed\n", malo_txbuf); return ENOMEM; } @@ -605,7 +580,8 @@ malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq) error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT, &bf->bf_dmamap); if (error != 0) { - if_printf(ifp, "unable to create dmamap for tx " + device_printf(sc->malo_dev, + "unable to create dmamap for tx " "buffer %u, error %u\n", i, error); return error; } @@ -1004,33 +980,19 @@ malo_tx_processq(struct malo_softc *sc, struct malo_txq *txq) if (status & MALO_TXD_STATUS_FAILED_AGING) sc->malo_stats.mst_tx_aging++; } - /* - * Do any tx complete callback. Note this must - * be done before releasing the node reference. - * XXX no way to figure out if frame was ACK'd - */ - if (bf->bf_m->m_flags & M_TXCB) { - /* XXX strip fw len in case header inspected */ - m_adj(bf->bf_m, sizeof(uint16_t)); - ieee80211_process_callback(ni, bf->bf_m, - (status & MALO_TXD_STATUS_OK) == 0); - } - /* - * Reclaim reference to node. - * - * NB: the node may be reclaimed here if, for example - * this is a DEAUTH message that was sent and the - * node was timed out due to inactivity. - */ - ieee80211_free_node(ni); - } + /* XXX strip fw len in case header inspected */ + m_adj(bf->bf_m, sizeof(uint16_t)); + ieee80211_tx_complete(ni, bf->bf_m, + (status & MALO_TXD_STATUS_OK) == 0); + } else + m_freem(bf->bf_m); + ds->status = htole32(MALO_TXD_STATUS_IDLE); ds->pktlen = htole32(0); bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap); - m_freem(bf->bf_m); bf->bf_m = NULL; bf->bf_node = NULL; @@ -1049,23 +1011,23 @@ static void malo_tx_proc(void *arg, int npending) { struct malo_softc *sc = arg; - struct ifnet *ifp = sc->malo_ifp; int i, nreaped; /* * Process each active queue. */ nreaped = 0; + MALO_LOCK(sc); for (i = 0; i < MALO_NUM_TX_QUEUES; i++) { if (!STAILQ_EMPTY(&sc->malo_txq[i].active)) nreaped += malo_tx_processq(sc, &sc->malo_txq[i]); } if (nreaped != 0) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->malo_timer = 0; - malo_start(ifp); + malo_start(sc); } + MALO_UNLOCK(sc); } static int @@ -1079,8 +1041,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, int error, ismcast, iswep; int copyhdrlen, hdrlen, pktlen; struct ieee80211_frame *wh; - struct ifnet *ifp = sc->malo_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->malo_ic; struct ieee80211vap *vap = ni->ni_vap; struct malo_txdesc *ds; struct malo_txrec *tr; @@ -1225,7 +1186,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, ds->txpriority = txq->qnum; break; default: - if_printf(ifp, "bogus frame type 0x%x (%s)\n", + device_printf(sc->malo_dev, "bogus frame type 0x%x (%s)\n", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__); /* XXX statistic */ m_freem(m0); @@ -1246,37 +1207,52 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, STAILQ_INSERT_TAIL(&txq->active, bf, bf_list); MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); sc->malo_timer = 5; MALO_TXQ_UNLOCK(txq); return 0; #undef IEEE80211_DIR_DSTODS } -static void -malo_start(struct ifnet *ifp) +static int +malo_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct malo_softc *sc = ic->ic_softc; + int error; + + MALO_LOCK(sc); + if (!sc->malo_running) { + MALO_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->malo_snd, m); + if (error) { + MALO_UNLOCK(sc); + return (error); + } + malo_start(sc); + MALO_UNLOCK(sc); + return (0); +} + +static void +malo_start(struct malo_softc *sc) { - struct malo_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct malo_txq *txq = &sc->malo_txq[0]; struct malo_txbuf *bf = NULL; struct mbuf *m; int nqueued = 0; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid) + MALO_LOCK_ASSERT(sc); + + if (!sc->malo_running || sc->malo_invalid) return; - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->malo_snd)) != NULL) { ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; bf = malo_getbuf(sc, txq); if (bf == NULL) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - - /* XXX blocks other traffic */ - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + mbufq_prepend(&sc->malo_snd, m); sc->malo_stats.mst_tx_qstop++; break; } @@ -1284,7 +1260,8 @@ malo_start(struct ifnet *ifp) * Pass the frame to the h/w for transmission. */ if (malo_tx_start(sc, ni, bf, m)) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); if (bf != NULL) { bf->bf_m = NULL; bf->bf_node = NULL; @@ -1328,21 +1305,18 @@ malo_start(struct ifnet *ifp) static void malo_watchdog(void *arg) { - struct malo_softc *sc; - struct ifnet *ifp; + struct malo_softc *sc = arg; - sc = arg; callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc); if (sc->malo_timer == 0 || --sc->malo_timer > 0) return; - ifp = sc->malo_ifp; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->malo_invalid) { - if_printf(ifp, "watchdog timeout\n"); + if (sc->malo_running && !sc->malo_invalid) { + device_printf(sc->malo_dev, "watchdog timeout\n"); /* XXX no way to reset h/w. now */ - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->malo_ic.ic_oerrors, 1); sc->malo_stats.mst_watchdog++; } } @@ -1351,8 +1325,7 @@ static int malo_hal_reset(struct malo_softc *sc) { static int first = 0; - struct ifnet *ifp = sc->malo_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->malo_ic; struct malo_hal *mh = sc->malo_mh; if (first == 0) { @@ -1392,7 +1365,7 @@ malo_getrxmbuf(struct malo_softc *sc, struct malo_rxbuf *bf) mtod(m, caddr_t), MJUMPAGESIZE, malo_load_cb, &paddr, BUS_DMA_NOWAIT); if (error != 0) { - if_printf(sc->malo_ifp, + device_printf(sc->malo_dev, "%s: bus_dmamap_load failed, error %d\n", __func__, error); m_freem(m); return NULL; @@ -1483,26 +1456,23 @@ malo_startrecv(struct malo_softc *sc) static void malo_init_locked(struct malo_softc *sc) { - struct ifnet *ifp = sc->malo_ifp; struct malo_hal *mh = sc->malo_mh; int error; - DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); - MALO_LOCK_ASSERT(sc); /* * Stop anything previously setup. This is safe whether this is * the first time through or not. */ - malo_stop_locked(ifp, 0); + malo_stop(sc); /* * Push state to the firmware. */ if (!malo_hal_reset(sc)) { - if_printf(ifp, "%s: unable to reset hardware\n", __func__); + device_printf(sc->malo_dev, + "%s: unable to reset hardware\n", __func__); return; } @@ -1511,7 +1481,8 @@ malo_init_locked(struct malo_softc *sc) */ error = malo_startrecv(sc); if (error != 0) { - if_printf(ifp, "%s: unable to start recv logic, error %d\n", + device_printf(sc->malo_dev, + "%s: unable to start recv logic, error %d\n", __func__, error); return; } @@ -1528,7 +1499,7 @@ malo_init_locked(struct malo_softc *sc) | MALO_A2HRIC_BIT_RADAR_DETECT | MALO_A2HRIC_BIT_CHAN_SWITCH; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->malo_running = 1; malo_hal_intrset(mh, sc->malo_imask); callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc); } @@ -1537,18 +1508,13 @@ static void malo_init(void *arg) { struct malo_softc *sc = (struct malo_softc *) arg; - struct ifnet *ifp = sc->malo_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->malo_ic; - DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); - MALO_LOCK(sc); malo_init_locked(sc); - MALO_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->malo_running) ieee80211_start_all(ic); /* start all vap's */ } @@ -1558,9 +1524,8 @@ malo_init(void *arg) static void malo_setmcastfilter(struct malo_softc *sc) { - struct ifnet *ifp = sc->malo_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ifmultiaddr *ifma; + struct ieee80211com *ic = &sc->malo_ic; + struct ieee80211vap *vap; uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX]; uint8_t *mp; int nmc; @@ -1568,26 +1533,32 @@ malo_setmcastfilter(struct malo_softc *sc) mp = macs; nmc = 0; - if (ic->ic_opmode == IEEE80211_M_MONITOR || - (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) + if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 || + ic->ic_promisc > 0) goto all; - - if_maddr_rlock(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - if (nmc == MALO_HAL_MCAST_MAX) { - ifp->if_flags |= IFF_ALLMULTI; - if_maddr_runlock(ifp); - goto all; + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + struct ifnet *ifp; + struct ifmultiaddr *ifma; + + ifp = vap->iv_ifp; + if_maddr_rlock(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + + if (nmc == MALO_HAL_MCAST_MAX) { + ifp->if_flags |= IFF_ALLMULTI; + if_maddr_runlock(ifp); + goto all; + } + IEEE80211_ADDR_COPY(mp, + LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); + + mp += IEEE80211_ADDR_LEN, nmc++; } - IEEE80211_ADDR_COPY(mp, - LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); - - mp += IEEE80211_ADDR_LEN, nmc++; + if_maddr_runlock(ifp); } - if_maddr_runlock(ifp); malo_hal_setmcast(sc->malo_mh, nmc, macs); @@ -1602,8 +1573,7 @@ malo_setmcastfilter(struct malo_softc *sc) static int malo_mode_init(struct malo_softc *sc) { - struct ifnet *ifp = sc->malo_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->malo_ic; struct malo_hal *mh = sc->malo_mh; /* @@ -1612,7 +1582,7 @@ malo_mode_init(struct malo_softc *sc) * identify internal requests (from the bridge) * versus external requests such as for tcpdump. */ - malo_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) && + malo_hal_setpromisc(mh, ic->ic_promisc > 0 && ic->ic_opmode != IEEE80211_M_HOSTAP); malo_setmcastfilter(sc); @@ -1641,8 +1611,7 @@ malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq) MALO_TXQ_UNLOCK(txq); #ifdef MALO_DEBUG if (sc->malo_debug & MALO_DEBUG_RESET) { - struct ifnet *ifp = sc->malo_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->malo_ic; const struct malo_txrec *tr = mtod(bf->bf_m, const struct malo_txrec *); malo_printtxbuf(bf, txq->qnum, ix); @@ -1670,18 +1639,17 @@ malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq) } static void -malo_stop_locked(struct ifnet *ifp, int disable) +malo_stop(struct malo_softc *sc) { - struct malo_softc *sc = ifp->if_softc; struct malo_hal *mh = sc->malo_mh; int i; - DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", - __func__, sc->malo_invalid, ifp->if_flags); + DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u running %u\n", + __func__, sc->malo_invalid, sc->malo_running); MALO_LOCK_ASSERT(sc); - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + if (!sc->malo_running) return; /* @@ -1693,10 +1661,10 @@ malo_stop_locked(struct ifnet *ifp, int disable) * Note that some of this work is not possible if the hardware * is gone (invalid). */ - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->malo_running = 0; callout_stop(&sc->malo_watchdog_timer); sc->malo_timer = 0; - /* diable interrupt. */ + /* disable interrupt. */ malo_hal_intrset(mh, 0); /* turn off the radio. */ malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE); @@ -1706,57 +1674,38 @@ malo_stop_locked(struct ifnet *ifp, int disable) malo_tx_draintxq(sc, &sc->malo_txq[i]); } -static int -malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +malo_parent(struct ieee80211com *ic) { -#define MALO_IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct malo_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct malo_softc *sc = ic->ic_softc; + int startall = 0; MALO_LOCK(sc); - switch (cmd) { - case SIOCSIFFLAGS: - if (MALO_IS_RUNNING(ifp)) { - /* - * To avoid rescanning another access point, - * do not call malo_init() here. Instead, - * only reflect promisc mode settings. - */ - malo_mode_init(sc); - } else if (ifp->if_flags & IFF_UP) { - /* - * Beware of being called during attach/detach - * to reset promiscuous mode. In that case we - * will still be marked UP but not RUNNING. - * However trying to re-init the interface - * is the wrong thing to do as we've already - * torn down much of our state. There's - * probably a better way to deal with this. - */ - if (!sc->malo_invalid) { - malo_init_locked(sc); - startall = 1; - } - } else - malo_stop_locked(ifp, 1); - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - default: - error = ether_ioctl(ifp, cmd, data); - break; - } + if (ic->ic_nrunning > 0) { + /* + * Beware of being called during attach/detach + * to reset promiscuous mode. In that case we + * will still be marked UP but not RUNNING. + * However trying to re-init the interface + * is the wrong thing to do as we've already + * torn down much of our state. There's + * probably a better way to deal with this. + */ + if (!sc->malo_running && !sc->malo_invalid) { + malo_init(sc); + startall = 1; + } + /* + * To avoid rescanning another access point, + * do not call malo_init() here. Instead, + * only reflect promisc mode settings. + */ + malo_mode_init(sc); + } else if (sc->malo_running) + malo_stop(sc); MALO_UNLOCK(sc); - if (startall) ieee80211_start_all(ic); - return error; -#undef MALO_IS_RUNNING } /* @@ -1773,7 +1722,7 @@ malo_updateslot(struct ieee80211com *ic) int error; /* NB: can be called early; suppress needless cmds */ - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if (!sc->malo_running) return; DPRINTF(sc, MALO_DEBUG_RESET, @@ -1795,7 +1744,7 @@ static int malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; - struct malo_softc *sc = ic->ic_ifp->if_softc; + struct malo_softc *sc = ic->ic_softc; struct malo_hal *mh = sc->malo_mh; int error; @@ -1839,12 +1788,11 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct malo_softc *sc = ifp->if_softc; + struct malo_softc *sc = ic->ic_softc; struct malo_txbuf *bf; struct malo_txq *txq; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid) { + if (!sc->malo_running || sc->malo_invalid) { ieee80211_free_node(ni); m_freem(m); return ENETDOWN; @@ -1859,8 +1807,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, txq = &sc->malo_txq[0]; bf = malo_getbuf(sc, txq); if (bf == NULL) { - /* XXX blocks other traffic */ - ifp->if_drv_flags |= IFF_DRV_OACTIVE; ieee80211_free_node(ni); m_freem(m); return ENOBUFS; @@ -1870,7 +1816,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, * Pass the frame to the h/w for transmission. */ if (malo_tx_start(sc, ni, bf, m) != 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); bf->bf_m = NULL; bf->bf_node = NULL; MALO_TXQ_LOCK(txq); @@ -1915,9 +1860,9 @@ malo_sysctlattach(struct malo_softc *sc) static void malo_announce(struct malo_softc *sc) { - struct ifnet *ifp = sc->malo_ifp; - if_printf(ifp, "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n", + device_printf(sc->malo_dev, + "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n", sc->malo_hwspecs.hwversion, (sc->malo_hwspecs.fw_releasenum >> 24) & 0xff, (sc->malo_hwspecs.fw_releasenum >> 16) & 0xff, @@ -1926,9 +1871,11 @@ malo_announce(struct malo_softc *sc) sc->malo_hwspecs.regioncode); if (bootverbose || malo_rxbuf != MALO_RXBUF) - if_printf(ifp, "using %u rx buffers\n", malo_rxbuf); + device_printf(sc->malo_dev, + "using %u rx buffers\n", malo_rxbuf); if (bootverbose || malo_txbuf != MALO_TXBUF) - if_printf(ifp, "using %u tx buffers\n", malo_txbuf); + device_printf(sc->malo_dev, + "using %u tx buffers\n", malo_txbuf); } /* @@ -1989,8 +1936,7 @@ malo_chan_set(struct malo_softc *sc, struct ieee80211_channel *chan) static void malo_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct malo_softc *sc = ifp->if_softc; + struct malo_softc *sc = ic->ic_softc; DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__); } @@ -1998,8 +1944,7 @@ malo_scan_start(struct ieee80211com *ic) static void malo_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct malo_softc *sc = ifp->if_softc; + struct malo_softc *sc = ic->ic_softc; DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__); } @@ -2007,8 +1952,7 @@ malo_scan_end(struct ieee80211com *ic) static void malo_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct malo_softc *sc = ifp->if_softc; + struct malo_softc *sc = ic->ic_softc; (void) malo_chan_set(sc, ic->ic_curchan); } @@ -2020,8 +1964,7 @@ malo_rx_proc(void *arg, int npending) ((((const struct ieee80211_frame *)wh)->i_fc[1] & \ IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) struct malo_softc *sc = arg; - struct ifnet *ifp = sc->malo_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->malo_ic; struct malo_rxbuf *bf; struct malo_rxdesc *ds; struct mbuf *m, *mnew; @@ -2078,7 +2021,7 @@ malo_rx_proc(void *arg, int npending) #endif status = ds->status; if (status & MALO_RXD_STATUS_DECRYPT_ERR_MASK) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto rx_next; } /* @@ -2117,7 +2060,7 @@ malo_rx_proc(void *arg, int npending) /* XXX don't need mbuf, just dma buffer */ mnew = malo_getrxmbuf(sc, bf); if (mnew == NULL) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto rx_next; } /* @@ -2128,7 +2071,6 @@ malo_rx_proc(void *arg, int npending) bf->bf_m = mnew; m->m_data += off - hdrlen; m->m_pkthdr.len = m->m_len = pktlen; - m->m_pkthdr.rcvif = ifp; /* * Piece 802.11 header together. @@ -2158,8 +2100,6 @@ malo_rx_proc(void *arg, int npending) len, ds->rate, rssi); } #endif - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - /* dispatch */ ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); @@ -2177,22 +2117,11 @@ malo_rx_proc(void *arg, int npending) malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read, readptr); sc->malo_rxnext = bf; - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) - malo_start(ifp); + if (mbufq_first(&sc->malo_snd) != NULL) + malo_start(sc); #undef IEEE80211_DIR_DSTODS } -static void -malo_stop(struct ifnet *ifp, int disable) -{ - struct malo_softc *sc = ifp->if_softc; - - MALO_LOCK(sc); - malo_stop_locked(ifp, disable); - MALO_UNLOCK(sc); -} - /* * Reclaim all tx queue resources. */ @@ -2208,13 +2137,9 @@ malo_tx_cleanup(struct malo_softc *sc) int malo_detach(struct malo_softc *sc) { - struct ifnet *ifp = sc->malo_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->malo_ic; - DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); - - malo_stop(ifp, 1); + malo_stop(sc); if (sc->malo_tq != NULL) { taskqueue_drain(sc->malo_tq, &sc->malo_rxtask); @@ -2240,8 +2165,7 @@ malo_detach(struct malo_softc *sc) malo_dma_cleanup(sc); malo_tx_cleanup(sc); malo_hal_detach(sc->malo_mh); - if_free(ifp); - + mbufq_drain(&sc->malo_snd); MALO_LOCK_DESTROY(sc); return 0; @@ -2250,28 +2174,21 @@ malo_detach(struct malo_softc *sc) void malo_shutdown(struct malo_softc *sc) { - malo_stop(sc->malo_ifp, 1); + + malo_stop(sc); } void malo_suspend(struct malo_softc *sc) { - struct ifnet *ifp = sc->malo_ifp; - DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); - - malo_stop(ifp, 1); + malo_stop(sc); } void malo_resume(struct malo_softc *sc) { - struct ifnet *ifp = sc->malo_ifp; - DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); - - if (ifp->if_flags & IFF_UP) + if (sc->malo_ic.ic_nrunning > 0) malo_init(sc); } diff --git a/sys/dev/malo/if_malo.h b/sys/dev/malo/if_malo.h index bac290c6330b..681e7501aa67 100644 --- a/sys/dev/malo/if_malo.h +++ b/sys/dev/malo/if_malo.h @@ -520,8 +520,9 @@ struct malo_vap { #define MALO_VAP(vap) ((struct malo_vap *)(vap)) struct malo_softc { + struct ieee80211com malo_ic; + struct mbufq malo_snd; device_t malo_dev; - struct ifnet *malo_ifp; /* interface common */ struct mtx malo_mtx; /* master lock (recursive) */ struct taskqueue *malo_tq; /* private task queue */ @@ -531,9 +532,10 @@ struct malo_softc { bus_space_handle_t malo_io1h; /* BAR 1 */ bus_space_tag_t malo_io1t; - unsigned int malo_invalid : 1,/* disable hardware accesses */ - malo_recvsetup : 1, /* recv setup */ - malo_fixedrate: 1; /* use fixed tx rate */ + unsigned int malo_invalid: 1,/* disable hardware accesses */ + malo_recvsetup: 1, /* recv setup */ + malo_fixedrate: 1, /* use fixed tx rate */ + malo_running: 1; struct malo_hal *malo_mh; /* h/w access layer */ struct malo_hal_hwspec malo_hwspecs; /* h/w capabilities */ diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c index 09975005eec2..42264ac2ffe0 100644 --- a/sys/dev/mwl/if_mwl.c +++ b/sys/dev/mwl/if_mwl.c @@ -91,17 +91,17 @@ static struct ieee80211vap *mwl_vap_create(struct ieee80211com *, static void mwl_vap_delete(struct ieee80211vap *); static int mwl_setupdma(struct mwl_softc *); static int mwl_hal_reset(struct mwl_softc *sc); -static int mwl_init_locked(struct mwl_softc *); -static void mwl_init(void *); -static void mwl_stop_locked(struct ifnet *, int); +static int mwl_init(struct mwl_softc *); +static void mwl_parent(struct ieee80211com *); static int mwl_reset(struct ieee80211vap *, u_long); -static void mwl_stop(struct ifnet *, int); -static void mwl_start(struct ifnet *); +static void mwl_stop(struct mwl_softc *); +static void mwl_start(struct mwl_softc *); +static int mwl_transmit(struct ieee80211com *, struct mbuf *); static int mwl_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static int mwl_media_change(struct ifnet *); static void mwl_watchdog(void *); -static int mwl_ioctl(struct ifnet *, u_long, caddr_t); +static int mwl_ioctl(struct ieee80211com *, u_long, void *); static void mwl_radar_proc(void *, int); static void mwl_chanswitch_proc(void *, int); static void mwl_bawatchdog_proc(void *, int); @@ -229,12 +229,11 @@ enum { ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK|IEEE80211_FC0_SUBTYPE_MASK)) == \ (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON)) #define IFF_DUMPPKTS_RECV(sc, wh) \ - (((sc->sc_debug & MWL_DEBUG_RECV) && \ - ((sc->sc_debug & MWL_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \ - (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) + ((sc->sc_debug & MWL_DEBUG_RECV) && \ + ((sc->sc_debug & MWL_DEBUG_RECV_ALL) || !IS_BEACON(wh))) #define IFF_DUMPPKTS_XMIT(sc) \ - ((sc->sc_debug & MWL_DEBUG_XMIT) || \ - (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) + (sc->sc_debug & MWL_DEBUG_XMIT) + #define DPRINTF(sc, m, fmt, ...) do { \ if (sc->sc_debug & (m)) \ printf(fmt, __VA_ARGS__); \ @@ -246,16 +245,10 @@ enum { static void mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix); static void mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix); #else -#define IFF_DUMPPKTS_RECV(sc, wh) \ - ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) -#define IFF_DUMPPKTS_XMIT(sc) \ - ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) -#define DPRINTF(sc, m, fmt, ...) do { \ - (void) sc; \ -} while (0) -#define KEYPRINTF(sc, k, mac) do { \ - (void) sc; \ -} while (0) +#define IFF_DUMPPKTS_RECV(sc, wh) do {} while (0) +#define IFF_DUMPPKTS_XMIT(sc) do {} while (0) +#define DPRINTF(sc, m, fmt, ...) do {} while (0) +#define KEYPRINTF(sc, k, mac) do {} while (0) #endif static MALLOC_DEFINE(M_MWLDEV, "mwldev", "mwl driver dma buffers"); @@ -293,34 +286,22 @@ WR4(struct mwl_softc *sc, bus_size_t off, uint32_t val) int mwl_attach(uint16_t devid, struct mwl_softc *sc) { - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_hal *mh; int error = 0; DPRINTF(sc, MWL_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "cannot if_alloc()\n"); - return ENOSPC; - } - ic = ifp->if_l2com; - /* * Setup the RX free list lock early, so it can be consistently * removed. */ MWL_RXFREE_INIT(sc); - /* set these up early for if_printf use */ - if_initname(ifp, device_get_name(sc->sc_dev), - device_get_unit(sc->sc_dev)); - mh = mwl_hal_attach(sc->sc_dev, devid, sc->sc_io1h, sc->sc_io1t, sc->sc_dmat); if (mh == NULL) { - if_printf(ifp, "unable to attach HAL\n"); + device_printf(sc->sc_dev, "unable to attach HAL\n"); error = EIO; goto bad; } @@ -331,12 +312,12 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) * needed so setting up the wrong mode isn't a big deal. */ if (mwl_hal_fwload(mh, NULL) != 0) { - if_printf(ifp, "unable to setup builtin firmware\n"); + device_printf(sc->sc_dev, "unable to setup builtin firmware\n"); error = EIO; goto bad1; } if (mwl_hal_gethwspecs(mh, &sc->sc_hwspecs) != 0) { - if_printf(ifp, "unable to fetch h/w specs\n"); + device_printf(sc->sc_dev, "unable to fetch h/w specs\n"); error = EIO; goto bad1; } @@ -356,7 +337,8 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) */ error = mwl_dma_setup(sc); if (error != 0) { - if_printf(ifp, "failed to setup descriptors: %d\n", error); + device_printf(sc->sc_dev, "failed to setup descriptors: %d\n", + error); goto bad1; } error = mwl_setupdma(sc); /* push to firmware */ @@ -365,11 +347,12 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) callout_init(&sc->sc_timer, 1); callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->sc_tq); taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, - "%s taskq", ifp->if_xname); + "%s taskq", device_get_nameunit(sc->sc_dev)); TASK_INIT(&sc->sc_rxtask, 0, mwl_rx_proc, sc); TASK_INIT(&sc->sc_radartask, 0, mwl_radar_proc, sc); @@ -378,8 +361,9 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) /* NB: insure BK queue is the lowest priority h/w queue */ if (!mwl_tx_setup(sc, WME_AC_BK, MWL_WME_AC_BK)) { - if_printf(ifp, "unable to setup xmit queue for %s traffic!\n", - ieee80211_wme_acnames[WME_AC_BK]); + device_printf(sc->sc_dev, + "unable to setup xmit queue for %s traffic!\n", + ieee80211_wme_acnames[WME_AC_BK]); error = EIO; goto bad2; } @@ -403,16 +387,6 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) } TASK_INIT(&sc->sc_txtask, 0, mwl_tx_proc, sc); - ifp->if_softc = sc; - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; - ifp->if_start = mwl_start; - ifp->if_ioctl = mwl_ioctl; - ifp->if_init = mwl_init; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(sc->sc_dev); /* XXX not right but it's not used anywhere important */ @@ -480,8 +454,10 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) ic->ic_headroom = sizeof(struct mwltxrec) - sizeof(struct ieee80211_frame); + IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->sc_hwspecs.macAddr); + /* call MI attach routine. */ - ieee80211_ifattach(ic, sc->sc_hwspecs.macAddr); + ieee80211_ifattach(ic); ic->ic_setregdomain = mwl_setregdomain; ic->ic_getradiocaps = mwl_getradiocaps; /* override default methods */ @@ -491,6 +467,9 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) ic->ic_update_mcast = mwl_update_mcast; ic->ic_update_promisc = mwl_update_promisc; ic->ic_wme.wme_update = mwl_wme_update; + ic->ic_transmit = mwl_transmit; + ic->ic_ioctl = mwl_ioctl; + ic->ic_parent = mwl_parent; ic->ic_node_alloc = mwl_node_alloc; sc->sc_node_cleanup = ic->ic_node_cleanup; @@ -537,7 +516,6 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) mwl_hal_detach(mh); bad: MWL_RXFREE_DESTROY(sc); - if_free(ifp); sc->sc_invalid = 1; return error; } @@ -545,13 +523,11 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc) int mwl_detach(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); - - mwl_stop(ifp, 1); + MWL_LOCK(sc); + mwl_stop(sc); + MWL_UNLOCK(sc); /* * NB: the order of these is important: * o call the 802.11 layer before detaching the hal to @@ -570,7 +546,7 @@ mwl_detach(struct mwl_softc *sc) MWL_RXFREE_DESTROY(sc); mwl_tx_cleanup(sc); mwl_hal_detach(sc->sc_mh); - if_free(ifp); + mbufq_drain(&sc->sc_snd); return 0; } @@ -601,7 +577,7 @@ assign_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN], int clone) } static void -reclaim_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN]) +reclaim_address(struct mwl_softc *sc, const uint8_t mac[IEEE80211_ADDR_LEN]) { int i = mac[0] >> 2; if (i != 0 || --sc->sc_nbssid0 == 0) @@ -614,8 +590,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac0[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; struct ieee80211vap *vap, *apvap; struct mwl_hal_vap *hvap; @@ -661,17 +636,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, return NULL; } - mvp = (struct mwl_vap *) malloc(sizeof(struct mwl_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (mvp == NULL) { - if (hvap != NULL) { - mwl_hal_delvap(hvap); - if ((flags & IEEE80211_CLONE_MACADDR) == 0) - reclaim_address(sc, mac); - } - /* XXX msg */ - return NULL; - } + mvp = malloc(sizeof(struct mwl_vap), M_80211_VAP, M_WAITOK | M_ZERO); mvp->mv_hvap = hvap; if (opmode == IEEE80211_M_WDS) { /* @@ -686,9 +651,7 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, KASSERT(mvp->mv_ap_hvap != NULL, ("no ap vap")); } vap = &mvp->mv_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); - if (hvap != NULL) - IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override with driver methods */ mvp->mv_newstate = vap->iv_newstate; vap->iv_newstate = mwl_newstate; @@ -713,7 +676,8 @@ mwl_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4; /* complete setup */ - ieee80211_vap_attach(vap, mwl_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, mwl_media_change, ieee80211_media_status, + mac); switch (vap->iv_opmode) { case IEEE80211_M_HOSTAP: @@ -752,14 +716,13 @@ static void mwl_vap_delete(struct ieee80211vap *vap) { struct mwl_vap *mvp = MWL_VAP(vap); - struct ifnet *parent = vap->iv_ic->ic_ifp; - struct mwl_softc *sc = parent->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; struct mwl_hal_vap *hvap = mvp->mv_hvap; enum ieee80211_opmode opmode = vap->iv_opmode; /* XXX disallow ap vap delete if WDS still present */ - if (parent->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_running) { /* quiesce h/w while we remove the vap */ mwl_hal_intrset(mh, 0); /* disable interrupts */ } @@ -786,31 +749,31 @@ mwl_vap_delete(struct ieee80211vap *vap) } mwl_cleartxq(sc, vap); free(mvp, M_80211_VAP); - if (parent->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_running) mwl_hal_intrset(mh, sc->sc_imask); } void mwl_suspend(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); - - mwl_stop(ifp, 1); + MWL_LOCK(sc); + mwl_stop(sc); + MWL_UNLOCK(sc); } void mwl_resume(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; + int error = EDOOFUS; - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", - __func__, ifp->if_flags); + MWL_LOCK(sc); + if (sc->sc_ic.ic_nrunning > 0) + error = mwl_init(sc); + MWL_UNLOCK(sc); - if (ifp->if_flags & IFF_UP) - mwl_init(sc); + if (error == 0) + ieee80211_start_all(&sc->sc_ic); /* start all vap's */ } void @@ -818,7 +781,9 @@ mwl_shutdown(void *arg) { struct mwl_softc *sc = arg; - mwl_stop(sc->sc_ifp, 1); + MWL_LOCK(sc); + mwl_stop(sc); + MWL_UNLOCK(sc); } /* @@ -884,8 +849,7 @@ static void mwl_radar_proc(void *arg, int pending) { struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; DPRINTF(sc, MWL_DEBUG_ANY, "%s: radar detected, pending %u\n", __func__, pending); @@ -902,8 +866,7 @@ static void mwl_chanswitch_proc(void *arg, int pending) { struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; DPRINTF(sc, MWL_DEBUG_ANY, "%s: channel switch notice, pending %u\n", __func__, pending); @@ -1031,8 +994,7 @@ mwl_setupdma(struct mwl_softc *sc) static int mwl_setcurchanrates(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct ieee80211_rateset *rs; MWL_HAL_TXRATE rates; @@ -1145,8 +1107,7 @@ mwl_map2regioncode(const struct ieee80211_regdomain *rd) static int mwl_hal_reset(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_hal *mh = sc->sc_mh; mwl_hal_setantenna(mh, WL_ANTENNATYPE_RX, sc->sc_rxantenna); @@ -1168,28 +1129,24 @@ mwl_hal_reset(struct mwl_softc *sc) } static int -mwl_init_locked(struct mwl_softc *sc) +mwl_init(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct mwl_hal *mh = sc->sc_mh; int error = 0; - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); - MWL_LOCK_ASSERT(sc); /* * Stop anything previously setup. This is safe * whether this is the first time through or not. */ - mwl_stop_locked(ifp, 0); + mwl_stop(sc); /* * Push vap-independent state to the firmware. */ if (!mwl_hal_reset(sc)) { - if_printf(ifp, "unable to reset hardware\n"); + device_printf(sc->sc_dev, "unable to reset hardware\n"); return EIO; } @@ -1198,7 +1155,7 @@ mwl_init_locked(struct mwl_softc *sc) */ error = mwl_startrecv(sc); if (error != 0) { - if_printf(ifp, "unable to start recv logic\n"); + device_printf(sc->sc_dev, "unable to start recv logic\n"); return error; } @@ -1221,7 +1178,7 @@ mwl_init_locked(struct mwl_softc *sc) | MACREQ_A2HRIC_BIT_TX_ACK ; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_running = 1; mwl_hal_intrset(mh, sc->sc_imask); callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc); @@ -1229,54 +1186,21 @@ mwl_init_locked(struct mwl_softc *sc) } static void -mwl_init(void *arg) +mwl_stop(struct mwl_softc *sc) { - struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - int error = 0; - - DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n", - __func__, ifp->if_flags); - - MWL_LOCK(sc); - error = mwl_init_locked(sc); - MWL_UNLOCK(sc); - - if (error == 0) - ieee80211_start_all(ic); /* start all vap's */ -} - -static void -mwl_stop_locked(struct ifnet *ifp, int disable) -{ - struct mwl_softc *sc = ifp->if_softc; - - DPRINTF(sc, MWL_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", - __func__, sc->sc_invalid, ifp->if_flags); MWL_LOCK_ASSERT(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_running) { /* * Shutdown the hardware and driver. */ - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sc->sc_running = 0; callout_stop(&sc->sc_watchdog); sc->sc_tx_timer = 0; mwl_draintxq(sc); } } -static void -mwl_stop(struct ifnet *ifp, int disable) -{ - struct mwl_softc *sc = ifp->if_softc; - - MWL_LOCK(sc); - mwl_stop_locked(ifp, disable); - MWL_UNLOCK(sc); -} - static int mwl_reset_vap(struct ieee80211vap *vap, int state) { @@ -1319,8 +1243,7 @@ mwl_reset(struct ieee80211vap *vap, u_long cmd) if (hvap != NULL) { /* WDS, MONITOR, etc. */ struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; /* XXX handle DWDS sta vap change */ @@ -1386,24 +1309,41 @@ mwl_puttxbuf_tail(struct mwl_txq *txq, struct mwl_txbuf *bf) MWL_TXQ_UNLOCK(txq); } -static void -mwl_start(struct ifnet *ifp) +static int +mwl_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct mwl_softc *sc = ic->ic_softc; + int error; + + MWL_LOCK(sc); + if (!sc->sc_running) { + MWL_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + MWL_UNLOCK(sc); + return (error); + } + mwl_start(sc); + MWL_UNLOCK(sc); + return (0); +} + +static void +mwl_start(struct mwl_softc *sc) { - struct mwl_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mwl_txbuf *bf; struct mbuf *m; struct mwl_txq *txq = NULL; /* XXX silence gcc */ int nqueued; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) + MWL_LOCK_ASSERT(sc); + if (!sc->sc_running || sc->sc_invalid) return; nqueued = 0; - for (;;) { - bf = NULL; - IFQ_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { /* * Grab the node for the destination. */ @@ -1421,8 +1361,6 @@ mwl_start(struct ifnet *ifp) ieee80211_free_node(ni); #ifdef MWL_TX_NODROP sc->sc_stats.mst_tx_qstop++; - /* XXX blocks other traffic */ - ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; #else DPRINTF(sc, MWL_DEBUG_XMIT, @@ -1436,7 +1374,8 @@ mwl_start(struct ifnet *ifp) * Pass the frame to the h/w for transmission. */ if (mwl_tx_start(sc, ni, bf, m)) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); mwl_puttxbuf_head(txq, bf); ieee80211_free_node(ni); continue; @@ -1474,12 +1413,11 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_txbuf *bf; struct mwl_txq *txq; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) { + if (!sc->sc_running || sc->sc_invalid) { ieee80211_free_node(ni); m_freem(m); return ENETDOWN; @@ -1496,8 +1434,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, bf = mwl_gettxbuf(sc, txq); if (bf == NULL) { sc->sc_stats.mst_tx_qstop++; - /* XXX blocks other traffic */ - ifp->if_drv_flags |= IFF_DRV_OACTIVE; ieee80211_free_node(ni); m_freem(m); return ENOBUFS; @@ -1506,7 +1442,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, * Pass the frame to the h/w for transmission. */ if (mwl_tx_start(sc, ni, bf, m)) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); mwl_puttxbuf_head(txq, bf); ieee80211_free_node(ni); @@ -1581,7 +1516,7 @@ static int mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { - struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; if (k->wk_keyix != IEEE80211_KEYIX_NONE || (k->wk_flags & IEEE80211_KEY_GROUP)) { @@ -1609,7 +1544,7 @@ mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, static int mwl_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) { - struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; MWL_HAL_KEYVAL hk; const uint8_t bcastaddr[IEEE80211_ADDR_LEN] = @@ -1676,7 +1611,7 @@ mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, #define IEEE80211_IS_STATICKEY(k) \ (((k)->wk_flags & (GRPXMIT|IEEE80211_KEY_RECV)) == \ (GRPXMIT|IEEE80211_KEY_RECV)) - struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; const struct ieee80211_cipher *cip = k->wk_cipher; const uint8_t *macaddr; @@ -1791,7 +1726,6 @@ mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, static void mwl_setmcastfilter(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; #if 0 struct ether_multi *enm; struct ether_multistep estep; @@ -1815,17 +1749,13 @@ mwl_setmcastfilter(struct mwl_softc *sc) } ifp->if_flags &= ~IFF_ALLMULTI; mwl_hal_setmcast(sc->sc_mh, nmc, macs); -#else - /* XXX no mcast filter support; we get everything */ - ifp->if_flags |= IFF_ALLMULTI; #endif } static int mwl_mode_init(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_hal *mh = sc->sc_mh; /* @@ -1834,7 +1764,7 @@ mwl_mode_init(struct mwl_softc *sc) * identify internal requests (from the bridge) * versus external requests such as for tcpdump. */ - mwl_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) && + mwl_hal_setpromisc(mh, ic->ic_promisc > 0 && ic->ic_opmode != IEEE80211_M_HOSTAP); mwl_setmcastfilter(sc); @@ -1864,8 +1794,7 @@ mwl_update_promisc(struct ieee80211com *ic) { struct mwl_softc *sc = ic->ic_softc; - mwl_hal_setpromisc(sc->sc_mh, - (ic->ic_ifp->if_flags & IFF_PROMISC) != 0); + mwl_hal_setpromisc(sc->sc_mh, ic->ic_promisc > 0); } /* @@ -1882,7 +1811,7 @@ mwl_updateslot(struct ieee80211com *ic) int prot; /* NB: can be called early; suppress needless cmds */ - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if (!sc->sc_running) return; /* @@ -2004,7 +1933,6 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name, struct mwl_descdma *dd, int nbuf, size_t bufsize, int ndesc, size_t descsize) { - struct ifnet *ifp = sc->sc_ifp; uint8_t *ds; int error; @@ -2032,7 +1960,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name, NULL, /* lockarg */ &dd->dd_dmat); if (error != 0) { - if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name); + device_printf(sc->sc_dev, "cannot allocate %s DMA tag\n", dd->dd_name); return error; } @@ -2041,7 +1969,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name, BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap); if (error != 0) { - if_printf(ifp, "unable to alloc memory for %u %s descriptors, " + device_printf(sc->sc_dev, "unable to alloc memory for %u %s descriptors, " "error %u\n", nbuf * ndesc, dd->dd_name, error); goto fail1; } @@ -2051,7 +1979,7 @@ mwl_desc_setup(struct mwl_softc *sc, const char *name, mwl_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT); if (error != 0) { - if_printf(ifp, "unable to map %s descriptors, error %u\n", + device_printf(sc->sc_dev, "unable to map %s descriptors, error %u\n", dd->dd_name, error); goto fail2; } @@ -2109,7 +2037,6 @@ mwl_txq_reset(struct mwl_softc *sc, struct mwl_txq *txq) static int mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq) { - struct ifnet *ifp = sc->sc_ifp; int error, bsize, i; struct mwl_txbuf *bf; struct mwl_txdesc *ds; @@ -2124,7 +2051,7 @@ mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq) bsize = mwl_txbuf * sizeof(struct mwl_txbuf); bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO); if (bf == NULL) { - if_printf(ifp, "malloc of %u tx buffers failed\n", + device_printf(sc->sc_dev, "malloc of %u tx buffers failed\n", mwl_txbuf); return ENOMEM; } @@ -2137,7 +2064,7 @@ mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq) error = bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT, &bf->bf_dmamap); if (error != 0) { - if_printf(ifp, "unable to create dmamap for tx " + device_printf(sc->sc_dev, "unable to create dmamap for tx " "buffer %u, error %u\n", i, error); return error; } @@ -2172,7 +2099,6 @@ mwl_txdma_cleanup(struct mwl_softc *sc, struct mwl_txq *txq) static int mwl_rxdma_setup(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int error, jumbosize, bsize, i; struct mwl_rxbuf *bf; struct mwl_jumbo *rbuf; @@ -2196,7 +2122,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) * us while frames are processed. */ if (mwl_rxbuf < 2*mwl_rxdesc) { - if_printf(ifp, + device_printf(sc->sc_dev, "too few rx dma buffers (%d); increasing to %d\n", mwl_rxbuf, 2*mwl_rxdesc); mwl_rxbuf = 2*mwl_rxdesc; @@ -2217,7 +2143,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) NULL, /* lockarg */ &sc->sc_rxdmat); if (error != 0) { - if_printf(ifp, "could not create rx DMA tag\n"); + device_printf(sc->sc_dev, "could not create rx DMA tag\n"); return error; } @@ -2225,7 +2151,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->sc_rxmap); if (error != 0) { - if_printf(ifp, "could not alloc %ju bytes of rx DMA memory\n", + device_printf(sc->sc_dev, "could not alloc %ju bytes of rx DMA memory\n", (uintmax_t) sc->sc_rxmemsize); return error; } @@ -2235,7 +2161,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) mwl_load_cb, &sc->sc_rxmem_paddr, BUS_DMA_NOWAIT); if (error != 0) { - if_printf(ifp, "could not load rx DMA map\n"); + device_printf(sc->sc_dev, "could not load rx DMA map\n"); return error; } @@ -2245,7 +2171,7 @@ mwl_rxdma_setup(struct mwl_softc *sc) bsize = mwl_rxdesc * sizeof(struct mwl_rxbuf); bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO); if (bf == NULL) { - if_printf(ifp, "malloc of %u rx buffers failed\n", bsize); + device_printf(sc->sc_dev, "malloc of %u rx buffers failed\n", bsize); return error; } sc->sc_rxdma.dd_bufptr = bf; @@ -2329,7 +2255,7 @@ static struct ieee80211_node * mwl_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ieee80211com *ic = vap->iv_ic; - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; const size_t space = sizeof(struct mwl_node); struct mwl_node *mn; @@ -2346,7 +2272,7 @@ static void mwl_node_cleanup(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_node *mn = MWL_NODE(ni); DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p ic %p staid %d\n", @@ -2441,7 +2367,7 @@ static void mwl_node_drain(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_node *mn = MWL_NODE(ni); DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p vap %p staid %d\n", @@ -2696,8 +2622,7 @@ mwl_rx_proc(void *arg, int npending) #define IEEE80211_DIR_DSTODS(wh) \ ((((const struct ieee80211_frame *)wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_rxbuf *bf; struct mwl_rxdesc *ds; struct mbuf *m; @@ -2744,7 +2669,7 @@ mwl_rx_proc(void *arg, int npending) #endif status = ds->Status; if (status & EAGLE_RXD_STATUS_DECRYPT_ERR_MASK) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); sc->sc_stats.mst_rx_crypto++; /* * NB: Check EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR @@ -2840,7 +2765,6 @@ mwl_rx_proc(void *arg, int npending) data, sc, 0, EXT_NET_DRV); m->m_data += off - hdrlen; m->m_pkthdr.len = m->m_len = pktlen; - m->m_pkthdr.rcvif = ifp; /* NB: dma buffer assumed read-only */ /* @@ -2890,8 +2814,6 @@ mwl_rx_proc(void *arg, int npending) ieee80211_dump_pkt(ic, mtod(m, caddr_t), len, ds->Rate, rssi); } - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - /* dispatch */ ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh); @@ -2918,11 +2840,10 @@ mwl_rx_proc(void *arg, int npending) rx_stop: sc->sc_rxnext = bf; - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) { + if (mbufq_first(&sc->sc_snd) != NULL) { /* NB: kick fw; the tx thread may have been preempted */ mwl_hal_txstart(sc->sc_mh, 0); - mwl_start(ifp); + mwl_start(sc); } #undef IEEE80211_DIR_DSTODS } @@ -2987,8 +2908,7 @@ static int mwl_txq_update(struct mwl_softc *sc, int ac) { #define MWL_EXPONENT_TO_VALUE(v) ((1<sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_txq *txq = sc->sc_ac2q[ac]; struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; struct mwl_hal *mh = sc->sc_mh; @@ -3016,7 +2936,7 @@ mwl_txq_update(struct mwl_softc *sc, int ac) static int mwl_wme_update(struct ieee80211com *ic) { - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; return !mwl_txq_update(sc, WME_AC_BE) || !mwl_txq_update(sc, WME_AC_BK) || @@ -3173,8 +3093,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf * { #define IEEE80211_DIR_DSTODS(wh) \ ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; int error, iswep, ismcast; int hdrlen, copyhdrlen, pktlen; @@ -3391,7 +3310,7 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf * ds->TxPriority = txq->qnum; break; default: - if_printf(ifp, "bogus frame type 0x%x (%s)\n", + device_printf(sc->sc_dev, "bogus frame type 0x%x (%s)\n", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__); sc->sc_stats.mst_tx_badframetype++; m_freem(m0); @@ -3408,7 +3327,6 @@ mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf * STAILQ_INSERT_TAIL(&txq->active, bf, bf_list); MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); sc->sc_tx_timer = 5; MWL_TXQ_UNLOCK(txq); @@ -3434,8 +3352,7 @@ mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq) { #define EAGLE_TXD_STATUS_MCAST \ (EAGLE_TXD_STATUS_MULTICAST_TX | EAGLE_TXD_STATUS_BROADCAST_TX) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mwl_txbuf *bf; struct mwl_txdesc *ds; struct ieee80211_node *ni; @@ -3497,32 +3414,18 @@ mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq) if (bf->bf_m->m_flags & M_FF) sc->sc_stats.mst_ff_txerr++; } - /* - * Do any tx complete callback. Note this must - * be done before releasing the node reference. - * XXX no way to figure out if frame was ACK'd - */ - if (bf->bf_m->m_flags & M_TXCB) { + if (bf->bf_m->m_flags & M_TXCB) /* XXX strip fw len in case header inspected */ m_adj(bf->bf_m, sizeof(uint16_t)); - ieee80211_process_callback(ni, bf->bf_m, - (status & EAGLE_TXD_STATUS_OK) == 0); - } - /* - * Reclaim reference to node. - * - * NB: the node may be reclaimed here if, for example - * this is a DEAUTH message that was sent and the - * node was timed out due to inactivity. - */ - ieee80211_free_node(ni); - } + ieee80211_tx_complete(ni, bf->bf_m, + (status & EAGLE_TXD_STATUS_OK) == 0); + } else + m_freem(bf->bf_m); ds->Status = htole32(EAGLE_TXD_STATUS_IDLE); bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); - m_freem(bf->bf_m); mwl_puttxbuf_tail(txq, bf); } @@ -3538,7 +3441,6 @@ static void mwl_tx_proc(void *arg, int npending) { struct mwl_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; int nreaped; /* @@ -3555,12 +3457,11 @@ mwl_tx_proc(void *arg, int npending) nreaped += mwl_tx_processq(sc, &sc->sc_txq[3]); if (nreaped != 0) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->sc_tx_timer = 0; - if (!IFQ_IS_EMPTY(&ifp->if_snd)) { + if (mbufq_first(&sc->sc_snd) != NULL) { /* NB: kick fw; the tx thread may have been preempted */ mwl_hal_txstart(sc->sc_mh, 0); - mwl_start(ifp); + mwl_start(sc); } } } @@ -3587,8 +3488,7 @@ mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq) MWL_TXQ_UNLOCK(txq); #ifdef MWL_DEBUG if (sc->sc_debug & MWL_DEBUG_RESET) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct mwltxrec *tr = mtod(bf->bf_m, const struct mwltxrec *); mwl_printtxbuf(bf, txq->qnum, ix); @@ -3616,12 +3516,10 @@ mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq) static void mwl_draintxq(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int i; for (i = 0; i < MWL_NUM_TX_QUEUES; i++) mwl_tx_draintxq(sc, &sc->sc_txq[i]); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->sc_tx_timer = 0; } @@ -3671,7 +3569,7 @@ static int mwl_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh, const uint8_t *frm, const uint8_t *efrm) { - struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct mwl_softc *sc = ni->ni_ic->ic_softc; const struct ieee80211_action *ia; ia = (const struct ieee80211_action *) frm; @@ -3692,7 +3590,7 @@ static int mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int dialogtoken, int baparamset, int batimeout) { - struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct mwl_softc *sc = ni->ni_ic->ic_softc; struct ieee80211vap *vap = ni->ni_vap; struct mwl_node *mn = MWL_NODE(ni); struct mwl_bastate *bas; @@ -3764,7 +3662,7 @@ static int mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int code, int baparamset, int batimeout) { - struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct mwl_softc *sc = ni->ni_ic->ic_softc; struct mwl_bastate *bas; bas = tap->txa_private; @@ -3830,7 +3728,7 @@ mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, static void mwl_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) { - struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct mwl_softc *sc = ni->ni_ic->ic_softc; struct mwl_bastate *bas; bas = tap->txa_private; @@ -3923,8 +3821,7 @@ static int mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan) { struct mwl_hal *mh = sc->sc_mh; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; MWL_HAL_CHANNEL hchan; int maxtxpow; @@ -3980,8 +3877,7 @@ mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan) static void mwl_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__); } @@ -3989,8 +3885,7 @@ mwl_scan_start(struct ieee80211com *ic) static void mwl_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__); } @@ -3998,8 +3893,7 @@ mwl_scan_end(struct ieee80211com *ic) static void mwl_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; (void) mwl_chan_set(sc, ic->ic_curchan); } @@ -4014,7 +3908,7 @@ static void mwl_startcsa(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; MWL_HAL_CHANNEL hchan; if (sc->sc_csapending) @@ -4215,8 +4109,7 @@ mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) struct mwl_hal_vap *hvap = mvp->mv_hvap; struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node *ni = NULL; - struct ifnet *ifp = ic->ic_ifp; - struct mwl_softc *sc = ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; enum ieee80211_state ostate = vap->iv_state; int error; @@ -4398,7 +4291,7 @@ static void mwl_newassoc(struct ieee80211_node *ni, int isnew) { struct ieee80211vap *vap = ni->ni_vap; - struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct mwl_softc *sc = vap->iv_ic->ic_softc; struct mwl_node *mn = MWL_NODE(ni); MWL_HAL_PEERINFO pi; uint16_t aid; @@ -4454,7 +4347,7 @@ static int mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, int nchan, struct ieee80211_channel chans[]) { - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; struct mwl_hal *mh = sc->sc_mh; const MWL_HAL_CHANNELINFO *ci; int i; @@ -4472,7 +4365,7 @@ mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, IEEE80211_IS_CHAN_HT40(c) ? MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci); } else { - if_printf(ic->ic_ifp, + device_printf(sc->sc_dev, "%s: channel %u freq %u/0x%x not 2.4/5GHz\n", __func__, c->ic_ieee, c->ic_freq, c->ic_flags); return EINVAL; @@ -4498,7 +4391,7 @@ mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, goto next; } } - if_printf(ic->ic_ifp, + device_printf(sc->sc_dev, "%s: no cal data for channel %u ext %u freq %u/0x%x\n", __func__, c->ic_ieee, c->ic_extieee, c->ic_freq, c->ic_flags); @@ -4654,7 +4547,7 @@ static void mwl_getradiocaps(struct ieee80211com *ic, int maxchans, int *nchans, struct ieee80211_channel chans[]) { - struct mwl_softc *sc = ic->ic_ifp->if_softc; + struct mwl_softc *sc = ic->ic_softc; getchannels(sc, maxchans, nchans, chans); } @@ -4662,8 +4555,7 @@ mwl_getradiocaps(struct ieee80211com *ic, static int mwl_getchannels(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* * Use the channel info from the hal to craft the @@ -4768,25 +4660,24 @@ mwl_txq_dump(struct mwl_txq *txq) static void mwl_watchdog(void *arg) { - struct mwl_softc *sc; - struct ifnet *ifp; + struct mwl_softc *sc = arg; - sc = arg; callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc); if (sc->sc_tx_timer == 0 || --sc->sc_tx_timer > 0) return; - ifp = sc->sc_ifp; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) { + if (sc->sc_running && !sc->sc_invalid) { if (mwl_hal_setkeepalive(sc->sc_mh)) - if_printf(ifp, "transmit timeout (firmware hung?)\n"); + device_printf(sc->sc_dev, + "transmit timeout (firmware hung?)\n"); else - if_printf(ifp, "transmit timeout\n"); + device_printf(sc->sc_dev, + "transmit timeout\n"); #if 0 - mwl_reset(ifp); + mwl_reset(sc); mwl_txq_dump(&sc->sc_txq[0]);/*XXX*/ #endif - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); sc->sc_stats.mst_watchdog++; } } @@ -4885,28 +4776,22 @@ mwl_ioctl_reset(struct mwl_softc *sc, struct mwl_diag *md) } #endif /* MWL_DIAGAPI */ -static int -mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +mwl_parent(struct ieee80211com *ic) { -#define IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct mwl_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0, startall; + struct mwl_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - MWL_LOCK(sc); - startall = 0; - if (IS_RUNNING(ifp)) { + MWL_LOCK(sc); + if (ic->ic_nrunning > 0) { + if (sc->sc_running) { /* * To avoid rescanning another access point, * do not call mwl_init() here. Instead, * only reflect promisc mode settings. */ mwl_mode_init(sc); - } else if (ifp->if_flags & IFF_UP) { + } else { /* * Beware of being called during attach/detach * to reset promiscuous mode. In that case we @@ -4917,30 +4802,42 @@ mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * probably a better way to deal with this. */ if (!sc->sc_invalid) { - mwl_init_locked(sc); /* XXX lose error */ + mwl_init(sc); /* XXX lose error */ startall = 1; } - } else - mwl_stop_locked(ifp, 1); - MWL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; + } + } else + mwl_stop(sc); + MWL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); +} + +static int +mwl_ioctl(struct ieee80211com *ic, u_long cmd, void *data) +{ + struct mwl_softc *sc = ic->ic_softc; + struct ifreq *ifr = data; + int error = 0; + + switch (cmd) { case SIOCGMVSTATS: mwl_hal_gethwstats(sc->sc_mh, &sc->sc_stats.hw_stats); +#if 0 /* NB: embed these numbers to get a consistent view */ sc->sc_stats.mst_tx_packets = ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS); sc->sc_stats.mst_rx_packets = ifp->if_get_counter(ifp, IFCOUNTER_IPACKETS); +#endif /* * NB: Drop the softc lock in case of a page fault; * we'll accept any potential inconsisentcy in the * statistics. The alternative is to copy the data * to a local structure. */ - return copyout(&sc->sc_stats, - ifr->ifr_data, sizeof (sc->sc_stats)); + return (copyout(&sc->sc_stats, + ifr->ifr_data, sizeof (sc->sc_stats))); #ifdef MWL_DIAGAPI case SIOCGMVDIAG: /* XXX check privs */ @@ -4952,18 +4849,11 @@ mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) MWL_UNLOCK(sc); break; #endif /* MWL_DIAGAPI */ - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; default: - error = EINVAL; + error = ENOTTY; break; } - return error; -#undef IS_RUNNING + return (error); } #ifdef MWL_DEBUG @@ -5003,9 +4893,8 @@ mwl_sysctlattach(struct mwl_softc *sc) static void mwl_announce(struct mwl_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - if_printf(ifp, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n", + device_printf(sc->sc_dev, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n", sc->sc_hwspecs.hwVersion, (sc->sc_hwspecs.fwReleaseNumber>>24) & 0xff, (sc->sc_hwspecs.fwReleaseNumber>>16) & 0xff, @@ -5018,20 +4907,20 @@ mwl_announce(struct mwl_softc *sc) int i; for (i = 0; i <= WME_AC_VO; i++) { struct mwl_txq *txq = sc->sc_ac2q[i]; - if_printf(ifp, "Use hw queue %u for %s traffic\n", + device_printf(sc->sc_dev, "Use hw queue %u for %s traffic\n", txq->qnum, ieee80211_wme_acnames[i]); } } if (bootverbose || mwl_rxdesc != MWL_RXDESC) - if_printf(ifp, "using %u rx descriptors\n", mwl_rxdesc); + device_printf(sc->sc_dev, "using %u rx descriptors\n", mwl_rxdesc); if (bootverbose || mwl_rxbuf != MWL_RXBUF) - if_printf(ifp, "using %u rx buffers\n", mwl_rxbuf); + device_printf(sc->sc_dev, "using %u rx buffers\n", mwl_rxbuf); if (bootverbose || mwl_txbuf != MWL_TXBUF) - if_printf(ifp, "using %u tx buffers\n", mwl_txbuf); + device_printf(sc->sc_dev, "using %u tx buffers\n", mwl_txbuf); if (bootverbose && mwl_hal_ismbsscapable(sc->sc_mh)) - if_printf(ifp, "multi-bss support\n"); + device_printf(sc->sc_dev, "multi-bss support\n"); #ifdef MWL_TX_NODROP if (bootverbose) - if_printf(ifp, "no tx drop\n"); + device_printf(sc->sc_dev, "no tx drop\n"); #endif } diff --git a/sys/dev/mwl/if_mwl_pci.c b/sys/dev/mwl/if_mwl_pci.c index ef7009c785d1..d9da128af70e 100644 --- a/sys/dev/mwl/if_mwl_pci.c +++ b/sys/dev/mwl/if_mwl_pci.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/dev/mwl/if_mwlvar.h b/sys/dev/mwl/if_mwlvar.h index 7071ba03562b..4a4b338239e5 100644 --- a/sys/dev/mwl/if_mwlvar.h +++ b/sys/dev/mwl/if_mwlvar.h @@ -244,7 +244,8 @@ struct mwl_vap { #define MWL_VAP_CONST(vap) ((const struct mwl_vap *)(vap)) struct mwl_softc { - struct ifnet *sc_ifp; /* interface common */ + struct ieee80211com sc_ic; + struct mbufq sc_snd; struct mwl_stats sc_stats; /* interface statistics */ int sc_debug; device_t sc_dev; @@ -257,7 +258,8 @@ struct mwl_softc { struct taskqueue *sc_tq; /* private task queue */ struct callout sc_watchdog; int sc_tx_timer; - unsigned int sc_invalid : 1, /* disable hardware accesses */ + unsigned int sc_running : 1, + sc_invalid : 1, /* disable hardware accesses */ sc_recvsetup:1, /* recv setup */ sc_csapending:1,/* 11h channel switch pending */ sc_radarena : 1,/* radar detection enabled */ diff --git a/sys/dev/ral/if_ral_pci.c b/sys/dev/ral/if_ral_pci.c index 519b4ca30d78..42ec03424bdf 100644 --- a/sys/dev/ral/if_ral_pci.c +++ b/sys/dev/ral/if_ral_pci.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index 29ce8cbf8014..ea9c4162b8f8 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -127,10 +127,10 @@ static int rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); static int rt2560_tx_data(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); -static void rt2560_start_locked(struct ifnet *); -static void rt2560_start(struct ifnet *); +static int rt2560_transmit(struct ieee80211com *, struct mbuf *); +static void rt2560_start(struct rt2560_softc *); static void rt2560_watchdog(void *); -static int rt2560_ioctl(struct ifnet *, u_long, caddr_t); +static void rt2560_parent(struct ieee80211com *); static void rt2560_bbp_write(struct rt2560_softc *, uint8_t, uint8_t); static uint8_t rt2560_bbp_read(struct rt2560_softc *, uint8_t); @@ -149,7 +149,8 @@ static void rt2560_set_basicrates(struct rt2560_softc *, const struct ieee80211_rateset *); static void rt2560_update_led(struct rt2560_softc *, int, int); static void rt2560_set_bssid(struct rt2560_softc *, const uint8_t *); -static void rt2560_set_macaddr(struct rt2560_softc *, uint8_t *); +static void rt2560_set_macaddr(struct rt2560_softc *, + const uint8_t *); static void rt2560_get_macaddr(struct rt2560_softc *, uint8_t *); static void rt2560_update_promisc(struct ieee80211com *); static const char *rt2560_get_rf(int); @@ -197,11 +198,9 @@ int rt2560_attach(device_t dev, int id) { struct rt2560_softc *sc = device_get_softc(dev); - struct ieee80211com *ic; - struct ifnet *ifp; - int error; + struct ieee80211com *ic = &sc->sc_ic; uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; + int error; sc->sc_dev = dev; @@ -209,6 +208,7 @@ rt2560_attach(device_t dev, int id) MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* retrieve RT2560 rev. no */ sc->asic_rev = RAL_READ(sc, RT2560_CSR0); @@ -252,27 +252,9 @@ rt2560_attach(device_t dev, int id) goto fail5; } - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto fail6; - } - ic = ifp->if_l2com; - /* retrieve MAC address */ - rt2560_get_macaddr(sc, macaddr); + rt2560_get_macaddr(sc, ic->ic_macaddr); - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rt2560_init; - ifp->if_ioctl = rt2560_ioctl; - ifp->if_start = rt2560_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_opmode = IEEE80211_M_STA; @@ -303,7 +285,7 @@ rt2560_attach(device_t dev, int id) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_raw_xmit = rt2560_raw_xmit; ic->ic_updateslot = rt2560_update_slot; ic->ic_update_promisc = rt2560_update_promisc; @@ -313,6 +295,8 @@ rt2560_attach(device_t dev, int id) ic->ic_vap_create = rt2560_vap_create; ic->ic_vap_delete = rt2560_vap_delete; + ic->ic_parent = rt2560_parent; + ic->ic_transmit = rt2560_transmit; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -341,7 +325,6 @@ rt2560_attach(device_t dev, int id) return 0; -fail6: rt2560_free_rx_ring(sc, &sc->rxq); fail5: rt2560_free_tx_ring(sc, &sc->bcnq); fail4: rt2560_free_tx_ring(sc, &sc->prioq); fail3: rt2560_free_tx_ring(sc, &sc->atimq); @@ -355,12 +338,12 @@ int rt2560_detach(void *xsc) { struct rt2560_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; rt2560_stop(sc); ieee80211_ifdetach(ic); + mbufq_drain(&sc->sc_snd); rt2560_free_tx_ring(sc, &sc->txq); rt2560_free_tx_ring(sc, &sc->atimq); @@ -368,8 +351,6 @@ rt2560_detach(void *xsc) rt2560_free_tx_ring(sc, &sc->bcnq); rt2560_free_rx_ring(sc, &sc->rxq); - if_free(ifp); - mtx_destroy(&sc->sc_mtx); return 0; @@ -381,7 +362,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; + struct rt2560_softc *sc = ic->ic_softc; struct rt2560_vap *rvp; struct ieee80211vap *vap; @@ -394,7 +375,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - if_printf(ifp, "only 1 vap supported\n"); + device_printf(sc->sc_dev, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -403,7 +384,8 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - if_printf(ifp, "wds only supported in ap mode\n"); + device_printf(sc->sc_dev, + "wds only supported in ap mode\n"); return NULL; } /* @@ -414,15 +396,12 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - if_printf(ifp, "unknown opmode %d\n", opmode); + device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); return NULL; } - rvp = (struct rt2560_vap *) malloc(sizeof(struct rt2560_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return NULL; + rvp = malloc(sizeof(struct rt2560_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -431,7 +410,8 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -451,9 +431,8 @@ void rt2560_resume(void *xsc) { struct rt2560_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) + if (sc->sc_ic.ic_nrunning > 0) rt2560_init(sc); } @@ -763,8 +742,7 @@ static int rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2560_vap *rvp = RT2560_VAP(vap); - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = vap->iv_ic->ic_softc; int error; if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { @@ -792,7 +770,8 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) vap->iv_opmode == IEEE80211_M_MBSS) { m = ieee80211_beacon_alloc(ni, &rvp->ral_bo); if (m == NULL) { - if_printf(ifp, "could not allocate beacon\n"); + device_printf(sc->sc_dev, + "could not allocate beacon\n"); return ENOBUFS; } ieee80211_ref_node(ni); @@ -926,14 +905,13 @@ rt2560_encryption_intr(struct rt2560_softc *sc) static void rt2560_tx_intr(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct mbuf *m; - uint32_t flags; - int retrycnt; struct ieee80211vap *vap; struct ieee80211_node *ni; + uint32_t flags; + int retrycnt, status; bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map, BUS_DMASYNC_POSTREAD); @@ -961,7 +939,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + status = 0; break; case RT2560_TX_SUCCESS_RETRY: @@ -973,7 +951,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + status = 0; break; case RT2560_TX_FAIL_RETRY: @@ -985,7 +963,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + status = 1; break; case RT2560_TX_FAIL_INVALID: @@ -993,16 +971,16 @@ rt2560_tx_intr(struct rt2560_softc *sc) default: device_printf(sc->sc_dev, "sending data frame failed " "0x%08x\n", flags); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + status = 1; } bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->txq.data_dmat, data->map); - m_freem(m); - data->m = NULL; - ieee80211_free_node(data->ni); + + ieee80211_tx_complete(ni, m, status); data->ni = NULL; + data->m = NULL; /* descriptor is no longer valid */ desc->flags &= ~htole32(RT2560_TX_VALID); @@ -1019,19 +997,13 @@ rt2560_tx_intr(struct rt2560_softc *sc) if (sc->prioq.queued == 0 && sc->txq.queued == 0) sc->sc_tx_timer = 0; - if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) { - sc->sc_flags &= ~RT2560_F_DATA_OACTIVE; - if ((sc->sc_flags & - (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2560_start_locked(ifp); - } + if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) + rt2560_start(sc); } static void rt2560_prio_intr(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct ieee80211_node *ni; @@ -1103,13 +1075,8 @@ rt2560_prio_intr(struct rt2560_softc *sc) if (sc->prioq.queued == 0 && sc->txq.queued == 0) sc->sc_tx_timer = 0; - if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) { - sc->sc_flags &= ~RT2560_F_PRIO_OACTIVE; - if ((sc->sc_flags & - (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2560_start_locked(ifp); - } + if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) + rt2560_start(sc); } /* @@ -1119,8 +1086,7 @@ rt2560_prio_intr(struct rt2560_softc *sc) static void rt2560_decryption_intr(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct rt2560_rx_desc *desc; struct rt2560_rx_data *data; bus_addr_t physaddr; @@ -1146,13 +1112,13 @@ rt2560_decryption_intr(struct rt2560_softc *sc) break; if (data->drop) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } if ((le32toh(desc->flags) & RT2560_RX_CIPHER_MASK) != 0 && (le32toh(desc->flags) & RT2560_RX_ICV_ERROR)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1165,7 +1131,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1188,7 +1154,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1201,7 +1167,6 @@ rt2560_decryption_intr(struct rt2560_softc *sc) desc->physaddr = htole32(physaddr); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; @@ -1321,8 +1286,7 @@ rt2560_beacon_update(struct ieee80211vap *vap, int item) static void rt2560_beacon_expire(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct rt2560_vap *rvp = RT2560_VAP(vap); struct rt2560_tx_data *data; @@ -1363,7 +1327,6 @@ void rt2560_intr(void *arg) { struct rt2560_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t r; RAL_LOCK(sc); @@ -1372,7 +1335,7 @@ rt2560_intr(void *arg) RAL_WRITE(sc, RT2560_CSR8, 0xffffffff); /* don't re-enable interrupts if we're shutting down */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RT2560_F_RUNNING)) { RAL_UNLOCK(sc); return; } @@ -1440,8 +1403,7 @@ static void rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t plcp_length; int remainder; @@ -1916,55 +1878,57 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, return 0; } -static void -rt2560_start_locked(struct ifnet *ifp) +static int +rt2560_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct rt2560_softc *sc = ifp->if_softc; - struct mbuf *m; - struct ieee80211_node *ni; + struct rt2560_softc *sc = ic->ic_softc; + int error; - RAL_LOCK_ASSERT(sc); - - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - sc->sc_flags |= RT2560_F_DATA_OACTIVE; - break; - } - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - if (rt2560_tx_data(sc, m, ni) != 0) { - ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - break; - } - - sc->sc_tx_timer = 5; + RAL_LOCK(sc); + if ((sc->sc_flags & RT2560_F_RUNNING) == 0) { + RAL_UNLOCK(sc); + return (ENXIO); } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RAL_UNLOCK(sc); + return (error); + } + rt2560_start(sc); + RAL_UNLOCK(sc); + + return (0); } static void -rt2560_start(struct ifnet *ifp) +rt2560_start(struct rt2560_softc *sc) { - struct rt2560_softc *sc = ifp->if_softc; + struct ieee80211_node *ni; + struct mbuf *m; - RAL_LOCK(sc); - rt2560_start_locked(ifp); - RAL_UNLOCK(sc); + RAL_LOCK_ASSERT(sc); + + while (sc->txq.queued < RT2560_TX_RING_COUNT - 1 && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + if (rt2560_tx_data(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); + ieee80211_free_node(ni); + break; + } + sc->sc_tx_timer = 5; + } } static void rt2560_watchdog(void *arg) { struct rt2560_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + KASSERT(sc->sc_flags & RT2560_F_RUNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; @@ -1973,51 +1937,33 @@ rt2560_watchdog(void *arg) rt2560_tx_intr(sc); if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); + device_printf(sc->sc_dev, "device timeout\n"); rt2560_init_locked(sc); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); /* NB: callout is reset in rt2560_init() */ return; } callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc); } -static int -rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rt2560_parent(struct ieee80211com *ic) { - struct rt2560_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct rt2560_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - RAL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rt2560_init_locked(sc); - startall = 1; - } else - rt2560_update_promisc(ic); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2560_stop_locked(sc); - } - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; + RAL_LOCK(sc); + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & RT2560_F_RUNNING) == 0) { + rt2560_init_locked(sc); + startall = 1; + } else + rt2560_update_promisc(ic); + } else if (sc->sc_flags & RT2560_F_RUNNING) + rt2560_stop_locked(sc); + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -2101,8 +2047,7 @@ rt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val) static void rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint8_t power, tmp; u_int i, chan; @@ -2201,8 +2146,7 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) static void rt2560_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; RAL_LOCK(sc); rt2560_set_chan(sc, ic->ic_curchan); @@ -2238,8 +2182,7 @@ rt2560_disable_rf_tune(struct rt2560_softc *sc) static void rt2560_enable_tsf_sync(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t logcwmin, preload; uint32_t tmp; @@ -2280,8 +2223,7 @@ rt2560_enable_tsf(struct rt2560_softc *sc) static void rt2560_update_plcp(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* no short preamble for 1Mbps */ RAL_WRITE(sc, RT2560_PLCP1MCSR, 0x00700400); @@ -2360,8 +2302,7 @@ rt2560_set_basicrates(struct rt2560_softc *sc, const struct ieee80211_rateset *rs) { #define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t mask = 0; uint8_t rate; int i; @@ -2406,7 +2347,7 @@ rt2560_set_bssid(struct rt2560_softc *sc, const uint8_t *bssid) } static void -rt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr) +rt2560_set_macaddr(struct rt2560_softc *sc, const uint8_t *addr) { uint32_t tmp; @@ -2444,13 +2385,13 @@ rt2560_update_promisc(struct ieee80211com *ic) tmp = RAL_READ(sc, RT2560_RXCSR0); tmp &= ~RT2560_DROP_NOT_TO_ME; - if (!(ic->ic_ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2560_DROP_NOT_TO_ME; RAL_WRITE(sc, RT2560_RXCSR0, tmp); DPRINTF(sc, "%s promiscuous mode\n", - (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving"); + (ic->ic_promisc > 0) ? "entering" : "leaving"); } static const char * @@ -2516,19 +2457,17 @@ rt2560_read_config(struct rt2560_softc *sc) static void rt2560_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; /* abort TSF synchronization */ RAL_WRITE(sc, RT2560_CSR14, 0); - rt2560_set_bssid(sc, ifp->if_broadcastaddr); + rt2560_set_bssid(sc, ieee80211broadcastaddr); } static void rt2560_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; struct ieee80211vap *vap = ic->ic_scan->ss_vap; rt2560_enable_tsf_sync(sc); @@ -2622,8 +2561,8 @@ static void rt2560_init_locked(struct rt2560_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; int i; @@ -2654,7 +2593,7 @@ rt2560_init_locked(struct rt2560_softc *sc) for (i = 0; i < N(rt2560_def_mac); i++) RAL_WRITE(sc, rt2560_def_mac[i].reg, rt2560_def_mac[i].val); - rt2560_set_macaddr(sc, IF_LLADDR(ifp)); + rt2560_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* set basic rate set (will be updated later) */ RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x153); @@ -2684,7 +2623,7 @@ rt2560_init_locked(struct rt2560_softc *sc) if (ic->ic_opmode != IEEE80211_M_HOSTAP && ic->ic_opmode != IEEE80211_M_MBSS) tmp |= RT2560_DROP_TODS; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2560_DROP_NOT_TO_ME; } RAL_WRITE(sc, RT2560_RXCSR0, tmp); @@ -2699,8 +2638,7 @@ rt2560_init_locked(struct rt2560_softc *sc) /* enable interrupts */ RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= RT2560_F_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc); #undef N @@ -2710,21 +2648,19 @@ static void rt2560_init(void *priv) { struct rt2560_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; RAL_LOCK(sc); rt2560_init_locked(sc); RAL_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RT2560_F_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } static void rt2560_stop_locked(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; volatile int *flags = &sc->sc_flags; RAL_LOCK_ASSERT(sc); @@ -2735,8 +2671,8 @@ rt2560_stop_locked(struct rt2560_softc *sc) callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + if (sc->sc_flags & RT2560_F_RUNNING) { + sc->sc_flags &= ~RT2560_F_RUNNING; /* abort Tx */ RAL_WRITE(sc, RT2560_TXCSR0, RT2560_ABORT_TX); @@ -2758,7 +2694,6 @@ rt2560_stop_locked(struct rt2560_softc *sc) rt2560_reset_tx_ring(sc, &sc->bcnq); rt2560_reset_rx_ring(sc, &sc->rxq); } - sc->sc_flags &= ~(RT2560_F_PRIO_OACTIVE | RT2560_F_DATA_OACTIVE); } void @@ -2776,29 +2711,24 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RT2560_F_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENETDOWN; } if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - sc->sc_flags |= RT2560_F_PRIO_OACTIVE; RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENOBUFS; /* XXX */ } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - if (params == NULL) { /* * Legacy path; interpret frame contents to decide @@ -2820,7 +2750,6 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); RAL_UNLOCK(sc); return EIO; /* XXX */ diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h index b6a8d68e9236..3a5fef981080 100644 --- a/sys/dev/ral/rt2560var.h +++ b/sys/dev/ral/rt2560var.h @@ -105,13 +105,13 @@ struct rt2560_vap { #define RT2560_VAP(vap) ((struct rt2560_vap *)(vap)) struct rt2560_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mtx sc_mtx; + struct mbufq sc_snd; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; - struct mtx sc_mtx; - struct callout watchdog_ch; int sc_tx_timer; @@ -152,8 +152,7 @@ struct rt2560_softc { struct rt2560_tx_radiotap_header sc_txtap; int sc_txtap_len; #define RT2560_F_INPUT_RUNNING 0x1 -#define RT2560_F_PRIO_OACTIVE 0x2 -#define RT2560_F_DATA_OACTIVE 0x4 +#define RT2560_F_RUNNING 0x2 int sc_flags; }; diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c index 15a2364a2c74..c77d4f88df76 100644 --- a/sys/dev/ral/rt2661.c +++ b/sys/dev/ral/rt2661.c @@ -121,12 +121,12 @@ static int rt2661_tx_data(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *, int); static int rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *); -static void rt2661_start_locked(struct ifnet *); -static void rt2661_start(struct ifnet *); +static int rt2661_transmit(struct ieee80211com *, struct mbuf *); +static void rt2661_start(struct rt2661_softc *); static int rt2661_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void rt2661_watchdog(void *); -static int rt2661_ioctl(struct ifnet *, u_long, caddr_t); +static void rt2661_parent(struct ieee80211com *); static void rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t); static uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t); @@ -197,27 +197,19 @@ int rt2661_attach(device_t dev, int id) { struct rt2661_softc *sc = device_get_softc(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint32_t val; int error, ac, ntries; uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_id = id; sc->sc_dev = dev; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - return ENOMEM; - } - ic = ifp->if_l2com; - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* wait for NIC to initialize */ for (ntries = 0; ntries < 1000; ntries++) { @@ -233,7 +225,7 @@ rt2661_attach(device_t dev, int id) } /* retrieve RF rev. no and various other things from EEPROM */ - rt2661_read_eeprom(sc, macaddr); + rt2661_read_eeprom(sc, ic->ic_macaddr); device_printf(dev, "MAC/BBP RT%X, RF %s\n", val, rt2661_get_rf(sc->rf_rev)); @@ -263,17 +255,6 @@ rt2661_attach(device_t dev, int id) goto fail3; } - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rt2661_init; - ifp->if_ioctl = rt2661_ioctl; - ifp->if_start = rt2661_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_opmode = IEEE80211_M_STA; @@ -305,7 +286,7 @@ rt2661_attach(device_t dev, int id) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); #if 0 ic->ic_wme.wme_update = rt2661_wme_update; #endif @@ -315,7 +296,8 @@ rt2661_attach(device_t dev, int id) ic->ic_updateslot = rt2661_update_slot; ic->ic_update_promisc = rt2661_update_promisc; ic->ic_raw_xmit = rt2661_raw_xmit; - + ic->ic_transmit = rt2661_transmit; + ic->ic_parent = rt2661_parent; ic->ic_vap_create = rt2661_vap_create; ic->ic_vap_delete = rt2661_vap_delete; @@ -339,7 +321,6 @@ fail3: rt2661_free_tx_ring(sc, &sc->mgtq); fail2: while (--ac >= 0) rt2661_free_tx_ring(sc, &sc->txq[ac]); fail1: mtx_destroy(&sc->sc_mtx); - if_free(ifp); return error; } @@ -347,14 +328,14 @@ int rt2661_detach(void *xsc) { struct rt2661_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; RAL_LOCK(sc); rt2661_stop_locked(sc); RAL_UNLOCK(sc); ieee80211_ifdetach(ic); + mbufq_drain(&sc->sc_snd); rt2661_free_tx_ring(sc, &sc->txq[0]); rt2661_free_tx_ring(sc, &sc->txq[1]); @@ -363,8 +344,6 @@ rt2661_detach(void *xsc) rt2661_free_tx_ring(sc, &sc->mgtq); rt2661_free_rx_ring(sc, &sc->rxq); - if_free(ifp); - mtx_destroy(&sc->sc_mtx); return 0; @@ -376,7 +355,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; + struct rt2661_softc *sc = ic->ic_softc; struct rt2661_vap *rvp; struct ieee80211vap *vap; @@ -389,7 +368,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - if_printf(ifp, "only 1 vap supported\n"); + device_printf(sc->sc_dev, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -398,7 +377,8 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - if_printf(ifp, "wds only supported in ap mode\n"); + device_printf(sc->sc_dev, + "wds only supported in ap mode\n"); return NULL; } /* @@ -409,15 +389,12 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - if_printf(ifp, "unknown opmode %d\n", opmode); + device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); return NULL; } - rvp = (struct rt2661_vap *) malloc(sizeof(struct rt2661_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return NULL; + rvp = malloc(sizeof(struct rt2661_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -428,7 +405,8 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -464,9 +442,8 @@ void rt2661_resume(void *xsc) { struct rt2661_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) + if (sc->sc_ic.ic_nrunning > 0) rt2661_init(sc); } @@ -770,7 +747,7 @@ rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2661_vap *rvp = RT2661_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rt2661_softc *sc = ic->ic_ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; int error; if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { @@ -869,11 +846,10 @@ rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr) static void rt2661_tx_intr(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct rt2661_tx_ring *txq; struct rt2661_tx_data *data; uint32_t val; - int qid, retrycnt; + int error, qid, retrycnt; struct ieee80211vap *vap; for (;;) { @@ -911,7 +887,7 @@ rt2661_tx_intr(struct rt2661_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + error = 0; break; case RT2661_TX_RETRY_FAIL: @@ -923,14 +899,14 @@ rt2661_tx_intr(struct rt2661_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + error = 1; break; default: /* other failure */ device_printf(sc->sc_dev, "sending data frame failed 0x%08x\n", val); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + error = 1; } DPRINTFN(sc, 15, "tx done q=%d idx=%u\n", qid, txq->stat); @@ -939,17 +915,12 @@ rt2661_tx_intr(struct rt2661_softc *sc) if (++txq->stat >= txq->count) /* faster than % count */ txq->stat = 0; - if (m->m_flags & M_TXCB) - ieee80211_process_callback(ni, m, - RT2661_TX_RESULT(val) != RT2661_TX_SUCCESS); - m_freem(m); - ieee80211_free_node(ni); + ieee80211_tx_complete(ni, m, error); } sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2661_start_locked(ifp); + rt2661_start(sc); } static void @@ -987,8 +958,7 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq) static void rt2661_rx_intr(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct rt2661_rx_desc *desc; struct rt2661_rx_data *data; bus_addr_t physaddr; @@ -1017,12 +987,12 @@ rt2661_rx_intr(struct rt2661_softc *sc) */ DPRINTFN(sc, 5, "PHY or CRC error flags 0x%08x\n", le32toh(desc->flags)); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } if ((le32toh(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1035,7 +1005,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1058,7 +1028,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1071,7 +1041,6 @@ rt2661_rx_intr(struct rt2661_softc *sc) desc->physaddr = htole32(physaddr); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; @@ -1156,7 +1125,6 @@ void rt2661_intr(void *arg) { struct rt2661_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t r1, r2; RAL_LOCK(sc); @@ -1166,7 +1134,7 @@ rt2661_intr(void *arg) RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); /* don't re-enable interrupts if we're shutting down */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RAL_RUNNING)) { RAL_UNLOCK(sc); return; } @@ -1242,8 +1210,7 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate, const bus_dma_segment_t *segs, int nsegs, int ac) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t plcp_length; int i, remainder; @@ -1461,8 +1428,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, int ac) { struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct rt2661_tx_ring *txq = &sc->txq[ac]; struct rt2661_tx_desc *desc; struct rt2661_tx_data *data; @@ -1604,10 +1570,31 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, return 0; } -static void -rt2661_start_locked(struct ifnet *ifp) +static int +rt2661_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct rt2661_softc *sc = ic->ic_softc; + int error; + + RAL_LOCK(sc); + if ((sc->sc_flags & RAL_RUNNING) == 0) { + RAL_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RAL_UNLOCK(sc); + return (error); + } + rt2661_start(sc); + RAL_UNLOCK(sc); + + return (0); +} + +static void +rt2661_start(struct rt2661_softc *sc) { - struct rt2661_softc *sc = ifp->if_softc; struct mbuf *m; struct ieee80211_node *ni; int ac; @@ -1615,69 +1602,50 @@ rt2661_start_locked(struct ifnet *ifp) RAL_LOCK_ASSERT(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || sc->sc_invalid) + if (!(sc->sc_flags & RAL_RUNNING) || sc->sc_invalid) return; - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ac = M_WME_GETAC(m); if (sc->txq[ac].queued >= RT2661_TX_RING_COUNT - 1) { /* there is no place left in this ring */ - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + mbufq_prepend(&sc->sc_snd, m); break; } ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (rt2661_tx_data(sc, m, ni, ac) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); break; } - sc->sc_tx_timer = 5; } } -static void -rt2661_start(struct ifnet *ifp) -{ - struct rt2661_softc *sc = ifp->if_softc; - - RAL_LOCK(sc); - rt2661_start_locked(ifp); - RAL_UNLOCK(sc); -} - static int rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RAL_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENETDOWN; } if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENOBUFS; /* XXX */ } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - /* * Legacy path; interpret frame contents to decide * precisely how to send the frame. @@ -1691,7 +1659,6 @@ rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); RAL_UNLOCK(sc); return EIO; /* XXX */ @@ -1701,61 +1668,42 @@ static void rt2661_watchdog(void *arg) { struct rt2661_softc *sc = (struct rt2661_softc *)arg; - struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + KASSERT(sc->sc_flags & RAL_RUNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); + device_printf(sc->sc_dev, "device timeout\n"); rt2661_init_locked(sc); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); /* NB: callout is reset in rt2661_init() */ return; } callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); } -static int -rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rt2661_parent(struct ieee80211com *ic) { - struct rt2661_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct rt2661_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - RAL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rt2661_init_locked(sc); - startall = 1; - } else - rt2661_update_promisc(ic); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2661_stop_locked(sc); - } - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; + RAL_LOCK(sc); + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & RAL_RUNNING) == 0) { + rt2661_init_locked(sc); + startall = 1; + } else + rt2661_update_promisc(ic); + } else if (sc->sc_flags & RAL_RUNNING) + rt2661_stop_locked(sc); + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -1879,8 +1827,7 @@ rt2661_select_antenna(struct rt2661_softc *sc) static void rt2661_enable_mrr(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR4); @@ -1896,8 +1843,7 @@ rt2661_enable_mrr(struct rt2661_softc *sc) static void rt2661_set_txpreamble(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR4); @@ -1914,8 +1860,7 @@ rt2661_set_basicrates(struct rt2661_softc *sc, const struct ieee80211_rateset *rs) { #define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t mask = 0; uint8_t rate; int i; @@ -1984,8 +1929,7 @@ rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c) static void rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct rfprog *rfprog; uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT; int8_t power; @@ -2088,13 +2032,13 @@ rt2661_update_promisc(struct ieee80211com *ic) tmp = RAL_READ(sc, RT2661_TXRX_CSR0); tmp &= ~RT2661_DROP_NOT_TO_ME; - if (!(ic->ic_ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2661_DROP_NOT_TO_ME; RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp); DPRINTF(sc, "%s promiscuous mode\n", - (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving"); + (ic->ic_promisc > 0) ? "entering" : "leaving"); } /* @@ -2103,7 +2047,7 @@ rt2661_update_promisc(struct ieee80211com *ic) static int rt2661_wme_update(struct ieee80211com *ic) { - struct rt2661_softc *sc = ic->ic_ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; const struct wmeParams *wmep; wmep = ic->ic_wme.wme_chanParams.cap_wmeParams; @@ -2301,8 +2245,8 @@ static void rt2661_init_locked(struct rt2661_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp, sta[3]; int i, error, ntries; @@ -2311,7 +2255,7 @@ rt2661_init_locked(struct rt2661_softc *sc) if ((sc->sc_flags & RAL_FW_LOADED) == 0) { error = rt2661_load_microcode(sc); if (error != 0) { - if_printf(ifp, + device_printf(sc->sc_dev, "%s: could not load 8051 microcode, error %d\n", __func__, error); return; @@ -2364,7 +2308,7 @@ rt2661_init_locked(struct rt2661_softc *sc) for (i = 0; i < N(rt2661_def_mac); i++) RAL_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val); - rt2661_set_macaddr(sc, IF_LLADDR(ifp)); + rt2661_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* set host ready */ RAL_WRITE(sc, RT2661_MAC_CSR1, 3); @@ -2403,7 +2347,7 @@ rt2661_init_locked(struct rt2661_softc *sc) if (ic->ic_opmode != IEEE80211_M_HOSTAP && ic->ic_opmode != IEEE80211_M_MBSS) tmp |= RT2661_DROP_TODS; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2661_DROP_NOT_TO_ME; } @@ -2425,8 +2369,7 @@ rt2661_init_locked(struct rt2661_softc *sc) /* kick Rx */ RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= RAL_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); #undef N @@ -2436,23 +2379,21 @@ static void rt2661_init(void *priv) { struct rt2661_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; RAL_LOCK(sc); rt2661_init_locked(sc); RAL_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RAL_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } void rt2661_stop_locked(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - uint32_t tmp; volatile int *flags = &sc->sc_flags; + uint32_t tmp; while (*flags & RAL_INPUT_RUNNING) msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10); @@ -2460,8 +2401,8 @@ rt2661_stop_locked(struct rt2661_softc *sc) callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + if (sc->sc_flags & RAL_RUNNING) { + sc->sc_flags &= ~RAL_RUNNING; /* abort Tx (for all 5 Tx rings) */ RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16); @@ -2505,7 +2446,6 @@ rt2661_stop(void *priv) static int rt2661_load_microcode(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; const struct firmware *fp; const char *imagename; int ntries, error; @@ -2517,7 +2457,7 @@ rt2661_load_microcode(struct rt2661_softc *sc) case 0x0302: imagename = "rt2561fw"; break; case 0x0401: imagename = "rt2661fw"; break; default: - if_printf(ifp, "%s: unexpected pci device id 0x%x, " + device_printf(sc->sc_dev, "%s: unexpected pci device id 0x%x, " "don't know how to retrieve firmware\n", __func__, sc->sc_id); return EINVAL; @@ -2526,7 +2466,8 @@ rt2661_load_microcode(struct rt2661_softc *sc) fp = firmware_get(imagename); RAL_LOCK(sc); if (fp == NULL) { - if_printf(ifp, "%s: unable to retrieve firmware image %s\n", + device_printf(sc->sc_dev, + "%s: unable to retrieve firmware image %s\n", __func__, imagename); return EINVAL; } @@ -2557,8 +2498,8 @@ rt2661_load_microcode(struct rt2661_softc *sc) DELAY(100); } if (ntries == 500) { - if_printf(ifp, "%s: timeout waiting for MCU to initialize\n", - __func__); + device_printf(sc->sc_dev, + "%s: timeout waiting for MCU to initialize\n", __func__); error = EIO; } else error = 0; @@ -2726,8 +2667,7 @@ rt2661_prepare_beacon(struct rt2661_softc *sc, struct ieee80211vap *vap) static void rt2661_enable_tsf_sync(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; @@ -2811,21 +2751,19 @@ rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw) static void rt2661_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; uint32_t tmp; /* abort TSF synchronization */ tmp = RAL_READ(sc, RT2661_TXRX_CSR9); RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0xffffff); - rt2661_set_bssid(sc, ifp->if_broadcastaddr); + rt2661_set_bssid(sc, ieee80211broadcastaddr); } static void rt2661_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); rt2661_enable_tsf_sync(sc); @@ -2836,8 +2774,7 @@ rt2661_scan_end(struct ieee80211com *ic) static void rt2661_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; RAL_LOCK(sc); rt2661_set_chan(sc, ic->ic_curchan); diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h index 9927d138fa71..7ea16f623d57 100644 --- a/sys/dev/ral/rt2661var.h +++ b/sys/dev/ral/rt2661var.h @@ -97,13 +97,13 @@ struct rt2661_vap { #define RT2661_VAP(vap) ((struct rt2661_vap *)(vap)) struct rt2661_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mtx sc_mtx; + struct mbufq sc_snd; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; - struct mtx sc_mtx; - struct callout watchdog_ch; int sc_tx_timer; @@ -117,6 +117,7 @@ struct rt2661_softc { int sc_flags; #define RAL_FW_LOADED 0x1 #define RAL_INPUT_RUNNING 0x2 +#define RAL_RUNNING 0x4 int sc_id; struct ieee80211_channel *sc_curchan; diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c index 782fa1f9780b..b3c737d67c66 100644 --- a/sys/dev/ral/rt2860.c +++ b/sys/dev/ral/rt2860.c @@ -122,10 +122,10 @@ static int rt2860_raw_xmit(struct ieee80211_node *, struct mbuf *, static int rt2860_tx_raw(struct rt2860_softc *, struct mbuf *, struct ieee80211_node *, const struct ieee80211_bpf_params *params); -static void rt2860_start(struct ifnet *); -static void rt2860_start_locked(struct ifnet *); +static int rt2860_transmit(struct ieee80211com *, struct mbuf *); +static void rt2860_start(struct rt2860_softc *); static void rt2860_watchdog(void *); -static int rt2860_ioctl(struct ifnet *, u_long, caddr_t); +static void rt2860_parent(struct ieee80211com *); static void rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t); static uint8_t rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t); static void rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t); @@ -156,7 +156,7 @@ static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *); static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *); static void rt2860_update_promisc(struct ieee80211com *); static void rt2860_updateslot(struct ieee80211com *); -static void rt2860_updateprot(struct ifnet *); +static void rt2860_updateprot(struct rt2860_softc *); static int rt2860_updateedca(struct ieee80211com *); #ifdef HW_CRYPTO static int rt2860_set_key(struct ieee80211com *, struct ieee80211_node *, @@ -230,27 +230,19 @@ int rt2860_attach(device_t dev, int id) { struct rt2860_softc *sc = device_get_softc(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; int error, ntries, qid; uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; sc->sc_debug = 0; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - return ENOMEM; - } - ic = ifp->if_l2com; - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* wait for NIC to initialize */ for (ntries = 0; ntries < 100; ntries++) { @@ -273,11 +265,11 @@ rt2860_attach(device_t dev, int id) sc->sc_flags |= RT2860_ADVANCED_PS; /* retrieve RF rev. no and various other things from EEPROM */ - rt2860_read_eeprom(sc, macaddr); + rt2860_read_eeprom(sc, ic->ic_macaddr); device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), " "RF %s (MIMO %dT%dR), address %6D\n", sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev), - sc->ntxchains, sc->nrxchains, macaddr, ":"); + sc->ntxchains, sc->nrxchains, ic->ic_macaddr, ":"); /* * Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings. @@ -304,17 +296,6 @@ rt2860_attach(device_t dev, int id) sc->mgtqid = (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) ? WME_AC_VO : 5; - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rt2860_init; - ifp->if_ioctl = rt2860_ioctl; - ifp->if_start = rt2860_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_opmode = IEEE80211_M_STA; @@ -345,7 +326,7 @@ rt2860_attach(device_t dev, int id) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_wme.wme_update = rt2860_updateedca; ic->ic_scan_start = rt2860_scan_start; @@ -357,7 +338,8 @@ rt2860_attach(device_t dev, int id) sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = rt2860_node_free; ic->ic_newassoc = rt2860_newassoc; - + ic->ic_transmit = rt2860_transmit; + ic->ic_parent = rt2860_parent; ic->ic_vap_create = rt2860_vap_create; ic->ic_vap_delete = rt2860_vap_delete; @@ -381,7 +363,6 @@ fail3: rt2860_free_rx_ring(sc, &sc->rxq); fail2: while (--qid >= 0) rt2860_free_tx_ring(sc, &sc->txq[qid]); fail1: mtx_destroy(&sc->sc_mtx); - if_free(ifp); return error; } @@ -389,8 +370,7 @@ int rt2860_detach(void *xsc) { struct rt2860_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int qid; RAL_LOCK(sc); @@ -398,14 +378,12 @@ rt2860_detach(void *xsc) RAL_UNLOCK(sc); ieee80211_ifdetach(ic); - + mbufq_drain(&sc->sc_snd); for (qid = 0; qid < 6; qid++) rt2860_free_tx_ring(sc, &sc->txq[qid]); rt2860_free_rx_ring(sc, &sc->rxq); rt2860_free_tx_pool(sc); - if_free(ifp); - mtx_destroy(&sc->sc_mtx); return 0; @@ -431,9 +409,8 @@ void rt2860_resume(void *xsc) { struct rt2860_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) + if (sc->sc_ic.ic_nrunning > 0) rt2860_init(sc); } @@ -443,7 +420,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ic->ic_softc; struct rt2860_vap *rvp; struct ieee80211vap *vap; @@ -456,7 +433,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - if_printf(ifp, "only 1 vap supported\n"); + device_printf(sc->sc_dev, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -465,7 +442,8 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - if_printf(ifp, "wds only supported in ap mode\n"); + device_printf(sc->sc_dev, + "wds only supported in ap mode\n"); return NULL; } /* @@ -476,14 +454,12 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - if_printf(ifp, "unknown opmode %d\n", opmode); + device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); return NULL; } - rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return NULL; + rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -497,7 +473,8 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -829,7 +806,7 @@ rt2860_free_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring) static void rt2860_updatestats(struct rt2860_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* * In IBSS or HostAP modes (when the hardware sends beacons), the @@ -856,7 +833,7 @@ static void rt2860_newassoc(struct ieee80211_node *ni, int isnew) { struct ieee80211com *ic = ni->ni_ic; - struct rt2860_softc *sc = ic->ic_ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint8_t wcid; wcid = IEEE80211_AID(ni->ni_associd); @@ -875,7 +852,7 @@ static void rt2860_node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct rt2860_softc *sc = ic->ic_ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint8_t wcid; if (ni->ni_associd != 0) { @@ -923,7 +900,7 @@ rt2860_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2860_vap *rvp = RT2860_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rt2860_softc *sc = ic->ic_ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint32_t tmp; int error; @@ -1101,7 +1078,6 @@ rt2860_intr_coherent(struct rt2860_softc *sc) static void rt2860_drain_stats_fifo(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct ieee80211_node *ni; uint32_t stat; int retrycnt; @@ -1137,7 +1113,8 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc) } else { ieee80211_ratectl_tx_complete(ni->ni_vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); } } } @@ -1145,7 +1122,6 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc) static void rt2860_tx_intr(struct rt2860_softc *sc, int qid) { - struct ifnet *ifp = sc->sc_ifp; struct rt2860_tx_ring *ring = &sc->txq[qid]; uint32_t hw; @@ -1163,15 +1139,11 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid) ieee80211_process_callback(data->ni, data->m, 0); } - m_freem(data->m); - ieee80211_free_node(data->ni); - data->m = NULL; + ieee80211_tx_complete(data->ni, data->m, 0); data->ni = NULL; - + data->m = NULL; SLIST_INSERT_HEAD(&sc->data_pool, data, next); ring->data[ring->next] = NULL; - - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); } ring->queued--; ring->next = (ring->next + 1) % RT2860_TX_RING_COUNT; @@ -1180,8 +1152,7 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid) sc->sc_tx_timer = 0; if (ring->queued < RT2860_TX_RING_COUNT) sc->qfullmsk &= ~(1 << qid); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2860_start_locked(ifp); + rt2860_start(sc); } /* @@ -1206,8 +1177,7 @@ static void rt2860_rx_intr(struct rt2860_softc *sc) { struct rt2860_rx_radiotap_header *tap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m, *m1; @@ -1234,7 +1204,7 @@ rt2860_rx_intr(struct rt2860_softc *sc) if (__predict_false(rxd->flags & htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1243,14 +1213,14 @@ rt2860_rx_intr(struct rt2860_softc *sc) /* report MIC failures to net80211 for TKIP */ ic->ic_stats.is_rx_locmicfail++; ieee80211_michael_mic_failure(ic, 0/* XXX */); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } #endif m1 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m1 == NULL)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1274,7 +1244,7 @@ rt2860_rx_intr(struct rt2860_softc *sc) } /* physical address may have changed */ rxd->sdp0 = htole32(physaddr); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1289,7 +1259,6 @@ rt2860_rx_intr(struct rt2860_softc *sc) rxwi = mtod(m, struct rt2860_rxwi *); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_data = (caddr_t)(rxwi + 1); m->m_pkthdr.len = m->m_len = le16toh(rxwi->len) & 0xfff; @@ -1399,7 +1368,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc) #endif /* check if protection mode has changed */ if ((sc->sc_ic_flags ^ ic->ic_flags) & IEEE80211_F_USEPROT) { - rt2860_updateprot(ic); + rt2860_updateprot(sc); sc->sc_ic_flags = ic->ic_flags; } #endif @@ -1408,7 +1377,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc) static void rt2860_gp_intr(struct rt2860_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTFN(2, ("GP timeout state=%d\n", vap->iv_state)); @@ -1480,8 +1449,7 @@ rt2860_intr(void *arg) static int rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct rt2860_tx_ring *ring; struct rt2860_tx_data *data; @@ -1725,14 +1693,13 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; int error; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RT2860_RUNNNING)) { RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); @@ -1754,7 +1721,6 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, if (error != 0) { /* NB: m is reclaimed on tx failure */ ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } sc->sc_tx_timer = 5; RAL_UNLOCK(sc); @@ -1765,8 +1731,7 @@ static int rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct rt2860_tx_ring *ring; struct rt2860_tx_data *data; @@ -1973,41 +1938,46 @@ rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m, return 0; } -static void -rt2860_start(struct ifnet *ifp) +static int +rt2860_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; + int error; RAL_LOCK(sc); - rt2860_start_locked(ifp); + if ((sc->sc_flags & RT2860_RUNNNING) == 0) { + RAL_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RAL_UNLOCK(sc); + return (error); + } + rt2860_start(sc); RAL_UNLOCK(sc); + + return (0); } static void -rt2860_start_locked(struct ifnet *ifp) +rt2860_start(struct rt2860_softc *sc) { - struct rt2860_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; RAL_LOCK_ASSERT(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - (ifp->if_drv_flags & IFF_DRV_OACTIVE)) + if ((sc->sc_flags & RT2860_RUNNNING) == 0) return; - for (;;) { - if (SLIST_EMPTY(&sc->data_pool) || sc->qfullmsk != 0) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while (!SLIST_EMPTY(&sc->data_pool) && sc->qfullmsk == 0 && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; if (rt2860_tx(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); continue; } sc->sc_tx_timer = 5; @@ -2018,61 +1988,42 @@ static void rt2860_watchdog(void *arg) { struct rt2860_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + KASSERT(sc->sc_flags & RT2860_RUNNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); + device_printf(sc->sc_dev, "device timeout\n"); rt2860_stop_locked(sc); rt2860_init_locked(sc); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); return; } callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc); } -static int -rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rt2860_parent(struct ieee80211com *ic) { - struct rt2860_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0, startall = 0; + struct rt2860_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - RAL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - rt2860_init_locked(sc); - startall = 1; - } else - rt2860_update_promisc(ic); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2860_stop_locked(sc); - } - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCSIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; + RAL_LOCK(sc); + if (ic->ic_nrunning> 0) { + if (!(sc->sc_flags & RT2860_RUNNNING)) { + rt2860_init_locked(sc); + startall = 1; + } else + rt2860_update_promisc(ic); + } else if (sc->sc_flags & RT2860_RUNNNING) + rt2860_stop_locked(sc); + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } /* @@ -2295,8 +2246,7 @@ rt2860_enable_mrr(struct rt2860_softc *sc) static void rt2860_set_txpreamble(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = RAL_READ(sc, RT2860_AUTO_RSP_CFG); @@ -2311,8 +2261,7 @@ rt2860_set_basicrates(struct rt2860_softc *sc, const struct ieee80211_rateset *rs) { #define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t mask = 0; uint8_t rate; int i; @@ -2333,8 +2282,7 @@ rt2860_set_basicrates(struct rt2860_softc *sc, static void rt2860_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG); @@ -2347,8 +2295,7 @@ rt2860_scan_start(struct ieee80211com *ic) static void rt2860_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); if (vap->iv_state == IEEE80211_S_RUN) { @@ -2360,8 +2307,7 @@ rt2860_scan_end(struct ieee80211com *ic) static void rt2860_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; RAL_LOCK(sc); rt2860_switch_chan(sc, ic->ic_curchan); @@ -3113,10 +3059,9 @@ rt2860_updateslot(struct ieee80211com *ic) } static void -rt2860_updateprot(struct ifnet *ifp) +rt2860_updateprot(struct rt2860_softc *sc) { - struct rt2860_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL; @@ -3145,7 +3090,7 @@ rt2860_update_promisc(struct ieee80211com *ic) tmp = RAL_READ(sc, RT2860_RX_FILTR_CFG); tmp &= ~RT2860_DROP_NOT_MYBSS; - if (!(ic->ic_ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2860_DROP_NOT_MYBSS; RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp); } @@ -3153,7 +3098,7 @@ rt2860_update_promisc(struct ieee80211com *ic) static int rt2860_updateedca(struct ieee80211com *ic) { - struct rt2860_softc *sc = ic->ic_ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; const struct wmeParams *wmep; int aci; @@ -3325,8 +3270,7 @@ rt2860_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, static int8_t rt2860_rssi2dbm(struct rt2860_softc *sc, uint8_t rssi, uint8_t rxchain) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_channel *c = ic->ic_curchan; int delta; @@ -3801,8 +3745,7 @@ rt5390_bbp_init(struct rt2860_softc *sc) static int rt2860_txrx_enable(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; int ntries; @@ -3848,22 +3791,21 @@ static void rt2860_init(void *arg) { struct rt2860_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; RAL_LOCK(sc); rt2860_init_locked(sc); RAL_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RT2860_RUNNNING) ieee80211_start_all(ic); } static void rt2860_init_locked(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; uint8_t bbp1, bbp3; int i, qid, ridx, ntries, error; @@ -3899,7 +3841,7 @@ rt2860_init_locked(struct rt2860_softc *sc) return; } - rt2860_set_macaddr(sc, IF_LLADDR(ifp)); + rt2860_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* init Tx power for all Tx rates (from EEPROM) */ for (ridx = 0; ridx < 5; ridx++) { @@ -4096,7 +4038,7 @@ rt2860_init_locked(struct rt2860_softc *sc) RAL_WRITE(sc, RT2860_TX_RTS_CFG, tmp); /* setup initial protection mode */ - rt2860_updateprot(ifp); + rt2860_updateprot(sc); /* turn radio LED on */ rt2860_set_leds(sc, RT2860_LED_RADIO); @@ -4115,8 +4057,7 @@ rt2860_init_locked(struct rt2860_softc *sc) if (sc->sc_flags & RT2860_ADVANCED_PS) rt2860_mcu_cmd(sc, RT2860_MCU_CMD_PSLEVEL, sc->pslevel, 0); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= RT2860_RUNNNING; callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc); } @@ -4134,16 +4075,15 @@ rt2860_stop(void *arg) static void rt2860_stop_locked(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; int qid; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RT2860_RUNNNING) rt2860_set_leds(sc, 0); /* turn all LEDs off */ callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~RT2860_RUNNNING; /* disable interrupts */ RAL_WRITE(sc, RT2860_INT_MASK, 0); @@ -4294,8 +4234,7 @@ rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux) static void rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; u_int chan, group; chan = ieee80211_chan2ieee(ic, c); @@ -4364,8 +4303,7 @@ rt2860_setup_beacon(struct rt2860_softc *sc, struct ieee80211vap *vap) static void rt2860_enable_tsf_sync(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; diff --git a/sys/dev/ral/rt2860var.h b/sys/dev/ral/rt2860var.h index 28a3d59b8263..3779e5beb1d1 100644 --- a/sys/dev/ral/rt2860var.h +++ b/sys/dev/ral/rt2860var.h @@ -115,13 +115,13 @@ struct rt2860_vap { #define RT2860_VAP(vap) ((struct rt2860_vap *)(vap)) struct rt2860_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; + struct mtx sc_mtx; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; - struct mtx sc_mtx; - struct callout watchdog_ch; int sc_invalid; @@ -139,6 +139,7 @@ struct rt2860_softc { #define RT2860_ENABLED (1 << 0) #define RT2860_ADVANCED_PS (1 << 1) #define RT2860_PCIE (1 << 2) +#define RT2860_RUNNNING (1 << 3) struct ieee80211_node *wcid2ni[RT2860_WCID_MAX]; diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c index 89b8c0007723..463a9bdc9a08 100644 --- a/sys/dev/usb/wlan/if_rsu.c +++ b/sys/dev/usb/wlan/if_rsu.c @@ -187,15 +187,13 @@ static struct mbuf * static void rsu_txeof(struct usb_xfer *, struct rsu_data *); static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void rsu_init(void *); -static void rsu_init_locked(struct rsu_softc *); +static void rsu_init(struct rsu_softc *); static int rsu_tx_start(struct rsu_softc *, struct ieee80211_node *, struct mbuf *, struct rsu_data *); -static void rsu_start(struct ifnet *); -static void rsu_start_locked(struct ifnet *); -static int rsu_ioctl(struct ifnet *, u_long, caddr_t); -static void rsu_stop(struct ifnet *, int); -static void rsu_stop_locked(struct ifnet *, int); +static int rsu_transmit(struct ieee80211com *, struct mbuf *); +static void rsu_start(struct rsu_softc *); +static void rsu_parent(struct ieee80211com *); +static void rsu_stop(struct rsu_softc *); static void rsu_ms_delay(struct rsu_softc *); static device_method_t rsu_methods[] = { @@ -285,8 +283,7 @@ rsu_attach(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); struct rsu_softc *sc = device_get_softc(self); - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; int error; uint8_t iface_index, bands; @@ -298,6 +295,7 @@ rsu_attach(device_t self) MTX_DEF); TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0, rsu_calib_task, sc); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* Allocate Tx/Rx buffers. */ error = rsu_alloc_rx_list(sc); @@ -333,28 +331,9 @@ rsu_attach(device_t self) device_printf(self, "could not read ROM\n"); goto fail_rom; } - IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->rom[0x12]); + IEEE80211_ADDR_COPY(ic->ic_macaddr, &sc->rom[0x12]); device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(self, "cannot allocate interface\n"); - goto fail_ifalloc; - } - ic = ifp->if_l2com; - ifp->if_softc = sc; - if_initname(ifp, "rsu", device_get_unit(self)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rsu_init; - ifp->if_ioctl = rsu_ioctl; - ifp->if_start = rsu_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - ifp->if_capabilities |= IFCAP_RXCSUM; - ifp->if_capenable |= IFCAP_RXCSUM; - ifp->if_hwassist = CSUM_TCP; - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(self); ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */ @@ -387,7 +366,7 @@ rsu_attach(device_t self) setbit(&bands, IEEE80211_MODE_11G); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_raw_xmit = rsu_raw_xmit; ic->ic_scan_start = rsu_scan_start; ic->ic_scan_end = rsu_scan_end; @@ -395,6 +374,8 @@ rsu_attach(device_t self) ic->ic_vap_create = rsu_vap_create; ic->ic_vap_delete = rsu_vap_delete; ic->ic_update_mcast = rsu_update_mcast; + ic->ic_parent = rsu_parent; + ic->ic_transmit = rsu_transmit; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), RSU_TX_RADIOTAP_PRESENT, @@ -406,7 +387,6 @@ rsu_attach(device_t self) return (0); -fail_ifalloc: fail_rom: usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); fail_usb: @@ -418,10 +398,11 @@ static int rsu_detach(device_t self) { struct rsu_softc *sc = device_get_softc(self); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; - rsu_stop(ifp, 1); + RSU_LOCK(sc); + rsu_stop(sc); + RSU_UNLOCK(sc); usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER); ieee80211_ifdetach(ic); @@ -431,7 +412,7 @@ rsu_detach(device_t self) rsu_free_tx_list(sc); rsu_free_rx_list(sc); - if_free(ifp); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -471,14 +452,11 @@ rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return (NULL); - uvp = (struct rsu_vap *) malloc(sizeof(struct rsu_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return (NULL); + uvp = malloc(sizeof(struct rsu_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &uvp->vap; if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags, bssid, mac) != 0) { + flags, bssid) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -490,7 +468,7 @@ rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); ic->ic_opmode = opmode; return (vap); @@ -508,9 +486,8 @@ rsu_vap_delete(struct ieee80211vap *vap) static void rsu_scan_start(struct ieee80211com *ic) { + struct rsu_softc *sc = ic->ic_softc; int error; - struct ifnet *ifp = ic->ic_ifp; - struct rsu_softc *sc = ifp->if_softc; /* Scanning is done by the firmware. */ RSU_LOCK(sc); @@ -676,11 +653,8 @@ rsu_getbuf(struct rsu_softc *sc) RSU_ASSERT_LOCKED(sc); bf = _rsu_getbuf(sc); - if (bf == NULL) { - struct ifnet *ifp = sc->sc_ifp; + if (bf == NULL) DPRINTF("stop queue\n"); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - } return (bf); } @@ -935,7 +909,7 @@ rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rsu_vap *uvp = RSU_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rsu_softc *sc = ic->ic_ifp->if_softc; + struct rsu_softc *sc = ic->ic_softc; struct ieee80211_node *ni; struct ieee80211_rateset *rs; enum ieee80211_state ostate; @@ -1033,29 +1007,27 @@ static int rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap) { struct r92s_fw_cmd_sitesurvey cmd; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; memset(&cmd, 0, sizeof(cmd)); - if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1) + if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->sc_scan_pass == 1) cmd.active = htole32(1); cmd.limit = htole32(48); - if (sc->scan_pass == 1 && vap->iv_des_nssid > 0) { + if (sc->sc_scan_pass == 1 && vap->iv_des_nssid > 0) { /* Do a directed scan for second pass. */ cmd.ssidlen = htole32(vap->iv_des_ssid[0].len); memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid, vap->iv_des_ssid[0].len); } - DPRINTF("sending site survey command, pass=%d\n", sc->scan_pass); + DPRINTF("sending site survey command, pass=%d\n", sc->sc_scan_pass); return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd))); } static int rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct ndis_wlan_bssid_ex *bss; struct ndis_802_11_fixed_ies *fixed; @@ -1133,8 +1105,7 @@ rsu_disconnect(struct rsu_softc *sc) static void rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_channel *c; struct ndis_wlan_bssid_ex *bss; @@ -1165,7 +1136,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) IEEE80211_FC0_SUBTYPE_BEACON; wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; USETW(wh->i_dur, 0); - IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr); + IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr); IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr); IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr); *(uint16_t *)wh->i_seq = 0; @@ -1173,7 +1144,6 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) /* Finalize mbuf. */ m->m_pkthdr.len = m->m_len = pktlen; - m->m_pkthdr.rcvif = ifp; /* Fix the channel. */ c = ieee80211_find_channel_byieee(ic, le32toh(bss->config.dsconfig), @@ -1191,8 +1161,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) static void rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni = vap->iv_bss; struct r92s_event_join_bss *rsp; @@ -1228,8 +1197,7 @@ rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len) static void rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTFN(4, "Rx event code=%d len=%d\n", code, len); @@ -1240,18 +1208,18 @@ rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len) break; case R92S_EVT_SURVEY_DONE: DPRINTF("site survey pass %d done, found %d BSS\n", - sc->scan_pass, le32toh(*(uint32_t *)buf)); + sc->sc_scan_pass, le32toh(*(uint32_t *)buf)); if (vap->iv_state != IEEE80211_S_SCAN) break; /* Ignore if not scanning. */ - if (sc->scan_pass == 0 && vap->iv_des_nssid != 0) { + if (sc->sc_scan_pass == 0 && vap->iv_des_nssid != 0) { /* Schedule a directed scan for hidden APs. */ - sc->scan_pass = 1; + sc->sc_scan_pass = 1; RSU_UNLOCK(sc); ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); RSU_LOCK(sc); break; } - sc->scan_pass = 0; + sc->sc_scan_pass = 0; break; case R92S_EVT_JOIN_BSS: if (vap->iv_state == IEEE80211_S_AUTH) @@ -1274,7 +1242,7 @@ XXX and disrupts the WLAN traffic. Disable for now. DPRINTF("WPS PBC pushed.\n"); break; case R92S_EVT_FWDBG: - if (ifp->if_flags & IFF_DEBUG) { + if (vap->iv_ifp->if_flags & IFF_DEBUG) { buf[60] = '\0'; printf("FWDBG: %s\n", (char *)buf); } @@ -1341,8 +1309,7 @@ rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt) static struct mbuf * rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct r92s_rx_stat *stat; uint32_t rxdw0, rxdw3; @@ -1355,11 +1322,11 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) rxdw3 = le32toh(stat->rxdw3); if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return NULL; } if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return NULL; } @@ -1377,11 +1344,9 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m == NULL)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return NULL; } - /* Finalize mbuf. */ - m->m_pkthdr.rcvif = ifp; /* Hardware does Rx TCP checksum offload. */ if (rxdw3 & R92S_RXDW3_TCPCHKVALID) { if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT)) @@ -1479,6 +1444,7 @@ static struct mbuf * rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) { struct rsu_softc *sc = data->sc; + struct ieee80211com *ic = &sc->sc_ic; struct r92s_rx_stat *stat; int len; @@ -1486,7 +1452,7 @@ rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) if (__predict_false(len < sizeof(*stat))) { DPRINTF("xfer too short %d\n", len); - if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } /* Determine if it is a firmware C2H event or an 802.11 frame. */ @@ -1503,8 +1469,7 @@ static void rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct rsu_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m = NULL, *next; @@ -1564,7 +1529,7 @@ rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } break; @@ -1572,35 +1537,16 @@ rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) } - static void rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data) { - struct rsu_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; - RSU_ASSERT_LOCKED(sc); - - /* - * Do any tx complete callback. Note this must be done before releasing - * the node reference. - */ if (data->m) { - m = data->m; - if (m->m_flags & M_TXCB) { - /* XXX status? */ - ieee80211_process_callback(data->ni, m, 0); - } - m_freem(m); + /* XXX status? */ + ieee80211_tx_complete(data->ni, data->m, 0); data->m = NULL; - } - if (data->ni) { - ieee80211_free_node(data->ni); data->ni = NULL; } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void @@ -1608,7 +1554,7 @@ rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error, uint8_t which) { struct rsu_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; struct rsu_data *data; RSU_ASSERT_LOCKED(sc); @@ -1643,7 +1589,7 @@ rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error, rsu_txeof(xfer, data); STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); } - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(ic->ic_oerrors, 1); if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); @@ -1669,8 +1615,7 @@ static int rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, struct rsu_data *data) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_frame *wh; struct ieee80211_key *k = NULL; @@ -1772,82 +1717,75 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, return (0); } -static void -rsu_start(struct ifnet *ifp) +static int +rsu_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct rsu_softc *sc = ifp->if_softc; - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; + struct rsu_softc *sc = ic->ic_softc; + int error; RSU_LOCK(sc); - rsu_start_locked(ifp); + if (!sc->sc_running) { + RSU_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RSU_UNLOCK(sc); + return (error); + } + rsu_start(sc); RSU_UNLOCK(sc); + + return (0); } static void -rsu_start_locked(struct ifnet *ifp) +rsu_start(struct rsu_softc *sc) { - struct rsu_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct rsu_data *bf; struct mbuf *m; RSU_ASSERT_LOCKED(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + bf = rsu_getbuf(sc); + if (bf == NULL) { + mbufq_prepend(&sc->sc_snd, m); break; + } + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; m->m_pkthdr.rcvif = NULL; - bf = rsu_getbuf(sc); - if (bf == NULL) { - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); - m_freem(m); - ieee80211_free_node(ni); - } else if (rsu_tx_start(sc, ni, m, bf) != 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if (rsu_tx_start(sc, ni, m, bf) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); ieee80211_free_node(ni); + break; } } } -static int -rsu_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rsu_parent(struct ieee80211com *ic) { - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct rsu_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rsu_init(ifp->if_softc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rsu_stop(ifp, 1); + RSU_LOCK(sc); + if (ic->ic_nrunning > 0) { + if (!sc->sc_running) { + rsu_init(sc); + startall = 1; } - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } + } else if (sc->sc_running) + rsu_stop(sc); + RSU_UNLOCK(sc); - return (error); + if (startall) + ieee80211_start_all(ic); } /* @@ -2296,12 +2234,11 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rsu_softc *sc = ifp->if_softc; + struct rsu_softc *sc = ic->ic_softc; struct rsu_data *bf; /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!sc->sc_running) { m_freem(m); ieee80211_free_node(ni); return (ENETDOWN); @@ -2314,10 +2251,8 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, RSU_UNLOCK(sc); return (ENOBUFS); } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if (rsu_tx_start(sc, ni, m, bf) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); RSU_UNLOCK(sc); return (EIO); @@ -2328,23 +2263,17 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, } static void -rsu_init(void *arg) +rsu_init(struct rsu_softc *sc) { - struct rsu_softc *sc = arg; - - RSU_LOCK(sc); - rsu_init_locked(arg); - RSU_UNLOCK(sc); -} - -static void -rsu_init_locked(struct rsu_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + uint8_t macaddr[IEEE80211_ADDR_LEN]; struct r92s_set_pwr_mode cmd; int error; int i; + RSU_ASSERT_LOCKED(sc); + /* Init host async commands ring. */ sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0; @@ -2384,14 +2313,14 @@ rsu_init_locked(struct rsu_softc *sc) rsu_read_1(sc, 0xfe5c) | 0x80); /* Set MAC address. */ - rsu_write_region_1(sc, R92S_MACID, IF_LLADDR(ifp), - IEEE80211_ADDR_LEN); + IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr); + rsu_write_region_1(sc, R92S_MACID, macaddr, IEEE80211_ADDR_LEN); /* It really takes 1.5 seconds for the firmware to boot: */ usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2); - DPRINTF("setting MAC address to %s\n", ether_sprintf(IF_LLADDR(ifp))); - error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp), + DPRINTF("setting MAC address to %s\n", ether_sprintf(macaddr)); + error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, macaddr, IEEE80211_ADDR_LEN); if (error != 0) { device_printf(sc->sc_dev, "could not set MAC address\n"); @@ -2427,12 +2356,11 @@ rsu_init_locked(struct rsu_softc *sc) /* Set default channel. */ ic->ic_bss->ni_chan = ic->ic_ibss_chan; #endif - sc->scan_pass = 0; + sc->sc_scan_pass = 0; usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]); /* We're ready to go. */ - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_running = 1; return; fail: /* Need to stop all failed transfers, if any */ @@ -2441,22 +2369,11 @@ rsu_init_locked(struct rsu_softc *sc) } static void -rsu_stop(struct ifnet *ifp, int disable) +rsu_stop(struct rsu_softc *sc) { - struct rsu_softc *sc = ifp->if_softc; - - RSU_LOCK(sc); - rsu_stop_locked(ifp, disable); - RSU_UNLOCK(sc); -} - -static void -rsu_stop_locked(struct ifnet *ifp, int disable __unused) -{ - struct rsu_softc *sc = ifp->if_softc; int i; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_running = 0; sc->sc_calibrating = 0; taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL); diff --git a/sys/dev/usb/wlan/if_rsureg.h b/sys/dev/usb/wlan/if_rsureg.h index db0751dfcd09..4e6cd884fab8 100644 --- a/sys/dev/usb/wlan/if_rsureg.h +++ b/sys/dev/usb/wlan/if_rsureg.h @@ -726,7 +726,8 @@ struct rsu_vap { #define RSU_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) struct rsu_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct usb_device *sc_udev; int (*sc_newstate)(struct ieee80211com *, @@ -736,17 +737,17 @@ struct rsu_softc { const uint8_t *qid2idx; struct mtx sc_mtx; + u_int sc_running:1, + sc_calibrating:1, + sc_scan_pass:1; u_int cut; - int scan_pass; struct rsu_host_cmd_ring cmdq; struct rsu_data sc_rx[RSU_RX_LIST_COUNT]; struct rsu_data sc_tx[RSU_TX_LIST_COUNT]; struct rsu_data *fwcmd_data; uint8_t cmd_seq; uint8_t rom[128]; - uint8_t sc_bssid[IEEE80211_ADDR_LEN]; struct usb_xfer *sc_xfer[RSU_N_TRANSFER]; - uint8_t sc_calibrating; STAILQ_HEAD(, rsu_data) sc_rx_active; STAILQ_HEAD(, rsu_data) sc_rx_inactive; diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index d5142ea8315e..6a558f66395f 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -175,8 +175,9 @@ static int rum_tx_raw(struct rum_softc *, struct mbuf *, const struct ieee80211_bpf_params *); static int rum_tx_data(struct rum_softc *, struct mbuf *, struct ieee80211_node *); -static void rum_start(struct ifnet *); -static int rum_ioctl(struct ifnet *, u_long, caddr_t); +static int rum_transmit(struct ieee80211com *, struct mbuf *); +static void rum_start(struct rum_softc *); +static void rum_parent(struct ieee80211com *); static void rum_eeprom_read(struct rum_softc *, uint16_t, void *, int); static uint32_t rum_read(struct rum_softc *, uint16_t); @@ -198,7 +199,7 @@ static void rum_set_chan(struct rum_softc *, struct ieee80211_channel *); static void rum_enable_tsf_sync(struct rum_softc *); static void rum_enable_tsf(struct rum_softc *); -static void rum_update_slot(struct ifnet *); +static void rum_update_slot(struct rum_softc *); static void rum_set_bssid(struct rum_softc *, const uint8_t *); static void rum_set_macaddr(struct rum_softc *, const uint8_t *); static void rum_update_mcast(struct ieee80211com *); @@ -207,8 +208,7 @@ static void rum_setpromisc(struct rum_softc *); static const char *rum_get_rf(int); static void rum_read_eeprom(struct rum_softc *); static int rum_bbp_init(struct rum_softc *); -static void rum_init_locked(struct rum_softc *); -static void rum_init(void *); +static void rum_init(struct rum_softc *); static void rum_stop(struct rum_softc *); static void rum_load_microcode(struct rum_softc *, const uint8_t *, size_t); @@ -425,8 +425,7 @@ rum_attach(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); struct rum_softc *sc = device_get_softc(self); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint8_t iface_index, bands; uint32_t tmp; int error, ntries; @@ -437,6 +436,7 @@ rum_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); + mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = RT2573_IFACE_INDEX; error = usbd_transfer_setup(uaa->device, &iface_index, @@ -470,24 +470,6 @@ rum_attach(device_t self) rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); RUM_UNLOCK(sc); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto detach; - } - ic = ifp->if_l2com; - - ifp->if_softc = sc; - if_initname(ifp, "rum", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rum_init; - ifp->if_ioctl = rum_ioctl; - ifp->if_start = rum_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(self); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -512,13 +494,14 @@ rum_attach(device_t self) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_update_promisc = rum_update_promisc; ic->ic_raw_xmit = rum_raw_xmit; ic->ic_scan_start = rum_scan_start; ic->ic_scan_end = rum_scan_end; ic->ic_set_channel = rum_set_channel; - + ic->ic_transmit = rum_transmit; + ic->ic_parent = rum_parent; ic->ic_vap_create = rum_vap_create; ic->ic_vap_delete = rum_vap_delete; ic->ic_update_mcast = rum_update_mcast; @@ -543,8 +526,6 @@ static int rum_detach(device_t self) { struct rum_softc *sc = device_get_softc(self); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic; /* Prevent further ioctls */ RUM_LOCK(sc); @@ -559,11 +540,9 @@ rum_detach(device_t self) rum_unsetup_tx_list(sc); RUM_UNLOCK(sc); - if (ifp) { - ic = ifp->if_l2com; - ieee80211_ifdetach(ic); - if_free(ifp); - } + if (sc->sc_ic.ic_softc == sc) + ieee80211_ifdetach(&sc->sc_ic); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); } @@ -595,21 +574,18 @@ rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct rum_softc *sc = ic->ic_ifp->if_softc; + struct rum_softc *sc = ic->ic_softc; struct rum_vap *rvp; struct ieee80211vap *vap; if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return NULL; + rvp = malloc(sizeof(struct rum_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &rvp->vap; /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { /* out of memory */ free(rvp, M_80211_VAP); return (NULL); @@ -624,7 +600,8 @@ rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); ic->ic_opmode = opmode; return vap; } @@ -648,13 +625,8 @@ rum_tx_free(struct rum_tx_data *data, int txerr) struct rum_softc *sc = data->sc; if (data->m != NULL) { - if (data->m->m_flags & M_TXCB) - ieee80211_process_callback(data->ni, data->m, - txerr ? ETIMEDOUT : 0); - m_freem(data->m); + ieee80211_tx_complete(data->ni, data->m, txerr); data->m = NULL; - - ieee80211_free_node(data->ni); data->ni = NULL; } STAILQ_INSERT_TAIL(&sc->tx_free, data, next); @@ -711,7 +683,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rum_vap *rvp = RUM_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rum_softc *sc = ic->ic_ifp->if_softc; + struct rum_softc *sc = ic->ic_softc; const struct ieee80211_txparam *tp; enum ieee80211_state ostate; struct ieee80211_node *ni; @@ -745,12 +717,12 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) ieee80211_free_node(ni); return (-1); } - rum_update_slot(ic->ic_ifp); + rum_update_slot(sc); rum_enable_mrr(sc); rum_set_txpreamble(sc); rum_set_basicrates(sc); - IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); - rum_set_bssid(sc, sc->sc_bssid); + IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid); + rum_set_bssid(sc, ic->ic_macaddr); } if (vap->iv_opmode == IEEE80211_M_HOSTAP || @@ -780,7 +752,6 @@ static void rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) { struct rum_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap; struct rum_tx_data *data; struct mbuf *m; @@ -799,9 +770,6 @@ rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) rum_tx_free(data, 0); usbd_xfer_set_priv(xfer, NULL); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: @@ -844,16 +812,14 @@ rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) usbd_transfer_submit(xfer); } - RUM_UNLOCK(sc); - rum_start(ifp); - RUM_LOCK(sc); + rum_start(sc); break; default: /* Error */ DPRINTFN(11, "transfer error, %s\n", usbd_errstr(error)); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); data = usbd_xfer_get_priv(xfer); if (data != NULL) { rum_tx_free(data, error); @@ -880,8 +846,7 @@ static void rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) { struct rum_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; struct mbuf *m = NULL; struct usb_page_cache *pc; @@ -899,7 +864,7 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) if (len < (int)(RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) { DPRINTF("%s: xfer too short %d\n", device_get_nameunit(sc->sc_dev), len); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } @@ -916,21 +881,20 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) * filled RUM_TXRX_CSR2: */ DPRINTFN(5, "PHY or CRC error\n"); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (m == NULL) { DPRINTF("could not allocate mbuf\n"); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } usbd_copy_out(pc, RT2573_RX_DESC_SIZE, mtod(m, uint8_t *), len); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; if (ieee80211_radiotap_active(ic)) { @@ -968,10 +932,8 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) (void) ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR); } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) - rum_start(ifp); RUM_LOCK(sc); + rum_start(sc); return; default: /* Error */ @@ -1011,8 +973,7 @@ static void rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t plcp_length; int remainder; @@ -1109,8 +1070,7 @@ static int rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct rum_tx_data *data; struct ieee80211_frame *wh; const struct ieee80211_txparam *tp; @@ -1221,8 +1181,7 @@ static int rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct rum_tx_data *data; struct ieee80211_frame *wh; const struct ieee80211_txparam *tp; @@ -1299,80 +1258,73 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) return 0; } -static void -rum_start(struct ifnet *ifp) +static int +rum_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct rum_softc *sc = ic->ic_softc; + int error; + + RUM_LOCK(sc); + if (!sc->sc_running) { + RUM_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RUM_UNLOCK(sc); + return (error); + } + rum_start(sc); + RUM_UNLOCK(sc); + + return (0); +} + +static void +rum_start(struct rum_softc *sc) { - struct rum_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - RUM_LOCK(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - RUM_UNLOCK(sc); + RUM_LOCK_ASSERT(sc, MA_OWNED); + + if (!sc->sc_running) return; - } - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->tx_nfree < RUM_TX_MINFREE) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } + + while (sc->tx_nfree >= RUM_TX_MINFREE && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (rum_tx_data(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); break; } } - RUM_UNLOCK(sc); } -static int -rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rum_parent(struct ieee80211com *ic) { - struct rum_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error; + struct rum_softc *sc = ic->ic_softc; int startall = 0; RUM_LOCK(sc); - error = sc->sc_detached ? ENXIO : 0; - RUM_UNLOCK(sc); - if (error) - return (error); - - switch (cmd) { - case SIOCSIFFLAGS: - RUM_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rum_init_locked(sc); - startall = 1; - } else - rum_setpromisc(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rum_stop(sc); - } + if (sc->sc_detached) { RUM_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; + return; } - return error; + if (ic->ic_nrunning > 0) { + if (!sc->sc_running) { + rum_init(sc); + startall = 1; + } else + rum_setpromisc(sc); + } else if (sc->sc_running) + rum_stop(sc); + RUM_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -1572,8 +1524,7 @@ rum_select_antenna(struct rum_softc *sc) static void rum_enable_mrr(struct rum_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR4); @@ -1589,8 +1540,7 @@ rum_enable_mrr(struct rum_softc *sc) static void rum_set_txpreamble(struct rum_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR4); @@ -1605,8 +1555,7 @@ rum_set_txpreamble(struct rum_softc *sc) static void rum_set_basicrates(struct rum_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* update basic rate set */ if (ic->ic_curmode == IEEE80211_MODE_11B) { @@ -1671,8 +1620,7 @@ rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) static void rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct rfprog *rfprog; uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT; int8_t power; @@ -1748,8 +1696,7 @@ rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) static void rum_enable_tsf_sync(struct rum_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; @@ -1784,10 +1731,9 @@ rum_enable_tsf(struct rum_softc *sc) } static void -rum_update_slot(struct ifnet *ifp) +rum_update_slot(struct rum_softc *sc) { - struct rum_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint8_t slottime; uint32_t tmp; @@ -1827,18 +1773,17 @@ rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) static void rum_setpromisc(struct rum_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR0); tmp &= ~RT2573_DROP_NOT_TO_ME; - if (!(ifp->if_flags & IFF_PROMISC)) + if (sc->sc_ic.ic_promisc == 0) tmp |= RT2573_DROP_NOT_TO_ME; rum_write(sc, RT2573_TXRX_CSR0, tmp); - DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? + DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc > 0 ? "entering" : "leaving"); } @@ -1847,10 +1792,11 @@ rum_update_promisc(struct ieee80211com *ic) { struct rum_softc *sc = ic->ic_softc; - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; - RUM_LOCK(sc); + if (!sc->sc_running) { + RUM_UNLOCK(sc); + return; + } rum_setpromisc(sc); RUM_UNLOCK(sc); } @@ -1887,7 +1833,7 @@ rum_read_eeprom(struct rum_softc *sc) #endif /* read MAC address */ - rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_bssid, 6); + rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_ic.ic_macaddr, 6); rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2); val = le16toh(val); @@ -1994,10 +1940,10 @@ rum_bbp_init(struct rum_softc *sc) } static void -rum_init_locked(struct rum_softc *sc) +rum_init(struct rum_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; usb_error_t error; int i, ntries; @@ -2039,7 +1985,7 @@ rum_init_locked(struct rum_softc *sc) /* clear STA registers */ rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); - rum_set_macaddr(sc, IF_LLADDR(ifp)); + rum_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* initialize ASIC */ rum_write(sc, RT2573_MAC_CSR1, 4); @@ -2058,13 +2004,12 @@ rum_init_locked(struct rum_softc *sc) RT2573_DROP_ACKCTS; if (ic->ic_opmode != IEEE80211_M_HOSTAP) tmp |= RT2573_DROP_TODS; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2573_DROP_NOT_TO_ME; } rum_write(sc, RT2573_TXRX_CSR0, tmp); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_running = 1; usbd_xfer_set_stall(sc->sc_xfer[RUM_BULK_WR]); usbd_transfer_start(sc->sc_xfer[RUM_BULK_RD]); return; @@ -2073,30 +2018,14 @@ fail: rum_stop(sc); #undef N } -static void -rum_init(void *priv) -{ - struct rum_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - RUM_LOCK(sc); - rum_init_locked(sc); - RUM_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - static void rum_stop(struct rum_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; RUM_LOCK_ASSERT(sc, MA_OWNED); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_running = 0; RUM_UNLOCK(sc); @@ -2188,27 +2117,23 @@ static int rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = ni->ni_ic->ic_ifp; - struct rum_softc *sc = ifp->if_softc; + struct rum_softc *sc = ni->ni_ic->ic_softc; RUM_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!sc->sc_running) { RUM_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENETDOWN; } if (sc->tx_nfree < RUM_TX_MINFREE) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; RUM_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return EIO; } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - if (params == NULL) { /* * Legacy path; interpret frame contents to decide @@ -2228,7 +2153,6 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); RUM_UNLOCK(sc); ieee80211_free_node(ni); return EIO; @@ -2262,8 +2186,7 @@ rum_ratectl_task(void *arg, int pending) struct rum_vap *rvp = arg; struct ieee80211vap *vap = &rvp->vap; struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rum_softc *sc = ifp->if_softc; + struct rum_softc *sc = ic->ic_softc; struct ieee80211_node *ni; int ok, fail; int sum, retrycnt; @@ -2283,7 +2206,8 @@ rum_ratectl_task(void *arg, int pending) (void) ieee80211_ratectl_rate(ni, NULL, 0); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, fail); /* count TX retry-fail as Tx errors */ + /* count TX retry-fail as Tx errors */ + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, fail); usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp); RUM_UNLOCK(sc); @@ -2292,15 +2216,14 @@ rum_ratectl_task(void *arg, int pending) static void rum_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rum_softc *sc = ifp->if_softc; + struct rum_softc *sc = ic->ic_softc; uint32_t tmp; RUM_LOCK(sc); /* abort TSF synchronization */ tmp = rum_read(sc, RT2573_TXRX_CSR9); rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); - rum_set_bssid(sc, ifp->if_broadcastaddr); + rum_set_bssid(sc, ieee80211broadcastaddr); RUM_UNLOCK(sc); } @@ -2308,11 +2231,11 @@ rum_scan_start(struct ieee80211com *ic) static void rum_scan_end(struct ieee80211com *ic) { - struct rum_softc *sc = ic->ic_ifp->if_softc; + struct rum_softc *sc = ic->ic_softc; RUM_LOCK(sc); rum_enable_tsf_sync(sc); - rum_set_bssid(sc, sc->sc_bssid); + rum_set_bssid(sc, ic->ic_macaddr); RUM_UNLOCK(sc); } @@ -2320,7 +2243,7 @@ rum_scan_end(struct ieee80211com *ic) static void rum_set_channel(struct ieee80211com *ic) { - struct rum_softc *sc = ic->ic_ifp->if_softc; + struct rum_softc *sc = ic->ic_softc; RUM_LOCK(sc); rum_set_chan(sc, ic->ic_curchan); @@ -2330,8 +2253,7 @@ rum_set_channel(struct ieee80211com *ic) static int rum_get_rssi(struct rum_softc *sc, uint8_t raw) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int lna, agc, rssi; lna = (raw >> 5) & 0x3; diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h index 17944aaf3b41..35da6d38a0e9 100644 --- a/sys/dev/usb/wlan/if_rumvar.h +++ b/sys/dev/usb/wlan/if_rumvar.h @@ -85,7 +85,8 @@ enum { }; struct rum_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct usb_device *sc_udev; @@ -105,8 +106,8 @@ struct rum_softc { uint32_t sta[6]; uint32_t rf_regs[4]; uint8_t txpow[44]; - uint8_t sc_bssid[6]; - uint8_t sc_detached; + u_int sc_detached:1, + sc_running:1; struct { uint8_t val; diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index ac14178a3c7e..193b9adcb213 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -410,8 +410,9 @@ static int run_tx_param(struct run_softc *, struct mbuf *, const struct ieee80211_bpf_params *); static int run_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void run_start(struct ifnet *); -static int run_ioctl(struct ifnet *, u_long, caddr_t); +static int run_transmit(struct ieee80211com *, struct mbuf *); +static void run_start(struct run_softc *); +static void run_parent(struct ieee80211com *); static void run_iq_calib(struct run_softc *, u_int); static void run_set_agc(struct run_softc *, uint8_t); static void run_select_chan_group(struct run_softc *, int); @@ -457,7 +458,6 @@ static void run_rt3593_rf_setup(struct run_softc *); static void run_rt5390_rf_setup(struct run_softc *); static int run_txrx_enable(struct run_softc *); static void run_adjust_freq_offset(struct run_softc *); -static void run_init(void *); static void run_init_locked(struct run_softc *); static void run_stop(void *); static void run_delay(struct run_softc *, u_int); @@ -702,8 +702,7 @@ run_attach(device_t self) { struct run_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint32_t ver; int ntries, error; uint8_t iface_index, bands; @@ -716,6 +715,7 @@ run_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, MTX_DEF); + mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = RT2860_IFACE_INDEX; @@ -754,28 +754,10 @@ run_attach(device_t self) device_printf(sc->sc_dev, "MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n", sc->mac_ver, sc->mac_rev, run_get_rf(sc->rf_rev), - sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid)); + sc->ntxchains, sc->nrxchains, ether_sprintf(ic->ic_macaddr)); RUN_UNLOCK(sc); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto detach; - } - ic = ifp->if_l2com; - - ifp->if_softc = sc; - if_initname(ifp, "run", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = run_init; - ifp->if_ioctl = run_ioctl; - ifp->if_start = run_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(self); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -812,7 +794,7 @@ run_attach(device_t self) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_scan_start = run_scan_start; ic->ic_scan_end = run_scan_end; @@ -824,9 +806,10 @@ run_attach(device_t self) ic->ic_wme.wme_update = run_wme_update; ic->ic_raw_xmit = run_raw_xmit; ic->ic_update_promisc = run_update_promisc; - ic->ic_vap_create = run_vap_create; ic->ic_vap_delete = run_vap_delete; + ic->ic_transmit = run_transmit; + ic->ic_parent = run_parent; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -852,8 +835,7 @@ static int run_detach(device_t self) { struct run_softc *sc = device_get_softc(self); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; int i; RUN_LOCK(sc); @@ -872,16 +854,15 @@ run_detach(device_t self) run_unsetup_tx_list(sc, &sc->sc_epq[i]); RUN_UNLOCK(sc); - if (ifp) { - ic = ifp->if_l2com; + if (sc->sc_ic.ic_softc == sc) { /* drain tasks */ usb_callout_drain(&sc->ratectl_ch); ieee80211_draintask(ic, &sc->cmdq_task); ieee80211_draintask(ic, &sc->ratectl_task); ieee80211_ifdetach(ic); - if_free(ifp); } + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -893,14 +874,13 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; - struct run_softc *sc = ifp->if_softc; + struct run_softc *sc = ic->ic_softc; struct run_vap *rvp; struct ieee80211vap *vap; int i; if (sc->rvp_cnt >= RUN_VAP_MAX) { - if_printf(ifp, "number of VAPs maxed out\n"); + device_printf(sc->sc_dev, "number of VAPs maxed out\n"); return (NULL); } @@ -926,23 +906,21 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, break; } if (vap == NULL) { - if_printf(ifp, "wds only supported in ap mode\n"); + device_printf(sc->sc_dev, + "wds only supported in ap mode\n"); return (NULL); } break; default: - if_printf(ifp, "unknown opmode %d\n", opmode); + device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); return (NULL); } - rvp = (struct run_vap *) malloc(sizeof(struct run_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return (NULL); + rvp = malloc(sizeof(struct run_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &rvp->vap; - if (ieee80211_vap_setup(ic, vap, name, unit, - opmode, flags, bssid, mac) != 0) { + if (ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, + bssid) != 0) { /* out of memory */ free(rvp, M_80211_VAP); return (NULL); @@ -969,7 +947,8 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */); /* complete setup */ - ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status, + mac); /* make sure id is always unique */ for (i = 0; i < RUN_VAP_MAX; i++) { @@ -995,7 +974,6 @@ static void run_vap_delete(struct ieee80211vap *vap) { struct run_vap *rvp = RUN_VAP(vap); - struct ifnet *ifp; struct ieee80211com *ic; struct run_softc *sc; uint8_t rvp_id; @@ -1004,9 +982,7 @@ run_vap_delete(struct ieee80211vap *vap) return; ic = vap->iv_ic; - ifp = ic->ic_ifp; - - sc = ifp->if_softc; + sc = ic->ic_softc; RUN_LOCK(sc); @@ -1740,6 +1716,7 @@ run_get_txpower(struct run_softc *sc) static int run_read_eeprom(struct run_softc *sc) { + struct ieee80211com *ic = &sc->sc_ic; int8_t delta_2ghz, delta_5ghz; uint32_t tmp; uint16_t val; @@ -1760,14 +1737,14 @@ run_read_eeprom(struct run_softc *sc) /* read MAC address */ run_srom_read(sc, RT2860_EEPROM_MAC01, &val); - sc->sc_bssid[0] = val & 0xff; - sc->sc_bssid[1] = val >> 8; + ic->ic_macaddr[0] = val & 0xff; + ic->ic_macaddr[1] = val >> 8; run_srom_read(sc, RT2860_EEPROM_MAC23, &val); - sc->sc_bssid[2] = val & 0xff; - sc->sc_bssid[3] = val >> 8; + ic->ic_macaddr[2] = val & 0xff; + ic->ic_macaddr[3] = val >> 8; run_srom_read(sc, RT2860_EEPROM_MAC45, &val); - sc->sc_bssid[4] = val & 0xff; - sc->sc_bssid[5] = val >> 8; + ic->ic_macaddr[4] = val & 0xff; + ic->ic_macaddr[5] = val >> 8; if (sc->mac_ver < 0x3593) { /* read vender BBP settings */ @@ -2002,7 +1979,7 @@ run_media_change(struct ifnet *ifp) struct ieee80211vap *vap = ifp->if_softc; struct ieee80211com *ic = vap->iv_ic; const struct ieee80211_txparam *tp; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; uint8_t rate, ridx; int error; @@ -2033,7 +2010,7 @@ run_media_change(struct ifnet *ifp) #if 0 if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)){ + (ifp->if_drv_flags & RUN_RUNNING)){ run_init_locked(sc); } #endif @@ -2048,7 +2025,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { const struct ieee80211_txparam *tp; struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; struct run_vap *rvp = RUN_VAP(vap); enum ieee80211_state ostate; uint32_t sta[3]; @@ -2144,7 +2121,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) run_set_txpreamble(sc); run_set_basicrates(sc); ni = ieee80211_ref_node(vap->iv_bss); - IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); + IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid); run_set_bssid(sc, ni->ni_bssid); ieee80211_free_node(ni); run_enable_tsf_sync(sc); @@ -2181,7 +2158,7 @@ static void run_wme_update_cb(void *arg) { struct ieee80211com *ic = arg; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; struct ieee80211_wme_state *wmesp = &ic->ic_wme; int aci, error = 0; @@ -2234,7 +2211,7 @@ run_wme_update_cb(void *arg) static int run_wme_update(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; /* sometime called wothout lock */ if (mtx_owned(&ic->ic_comlock.mtx)) { @@ -2277,7 +2254,7 @@ run_key_set_cb(void *arg) struct ieee80211vap *vap = cmdq->arg1; struct ieee80211_key *k = cmdq->k; struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; struct ieee80211_node *ni; uint32_t attr; uint16_t base, associd; @@ -2399,7 +2376,7 @@ run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k, const uint8_t mac[IEEE80211_ADDR_LEN]) { struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; uint32_t i; i = RUN_CMDQ_GET(&sc->cmdq_store); @@ -2467,7 +2444,7 @@ static int run_key_delete(struct ieee80211vap *vap, struct ieee80211_key *k) { struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; struct ieee80211_key *k0; uint32_t i; @@ -2498,7 +2475,7 @@ run_ratectl_to(void *arg) struct run_softc *sc = arg; /* do it in a process context, so it can go sleep */ - ieee80211_runtask(sc->sc_ifp->if_l2com, &sc->ratectl_task); + ieee80211_runtask(&sc->sc_ic, &sc->ratectl_task); /* next timeout will be rescheduled in the callback task */ } @@ -2507,7 +2484,7 @@ static void run_ratectl_cb(void *arg, int pending) { struct run_softc *sc = arg; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); if (vap == NULL) @@ -2540,7 +2517,6 @@ static void run_drain_fifo(void *arg) { struct run_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t stat; uint16_t (*wstat)[3]; uint8_t wcid, mcs, pid; @@ -2577,7 +2553,7 @@ run_drain_fifo(void *arg) if (stat & RT2860_TXQ_OK) (*wstat)[RUN_SUCCESS]++; else - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); /* * Check if there were retries, ie if the Tx success rate is * different from the requested rate. Note that it works only @@ -2600,8 +2576,6 @@ run_iter_func(void *arg, struct ieee80211_node *ni) { struct run_softc *sc = arg; struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; struct run_node *rn = (void *)ni; union run_stats sta[2]; uint16_t (*wstat)[3]; @@ -2623,7 +2597,8 @@ run_iter_func(void *arg, struct ieee80211_node *ni) goto fail; /* count failed TX as errors */ - if_inc_counter(ifp, IFCOUNTER_OERRORS, le16toh(sta[0].error.fail)); + if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, + le16toh(sta[0].error.fail)); retrycnt = le16toh(sta[1].tx.retry); success = le16toh(sta[1].tx.success); @@ -2661,7 +2636,7 @@ run_newassoc_cb(void *arg) { struct run_cmdq *cmdq = arg; struct ieee80211_node *ni = cmdq->arg1; - struct run_softc *sc = ni->ni_vap->iv_ic->ic_ifp->if_softc; + struct run_softc *sc = ni->ni_vap->iv_ic->ic_softc; uint8_t wcid = cmdq->wcid; RUN_LOCK_ASSERT(sc, MA_OWNED); @@ -2679,7 +2654,7 @@ run_newassoc(struct ieee80211_node *ni, int isnew) struct ieee80211_rateset *rs = &ni->ni_rates; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; uint8_t rate; uint8_t ridx; uint8_t wcid; @@ -2769,8 +2744,7 @@ run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi) static void run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct rt2870_rxd *rxd; @@ -2789,7 +2763,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) rxwisize += sizeof(uint32_t); if (__predict_false(len > dmalen)) { m_freem(m); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); DPRINTF("bad RXWI length %u > %u\n", len, dmalen); return; } @@ -2799,7 +2773,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) if (__predict_false(flags & (RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { m_freem(m); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); DPRINTF("%s error.\n", (flags & RT2860_RX_CRCERR)?"CRC":"ICV"); return; } @@ -2828,7 +2802,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) ieee80211_notify_michael_failure(ni->ni_vap, wh, rxwi->keyidx); m_freem(m); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); DPRINTF("MIC error. Someone is lying.\n"); return; } @@ -2837,7 +2811,6 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen) rssi = rxwi->rssi[ant]; nf = run_rssi2dbm(sc, rssi, ant); - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = len; if (ni != NULL) { @@ -2890,7 +2863,7 @@ static void run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct run_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; struct mbuf *m = NULL; struct mbuf *m0; uint32_t dmalen; @@ -2928,7 +2901,7 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) } if (sc->rx_m == NULL) { DPRINTF("could not allocate mbuf - idle with stall\n"); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); usbd_xfer_set_stall(xfer); usbd_xfer_set_frames(xfer, 0); } else { @@ -2948,12 +2921,9 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) if (error != USB_ERR_CANCELLED) { /* try to clear stall first */ usbd_xfer_set_stall(xfer); - if (error == USB_ERR_TIMEOUT) device_printf(sc->sc_dev, "device timeout\n"); - - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } if (sc->rx_m != NULL) { @@ -3001,7 +2971,7 @@ run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m0 == NULL)) { DPRINTF("could not allocate mbuf\n"); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); break; } m_copydata(m, 4 /* skip 32-bit DMA-len header */, @@ -3048,8 +3018,7 @@ static void run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index) { struct run_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct run_tx_data *data; struct ieee80211vap *vap = NULL; struct usb_page_cache *pc; @@ -3067,14 +3036,9 @@ run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index) "bytes @ index %d\n", actlen, index); data = usbd_xfer_get_priv(xfer); - run_tx_free(pq, data, 0); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - usbd_xfer_set_priv(xfer, NULL); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: @@ -3091,11 +3055,7 @@ run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index) size + 3 + 8) > RUN_MAX_TXSZ) { DPRINTF("data overflow, %u bytes\n", m->m_pkthdr.len); - - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - run_tx_free(pq, data, 1); - goto tr_setup; } @@ -3132,12 +3092,8 @@ run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index) usbd_xfer_set_frame_len(xfer, 0, size); usbd_xfer_set_priv(xfer, data); - usbd_transfer_submit(xfer); - - RUN_UNLOCK(sc); - run_start(ifp); - RUN_LOCK(sc); + run_start(sc); break; @@ -3147,14 +3103,13 @@ run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index) data = usbd_xfer_get_priv(xfer); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - if (data != NULL) { if(data->ni != NULL) vap = data->ni->ni_vap; run_tx_free(pq, data, error); usbd_xfer_set_priv(xfer, NULL); } + if (vap == NULL) vap = TAILQ_FIRST(&ic->ic_vaps); @@ -3220,7 +3175,7 @@ static void run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data) { struct mbuf *m = data->m; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = data->ni->ni_vap; struct ieee80211_frame *wh; struct rt2870_txd *txd; @@ -3283,7 +3238,7 @@ run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data) static int run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_frame *wh; struct ieee80211_channel *chan; @@ -3451,8 +3406,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) static int run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct run_node *rn = (void *)ni; struct run_tx_data *data; struct ieee80211_frame *wh; @@ -3483,11 +3437,9 @@ run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) USETW(wh->i_dur, dur); } - if (sc->sc_epq[0].tx_nfree == 0) { + if (sc->sc_epq[0].tx_nfree == 0) /* let caller free mbuf */ - ifp->if_drv_flags |= IFF_DRV_OACTIVE; return (EIO); - } data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh); STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next); sc->sc_epq[0].tx_nfree--; @@ -3555,11 +3507,9 @@ run_sendprot(struct run_softc *sc, wflags = RT2860_TX_FRAG; /* check that there are free slots before allocating the mbuf */ - if (sc->sc_epq[0].tx_nfree == 0) { + if (sc->sc_epq[0].tx_nfree == 0) /* let caller free mbuf */ - sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE; return (ENOBUFS); - } if (prot == IEEE80211_PROT_RTSCTS) { /* NB: CTS is the same size as an ACK */ @@ -3570,7 +3520,7 @@ run_sendprot(struct run_softc *sc, mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); } if (mprot == NULL) { - if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); DPRINTF("could not allocate mbuf\n"); return (ENOBUFS); } @@ -3652,7 +3602,6 @@ run_tx_param(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni, if (sc->sc_epq[0].tx_nfree == 0) { /* let caller free mbuf */ - sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE; DPRINTF("sending raw frame, but tx ring is full\n"); return (EIO); } @@ -3691,36 +3640,31 @@ static int run_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = ni->ni_ic->ic_ifp; - struct run_softc *sc = ifp->if_softc; + struct run_softc *sc = ni->ni_ic->ic_softc; int error = 0; RUN_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - error = ENETDOWN; + if (!(sc->sc_flags & RUN_RUNNING)) { + error = ENETDOWN; goto done; } if (params == NULL) { /* tx mgt packet */ if ((error = run_tx_mgt(sc, m, ni)) != 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); DPRINTF("mgt tx failed\n"); goto done; } } else { /* tx raw packet with param */ if ((error = run_tx_param(sc, m, ni, params)) != 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); DPRINTF("tx with param failed\n"); goto done; } } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - done: RUN_UNLOCK(sc); @@ -3733,83 +3677,71 @@ run_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return (error); } -static void -run_start(struct ifnet *ifp) +static int +run_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct run_softc *sc = ic->ic_softc; + int error; + + RUN_LOCK(sc); + if ((sc->sc_flags & RUN_RUNNING) == 0) { + RUN_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RUN_UNLOCK(sc); + return (error); + } + run_start(sc); + RUN_UNLOCK(sc); + + return (0); +} + +static void +run_start(struct run_softc *sc) { - struct run_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - RUN_LOCK(sc); + RUN_LOCK_ASSERT(sc, MA_OWNED); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((sc->sc_flags & RUN_RUNNING) == 0) + return; + + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + if (run_tx(sc, m, ni) != 0) { + mbufq_prepend(&sc->sc_snd, m); + break; + } + } +} + +static void +run_parent(struct ieee80211com *ic) +{ + struct run_softc *sc = ic->ic_softc; + int startall = 0; + + RUN_LOCK(sc); + if (sc->sc_detached) { RUN_UNLOCK(sc); return; } - for (;;) { - /* send data frames */ - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - - ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; - if (run_tx(sc, m, ni) != 0) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - } - + if (ic->ic_nrunning > 0) { + if (!(sc->sc_flags & RUN_RUNNING)) { + startall = 1; + run_init_locked(sc); + } else + run_update_promisc_locked(sc); + } else if ((sc->sc_flags & RUN_RUNNING) && sc->rvp_cnt <= 1) + run_stop(sc); RUN_UNLOCK(sc); -} - -static int -run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct run_softc *sc = ifp->if_softc; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int startall = 0; - int error; - - RUN_LOCK(sc); - error = sc->sc_detached ? ENXIO : 0; - RUN_UNLOCK(sc); - if (error) - return (error); - - switch (cmd) { - case SIOCSIFFLAGS: - RUN_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)){ - startall = 1; - run_init_locked(sc); - } else - run_update_promisc_locked(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - (ic->ic_nrunning == 0 || sc->rvp_cnt <= 1)) { - run_stop(sc); - } - } - RUN_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - - return (error); + if (startall) + ieee80211_start_all(ic); } static void @@ -4796,7 +4728,7 @@ run_set_rx_antenna(struct run_softc *sc, int aux) static int run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; u_int chan, group; chan = ieee80211_chan2ieee(ic, c); @@ -4841,7 +4773,7 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) static void run_set_channel(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; RUN_LOCK(sc); run_set_chan(sc, ic->ic_curchan); @@ -4853,7 +4785,7 @@ run_set_channel(struct ieee80211com *ic) static void run_scan_start(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; uint32_t tmp; RUN_LOCK(sc); @@ -4863,7 +4795,7 @@ run_scan_start(struct ieee80211com *ic) run_write(sc, RT2860_BCN_TIME_CFG, tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | RT2860_TBTT_TIMER_EN)); - run_set_bssid(sc, sc->sc_ifp->if_broadcastaddr); + run_set_bssid(sc, ieee80211broadcastaddr); RUN_UNLOCK(sc); @@ -4873,13 +4805,13 @@ run_scan_start(struct ieee80211com *ic) static void run_scan_end(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; RUN_LOCK(sc); run_enable_tsf_sync(sc); /* XXX keep local copy */ - run_set_bssid(sc, sc->sc_bssid); + run_set_bssid(sc, ic->ic_macaddr); RUN_UNLOCK(sc); @@ -4894,7 +4826,7 @@ static void run_update_beacon(struct ieee80211vap *vap, int item) { struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; struct run_vap *rvp = RUN_VAP(vap); int mcast = 0; uint32_t i; @@ -4939,7 +4871,7 @@ run_update_beacon_cb(void *arg) struct ieee80211vap *vap = arg; struct run_vap *rvp = RUN_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; struct rt2860_txwi txwi; struct mbuf *m; uint16_t txwisize; @@ -4987,7 +4919,7 @@ run_update_beacon_cb(void *arg) static void run_updateprot(struct ieee80211com *ic) { - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; uint32_t i; i = RUN_CMDQ_GET(&sc->cmdq_store); @@ -5001,7 +4933,7 @@ static void run_updateprot_cb(void *arg) { struct ieee80211com *ic = arg; - struct run_softc *sc = ic->ic_ifp->if_softc; + struct run_softc *sc = ic->ic_softc; uint32_t tmp; tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL; @@ -5025,7 +4957,7 @@ static void run_usb_timeout_cb(void *arg) { struct ieee80211vap *vap = arg; - struct run_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct run_softc *sc = vap->iv_ic->ic_softc; RUN_LOCK_ASSERT(sc, MA_OWNED); @@ -5071,12 +5003,12 @@ run_update_promisc_locked(struct run_softc *sc) run_read(sc, RT2860_RX_FILTR_CFG, &tmp); tmp |= RT2860_DROP_UC_NOME; - if (sc->sc_ifp->if_flags & IFF_PROMISC) + if (sc->sc_ic.ic_promisc > 0) tmp &= ~RT2860_DROP_UC_NOME; run_write(sc, RT2860_RX_FILTR_CFG, tmp); - DPRINTF("%s promiscuous mode\n", (sc->sc_ifp->if_flags & IFF_PROMISC) ? + DPRINTF("%s promiscuous mode\n", (sc->sc_ic.ic_promisc > 0) ? "entering" : "leaving"); } @@ -5085,7 +5017,7 @@ run_update_promisc(struct ieee80211com *ic) { struct run_softc *sc = ic->ic_softc; - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & RUN_RUNNING) == 0) return; RUN_LOCK(sc); @@ -5096,7 +5028,7 @@ run_update_promisc(struct ieee80211com *ic) static void run_enable_tsf_sync(struct run_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; @@ -5161,7 +5093,7 @@ run_enable_mrr(struct run_softc *sc) static void run_set_txpreamble(struct run_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; run_read(sc, RT2860_AUTO_RSP_CFG, &tmp); @@ -5175,7 +5107,7 @@ run_set_txpreamble(struct run_softc *sc) static void run_set_basicrates(struct run_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* set basic rates mask */ if (ic->ic_curmode == IEEE80211_MODE_11B) @@ -5220,7 +5152,7 @@ run_updateslot(struct ieee80211com *ic) i = RUN_CMDQ_GET(&sc->cmdq_store); DPRINTF("cmdq_store=%d\n", i); sc->cmdq[i].func = run_updateslot_cb; - sc->cmdq[i].arg0 = ic->ic_ifp; + sc->cmdq[i].arg0 = ic; ieee80211_runtask(ic, &sc->cmdq_task); return; @@ -5230,9 +5162,8 @@ run_updateslot(struct ieee80211com *ic) static void run_updateslot_cb(void *arg) { - struct ifnet *ifp = arg; - struct run_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = arg; + struct run_softc *sc = ic->ic_softc; uint32_t tmp; run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp); @@ -5244,15 +5175,12 @@ run_updateslot_cb(void *arg) static void run_update_mcast(struct ieee80211com *ic) { - - /* h/w filter supports getting everything or nothing */ - ic->ic_ifp->if_flags |= IFF_ALLMULTI; } static int8_t run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_channel *c = ic->ic_curchan; int delta; @@ -5902,7 +5830,7 @@ run_rt5390_rf_setup(struct run_softc *sc) static int run_txrx_enable(struct run_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; int error, ntries; @@ -5962,8 +5890,8 @@ run_adjust_freq_offset(struct run_softc *sc) static void run_init_locked(struct run_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; uint8_t bbp1, bbp3; int i; @@ -5993,7 +5921,7 @@ run_init_locked(struct run_softc *sc) for (i = 0; i != RUN_EP_QUEUES; i++) run_setup_tx_list(sc, &sc->sc_epq[i]); - run_set_macaddr(sc, IF_LLADDR(ifp)); + run_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); for (ntries = 0; ntries < 100; ntries++) { if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0) @@ -6166,8 +6094,7 @@ run_init_locked(struct run_softc *sc) /* turn radio LED on */ run_set_leds(sc, RT2860_LED_RADIO); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= RUN_RUNNING; sc->cmdq_run = RUN_CMDQ_GO; for (i = 0; i != RUN_N_XFER; i++) @@ -6184,36 +6111,20 @@ run_init_locked(struct run_softc *sc) run_stop(sc); } -static void -run_init(void *arg) -{ - struct run_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - RUN_LOCK(sc); - run_init_locked(sc); - RUN_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); -} - static void run_stop(void *arg) { struct run_softc *sc = (struct run_softc *)arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; int i; int ntries; RUN_LOCK_ASSERT(sc, MA_OWNED); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RUN_RUNNING) run_set_leds(sc, 0); /* turn all LEDs off */ - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~RUN_RUNNING; sc->ratectl_run = RUN_RATECTL_OFF; sc->cmdq_run = sc->cmdq_key_set; diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h index ad0fc30fe599..b8cb12f5e1b6 100644 --- a/sys/dev/usb/wlan/if_runvar.h +++ b/sys/dev/usb/wlan/if_runvar.h @@ -151,13 +151,16 @@ struct run_endpoint_queue { }; struct run_softc { + struct mtx sc_mtx; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct usb_device *sc_udev; - struct ifnet *sc_ifp; int sc_need_fwload; int sc_flags; #define RUN_FLAG_FWLOAD_NEEDED 0x01 +#define RUN_RUNNING 0x02 uint16_t wcid_stats[RT2870_WCID_MAX + 1][3]; #define RUN_TXCNT 0 @@ -203,10 +206,6 @@ struct run_softc { uint32_t txpow40mhz_2ghz[5]; uint32_t txpow40mhz_5ghz[5]; - uint8_t sc_bssid[6]; - - struct mtx sc_mtx; - struct run_endpoint_queue sc_epq[RUN_EP_QUEUES]; struct task ratectl_task; diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index fca9e39a6a27..04e092040c14 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -279,12 +279,11 @@ static int uath_alloc_rx_data_list(struct uath_softc *); static int uath_alloc_tx_data_list(struct uath_softc *); static void uath_free_rx_data_list(struct uath_softc *); static void uath_free_tx_data_list(struct uath_softc *); -static int uath_init_locked(void *); -static void uath_init(void *); -static void uath_stop_locked(struct ifnet *); -static void uath_stop(struct ifnet *); -static int uath_ioctl(struct ifnet *, u_long, caddr_t); -static void uath_start(struct ifnet *); +static int uath_init(struct uath_softc *); +static void uath_stop(struct uath_softc *); +static void uath_parent(struct ieee80211com *); +static int uath_transmit(struct ieee80211com *, struct mbuf *); +static void uath_start(struct uath_softc *); static int uath_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void uath_scan_start(struct ieee80211com *); @@ -336,11 +335,9 @@ uath_attach(device_t dev) { struct uath_softc *sc = device_get_softc(dev); struct usb_attach_arg *uaa = device_get_ivars(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint8_t bands, iface_index = UATH_IFACE_INDEX; /* XXX */ usb_error_t error; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; sc->sc_udev = uaa->device; @@ -356,6 +353,7 @@ uath_attach(device_t dev) MTX_DEF); callout_init(&sc->stat_ch, 0); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, uath_usbconfig, UATH_N_XFERS, sc, &sc->sc_mtx); @@ -387,31 +385,24 @@ uath_attach(device_t dev) error = uath_host_available(sc); if (error != 0) { device_printf(sc->sc_dev, "could not initialize adapter\n"); - goto fail3; + goto fail2; } error = uath_get_devcap(sc); if (error != 0) { device_printf(sc->sc_dev, "could not get device capabilities\n"); - goto fail3; + goto fail2; } UATH_UNLOCK(sc); /* Create device sysctl node. */ uath_sysctl_node(sc); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not allocate ifnet\n"); - error = ENXIO; - goto fail2; - } - UATH_LOCK(sc); - error = uath_get_devstatus(sc, macaddr); + error = uath_get_devstatus(sc, ic->ic_macaddr); if (error != 0) { device_printf(sc->sc_dev, "could not get device status\n"); - goto fail4; + goto fail2; } /* @@ -420,28 +411,15 @@ uath_attach(device_t dev) error = uath_alloc_rx_data_list(sc); if (error != 0) { device_printf(sc->sc_dev, "could not allocate Rx data list\n"); - goto fail4; + goto fail2; } error = uath_alloc_tx_data_list(sc); if (error != 0) { device_printf(sc->sc_dev, "could not allocate Tx data list\n"); - goto fail4; + goto fail2; } UATH_UNLOCK(sc); - ifp->if_softc = sc; - if_initname(ifp, "uath", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = uath_init; - ifp->if_ioctl = uath_ioctl; - ifp->if_start = uath_start; - /* XXX UATH_TX_DATA_LIST_COUNT */ - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -469,16 +447,17 @@ uath_attach(device_t dev) /* XXX turbo */ ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_raw_xmit = uath_raw_xmit; ic->ic_scan_start = uath_scan_start; ic->ic_scan_end = uath_scan_end; ic->ic_set_channel = uath_set_channel; - ic->ic_vap_create = uath_vap_create; ic->ic_vap_delete = uath_vap_delete; ic->ic_update_mcast = uath_update_mcast; ic->ic_update_promisc = uath_update_promisc; + ic->ic_transmit = uath_transmit; + ic->ic_parent = uath_parent; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -491,9 +470,8 @@ uath_attach(device_t dev) return (0); -fail4: if_free(ifp); -fail3: UATH_UNLOCK(sc); -fail2: uath_free_cmd_list(sc, sc->sc_cmd); +fail2: UATH_UNLOCK(sc); + uath_free_cmd_list(sc, sc->sc_cmd); fail1: usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS); fail: return (error); @@ -503,8 +481,7 @@ static int uath_detach(device_t dev) { struct uath_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; unsigned int x; /* @@ -525,9 +502,9 @@ uath_detach(device_t dev) STAILQ_INIT(&sc->sc_cmd_pending); STAILQ_INIT(&sc->sc_cmd_waiting); STAILQ_INIT(&sc->sc_cmd_inactive); - UATH_UNLOCK(sc); - uath_stop(ifp); + uath_stop(sc); + UATH_UNLOCK(sc); callout_drain(&sc->stat_ch); callout_drain(&sc->watchdog_ch); @@ -547,7 +524,7 @@ uath_detach(device_t dev) usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS); ieee80211_ifdetach(ic); - if_free(ifp); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); } @@ -1067,15 +1044,12 @@ uath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return (NULL); - uvp = (struct uath_vap *) malloc(sizeof(struct uath_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return (NULL); + uvp = malloc(sizeof(struct uath_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &uvp->vap; /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -1087,7 +1061,7 @@ uath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); ic->ic_opmode = opmode; return (vap); } @@ -1102,18 +1076,17 @@ uath_vap_delete(struct ieee80211vap *vap) } static int -uath_init_locked(void *arg) +uath_init(struct uath_softc *sc) { - struct uath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t val; int error; UATH_ASSERT_LOCKED(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - uath_stop_locked(ifp); + if (sc->sc_flags & UATH_FLAG_INITDONE) + uath_stop(sc); /* reset variables */ sc->sc_intrx_nextnum = sc->sc_msgid = 0; @@ -1122,7 +1095,8 @@ uath_init_locked(void *arg) uath_cmd_write(sc, WDCMSG_BIND, &val, sizeof val, 0); /* set MAC address */ - uath_config_multi(sc, CFG_MAC_ADDR, IF_LLADDR(ifp), IEEE80211_ADDR_LEN); + uath_config_multi(sc, CFG_MAC_ADDR, + vap ? vap->iv_myaddr : ic->ic_macaddr, IEEE80211_ADDR_LEN); /* XXX honor net80211 state */ uath_config(sc, CFG_RATE_CONTROL_ENABLE, 0x00000001); @@ -1171,8 +1145,6 @@ uath_init_locked(void *arg) UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON, UATH_FILTER_OP_SET); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; sc->sc_flags |= UATH_FLAG_INITDONE; callout_reset(&sc->watchdog_ch, hz, uath_watchdog, sc); @@ -1180,28 +1152,16 @@ uath_init_locked(void *arg) return (0); fail: - uath_stop_locked(ifp); + uath_stop(sc); return (error); } static void -uath_init(void *arg) +uath_stop(struct uath_softc *sc) { - struct uath_softc *sc = arg; - - UATH_LOCK(sc); - (void)uath_init_locked(sc); - UATH_UNLOCK(sc); -} - -static void -uath_stop_locked(struct ifnet *ifp) -{ - struct uath_softc *sc = ifp->if_softc; UATH_ASSERT_LOCKED(sc); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); sc->sc_flags &= ~UATH_FLAG_INITDONE; callout_stop(&sc->stat_ch); @@ -1217,16 +1177,6 @@ uath_stop_locked(struct ifnet *ifp) uath_cmd_write(sc, WDCMSG_TARGET_STOP, NULL, 0, 0); } -static void -uath_stop(struct ifnet *ifp) -{ - struct uath_softc *sc = ifp->if_softc; - - UATH_LOCK(sc); - uath_stop_locked(ifp); - UATH_UNLOCK(sc); -} - static int uath_config(struct uath_softc *sc, uint32_t reg, uint32_t val) { @@ -1329,13 +1279,13 @@ static void uath_watchdog(void *arg) { struct uath_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; if (sc->sc_tx_timer > 0) { if (--sc->sc_tx_timer == 0) { device_printf(sc->sc_dev, "device timeout\n"); - /*uath_init(ifp); XXX needs a process context! */ - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + /*uath_init(sc); XXX needs a process context! */ + counter_u64_add(ic->ic_oerrors, 1); return; } callout_reset(&sc->watchdog_ch, hz, uath_watchdog, sc); @@ -1450,12 +1400,8 @@ uath_getbuf(struct uath_softc *sc) UATH_ASSERT_LOCKED(sc); bf = _uath_getbuf(sc); - if (bf == NULL) { - struct ifnet *ifp = sc->sc_ifp; - + if (bf == NULL) DPRINTF(sc, UATH_DEBUG_XMIT, "%s: stop queue\n", __func__); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - } return (bf); } @@ -1474,8 +1420,7 @@ static int uath_set_chan(struct uath_softc *sc, struct ieee80211_channel *c) { #ifdef UATH_DEBUG - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; #endif struct uath_cmd_reset reset; @@ -1554,47 +1499,28 @@ uath_wme_init(struct uath_softc *sc) return (error); } -static int -uath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +uath_parent(struct ieee80211com *ic) { - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - struct uath_softc *sc = ifp->if_softc; - int error; + struct uath_softc *sc = ic->ic_softc; int startall = 0; UATH_LOCK(sc); - error = (sc->sc_flags & UATH_FLAG_INVALID) ? ENXIO : 0; - UATH_UNLOCK(sc); - if (error) - return (error); - - switch (cmd) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - uath_init(ifp->if_softc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - uath_stop(ifp); - } - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; + if (sc->sc_flags & UATH_FLAG_INVALID) { + UATH_UNLOCK(sc); + return; } - return (error); + if (ic->ic_nrunning > 0) { + if (!(sc->sc_flags & UATH_FLAG_INITDONE)) { + uath_init(sc); + startall = 1; + } + } else if (sc->sc_flags & UATH_FLAG_INITDONE) + uath_stop(sc); + UATH_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static int @@ -1763,31 +1689,49 @@ uath_freetx(struct mbuf *m) } while ((m = next) != NULL); } +static int +uath_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct uath_softc *sc = ic->ic_softc; + int error; + + UATH_LOCK(sc); + if ((sc->sc_flags & UATH_FLAG_INITDONE) == 0) { + UATH_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + UATH_UNLOCK(sc); + return (error); + } + uath_start(sc); + UATH_UNLOCK(sc); + + return (0); +} + static void -uath_start(struct ifnet *ifp) +uath_start(struct uath_softc *sc) { struct uath_data *bf; - struct uath_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m, *next; uath_datahead frags; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || + UATH_ASSERT_LOCKED(sc); + + if ((sc->sc_flags & UATH_FLAG_INITDONE) == 0 || (sc->sc_flags & UATH_FLAG_INVALID)) return; - UATH_LOCK(sc); - for (;;) { + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { bf = uath_getbuf(sc); - if (bf == NULL) - break; - - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) { - STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); - UATH_STAT_INC(sc, st_tx_inactive); + if (bf == NULL) { + mbufq_prepend(&sc->sc_snd, m); break; } + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; m->m_pkthdr.rcvif = NULL; @@ -1816,7 +1760,8 @@ uath_start(struct ifnet *ifp) next = m->m_nextpkt; if (uath_tx_start(sc, m, ni, bf) != 0) { bad: - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); reclaim: STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); UATH_STAT_INC(sc, st_tx_inactive); @@ -1847,7 +1792,6 @@ uath_start(struct ifnet *ifp) sc->sc_tx_timer = 5; } - UATH_UNLOCK(sc); } static int @@ -1855,19 +1799,19 @@ uath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; struct uath_data *bf; - struct uath_softc *sc = ifp->if_softc; + struct uath_softc *sc = ic->ic_softc; + UATH_LOCK(sc); /* prevent management frames from being sent if we're not ready */ if ((sc->sc_flags & UATH_FLAG_INVALID) || - !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + !(sc->sc_flags & UATH_FLAG_INITDONE)) { m_freem(m); ieee80211_free_node(ni); + UATH_UNLOCK(sc); return (ENETDOWN); } - UATH_LOCK(sc); /* grab a TX buffer */ bf = uath_getbuf(sc); if (bf == NULL) { @@ -1880,7 +1824,6 @@ uath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, sc->sc_seqnum = 0; if (uath_tx_start(sc, m, ni, bf) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); UATH_STAT_INC(sc, st_tx_inactive); UATH_UNLOCK(sc); @@ -1907,12 +1850,11 @@ uath_scan_end(struct ieee80211com *ic) static void uath_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct uath_softc *sc = ifp->if_softc; + struct uath_softc *sc = ic->ic_softc; UATH_LOCK(sc); if ((sc->sc_flags & UATH_FLAG_INVALID) || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + (sc->sc_flags & UATH_FLAG_INITDONE) == 0) { UATH_UNLOCK(sc); return; } @@ -1933,7 +1875,7 @@ uath_update_mcast(struct ieee80211com *ic) UATH_LOCK(sc); if ((sc->sc_flags & UATH_FLAG_INVALID) || - (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + (sc->sc_flags & UATH_FLAG_INITDONE) == 0) { UATH_UNLOCK(sc); return; } @@ -1953,7 +1895,7 @@ uath_update_promisc(struct ieee80211com *ic) UATH_LOCK(sc); if ((sc->sc_flags & UATH_FLAG_INVALID) || - (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + (sc->sc_flags & UATH_FLAG_INITDONE) == 0) { UATH_UNLOCK(sc); return; } @@ -1970,7 +1912,7 @@ static int uath_create_connection(struct uath_softc *sc, uint32_t connid) { const struct ieee80211_rateset *rs; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni; struct uath_cmd_create_connection create; @@ -2021,7 +1963,7 @@ uath_set_rates(struct uath_softc *sc, const struct ieee80211_rateset *rs) static int uath_write_associd(struct uath_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni; struct uath_cmd_set_associd associd; @@ -2075,7 +2017,7 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) int error; struct ieee80211_node *ni; struct ieee80211com *ic = vap->iv_ic; - struct uath_softc *sc = ic->ic_ifp->if_softc; + struct uath_softc *sc = ic->ic_softc; struct uath_vap *uvp = UATH_VAP(vap); DPRINTF(sc, UATH_DEBUG_STATE, @@ -2542,8 +2484,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, struct uath_rx_desc **pdesc) { struct uath_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct uath_chunk *chunk; struct uath_rx_desc *desc; struct mbuf *m = data->m, *mnew, *mp; @@ -2555,14 +2496,14 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, if (actlen < (int)UATH_MIN_RXBUFSZ) { DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL, "%s: wrong xfer size (len=%d)\n", __func__, actlen); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } chunk = (struct uath_chunk *)data->buf; if (chunk->seqnum == 0 && chunk->flags == 0 && chunk->length == 0) { device_printf(sc->sc_dev, "%s: strange response\n", __func__); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); UATH_RESET_INTRX(sc); return (NULL); } @@ -2595,7 +2536,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, if ((sc->sc_intrx_len + sizeof(struct uath_rx_desc) + chunklen) > UATH_MAX_INTRX_SIZE) { UATH_STAT_INC(sc, st_invalidlen); - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); + counter_u64_add(ic->ic_ierrors, 1); if (sc->sc_intrx_head != NULL) m_freem(sc->sc_intrx_head); UATH_RESET_INTRX(sc); @@ -2620,7 +2561,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, if (mnew == NULL) { DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL, "%s: can't get new mbuf, drop frame\n", __func__); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); if (sc->sc_intrx_head != NULL) m_freem(sc->sc_intrx_head); UATH_RESET_INTRX(sc); @@ -2661,7 +2602,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL, "%s: bad descriptor (len=%d)\n", __func__, be32toh(desc->len)); - if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); + counter_u64_add(ic->ic_ierrors, 1); UATH_STAT_INC(sc, st_toobigrxpkt); if (sc->sc_intrx_head != NULL) m_freem(sc->sc_intrx_head); @@ -2673,13 +2614,11 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, /* finalize mbuf */ if (sc->sc_intrx_head == NULL) { - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = be32toh(desc->framelen) - UATH_RX_DUMMYSIZE; m->m_data += sizeof(struct uath_chunk); } else { mp = sc->sc_intrx_head; - mp->m_pkthdr.rcvif = ifp; mp->m_flags |= M_PKTHDR; mp->m_pkthdr.len = sc->sc_intrx_len; m = mp; @@ -2705,7 +2644,6 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data, tap->wr_antnoise = -95; } - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); UATH_RESET_INTRX(sc); return (m); @@ -2715,8 +2653,7 @@ static void uath_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct uath_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m = NULL; @@ -2776,10 +2713,8 @@ uath_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) m = NULL; desc = NULL; } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) - uath_start(ifp); UATH_LOCK(sc); + uath_start(sc); break; default: /* needs it to the inactive queue due to a error. */ @@ -2792,7 +2727,7 @@ uath_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto setup; } break; @@ -2803,40 +2738,22 @@ static void uath_data_txeof(struct usb_xfer *xfer, struct uath_data *data) { struct uath_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; UATH_ASSERT_LOCKED(sc); - /* - * Do any tx complete callback. Note this must be done before releasing - * the node reference. - */ if (data->m) { - m = data->m; - if (m->m_flags & M_TXCB && - (sc->sc_flags & UATH_FLAG_INVALID) == 0) { - /* XXX status? */ - ieee80211_process_callback(data->ni, m, 0); - } - m_freem(m); + /* XXX status? */ + ieee80211_tx_complete(data->ni, data->m, 0); data->m = NULL; - } - if (data->ni) { - if ((sc->sc_flags & UATH_FLAG_INVALID) == 0) - ieee80211_free_node(data->ni); data->ni = NULL; } sc->sc_tx_timer = 0; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void uath_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) { struct uath_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; struct uath_data *data; UATH_ASSERT_LOCKED(sc); @@ -2868,19 +2785,18 @@ uath_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); usbd_transfer_submit(xfer); - UATH_UNLOCK(sc); - uath_start(ifp); - UATH_LOCK(sc); + uath_start(sc); break; default: data = STAILQ_FIRST(&sc->sc_tx_active); if (data == NULL) goto setup; if (data->ni != NULL) { + if_inc_counter(data->ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); if ((sc->sc_flags & UATH_FLAG_INVALID) == 0) ieee80211_free_node(data->ni); data->ni = NULL; - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); diff --git a/sys/dev/usb/wlan/if_uathvar.h b/sys/dev/usb/wlan/if_uathvar.h index fae360460bbb..56b5ba35a2b6 100644 --- a/sys/dev/usb/wlan/if_uathvar.h +++ b/sys/dev/usb/wlan/if_uathvar.h @@ -183,7 +183,8 @@ struct uath_vap { #define UATH_VAP(vap) ((struct uath_vap *)(vap)) struct uath_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct usb_device *sc_udev; void *sc_cmd_dma_buf; diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index a2e493ed64fa..b882fe36164e 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -128,10 +128,10 @@ static void upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int); static void upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int); static uint32_t upgt_chksum_le(const uint32_t *, size_t); static void upgt_tx_done(struct upgt_softc *, uint8_t *); -static void upgt_init(void *); -static void upgt_init_locked(struct upgt_softc *); -static int upgt_ioctl(struct ifnet *, u_long, caddr_t); -static void upgt_start(struct ifnet *); +static void upgt_init(struct upgt_softc *); +static void upgt_parent(struct ieee80211com *); +static int upgt_transmit(struct ieee80211com *, struct mbuf *); +static void upgt_start(struct upgt_softc *); static int upgt_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void upgt_scan_start(struct ieee80211com *); @@ -240,12 +240,11 @@ upgt_match(device_t dev) static int upgt_attach(device_t dev) { - int error; - struct ieee80211com *ic; - struct ifnet *ifp; struct upgt_softc *sc = device_get_softc(dev); + struct ieee80211com *ic = &sc->sc_ic; struct usb_attach_arg *uaa = device_get_ivars(dev); uint8_t bands, iface_index = UPGT_IFACE_INDEX; + int error; sc->sc_dev = dev; sc->sc_udev = uaa->device; @@ -258,6 +257,7 @@ upgt_attach(device_t dev) MTX_DEF); callout_init(&sc->sc_led_ch, 0); callout_init(&sc->sc_watchdog_ch, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, upgt_config, UPGT_N_XFERS, sc, &sc->sc_mtx); @@ -280,26 +280,20 @@ upgt_attach(device_t dev) if (error) goto fail3; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - goto fail4; - } - /* Initialize the device. */ error = upgt_device_reset(sc); if (error) - goto fail5; + goto fail4; /* Verify the firmware. */ error = upgt_fw_verify(sc); if (error) - goto fail5; + goto fail4; /* Calculate device memory space. */ if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) { device_printf(dev, "could not find memory space addresses on FW\n"); error = EIO; - goto fail5; + goto fail4; } sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1; sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1; @@ -316,31 +310,19 @@ upgt_attach(device_t dev) /* Load the firmware. */ error = upgt_fw_load(sc); if (error) - goto fail5; + goto fail4; /* Read the whole EEPROM content and parse it. */ error = upgt_eeprom_read(sc); if (error) - goto fail5; + goto fail4; error = upgt_eeprom_parse(sc); if (error) - goto fail5; + goto fail4; /* all works related with the device have done here. */ upgt_abort_xfers(sc); - /* Setup the 802.11 device. */ - ifp->if_softc = sc; - if_initname(ifp, "upgt", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = upgt_init; - ifp->if_ioctl = upgt_ioctl; - ifp->if_start = upgt_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - IFQ_SET_READY(&ifp->if_snd); - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -360,15 +342,16 @@ upgt_attach(device_t dev) setbit(&bands, IEEE80211_MODE_11G); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_myaddr); + ieee80211_ifattach(ic); ic->ic_raw_xmit = upgt_raw_xmit; ic->ic_scan_start = upgt_scan_start; ic->ic_scan_end = upgt_scan_end; ic->ic_set_channel = upgt_set_channel; - ic->ic_vap_create = upgt_vap_create; ic->ic_vap_delete = upgt_vap_delete; ic->ic_update_mcast = upgt_update_mcast; + ic->ic_transmit = upgt_transmit; + ic->ic_parent = upgt_parent; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -383,7 +366,6 @@ upgt_attach(device_t dev) return (0); -fail5: if_free(ifp); fail4: upgt_free_rx(sc); fail3: upgt_free_tx(sc); fail2: usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS); @@ -395,30 +377,13 @@ fail1: mtx_destroy(&sc->sc_mtx); static void upgt_txeof(struct usb_xfer *xfer, struct upgt_data *data) { - struct upgt_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; - UPGT_ASSERT_LOCKED(sc); - - /* - * Do any tx complete callback. Note this must be done before releasing - * the node reference. - */ if (data->m) { - m = data->m; - if (m->m_flags & M_TXCB) { - /* XXX status? */ - ieee80211_process_callback(data->ni, m, 0); - } - m_freem(m); + /* XXX status? */ + ieee80211_tx_complete(data->ni, data->m, 0); data->m = NULL; - } - if (data->ni) { - ieee80211_free_node(data->ni); data->ni = NULL; } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); } static void @@ -462,77 +427,43 @@ upgt_get_stats(struct upgt_softc *sc) upgt_bulk_tx(sc, data_cmd); } -static int -upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +upgt_parent(struct ieee80211com *ic) { - struct upgt_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error; + struct upgt_softc *sc = ic->ic_softc; int startall = 0; UPGT_LOCK(sc); - error = (sc->sc_flags & UPGT_FLAG_DETACHED) ? ENXIO : 0; - UPGT_UNLOCK(sc); - if (error) - return (error); - - switch (cmd) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if ((ifp->if_flags ^ sc->sc_if_flags) & - (IFF_ALLMULTI | IFF_PROMISC)) - upgt_set_multi(sc); - } else { - upgt_init(sc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - upgt_stop(sc); - } - sc->sc_if_flags = ifp->if_flags; - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; + if (sc->sc_flags & UPGT_FLAG_DETACHED) { + UPGT_UNLOCK(sc); + return; } - return error; -} - -static void -upgt_stop_locked(struct upgt_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - - UPGT_ASSERT_LOCKED(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - upgt_set_macfilter(sc, IEEE80211_S_INIT); - upgt_abort_xfers_locked(sc); + if (ic->ic_nrunning > 0) { + if (sc->sc_flags & UPGT_FLAG_INITDONE) { + if (ic->ic_allmulti > 0 || ic->ic_promisc > 0) + upgt_set_multi(sc); + } else { + upgt_init(sc); + startall = 1; + } + } else if (sc->sc_flags & UPGT_FLAG_INITDONE) + upgt_stop(sc); + UPGT_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void upgt_stop(struct upgt_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - UPGT_LOCK(sc); - upgt_stop_locked(sc); - UPGT_UNLOCK(sc); + UPGT_ASSERT_LOCKED(sc); + if (sc->sc_flags & UPGT_FLAG_INITDONE) + upgt_set_macfilter(sc, IEEE80211_S_INIT); + upgt_abort_xfers_locked(sc); /* device down */ sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); sc->sc_flags &= ~UPGT_FLAG_INITDONE; } @@ -624,36 +555,18 @@ upgt_set_led_blink(void *arg) } static void -upgt_init(void *priv) +upgt_init(struct upgt_softc *sc) { - struct upgt_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - UPGT_LOCK(sc); - upgt_init_locked(sc); - UPGT_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - -static void -upgt_init_locked(struct upgt_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; UPGT_ASSERT_LOCKED(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - upgt_stop_locked(sc); + if (sc->sc_flags & UPGT_FLAG_INITDONE) + upgt_stop(sc); usbd_transfer_start(sc->sc_xfer[UPGT_BULK_RX]); (void)upgt_set_macfilter(sc, IEEE80211_S_SCAN); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; sc->sc_flags |= UPGT_FLAG_INITDONE; callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc); @@ -662,14 +575,12 @@ upgt_init_locked(struct upgt_softc *sc) static int upgt_set_macfilter(struct upgt_softc *sc, uint8_t state) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni; struct upgt_data *data_cmd; struct upgt_lmac_mem *mem; struct upgt_lmac_filter *filter; - uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; UPGT_ASSERT_LOCKED(sc); @@ -709,10 +620,11 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state) case IEEE80211_S_SCAN: DPRINTF(sc, UPGT_DEBUG_STATE, "set MAC filter to SCAN (bssid %s)\n", - ether_sprintf(broadcast)); + ether_sprintf(ieee80211broadcastaddr)); filter->type = htole16(UPGT_FILTER_TYPE_NONE); - IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr); - IEEE80211_ADDR_COPY(filter->src, broadcast); + IEEE80211_ADDR_COPY(filter->dst, + vap ? vap->iv_myaddr : ic->ic_macaddr); + IEEE80211_ADDR_COPY(filter->src, ieee80211broadcastaddr); filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1); filter->rxaddr = htole32(sc->sc_memaddr_rx_start); filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2); @@ -724,7 +636,8 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state) /* XXX monitor mode isn't tested yet. */ if (vap->iv_opmode == IEEE80211_M_MONITOR) { filter->type = htole16(UPGT_FILTER_TYPE_MONITOR); - IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr); + IEEE80211_ADDR_COPY(filter->dst, + vap ? vap->iv_myaddr : ic->ic_macaddr); IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid); filter->unknown1 = htole16(UPGT_FILTER_MONITOR_UNKNOWN1); filter->rxaddr = htole32(sc->sc_memaddr_rx_start); @@ -736,7 +649,8 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state) "set MAC filter to RUN (bssid %s)\n", ether_sprintf(ni->ni_bssid)); filter->type = htole16(UPGT_FILTER_TYPE_STA); - IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr); + IEEE80211_ADDR_COPY(filter->dst, + vap ? vap->iv_myaddr : ic->ic_macaddr); IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid); filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1); filter->rxaddr = htole32(sc->sc_memaddr_rx_start); @@ -765,8 +679,7 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state) static void upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct upgt_softc *sc = ifp->if_softc; + struct upgt_softc *sc = ic->ic_softc; const struct ieee80211_txparam *tp; /* @@ -813,39 +726,48 @@ upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic) static void upgt_set_multi(void *arg) { - struct upgt_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - if (!(ifp->if_flags & IFF_UP)) - return; + /* XXX don't know how to set a device. Lack of docs. */ +} - /* - * XXX don't know how to set a device. Lack of docs. Just try to set - * IFF_ALLMULTI flag here. - */ - ifp->if_flags |= IFF_ALLMULTI; +static int +upgt_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct upgt_softc *sc = ic->ic_softc; + int error; + + UPGT_LOCK(sc); + if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0) { + UPGT_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + UPGT_UNLOCK(sc); + return (error); + } + upgt_start(sc); + UPGT_UNLOCK(sc); + + return (0); } static void -upgt_start(struct ifnet *ifp) +upgt_start(struct upgt_softc *sc) { - struct upgt_softc *sc = ifp->if_softc; struct upgt_data *data_tx; struct ieee80211_node *ni; struct mbuf *m; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + UPGT_ASSERT_LOCKED(sc); + + if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0) return; - UPGT_LOCK(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { data_tx = upgt_gettxbuf(sc); if (data_tx == NULL) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); + mbufq_prepend(&sc->sc_snd, m); break; } @@ -853,15 +775,15 @@ upgt_start(struct ifnet *ifp) m->m_pkthdr.rcvif = NULL; if (upgt_tx_start(sc, m, ni, data_tx) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next); UPGT_STAT_INC(sc, st_tx_inactive); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); continue; } sc->sc_tx_timer = 5; } - UPGT_UNLOCK(sc); } static int @@ -869,18 +791,18 @@ upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct upgt_softc *sc = ifp->if_softc; + struct upgt_softc *sc = ic->ic_softc; struct upgt_data *data_tx = NULL; + UPGT_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & UPGT_FLAG_INITDONE)) { m_freem(m); ieee80211_free_node(ni); + UPGT_UNLOCK(sc); return ENETDOWN; } - UPGT_LOCK(sc); data_tx = upgt_gettxbuf(sc); if (data_tx == NULL) { ieee80211_free_node(ni); @@ -893,7 +815,6 @@ upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next); UPGT_STAT_INC(sc, st_tx_inactive); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); UPGT_UNLOCK(sc); return (EIO); } @@ -907,13 +828,13 @@ static void upgt_watchdog(void *arg) { struct upgt_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; if (sc->sc_tx_timer > 0) { if (--sc->sc_tx_timer == 0) { device_printf(sc->sc_dev, "watchdog timeout\n"); - /* upgt_init(ifp); XXX needs a process context ? */ - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + /* upgt_init(sc); XXX needs a process context ? */ + counter_u64_add(ic->ic_oerrors, 1); return; } callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc); @@ -950,7 +871,7 @@ upgt_scan_end(struct ieee80211com *ic) static void upgt_set_channel(struct ieee80211com *ic) { - struct upgt_softc *sc = ic->ic_ifp->if_softc; + struct upgt_softc *sc = ic->ic_softc; UPGT_LOCK(sc); upgt_set_chan(sc, ic->ic_curchan); @@ -960,8 +881,7 @@ upgt_set_channel(struct ieee80211com *ic) static void upgt_set_chan(struct upgt_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct upgt_data *data_cmd; struct upgt_lmac_mem *mem; struct upgt_lmac_channel *chan; @@ -1044,7 +964,7 @@ upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -1059,7 +979,7 @@ upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); ic->ic_opmode = opmode; return vap; } @@ -1069,7 +989,7 @@ upgt_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct upgt_vap *uvp = UPGT_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct upgt_softc *sc = ic->ic_ifp->if_softc; + struct upgt_softc *sc = ic->ic_softc; /* do it in a process context */ sc->sc_state = nstate; @@ -1125,6 +1045,7 @@ upgt_update_mcast(struct ieee80211com *ic) static int upgt_eeprom_parse(struct upgt_softc *sc) { + struct ieee80211com *ic = &sc->sc_ic; struct upgt_eeprom_header *eeprom_header; struct upgt_eeprom_option *eeprom_option; uint16_t option_len; @@ -1169,7 +1090,8 @@ upgt_eeprom_parse(struct upgt_softc *sc) DPRINTF(sc, UPGT_DEBUG_FW, "EEPROM mac len=%d\n", option_len); - IEEE80211_ADDR_COPY(sc->sc_myaddr, eeprom_option->data); + IEEE80211_ADDR_COPY(ic->ic_macaddr, + eeprom_option->data); break; case UPGT_EEPROM_TYPE_HWRX: DPRINTF(sc, UPGT_DEBUG_FW, @@ -1518,8 +1440,7 @@ upgt_chksum_le(const uint32_t *buf, size_t size) static struct mbuf * upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct upgt_lmac_rx_desc *rxdesc; struct mbuf *m; @@ -1527,7 +1448,7 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi) * don't pass packets to the ieee80211 framework if the driver isn't * RUNNING. */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + if (!(sc->sc_flags & UPGT_FLAG_INITDONE)) return (NULL); /* access RX packet descriptor */ @@ -1545,7 +1466,6 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi) memcpy(mtod(m, char *), rxdesc->data, pkglen); /* trim FCS */ m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN; - m->m_pkthdr.rcvif = ifp; if (ieee80211_radiotap_active(ic)) { struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap; @@ -1554,7 +1474,6 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi) tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate); tap->wr_antsignal = rxdesc->rssi; } - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); DPRINTF(sc, UPGT_DEBUG_RX_PROC, "%s: RX done\n", __func__); *rssi = rxdesc->rssi; @@ -1564,8 +1483,7 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi) static uint8_t upgt_rx_rate(struct upgt_softc *sc, const int rate) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; static const uint8_t cck_upgt2rate[4] = { 2, 4, 11, 22 }; static const uint8_t ofdm_upgt2rate[12] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; @@ -1584,7 +1502,6 @@ upgt_rx_rate(struct upgt_softc *sc, const int rate) static void upgt_tx_done(struct upgt_softc *sc, uint8_t *data) { - struct ifnet *ifp = sc->sc_ifp; struct upgt_lmac_tx_done_desc *desc; int i, freed = 0; @@ -1613,10 +1530,9 @@ upgt_tx_done(struct upgt_softc *sc, uint8_t *data) } if (freed != 0) { - sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; UPGT_UNLOCK(sc); - upgt_start(ifp); + sc->sc_tx_timer = 0; + upgt_start(sc); UPGT_LOCK(sc); } } @@ -2022,8 +1938,7 @@ static int upgt_detach(device_t dev) { struct upgt_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; unsigned int x; /* @@ -2039,9 +1954,9 @@ upgt_detach(device_t dev) STAILQ_INIT(&sc->sc_rx_active); STAILQ_INIT(&sc->sc_rx_inactive); - UPGT_UNLOCK(sc); upgt_stop(sc); + UPGT_UNLOCK(sc); callout_drain(&sc->sc_led_ch); callout_drain(&sc->sc_watchdog_ch); @@ -2060,7 +1975,7 @@ upgt_detach(device_t dev) usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS); ieee80211_ifdetach(ic); - if_free(ifp); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -2168,12 +2083,8 @@ upgt_getbuf(struct upgt_softc *sc) UPGT_ASSERT_LOCKED(sc); bf = _upgt_getbuf(sc); - if (bf == NULL) { - struct ifnet *ifp = sc->sc_ifp; - + if (bf == NULL) DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: stop queue\n", __func__); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - } return (bf); } @@ -2191,14 +2102,10 @@ upgt_gettxbuf(struct upgt_softc *sc) bf->addr = upgt_mem_alloc(sc); if (bf->addr == 0) { - struct ifnet *ifp = sc->sc_ifp; - DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: no free prism memory!\n", __func__); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); UPGT_STAT_INC(sc, st_tx_inactive); - if (!(ifp->if_drv_flags & IFF_DRV_OACTIVE)) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; return (NULL); } return (bf); @@ -2212,7 +2119,6 @@ upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int error = 0, len; struct ieee80211_frame *wh; struct ieee80211_key *k; - struct ifnet *ifp = sc->sc_ifp; struct upgt_lmac_mem *mem; struct upgt_lmac_tx_desc *txdesc; @@ -2295,7 +2201,7 @@ upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni, * will stall. It's strange, but it works, so we keep reading * the statistics here. *shrug* */ - if (!(ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS) % + if (!(vap->iv_ifp->if_get_counter(vap->iv_ifp, IFCOUNTER_OPACKETS) % UPGT_TX_STAT_INTERVAL)) upgt_get_stats(sc); @@ -2306,8 +2212,7 @@ static void upgt_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct upgt_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m = NULL; @@ -2355,10 +2260,8 @@ upgt_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) (void) ieee80211_input_all(ic, m, rssi, nf); m = NULL; } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) - upgt_start(ifp); UPGT_LOCK(sc); + upgt_start(sc); break; default: /* needs it to the inactive queue due to a error. */ @@ -2369,7 +2272,7 @@ upgt_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto setup; } break; @@ -2380,7 +2283,6 @@ static void upgt_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) { struct upgt_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; struct upgt_data *data; UPGT_ASSERT_LOCKED(sc); @@ -2410,18 +2312,17 @@ upgt_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); usbd_transfer_submit(xfer); - UPGT_UNLOCK(sc); - upgt_start(ifp); - UPGT_LOCK(sc); + upgt_start(sc); break; default: data = STAILQ_FIRST(&sc->sc_tx_active); if (data == NULL) goto setup; if (data->ni != NULL) { + if_inc_counter(data->ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(data->ni); data->ni = NULL; - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); diff --git a/sys/dev/usb/wlan/if_upgtvar.h b/sys/dev/usb/wlan/if_upgtvar.h index c50276be9cb4..3dcd335aa248 100644 --- a/sys/dev/usb/wlan/if_upgtvar.h +++ b/sys/dev/usb/wlan/if_upgtvar.h @@ -418,8 +418,9 @@ struct upgt_vap { #define UPGT_VAP(vap) ((struct upgt_vap *)(vap)) struct upgt_softc { + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; - struct ifnet *sc_ifp; struct usb_device *sc_udev; void *sc_rx_dma_buf; void *sc_tx_dma_buf; @@ -429,11 +430,8 @@ struct upgt_softc { #define UPGT_FLAG_FWLOADED (1 << 0) #define UPGT_FLAG_INITDONE (1 << 1) #define UPGT_FLAG_DETACHED (1 << 2) - int sc_if_flags; int sc_debug; - uint8_t sc_myaddr[IEEE80211_ADDR_LEN]; - enum ieee80211_state sc_state; int sc_arg; int sc_led_blink; diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index 79a5be0a63f7..e8224ba3f149 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -149,8 +149,9 @@ static int ural_tx_mgt(struct ural_softc *, struct mbuf *, struct ieee80211_node *); static int ural_tx_data(struct ural_softc *, struct mbuf *, struct ieee80211_node *); -static void ural_start(struct ifnet *); -static int ural_ioctl(struct ifnet *, u_long, caddr_t); +static int ural_transmit(struct ieee80211com *, struct mbuf *); +static void ural_start(struct ural_softc *); +static void ural_parent(struct ieee80211com *); static void ural_set_testmode(struct ural_softc *); static void ural_eeprom_read(struct ural_softc *, uint16_t, void *, int); @@ -171,12 +172,12 @@ static void ural_set_chan(struct ural_softc *, static void ural_disable_rf_tune(struct ural_softc *); static void ural_enable_tsf_sync(struct ural_softc *); static void ural_enable_tsf(struct ural_softc *); -static void ural_update_slot(struct ifnet *); +static void ural_update_slot(struct ural_softc *); static void ural_set_txpreamble(struct ural_softc *); static void ural_set_basicrates(struct ural_softc *, const struct ieee80211_channel *); static void ural_set_bssid(struct ural_softc *, const uint8_t *); -static void ural_set_macaddr(struct ural_softc *, uint8_t *); +static void ural_set_macaddr(struct ural_softc *, const uint8_t *); static void ural_update_promisc(struct ieee80211com *); static void ural_setpromisc(struct ural_softc *); static const char *ural_get_rf(int); @@ -184,8 +185,7 @@ static void ural_read_eeprom(struct ural_softc *); static int ural_bbp_init(struct ural_softc *); static void ural_set_txantenna(struct ural_softc *, int); static void ural_set_rxantenna(struct ural_softc *, int); -static void ural_init_locked(struct ural_softc *); -static void ural_init(void *); +static void ural_init(struct ural_softc *); static void ural_stop(struct ural_softc *); static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); @@ -422,8 +422,7 @@ ural_attach(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); struct ural_softc *sc = device_get_softc(self); - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; uint8_t iface_index, bands; int error; @@ -433,6 +432,7 @@ ural_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); + mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = RAL_IFACE_INDEX; error = usbd_transfer_setup(uaa->device, @@ -455,24 +455,6 @@ ural_attach(device_t self) device_printf(self, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", sc->asic_rev, ural_get_rf(sc->rf_rev)); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto detach; - } - ic = ifp->if_l2com; - - ifp->if_softc = sc; - if_initname(ifp, "ural", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = ural_init; - ifp->if_ioctl = ural_ioctl; - ifp->if_start = ural_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(self); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -497,13 +479,14 @@ ural_attach(device_t self) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_update_promisc = ural_update_promisc; ic->ic_raw_xmit = ural_raw_xmit; ic->ic_scan_start = ural_scan_start; ic->ic_scan_end = ural_scan_end; ic->ic_set_channel = ural_set_channel; - + ic->ic_parent = ural_parent; + ic->ic_transmit = ural_transmit; ic->ic_vap_create = ural_vap_create; ic->ic_vap_delete = ural_vap_delete; @@ -527,8 +510,7 @@ static int ural_detach(device_t self) { struct ural_softc *sc = device_get_softc(self); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; /* prevent further ioctls */ RAL_LOCK(sc); @@ -543,11 +525,9 @@ ural_detach(device_t self) ural_unsetup_tx_list(sc); RAL_UNLOCK(sc); - if (ifp) { - ic = ifp->if_l2com; + if (ic->ic_softc == sc) ieee80211_ifdetach(ic); - if_free(ifp); - } + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -580,7 +560,7 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ural_softc *sc = ic->ic_ifp->if_softc; + struct ural_softc *sc = ic->ic_softc; struct ural_vap *uvp; struct ieee80211vap *vap; @@ -594,7 +574,7 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -610,7 +590,8 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); ic->ic_opmode = opmode; return vap; } @@ -634,13 +615,8 @@ ural_tx_free(struct ural_tx_data *data, int txerr) struct ural_softc *sc = data->sc; if (data->m != NULL) { - if (data->m->m_flags & M_TXCB) - ieee80211_process_callback(data->ni, data->m, - txerr ? ETIMEDOUT : 0); - m_freem(data->m); + ieee80211_tx_complete(data->ni, data->m, txerr); data->m = NULL; - - ieee80211_free_node(data->ni); data->ni = NULL; } STAILQ_INSERT_TAIL(&sc->tx_free, data, next); @@ -697,7 +673,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ural_vap *uvp = URAL_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct ural_softc *sc = ic->ic_ifp->if_softc; + struct ural_softc *sc = ic->ic_softc; const struct ieee80211_txparam *tp; struct ieee80211_node *ni; struct mbuf *m; @@ -731,11 +707,11 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) ieee80211_free_node(ni); return (-1); } - ural_update_slot(ic->ic_ifp); + ural_update_slot(sc); ural_set_txpreamble(sc); ural_set_basicrates(sc, ic->ic_bsschan); - IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); - ural_set_bssid(sc, sc->sc_bssid); + IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid); + ural_set_bssid(sc, ic->ic_macaddr); } if (vap->iv_opmode == IEEE80211_M_HOSTAP || @@ -789,7 +765,6 @@ static void ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) { struct ural_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap; struct ural_tx_data *data; struct mbuf *m; @@ -807,9 +782,6 @@ ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) ural_tx_free(data, 0); usbd_xfer_set_priv(xfer, NULL); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: @@ -852,16 +824,13 @@ ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) usbd_transfer_submit(xfer); } - RAL_UNLOCK(sc); - ural_start(ifp); - RAL_LOCK(sc); + ural_start(sc); break; default: /* Error */ DPRINTFN(11, "transfer error, %s\n", usbd_errstr(error)); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); data = usbd_xfer_get_priv(xfer); if (data != NULL) { ural_tx_free(data, error); @@ -883,8 +852,7 @@ static void ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) { struct ural_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; struct mbuf *m = NULL; struct usb_page_cache *pc; @@ -902,7 +870,7 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) if (len < (int)(RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN)) { DPRINTF("%s: xfer too short %d\n", device_get_nameunit(sc->sc_dev), len); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } @@ -921,20 +889,19 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) * filled RAL_TXRX_CSR2: */ DPRINTFN(5, "PHY or CRC error\n"); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (m == NULL) { DPRINTF("could not allocate mbuf\n"); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } usbd_copy_out(pc, 0, mtod(m, uint8_t *), len); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; if (ieee80211_radiotap_active(ic)) { @@ -973,10 +940,8 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) } else (void) ieee80211_input_all(ic, m, rssi, nf); } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) - ural_start(ifp); RAL_LOCK(sc); + ural_start(sc); return; default: /* Error */ @@ -1016,8 +981,7 @@ static void ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, uint32_t flags, int len, int rate) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t plcp_length; int remainder; @@ -1066,12 +1030,10 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; const struct ieee80211_txparam *tp; struct ural_tx_data *data; if (sc->tx_nfree == 0) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; m_freem(m0); ieee80211_free_node(ni); return (EIO); @@ -1348,78 +1310,73 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) return 0; } -static void -ural_start(struct ifnet *ifp) +static int +ural_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct ural_softc *sc = ic->ic_softc; + int error; + + RAL_LOCK(sc); + if (!sc->sc_running) { + RAL_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RAL_UNLOCK(sc); + return (error); + } + ural_start(sc); + RAL_UNLOCK(sc); + + return (0); +} + +static void +ural_start(struct ural_softc *sc) { - struct ural_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - RAL_LOCK(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - RAL_UNLOCK(sc); + RAL_LOCK_ASSERT(sc, MA_OWNED); + + if (sc->sc_running == 0) return; - } - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->tx_nfree < RAL_TX_MINFREE) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } + + while (sc->tx_nfree >= RAL_TX_MINFREE && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (ural_tx_data(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); break; } } - RAL_UNLOCK(sc); } -static int -ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +ural_parent(struct ieee80211com *ic) { - struct ural_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error; + struct ural_softc *sc = ic->ic_softc; int startall = 0; RAL_LOCK(sc); - error = sc->sc_detached ? ENXIO : 0; - RAL_UNLOCK(sc); - if (error) - return (error); - - switch (cmd) { - case SIOCSIFFLAGS: - RAL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - ural_init_locked(sc); - startall = 1; - } else - ural_setpromisc(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ural_stop(sc); - } + if (sc->sc_detached) { RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - default: - error = ether_ioctl(ifp, cmd, data); - break; + return; } - return error; + if (ic->ic_nrunning > 0) { + if (sc->sc_running == 0) { + ural_init(sc); + startall = 1; + } else + ural_setpromisc(sc); + } else if (sc->sc_running) + ural_stop(sc); + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -1614,23 +1571,22 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val) static void ural_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ural_softc *sc = ifp->if_softc; + struct ural_softc *sc = ic->ic_softc; RAL_LOCK(sc); ural_write(sc, RAL_TXRX_CSR19, 0); - ural_set_bssid(sc, ifp->if_broadcastaddr); + ural_set_bssid(sc, ieee80211broadcastaddr); RAL_UNLOCK(sc); } static void ural_scan_end(struct ieee80211com *ic) { - struct ural_softc *sc = ic->ic_ifp->if_softc; + struct ural_softc *sc = ic->ic_softc; RAL_LOCK(sc); ural_enable_tsf_sync(sc); - ural_set_bssid(sc, sc->sc_bssid); + ural_set_bssid(sc, ic->ic_macaddr); RAL_UNLOCK(sc); } @@ -1638,7 +1594,7 @@ ural_scan_end(struct ieee80211com *ic) static void ural_set_channel(struct ieee80211com *ic) { - struct ural_softc *sc = ic->ic_ifp->if_softc; + struct ural_softc *sc = ic->ic_softc; RAL_LOCK(sc); ural_set_chan(sc, ic->ic_curchan); @@ -1648,8 +1604,7 @@ ural_set_channel(struct ieee80211com *ic) static void ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint8_t power, tmp; int i, chan; @@ -1780,8 +1735,7 @@ ural_disable_rf_tune(struct ural_softc *sc) static void ural_enable_tsf_sync(struct ural_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t logcwmin, preload, tmp; @@ -1817,10 +1771,9 @@ ural_enable_tsf(struct ural_softc *sc) #define RAL_RXTX_TURNAROUND 5 /* us */ static void -ural_update_slot(struct ifnet *ifp) +ural_update_slot(struct ural_softc *sc) { - struct ural_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t slottime, sifs, eifs; slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; @@ -1845,8 +1798,7 @@ ural_update_slot(struct ifnet *ifp) static void ural_set_txpreamble(struct ural_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t tmp; tmp = ural_read(sc, RAL_TXRX_CSR10); @@ -1893,7 +1845,7 @@ ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid) } static void -ural_set_macaddr(struct ural_softc *sc, uint8_t *addr) +ural_set_macaddr(struct ural_softc *sc, const uint8_t *addr) { uint16_t tmp; @@ -1912,18 +1864,17 @@ ural_set_macaddr(struct ural_softc *sc, uint8_t *addr) static void ural_setpromisc(struct ural_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; tmp = ural_read(sc, RAL_TXRX_CSR2); tmp &= ~RAL_DROP_NOT_TO_ME; - if (!(ifp->if_flags & IFF_PROMISC)) + if (sc->sc_ic.ic_promisc == 0) tmp |= RAL_DROP_NOT_TO_ME; ural_write(sc, RAL_TXRX_CSR2, tmp); - DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? + DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc ? "entering" : "leaving"); } @@ -1932,11 +1883,9 @@ ural_update_promisc(struct ieee80211com *ic) { struct ural_softc *sc = ic->ic_softc; - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; - RAL_LOCK(sc); - ural_setpromisc(sc); + if (sc->sc_running) + ural_setpromisc(sc); RAL_UNLOCK(sc); } @@ -1958,6 +1907,7 @@ ural_get_rf(int rev) static void ural_read_eeprom(struct ural_softc *sc) { + struct ieee80211com *ic = &sc->sc_ic; uint16_t val; ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2); @@ -1970,7 +1920,7 @@ ural_read_eeprom(struct ural_softc *sc) sc->nb_ant = val & 0x3; /* read MAC address */ - ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, sc->sc_bssid, 6); + ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, ic->ic_macaddr, 6); /* read default values for BBP registers */ ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16); @@ -2064,11 +2014,11 @@ ural_set_rxantenna(struct ural_softc *sc, int antenna) } static void -ural_init_locked(struct ural_softc *sc) +ural_init(struct ural_softc *sc) { #define N(a) ((int)(sizeof (a) / sizeof ((a)[0]))) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t tmp; int i, ntries; @@ -2115,7 +2065,7 @@ ural_init_locked(struct ural_softc *sc) ural_set_txantenna(sc, sc->tx_ant); ural_set_rxantenna(sc, sc->rx_ant); - ural_set_macaddr(sc, IF_LLADDR(ifp)); + ural_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* * Allocate Tx and Rx xfer queues. @@ -2128,13 +2078,12 @@ ural_init_locked(struct ural_softc *sc) tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION; if (ic->ic_opmode != IEEE80211_M_HOSTAP) tmp |= RAL_DROP_TODS; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RAL_DROP_NOT_TO_ME; } ural_write(sc, RAL_TXRX_CSR2, tmp); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_running = 1; usbd_xfer_set_stall(sc->sc_xfer[URAL_BULK_WR]); usbd_transfer_start(sc->sc_xfer[URAL_BULK_RD]); return; @@ -2143,29 +2092,13 @@ fail: ural_stop(sc); #undef N } -static void -ural_init(void *priv) -{ - struct ural_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - RAL_LOCK(sc); - ural_init_locked(sc); - RAL_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - static void ural_stop(struct ural_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc, MA_OWNED); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_running = 0; /* * Drain all the transfers, if not already drained: @@ -2193,27 +2126,23 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ural_softc *sc = ifp->if_softc; + struct ural_softc *sc = ic->ic_softc; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!sc->sc_running) { RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENETDOWN; } if (sc->tx_nfree < RAL_TX_MINFREE) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return EIO; } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - if (params == NULL) { /* * Legacy path; interpret frame contents to decide @@ -2232,7 +2161,6 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, RAL_UNLOCK(sc); return 0; bad: - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); RAL_UNLOCK(sc); ieee80211_free_node(ni); return EIO; /* XXX */ @@ -2266,8 +2194,7 @@ ural_ratectl_task(void *arg, int pending) struct ural_vap *uvp = arg; struct ieee80211vap *vap = &uvp->vap; struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ural_softc *sc = ifp->if_softc; + struct ural_softc *sc = ic->ic_softc; struct ieee80211_node *ni; int ok, fail; int sum, retrycnt; @@ -2286,7 +2213,8 @@ ural_ratectl_task(void *arg, int pending) ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt); (void) ieee80211_ratectl_rate(ni, NULL, 0); - if_inc_counter(ifp, IFCOUNTER_OERRORS, fail); /* count TX retry-fail as Tx errors */ + /* count TX retry-fail as Tx errors */ + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, fail); usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp); RAL_UNLOCK(sc); diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h index c62b0e449680..f40f71d9de08 100644 --- a/sys/dev/usb/wlan/if_uralvar.h +++ b/sys/dev/usb/wlan/if_uralvar.h @@ -89,7 +89,8 @@ enum { }; struct ural_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct usb_device *sc_udev; @@ -109,8 +110,8 @@ struct ural_softc { uint16_t sta[11]; uint32_t rf_regs[4]; uint8_t txpow[14]; - uint8_t sc_bssid[6]; - uint8_t sc_detached; + u_int sc_detached:1, + sc_running:1; struct { uint8_t val; diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c index f8b77d427521..f0d2674e56e7 100644 --- a/sys/dev/usb/wlan/if_urtw.c +++ b/sys/dev/usb/wlan/if_urtw.c @@ -651,11 +651,11 @@ static struct ieee80211vap *urtw_vap_create(struct ieee80211com *, int, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void urtw_vap_delete(struct ieee80211vap *); -static void urtw_init(void *); -static void urtw_stop(struct ifnet *); -static void urtw_stop_locked(struct ifnet *); -static int urtw_ioctl(struct ifnet *, u_long, caddr_t); -static void urtw_start(struct ifnet *); +static void urtw_init(struct urtw_softc *); +static void urtw_stop(struct urtw_softc *); +static void urtw_parent(struct ieee80211com *); +static int urtw_transmit(struct ieee80211com *, struct mbuf *); +static void urtw_start(struct urtw_softc *); static int urtw_alloc_rx_data_list(struct urtw_softc *); static int urtw_alloc_tx_data_list(struct urtw_softc *); static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *, @@ -784,8 +784,7 @@ urtw_attach(device_t dev) int ret = ENXIO; struct urtw_softc *sc = device_get_softc(dev); struct usb_attach_arg *uaa = device_get_ivars(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint8_t bands, iface_index = URTW_IFACE_INDEX; /* XXX */ uint16_t n_setup; uint32_t data; @@ -807,6 +806,7 @@ urtw_attach(device_t dev) TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc); TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc); callout_init(&sc->sc_watchdog_ch, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); if (sc->sc_flags & URTW_RTL8187B) { setup_start = urtw_8187b_usbconfig; @@ -861,26 +861,6 @@ urtw_attach(device_t dev) sc->sc_currate = 3; sc->sc_preamble_mode = urtw_preamble_mode; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not allocate ifnet\n"); - ret = ENOMEM; - goto fail1; - } - - ifp->if_softc = sc; - if_initname(ifp, "urtw", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = urtw_init; - ifp->if_ioctl = urtw_ioctl; - ifp->if_start = urtw_start; - /* XXX URTW_TX_DATA_LIST_COUNT */ - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -901,7 +881,7 @@ urtw_attach(device_t dev) setbit(&bands, IEEE80211_MODE_11G); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_raw_xmit = urtw_raw_xmit; ic->ic_scan_start = urtw_scan_start; ic->ic_scan_end = urtw_scan_end; @@ -910,6 +890,8 @@ urtw_attach(device_t dev) ic->ic_vap_create = urtw_vap_create; ic->ic_vap_delete = urtw_vap_delete; ic->ic_update_mcast = urtw_update_mcast; + ic->ic_parent = urtw_parent; + ic->ic_transmit = urtw_transmit; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -923,8 +905,9 @@ urtw_attach(device_t dev) ieee80211_announce(ic); return (0); -fail: URTW_UNLOCK(sc); -fail1: usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ? +fail: + URTW_UNLOCK(sc); + usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ? URTW_8187B_N_XFERS : URTW_8187L_N_XFERS); fail0: return (ret); @@ -934,18 +917,16 @@ static int urtw_detach(device_t dev) { struct urtw_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; unsigned int x; unsigned int n_xfers; /* Prevent further ioctls */ URTW_LOCK(sc); sc->sc_flags |= URTW_DETACHED; + urtw_stop(sc); URTW_UNLOCK(sc); - urtw_stop(ifp); - ieee80211_draintask(ic, &sc->sc_updateslot_task); ieee80211_draintask(ic, &sc->sc_led_task); @@ -979,7 +960,7 @@ urtw_detach(device_t dev) usbd_transfer_unsetup(sc->sc_xfer, n_xfers); ieee80211_ifdetach(ic); - if_free(ifp); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); } @@ -1032,15 +1013,12 @@ urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return (NULL); - uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return (NULL); + uvp = malloc(sizeof(struct urtw_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &uvp->vap; /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -1052,7 +1030,7 @@ urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); ic->ic_opmode = opmode; return (vap); } @@ -1067,15 +1045,15 @@ urtw_vap_delete(struct ieee80211vap *vap) } static void -urtw_init_locked(void *arg) +urtw_init(struct urtw_softc *sc) { - int ret; - struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; usb_error_t error; + int ret; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - urtw_stop_locked(ifp); + URTW_ASSERT_LOCKED(sc); + + if (sc->sc_flags & URTW_RUNNING) + urtw_stop(sc); error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) : urtw_adapter_start(sc); @@ -1105,24 +1083,13 @@ urtw_init_locked(void *arg) if (sc->sc_flags & URTW_RTL8187B) usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= URTW_RUNNING; callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); fail: return; } -static void -urtw_init(void *arg) -{ - struct urtw_softc *sc = arg; - - URTW_LOCK(sc); - urtw_init_locked(arg); - URTW_UNLOCK(sc); -} - static usb_error_t urtw_adapter_start_b(struct urtw_softc *sc) { @@ -1215,6 +1182,7 @@ urtw_adapter_start_b(struct urtw_softc *sc) static usb_error_t urtw_adapter_start(struct urtw_softc *sc) { + struct ieee80211com *ic = &sc->sc_ic; usb_error_t error; error = urtw_reset(sc); @@ -1234,8 +1202,8 @@ urtw_adapter_start(struct urtw_softc *sc) if (error) goto fail; /* applying MAC address again. */ - urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]); - urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff); + urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]); + urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff); error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL); if (error) goto fail; @@ -1338,13 +1306,14 @@ urtw_do_request(struct urtw_softc *sc, } static void -urtw_stop_locked(struct ifnet *ifp) +urtw_stop(struct urtw_softc *sc) { - struct urtw_softc *sc = ifp->if_softc; uint8_t data8; usb_error_t error; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + URTW_ASSERT_LOCKED(sc); + + sc->sc_flags &= ~URTW_RUNNING; error = urtw_intr_disable(sc); if (error) @@ -1376,16 +1345,6 @@ urtw_stop_locked(struct ifnet *ifp) urtw_abort_xfers(sc); } -static void -urtw_stop(struct ifnet *ifp) -{ - struct urtw_softc *sc = ifp->if_softc; - - URTW_LOCK(sc); - urtw_stop_locked(ifp); - URTW_UNLOCK(sc); -} - static void urtw_abort_xfers(struct urtw_softc *sc) { @@ -1401,72 +1360,71 @@ urtw_abort_xfers(struct urtw_softc *sc) usbd_transfer_stop(sc->sc_xfer[i]); } -static int -urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +urtw_parent(struct ieee80211com *ic) { - struct urtw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error; + struct urtw_softc *sc = ic->ic_softc; int startall = 0; URTW_LOCK(sc); - error = (sc->sc_flags & URTW_DETACHED) ? ENXIO : 0; - URTW_UNLOCK(sc); - if (error) - return (error); - - switch (cmd) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if ((ifp->if_flags ^ sc->sc_if_flags) & - (IFF_ALLMULTI | IFF_PROMISC)) - urtw_set_multi(sc); - } else { - urtw_init(ifp->if_softc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - urtw_stop(ifp); - } - sc->sc_if_flags = ifp->if_flags; - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; + if (sc->sc_flags & URTW_DETACHED) { + URTW_UNLOCK(sc); + return; } - return (error); + + if (ic->ic_nrunning > 0) { + if (sc->sc_flags & URTW_RUNNING) { + if (ic->ic_promisc > 0 || ic->ic_allmulti > 0) + urtw_set_multi(sc); + } else { + urtw_init(sc); + startall = 1; + } + } else if (sc->sc_flags & URTW_RUNNING) + urtw_stop(sc); + URTW_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); +} + +static int +urtw_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct urtw_softc *sc = ic->ic_softc; + int error; + + URTW_LOCK(sc); + if ((sc->sc_flags & URTW_RUNNING) == 0) { + URTW_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + URTW_UNLOCK(sc); + return (error); + } + urtw_start(sc); + URTW_UNLOCK(sc); + + return (0); } static void -urtw_start(struct ifnet *ifp) +urtw_start(struct urtw_softc *sc) { struct urtw_data *bf; - struct urtw_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + URTW_ASSERT_LOCKED(sc); + + if ((sc->sc_flags & URTW_RUNNING) == 0) return; - URTW_LOCK(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { bf = urtw_getbuf(sc); if (bf == NULL) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); + mbufq_prepend(&sc->sc_snd, m); break; } @@ -1474,7 +1432,8 @@ urtw_start(struct ifnet *ifp) m->m_pkthdr.rcvif = NULL; if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); ieee80211_free_node(ni); break; @@ -1483,7 +1442,6 @@ urtw_start(struct ifnet *ifp) sc->sc_txtimer = 5; callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); } - URTW_UNLOCK(sc); } static int @@ -1565,12 +1523,11 @@ urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; + struct urtw_softc *sc = ic->ic_softc; struct urtw_data *bf; - struct urtw_softc *sc = ifp->if_softc; /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & URTW_RUNNING)) { m_freem(m); ieee80211_free_node(ni); return ENETDOWN; @@ -1584,10 +1541,8 @@ urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return (ENOBUFS); /* XXX */ } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); URTW_UNLOCK(sc); return (EIO); @@ -1615,8 +1570,7 @@ urtw_scan_end(struct ieee80211com *ic) static void urtw_set_channel(struct ieee80211com *ic) { - struct urtw_softc *sc = ic->ic_ifp->if_softc; - struct ifnet *ifp = sc->sc_ifp; + struct urtw_softc *sc = ic->ic_softc; uint32_t data, orig; usb_error_t error; @@ -1626,7 +1580,7 @@ urtw_set_channel(struct ieee80211com *ic) * initialization would be failed if setting a channel is called before * the init have done. */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + if (!(sc->sc_flags & URTW_RUNNING)) return; if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan) @@ -1673,11 +1627,10 @@ static int urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, struct urtw_data *data, int prior) { - struct ifnet *ifp = sc->sc_ifp; struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *); struct ieee80211_key *k; const struct ieee80211_txparam *tp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = { sc->sc_xfer[URTW_8187B_BULK_TX_BE], @@ -1862,7 +1815,7 @@ static int urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; - struct urtw_softc *sc = ic->ic_ifp->if_softc; + struct urtw_softc *sc = ic->ic_softc; struct urtw_vap *uvp = URTW_VAP(vap); struct ieee80211_node *ni; usb_error_t error = 0; @@ -1915,12 +1868,11 @@ static void urtw_watchdog(void *arg) { struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; if (sc->sc_txtimer > 0) { if (--sc->sc_txtimer == 0) { device_printf(sc->sc_dev, "device timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); return; } callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc); @@ -1930,17 +1882,7 @@ urtw_watchdog(void *arg) static void urtw_set_multi(void *arg) { - struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - - if (!(ifp->if_flags & IFF_UP)) - return; - - /* - * XXX don't know how to set a device. Lack of docs. Just try to set - * IFF_ALLMULTI flag here. - */ - ifp->if_flags |= IFF_ALLMULTI; + /* XXX don't know how to set a device. Lack of docs. */ } static usb_error_t @@ -2002,8 +1944,7 @@ urtw_rtl2rate(uint32_t rate) static usb_error_t urtw_update_msr(struct urtw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint8_t data; usb_error_t error; @@ -2144,24 +2085,25 @@ urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data) static usb_error_t urtw_get_macaddr(struct urtw_softc *sc) { + struct ieee80211com *ic = &sc->sc_ic; uint32_t data; usb_error_t error; error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data); if (error != 0) goto fail; - sc->sc_bssid[0] = data & 0xff; - sc->sc_bssid[1] = (data & 0xff00) >> 8; + ic->ic_macaddr[0] = data & 0xff; + ic->ic_macaddr[1] = (data & 0xff00) >> 8; error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data); if (error != 0) goto fail; - sc->sc_bssid[2] = data & 0xff; - sc->sc_bssid[3] = (data & 0xff00) >> 8; + ic->ic_macaddr[2] = data & 0xff; + ic->ic_macaddr[3] = (data & 0xff00) >> 8; error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data); if (error != 0) goto fail; - sc->sc_bssid[4] = data & 0xff; - sc->sc_bssid[5] = (data & 0xff00) >> 8; + ic->ic_macaddr[4] = data & 0xff; + ic->ic_macaddr[5] = (data & 0xff00) >> 8; fail: return (error); } @@ -3233,7 +3175,7 @@ urtw_8225_isv2(struct urtw_softc *sc, int *ret) static usb_error_t urtw_8225v2b_rf_init(struct urtw_softc *sc) { -#define N(a) ((int)(sizeof(a) / sizeof((a)[0]))) + struct ieee80211com *ic = &sc->sc_ic; int i; uint8_t data8; usb_error_t error; @@ -3281,8 +3223,8 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) urtw_write8_m(sc, URTW_CONFIG1, data8); /* applying MAC address again. */ - urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]); - urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff); + urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]); + urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff); error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL); if (error) @@ -3293,7 +3235,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) /* * MAC configuration */ - for (i = 0; i < N(urtw_8225v2b_rf_part1); i++) + for (i = 0; i < nitems(urtw_8225v2b_rf_part1); i++) urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg, urtw_8225v2b_rf_part1[i].val); urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50); @@ -3326,7 +3268,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff); usb_pause_mtx(&sc->sc_mtx, 1100); - for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) { + for (i = 0; i < nitems(urtw_8225v2b_rf_part0); i++) { urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg, urtw_8225v2b_rf_part0[i].val); usb_pause_mtx(&sc->sc_mtx, 1); @@ -3372,7 +3314,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc) } urtw_8187_write_phy_ofdm(sc, 0x80, 0x10); - for (i = 0; i < N(urtw_8225v2b_rf_part2); i++) + for (i = 0; i < nitems(urtw_8225v2b_rf_part2); i++) urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val); urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c); @@ -3787,8 +3729,7 @@ static void urtw_led_ch(void *arg) { struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; ieee80211_runtask(ic, &sc->sc_led_task); } @@ -3935,8 +3876,7 @@ urtw_tx_enable(struct urtw_softc *sc) static usb_error_t urtw_rx_setconf(struct urtw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t data; usb_error_t error; @@ -3961,7 +3901,7 @@ urtw_rx_setconf(struct urtw_softc *sc) data = data | URTW_RX_FILTER_CRCERR; if (ic->ic_opmode == IEEE80211_M_MONITOR || - (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) { + ic->ic_promisc > 0 || ic->ic_allmulti > 0) { data = data | URTW_RX_FILTER_ALLMAC; } else { data = data | URTW_RX_FILTER_NICMAC; @@ -3988,14 +3928,13 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, struct ieee80211_frame *wh; struct mbuf *m, *mnew; struct urtw_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint8_t noise = 0, rate; usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); if (actlen < (int)URTW_MIN_RXBUFSZ) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -4006,7 +3945,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, (actlen - (sizeof(struct urtw_8187b_rxhdr)))); flen = le32toh(rx->flag) & 0xfff; if (flen > actlen) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf; @@ -4020,7 +3959,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, (actlen - (sizeof(struct urtw_8187l_rxhdr)))); flen = le32toh(rx->flag) & 0xfff; if (flen > actlen) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -4032,7 +3971,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -4041,7 +3980,6 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p, data->buf = mtod(mnew, uint8_t *); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN; if (ieee80211_radiotap_active(ic)) { @@ -4067,8 +4005,7 @@ static void urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m = NULL; @@ -4129,7 +4066,7 @@ urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto setup; } break; @@ -4143,7 +4080,7 @@ static void urtw_txstatus_eof(struct usb_xfer *xfer) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; int actlen, type, pktretry, seq; uint64_t val; @@ -4158,7 +4095,7 @@ urtw_txstatus_eof(struct usb_xfer *xfer) pktretry = val & 0xff; seq = (val >> 16) & 0xff; if (pktretry == URTW_TX_MAXRETRY) - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(ic->ic_oerrors, 1); DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n", pktretry, seq); } @@ -4168,7 +4105,7 @@ static void urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0); URTW_ASSERT_LOCKED(sc); @@ -4186,7 +4123,7 @@ urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error) default: if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto setup; } break; @@ -4197,38 +4134,22 @@ static void urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; URTW_ASSERT_LOCKED(sc); - /* - * Do any tx complete callback. Note this must be done before releasing - * the node reference. - */ if (data->m) { - m = data->m; - if (m->m_flags & M_TXCB) { - /* XXX status? */ - ieee80211_process_callback(data->ni, m, 0); - } - m_freem(m); + /* XXX status? */ + ieee80211_tx_complete(data->ni, data->m, 0); data->m = NULL; - } - if (data->ni) { - ieee80211_free_node(data->ni); data->ni = NULL; } sc->sc_txtimer = 0; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtw_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; struct urtw_data *data; URTW_ASSERT_LOCKED(sc); @@ -4256,18 +4177,17 @@ urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); usbd_transfer_submit(xfer); - URTW_UNLOCK(sc); - urtw_start(ifp); - URTW_LOCK(sc); + urtw_start(sc); break; default: data = STAILQ_FIRST(&sc->sc_tx_active); if (data == NULL) goto setup; if (data->ni != NULL) { + if_inc_counter(data->ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(data->ni); data->ni = NULL; - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); @@ -4301,12 +4221,8 @@ urtw_getbuf(struct urtw_softc *sc) URTW_ASSERT_LOCKED(sc); bf = _urtw_getbuf(sc); - if (bf == NULL) { - struct ifnet *ifp = sc->sc_ifp; - + if (bf == NULL) DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - } return (bf); } @@ -4378,14 +4294,14 @@ static void urtw_updateslottask(void *arg, int pending) { struct urtw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int error; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; - URTW_LOCK(sc); + if ((sc->sc_flags & URTW_RUNNING) == 0) { + URTW_UNLOCK(sc); + return; + } if (sc->sc_flags & URTW_RTL8187B) { urtw_write8_m(sc, URTW_SIFS, 0x22); if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c index 6b712b3dbcb6..457a88526516 100644 --- a/sys/dev/usb/wlan/if_urtwn.c +++ b/sys/dev/usb/wlan/if_urtwn.c @@ -169,8 +169,8 @@ static device_detach_t urtwn_detach; static usb_callback_t urtwn_bulk_tx_callback; static usb_callback_t urtwn_bulk_rx_callback; -static usb_error_t urtwn_do_request(struct urtwn_softc *sc, - struct usb_device_request *req, void *data); +static usb_error_t urtwn_do_request(struct urtwn_softc *, + struct usb_device_request *, void *); static struct ieee80211vap *urtwn_vap_create(struct ieee80211com *, const char [IFNAMSIZ], int, enum ieee80211_opmode, int, const uint8_t [IEEE80211_ADDR_LEN], @@ -228,10 +228,9 @@ static int8_t urtwn_r88e_get_rssi(struct urtwn_softc *, int, void *); static int urtwn_tx_start(struct urtwn_softc *, struct ieee80211_node *, struct mbuf *, struct urtwn_data *); -static void urtwn_start(struct ifnet *); -static void urtwn_start_locked(struct ifnet *, - struct urtwn_softc *); -static int urtwn_ioctl(struct ifnet *, u_long, caddr_t); +static int urtwn_transmit(struct ieee80211com *, struct mbuf *); +static void urtwn_start(struct urtwn_softc *); +static void urtwn_parent(struct ieee80211com *); static int urtwn_r92c_power_on(struct urtwn_softc *); static int urtwn_r88e_power_on(struct urtwn_softc *); static int urtwn_llt_init(struct urtwn_softc *); @@ -269,10 +268,8 @@ static void urtwn_set_chan(struct urtwn_softc *, static void urtwn_update_mcast(struct ieee80211com *); static void urtwn_iq_calib(struct urtwn_softc *); static void urtwn_lc_calib(struct urtwn_softc *); -static void urtwn_init(void *); -static void urtwn_init_locked(void *); -static void urtwn_stop(struct ifnet *); -static void urtwn_stop_locked(struct ifnet *); +static void urtwn_init(struct urtwn_softc *); +static void urtwn_stop(struct urtwn_softc *); static void urtwn_abort_xfers(struct urtwn_softc *); static int urtwn_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); @@ -368,8 +365,7 @@ urtwn_attach(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); struct urtwn_softc *sc = device_get_softc(self); - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; uint8_t iface_index, bands; int error; @@ -382,6 +378,7 @@ urtwn_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); callout_init(&sc->sc_watchdog_ch, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = URTWN_IFACE_INDEX; error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, @@ -424,24 +421,6 @@ urtwn_attach(device_t self) URTWN_UNLOCK(sc); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto detach; - } - ic = ifp->if_l2com; - - ifp->if_softc = sc; - if_initname(ifp, "urtwn", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = urtwn_init; - ifp->if_ioctl = urtwn_ioctl; - ifp->if_start = urtwn_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(self); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -462,12 +441,13 @@ urtwn_attach(device_t self) setbit(&bands, IEEE80211_MODE_11G); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_raw_xmit = urtwn_raw_xmit; ic->ic_scan_start = urtwn_scan_start; ic->ic_scan_end = urtwn_scan_end; ic->ic_set_channel = urtwn_set_channel; - + ic->ic_transmit = urtwn_transmit; + ic->ic_parent = urtwn_parent; ic->ic_vap_create = urtwn_vap_create; ic->ic_vap_delete = urtwn_vap_delete; ic->ic_update_mcast = urtwn_update_mcast; @@ -491,17 +471,15 @@ static int urtwn_detach(device_t self) { struct urtwn_softc *sc = device_get_softc(self); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; unsigned int x; /* Prevent further ioctls. */ URTWN_LOCK(sc); sc->sc_flags |= URTWN_DETACHED; + urtwn_stop(sc); URTWN_UNLOCK(sc); - urtwn_stop(ifp); - callout_drain(&sc->sc_watchdog_ch); /* Prevent further allocations from RX/TX data lists. */ @@ -527,8 +505,7 @@ urtwn_detach(device_t self) /* stop all USB transfers */ usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER); ieee80211_ifdetach(ic); - - if_free(ifp); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -599,15 +576,12 @@ urtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return (NULL); - uvp = (struct urtwn_vap *) malloc(sizeof(struct urtwn_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return (NULL); + uvp = malloc(sizeof(struct urtwn_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &uvp->vap; /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { /* out of memory */ free(uvp, M_80211_VAP); return (NULL); @@ -619,7 +593,7 @@ urtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); ic->ic_opmode = opmode; return (vap); } @@ -636,8 +610,7 @@ urtwn_vap_delete(struct ieee80211vap *vap) static struct mbuf * urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct mbuf *m; struct r92c_rx_stat *stat; @@ -650,7 +623,7 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p) * don't pass packets to the ieee80211 framework if the driver isn't * RUNNING. */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + if (!(sc->sc_flags & URTWN_RUNNING)) return (NULL); stat = (struct r92c_rx_stat *)buf; @@ -662,11 +635,11 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p) * This should not happen since we setup our Rx filter * to not receive these frames. */ - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } if (pktlen < sizeof(*wh) || pktlen > MCLBYTES) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -695,7 +668,6 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p) } /* Finalize mbuf. */ - m->m_pkthdr.rcvif = ifp; wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz); memcpy(mtod(m, uint8_t *), wh, pktlen); m->m_pkthdr.len = m->m_len = pktlen; @@ -741,7 +713,7 @@ urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi, int8_t *nf) { struct urtwn_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; struct r92c_rx_stat *stat; struct mbuf *m, *m0 = NULL, *prevm = NULL; uint32_t rxdw0; @@ -751,7 +723,7 @@ urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi, usbd_xfer_status(xfer, &len, NULL, NULL, NULL); if (len < sizeof(*stat)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return (NULL); } @@ -802,8 +774,7 @@ static void urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtwn_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m = NULL, *next; @@ -866,7 +837,7 @@ urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto tr_setup; } break; @@ -877,38 +848,19 @@ static void urtwn_txeof(struct usb_xfer *xfer, struct urtwn_data *data) { struct urtwn_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct mbuf *m; URTWN_ASSERT_LOCKED(sc); - - /* - * Do any tx complete callback. Note this must be done before releasing - * the node reference. - */ - if (data->m) { - m = data->m; - if (m->m_flags & M_TXCB) { - /* XXX status? */ - ieee80211_process_callback(data->ni, m, 0); - } - m_freem(m); - data->m = NULL; - } - if (data->ni) { - ieee80211_free_node(data->ni); - data->ni = NULL; - } + /* XXX status? */ + ieee80211_tx_complete(data->ni, data->m, 0); + data->ni = NULL; + data->m = NULL; sc->sc_txtimer = 0; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) { struct urtwn_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; struct urtwn_data *data; URTWN_ASSERT_LOCKED(sc); @@ -933,16 +885,17 @@ urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next); usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); usbd_transfer_submit(xfer); - urtwn_start_locked(ifp, sc); + urtwn_start(sc); break; default: data = STAILQ_FIRST(&sc->sc_tx_active); if (data == NULL) goto tr_setup; if (data->ni != NULL) { + if_inc_counter(data->ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(data->ni); data->ni = NULL; - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); } if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); @@ -975,11 +928,8 @@ urtwn_getbuf(struct urtwn_softc *sc) URTWN_ASSERT_LOCKED(sc); bf = _urtwn_getbuf(sc); - if (bf == NULL) { - struct ifnet *ifp = sc->sc_ifp; + if (bf == NULL) DPRINTF("%s: stop queue\n", __func__); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - } return (bf); } @@ -1302,7 +1252,7 @@ urtwn_read_rom(struct urtwn_softc *sc) sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY); DPRINTF("regulatory type=%d\n", sc->regulatory); - IEEE80211_ADDR_COPY(sc->sc_bssid, rom->macaddr); + IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr); sc->sc_rf_write = urtwn_r92c_rf_write; sc->sc_power_on = urtwn_r92c_power_on; @@ -1363,7 +1313,7 @@ urtwn_r88e_read_rom(struct urtwn_softc *sc) if (sc->ofdm_tx_pwr_diff & 0x08) sc->ofdm_tx_pwr_diff |= 0xf0; sc->regulatory = MS(sc->r88e_rom[0xc1], R92C_ROM_RF1_REGULATORY); - IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->r88e_rom[0xd7]); + IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, &sc->r88e_rom[0xd7]); sc->sc_rf_write = urtwn_r88e_rf_write; sc->sc_power_on = urtwn_r88e_power_on; @@ -1378,7 +1328,7 @@ urtwn_ra_init(struct urtwn_softc *sc) { static const uint8_t map[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni; struct ieee80211_rateset *rs; @@ -1455,8 +1405,7 @@ urtwn_ra_init(struct urtwn_softc *sc) void urtwn_tsf_sync_enable(struct urtwn_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni = vap->iv_bss; @@ -1513,7 +1462,7 @@ urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct urtwn_vap *uvp = URTWN_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct urtwn_softc *sc = ic->ic_ifp->if_softc; + struct urtwn_softc *sc = ic->ic_softc; struct ieee80211_node *ni; enum ieee80211_state ostate; uint32_t reg; @@ -1669,12 +1618,11 @@ static void urtwn_watchdog(void *arg) { struct urtwn_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; if (sc->sc_txtimer > 0) { if (--sc->sc_txtimer == 0) { device_printf(sc->sc_dev, "device timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); return; } callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc); @@ -1800,10 +1748,9 @@ static int urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, struct urtwn_data *data) { - struct ifnet *ifp = sc->sc_ifp; struct ieee80211_frame *wh; struct ieee80211_key *k; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct usb_xfer *xfer; struct r92c_tx_desc *txd; @@ -1942,89 +1889,78 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni, return (0); } -static void -urtwn_start(struct ifnet *ifp) +static int +urtwn_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct urtwn_softc *sc = ifp->if_softc; + struct urtwn_softc *sc = ic->ic_softc; + int error; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; URTWN_LOCK(sc); - urtwn_start_locked(ifp, sc); + if ((sc->sc_flags & URTWN_RUNNING) == 0) { + URTWN_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + URTWN_UNLOCK(sc); + return (error); + } + urtwn_start(sc); URTWN_UNLOCK(sc); + + return (0); } static void -urtwn_start_locked(struct ifnet *ifp, struct urtwn_softc *sc) +urtwn_start(struct urtwn_softc *sc) { struct ieee80211_node *ni; struct mbuf *m; struct urtwn_data *bf; URTWN_ASSERT_LOCKED(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { bf = urtwn_getbuf(sc); if (bf == NULL) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); + mbufq_prepend(&sc->sc_snd, m); break; } ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; m->m_pkthdr.rcvif = NULL; - if (urtwn_tx_start(sc, ni, m, bf) != 0) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); ieee80211_free_node(ni); break; } - sc->sc_txtimer = 5; callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc); } } -static int -urtwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +urtwn_parent(struct ieee80211com *ic) { - struct urtwn_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct urtwn_softc *sc = ic->ic_softc; + int startall = 0; URTWN_LOCK(sc); - error = (sc->sc_flags & URTWN_DETACHED) ? ENXIO : 0; - URTWN_UNLOCK(sc); - if (error != 0) - return (error); - - switch (cmd) { - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - urtwn_init(ifp->if_softc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - urtwn_stop(ifp); - } - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; + if (sc->sc_flags & URTWN_DETACHED) { + URTWN_UNLOCK(sc); + return; } - return (error); + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & URTWN_RUNNING) == 0) { + urtwn_init(sc); + startall = 1; + } + } else if (sc->sc_flags & URTWN_RUNNING) + urtwn_stop(sc); + URTWN_UNLOCK(sc); + + if (startall) + ieee80211_start_all(ic); } static int @@ -2938,7 +2874,7 @@ urtwn_get_txpower(struct urtwn_softc *sc, int chain, struct ieee80211_channel *c, struct ieee80211_channel *extc, uint16_t power[URTWN_RIDX_COUNT]) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct r92c_rom *rom = &sc->rom; uint16_t cckpow, ofdmpow, htpow, diff, max; const struct urtwn_txpwr *base; @@ -3037,7 +2973,7 @@ urtwn_r88e_get_txpower(struct urtwn_softc *sc, int chain, struct ieee80211_channel *c, struct ieee80211_channel *extc, uint16_t power[URTWN_RIDX_COUNT]) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t cckpow, ofdmpow, bw20pow, htpow; const struct urtwn_r88e_txpwr *base; int ridx, chan, group; @@ -3134,7 +3070,7 @@ urtwn_scan_end(struct ieee80211com *ic) static void urtwn_set_channel(struct ieee80211com *ic) { - struct urtwn_softc *sc = ic->ic_ifp->if_softc; + struct urtwn_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); URTWN_LOCK(sc); @@ -3156,7 +3092,7 @@ static void urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c, struct ieee80211_channel *extc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t reg; u_int chan; int i; @@ -3287,17 +3223,18 @@ urtwn_lc_calib(struct urtwn_softc *sc) } static void -urtwn_init_locked(void *arg) +urtwn_init(struct urtwn_softc *sc) { - struct urtwn_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + uint8_t macaddr[IEEE80211_ADDR_LEN]; uint32_t reg; int error; URTWN_ASSERT_LOCKED(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - urtwn_stop_locked(ifp); + if (sc->sc_flags & URTWN_RUNNING) + urtwn_stop(sc); /* Init firmware commands ring. */ sc->fwcur = 0; @@ -3340,8 +3277,8 @@ urtwn_init_locked(void *arg) } /* Set MAC address. */ - urtwn_write_region_1(sc, R92C_MACID, IF_LLADDR(ifp), - IEEE80211_ADDR_LEN); + IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr); + urtwn_write_region_1(sc, R92C_MACID, macaddr, IEEE80211_ADDR_LEN); /* Set initial network type. */ reg = urtwn_read_4(sc, R92C_CR); @@ -3465,8 +3402,7 @@ urtwn_init_locked(void *arg) usbd_transfer_start(sc->sc_xfer[URTWN_BULK_RX]); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= URTWN_RUNNING; callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc); fail: @@ -3474,38 +3410,15 @@ urtwn_init_locked(void *arg) } static void -urtwn_init(void *arg) +urtwn_stop(struct urtwn_softc *sc) { - struct urtwn_softc *sc = arg; - - URTWN_LOCK(sc); - urtwn_init_locked(arg); - URTWN_UNLOCK(sc); -} - -static void -urtwn_stop_locked(struct ifnet *ifp) -{ - struct urtwn_softc *sc = ifp->if_softc; URTWN_ASSERT_LOCKED(sc); - - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - + sc->sc_flags &= ~URTWN_RUNNING; callout_stop(&sc->sc_watchdog_ch); urtwn_abort_xfers(sc); } -static void -urtwn_stop(struct ifnet *ifp) -{ - struct urtwn_softc *sc = ifp->if_softc; - - URTWN_LOCK(sc); - urtwn_stop_locked(ifp); - URTWN_UNLOCK(sc); -} - static void urtwn_abort_xfers(struct urtwn_softc *sc) { @@ -3523,12 +3436,11 @@ urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct urtwn_softc *sc = ifp->if_softc; + struct urtwn_softc *sc = ic->ic_softc; struct urtwn_data *bf; /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & URTWN_RUNNING)) { m_freem(m); ieee80211_free_node(ni); return (ENETDOWN); @@ -3542,10 +3454,8 @@ urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return (ENOBUFS); } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if (urtwn_tx_start(sc, ni, m, bf) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); URTWN_UNLOCK(sc); return (EIO); diff --git a/sys/dev/usb/wlan/if_urtwnreg.h b/sys/dev/usb/wlan/if_urtwnreg.h index 2bbec7a10647..0ca9db7bd230 100644 --- a/sys/dev/usb/wlan/if_urtwnreg.h +++ b/sys/dev/usb/wlan/if_urtwnreg.h @@ -1172,7 +1172,8 @@ enum { #define URTWN_EP_QUEUES URTWN_BULK_RX struct urtwn_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct usb_device *sc_udev; @@ -1180,6 +1181,7 @@ struct urtwn_softc { u_int sc_flags; #define URTWN_FLAG_CCK_HIPWR 0x01 #define URTWN_DETACHED 0x02 +#define URTWN_RUNNING 0x04 u_int chip; #define URTWN_CHIP_92C 0x01 @@ -1224,7 +1226,6 @@ struct urtwn_softc { uint8_t ht40_tx_pwr[5]; int8_t bw20_tx_pwr_diff; int8_t ofdm_tx_pwr_diff; - uint8_t sc_bssid[IEEE80211_ADDR_LEN]; struct callout sc_watchdog_ch; struct mtx sc_mtx; diff --git a/sys/dev/usb/wlan/if_urtwvar.h b/sys/dev/usb/wlan/if_urtwvar.h index e99cbf4e30a7..a423214de87b 100644 --- a/sys/dev/usb/wlan/if_urtwvar.h +++ b/sys/dev/usb/wlan/if_urtwvar.h @@ -93,14 +93,14 @@ struct urtw_vap { #define URTW_VAP(vap) ((struct urtw_vap *)(vap)) struct urtw_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct usb_device *sc_udev; struct mtx sc_mtx; void *sc_tx_dma_buf; int sc_debug; - int sc_if_flags; int sc_flags; #define URTW_INIT_ONCE (1 << 1) #define URTW_RTL8187B (1 << 2) @@ -108,13 +108,13 @@ struct urtw_softc { #define URTW_RTL8187B_REV_D (1 << 4) #define URTW_RTL8187B_REV_E (1 << 5) #define URTW_DETACHED (1 << 6) +#define URTW_RUNNING (1 << 7) enum ieee80211_state sc_state; int sc_epromtype; #define URTW_EEPROM_93C46 0 #define URTW_EEPROM_93C56 1 uint8_t sc_crcmon; - uint8_t sc_bssid[IEEE80211_ADDR_LEN]; struct ieee80211_channel *sc_curchan; diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index 8f9035eaeb0e..4c1c778472c6 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -154,12 +154,12 @@ static int zyd_set_beacon_interval(struct zyd_softc *, int); static void zyd_rx_data(struct usb_xfer *, int, uint16_t); static int zyd_tx_start(struct zyd_softc *, struct mbuf *, struct ieee80211_node *); -static void zyd_start(struct ifnet *); +static int zyd_transmit(struct ieee80211com *, struct mbuf *); +static void zyd_start(struct zyd_softc *); static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static int zyd_ioctl(struct ifnet *, u_long, caddr_t); +static void zyd_parent(struct ieee80211com *); static void zyd_init_locked(struct zyd_softc *); -static void zyd_init(void *); static void zyd_stop(struct zyd_softc *); static int zyd_loadfirmware(struct zyd_softc *); static void zyd_scan_start(struct ieee80211com *); @@ -333,8 +333,7 @@ zyd_attach(device_t dev) { struct usb_attach_arg *uaa = device_get_ivars(dev); struct zyd_softc *sc = device_get_softc(dev); - struct ifnet *ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; uint8_t iface_index, bands; int error; @@ -353,6 +352,7 @@ zyd_attach(device_t dev) mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, MTX_DEF); STAILQ_INIT(&sc->sc_rqh); + mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = ZYD_IFACE_INDEX; error = usbd_transfer_setup(uaa->device, @@ -372,22 +372,6 @@ zyd_attach(device_t dev) } ZYD_UNLOCK(sc); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto detach; - } - ifp->if_softc = sc; - if_initname(ifp, "zyd", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = zyd_init; - ifp->if_ioctl = zyd_ioctl; - ifp->if_start = zyd_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - IFQ_SET_READY(&ifp->if_snd); - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -408,16 +392,17 @@ zyd_attach(device_t dev) setbit(&bands, IEEE80211_MODE_11G); ieee80211_init_channels(ic, NULL, &bands); - ieee80211_ifattach(ic, sc->sc_bssid); + ieee80211_ifattach(ic); ic->ic_raw_xmit = zyd_raw_xmit; ic->ic_scan_start = zyd_scan_start; ic->ic_scan_end = zyd_scan_end; ic->ic_set_channel = zyd_set_channel; - ic->ic_vap_create = zyd_vap_create; ic->ic_vap_delete = zyd_vap_delete; ic->ic_update_mcast = zyd_update_mcast; ic->ic_update_promisc = zyd_update_mcast; + ic->ic_parent = zyd_parent; + ic->ic_transmit = zyd_transmit; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -439,8 +424,7 @@ static int zyd_detach(device_t dev) { struct zyd_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; unsigned int x; /* @@ -465,11 +449,9 @@ zyd_detach(device_t dev) /* free USB transfers and some data buffers */ usbd_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER); - if (ifp) { - ic = ifp->if_l2com; + if (ic->ic_softc == sc) ieee80211_ifdetach(ic); - if_free(ifp); - } + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); @@ -486,15 +468,12 @@ zyd_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return (NULL); - zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (zvp == NULL) - return (NULL); + zvp = malloc(sizeof(struct zyd_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &zvp->vap; /* enable s/w bmiss handling for sta mode */ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) { /* out of memory */ free(zvp, M_80211_VAP); return (NULL); @@ -509,7 +488,7 @@ zyd_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, /* complete setup */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); ic->ic_opmode = opmode; return (vap); } @@ -530,13 +509,8 @@ zyd_tx_free(struct zyd_tx_data *data, int txerr) struct zyd_softc *sc = data->sc; if (data->m != NULL) { - if (data->m->m_flags & M_TXCB) - ieee80211_process_callback(data->ni, data->m, - txerr ? ETIMEDOUT : 0); - m_freem(data->m); + ieee80211_tx_complete(data->ni, data->m, txerr); data->m = NULL; - - ieee80211_free_node(data->ni); data->ni = NULL; } STAILQ_INSERT_TAIL(&sc->tx_free, data, next); @@ -593,7 +567,7 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct zyd_vap *zvp = ZYD_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct zyd_softc *sc = ic->ic_ifp->if_softc; + struct zyd_softc *sc = ic->ic_softc; int error; DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__, @@ -618,8 +592,8 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) /* make data LED blink upon Tx */ zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1); - IEEE80211_ADDR_COPY(sc->sc_bssid, vap->iv_bss->ni_bssid); - zyd_set_bssid(sc, sc->sc_bssid); + IEEE80211_ADDR_COPY(ic->ic_macaddr, vap->iv_bss->ni_bssid); + zyd_set_bssid(sc, ic->ic_macaddr); break; default: break; @@ -637,8 +611,7 @@ static void zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error) { struct zyd_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni; struct zyd_cmd *cmd = &sc->sc_ibuf; @@ -681,7 +654,9 @@ zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error) ieee80211_free_node(ni); } if (le16toh(retry->count) & 0x100) - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); /* too many retries */ + /* too many retries */ + if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, + 1); break; } case ZYD_NOTIF_IORD: @@ -1243,8 +1218,7 @@ zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c) #define N(a) ((int)(sizeof(a) / sizeof((a)[0]))) int error = 0, i; struct zyd_softc *sc = rf->rf_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6; int chan = ieee80211_chan2ieee(ic, c); @@ -1932,7 +1906,7 @@ zyd_get_macaddr(struct zyd_softc *sc) USETW(req.wIndex, 0); USETW(req.wLength, IEEE80211_ADDR_LEN); - error = zyd_do_request(sc, &req, sc->sc_bssid); + error = zyd_do_request(sc, &req, sc->sc_ic.ic_macaddr); if (error != 0) { device_printf(sc->sc_dev, "could not read EEPROM: %s\n", usbd_errstr(error)); @@ -2004,36 +1978,41 @@ zyd_set_led(struct zyd_softc *sc, int which, int on) static void zyd_set_multi(struct zyd_softc *sc) { - int error; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ifmultiaddr *ifma; + struct ieee80211com *ic = &sc->sc_ic; uint32_t low, high; - uint8_t v; + int error; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) return; low = 0x00000000; high = 0x80000000; - if (ic->ic_opmode == IEEE80211_M_MONITOR || - (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) { + if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 || + ic->ic_promisc > 0) { low = 0xffffffff; high = 0xffffffff; } else { - if_maddr_rlock(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - v = ((uint8_t *)LLADDR((struct sockaddr_dl *) - ifma->ifma_addr))[5] >> 2; - if (v < 32) - low |= 1 << v; - else - high |= 1 << (v - 32); + struct ieee80211vap *vap; + struct ifnet *ifp; + struct ifmultiaddr *ifma; + uint8_t v; + + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + ifp = vap->iv_ifp; + if_maddr_rlock(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + v = ((uint8_t *)LLADDR((struct sockaddr_dl *) + ifma->ifma_addr))[5] >> 2; + if (v < 32) + low |= 1 << v; + else + high |= 1 << (v - 32); + } + if_maddr_runlock(ifp); } - if_maddr_runlock(ifp); } /* reprogram multicast global hash table */ @@ -2050,9 +2029,6 @@ zyd_update_mcast(struct ieee80211com *ic) { struct zyd_softc *sc = ic->ic_softc; - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; - ZYD_LOCK(sc); zyd_set_multi(sc); ZYD_UNLOCK(sc); @@ -2061,8 +2037,7 @@ zyd_update_mcast(struct ieee80211com *ic) static int zyd_set_rxfilter(struct zyd_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t rxfilter; switch (ic->ic_opmode) { @@ -2087,8 +2062,7 @@ static void zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c) { int error; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct zyd_rf *rf = &sc->sc_rf; uint32_t tmp; int chan; @@ -2179,8 +2153,7 @@ static void zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len) { struct zyd_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct zyd_plcphdr plcp; struct zyd_rx_stat stat; struct usb_page_cache *pc; @@ -2190,7 +2163,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len) if (len < ZYD_MIN_FRAGSZ) { DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n", device_get_nameunit(sc->sc_dev), len); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } pc = usbd_xfer_get_frame(xfer, 0); @@ -2201,7 +2174,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len) DPRINTF(sc, ZYD_DEBUG_RECV, "%s: RX status indicated error (%x)\n", device_get_nameunit(sc->sc_dev), stat.flags); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -2213,7 +2186,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len) if (rlen > (int)MCLBYTES) { DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too long (length=%d)\n", device_get_nameunit(sc->sc_dev), rlen); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } else if (rlen > (int)MHLEN) m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); @@ -2222,10 +2195,9 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len) if (m == NULL) { DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n", device_get_nameunit(sc->sc_dev)); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); return; } - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = rlen; usbd_copy_out(pc, offset + sizeof(plcp), mtod(m, uint8_t *), rlen); @@ -2255,8 +2227,7 @@ static void zyd_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) { struct zyd_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; struct zyd_rx_desc desc; struct mbuf *m; @@ -2328,10 +2299,8 @@ zyd_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) } else (void)ieee80211_input_all(ic, m, rssi, nf); } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_IS_EMPTY(&ifp->if_snd)) - zyd_start(ifp); ZYD_LOCK(sc); + zyd_start(sc); break; default: /* Error */ @@ -2386,7 +2355,6 @@ static void zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) { struct zyd_softc *sc = usbd_xfer_softc(xfer); - struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap; struct zyd_tx_data *data; struct mbuf *m; @@ -2405,9 +2373,6 @@ zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) zyd_tx_free(data, 0); usbd_xfer_set_priv(xfer, NULL); - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: @@ -2440,16 +2405,14 @@ zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error) usbd_xfer_set_priv(xfer, data); usbd_transfer_submit(xfer); } - ZYD_UNLOCK(sc); - zyd_start(ifp); - ZYD_LOCK(sc); + zyd_start(sc); break; default: /* Error */ DPRINTF(sc, ZYD_DEBUG_ANY, "transfer error, %s\n", usbd_errstr(error)); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); data = usbd_xfer_get_priv(xfer); usbd_xfer_set_priv(xfer, NULL); if (data != NULL) @@ -2590,31 +2553,45 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) return (0); } -static void -zyd_start(struct ifnet *ifp) +static int +zyd_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct zyd_softc *sc = ic->ic_softc; + int error; + + ZYD_LOCK(sc); + if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) { + ZYD_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + ZYD_UNLOCK(sc); + return (error); + } + zyd_start(sc); + ZYD_UNLOCK(sc); + + return (0); +} + +static void +zyd_start(struct zyd_softc *sc) { - struct zyd_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; - ZYD_LOCK(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->tx_nfree == 0) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } + ZYD_LOCK_ASSERT(sc, MA_LOCKED); + + while (sc->tx_nfree > 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; if (zyd_tx_start(sc, m, ni) != 0) { ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); break; } } - ZYD_UNLOCK(sc); } static int @@ -2622,19 +2599,17 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct zyd_softc *sc = ifp->if_softc; + struct zyd_softc *sc = ic->ic_softc; ZYD_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & ZYD_FLAG_RUNNING)) { ZYD_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return (ENETDOWN); } if (sc->tx_nfree == 0) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; ZYD_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); @@ -2648,7 +2623,6 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, */ if (zyd_tx_start(sc, m, ni) != 0) { ZYD_UNLOCK(sc); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); return (EIO); } @@ -2656,56 +2630,35 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return (0); } -static int -zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +zyd_parent(struct ieee80211com *ic) { - struct zyd_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error; + struct zyd_softc *sc = ic->ic_softc; int startall = 0; ZYD_LOCK(sc); - error = (sc->sc_flags & ZYD_FLAG_DETACHED) ? ENXIO : 0; - ZYD_UNLOCK(sc); - if (error) - return (error); - - switch (cmd) { - case SIOCSIFFLAGS: - ZYD_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - zyd_init_locked(sc); - startall = 1; - } else - zyd_set_multi(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - zyd_stop(sc); - } + if (sc->sc_flags & ZYD_FLAG_DETACHED) { ZYD_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; + return; } - return (error); + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) { + zyd_init_locked(sc); + startall = 1; + } else + zyd_set_multi(sc); + } else if (sc->sc_flags & ZYD_FLAG_RUNNING) + zyd_stop(sc); + ZYD_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void zyd_init_locked(struct zyd_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct usb_config_descriptor *cd; int error; uint32_t val; @@ -2757,12 +2710,12 @@ zyd_init_locked(struct zyd_softc *sc) sc->sc_flags |= ZYD_FLAG_INITONCE; } - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & ZYD_FLAG_RUNNING) zyd_stop(sc); DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %6D\n", - IF_LLADDR(ifp), ":"); - error = zyd_set_macaddr(sc, IF_LLADDR(ifp)); + vap ? vap->iv_myaddr : ic->ic_macaddr, ":"); + error = zyd_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); if (error != 0) return; @@ -2798,8 +2751,7 @@ zyd_init_locked(struct zyd_softc *sc) /* enable interrupts */ zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= ZYD_FLAG_RUNNING; usbd_xfer_set_stall(sc->sc_xfer[ZYD_BULK_WR]); usbd_transfer_start(sc->sc_xfer[ZYD_BULK_RD]); usbd_transfer_start(sc->sc_xfer[ZYD_INTR_RD]); @@ -2810,30 +2762,14 @@ fail: zyd_stop(sc); return; } -static void -zyd_init(void *priv) -{ - struct zyd_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - ZYD_LOCK(sc); - zyd_init_locked(sc); - ZYD_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - static void zyd_stop(struct zyd_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int error; ZYD_LOCK_ASSERT(sc, MA_OWNED); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~ZYD_FLAG_RUNNING; /* * Drain all the transfers, if not already drained: @@ -2925,30 +2861,29 @@ zyd_loadfirmware(struct zyd_softc *sc) static void zyd_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct zyd_softc *sc = ifp->if_softc; + struct zyd_softc *sc = ic->ic_softc; ZYD_LOCK(sc); /* want broadcast address while scanning */ - zyd_set_bssid(sc, ifp->if_broadcastaddr); + zyd_set_bssid(sc, ieee80211broadcastaddr); ZYD_UNLOCK(sc); } static void zyd_scan_end(struct ieee80211com *ic) { - struct zyd_softc *sc = ic->ic_ifp->if_softc; + struct zyd_softc *sc = ic->ic_softc; ZYD_LOCK(sc); /* restore previous bssid */ - zyd_set_bssid(sc, sc->sc_bssid); + zyd_set_bssid(sc, ic->ic_macaddr); ZYD_UNLOCK(sc); } static void zyd_set_channel(struct ieee80211com *ic) { - struct zyd_softc *sc = ic->ic_ifp->if_softc; + struct zyd_softc *sc = ic->ic_softc; ZYD_LOCK(sc); zyd_set_chan(sc, ic->ic_curchan); diff --git a/sys/dev/usb/wlan/if_zydreg.h b/sys/dev/usb/wlan/if_zydreg.h index 05d94e399709..ec61d06434f5 100644 --- a/sys/dev/usb/wlan/if_zydreg.h +++ b/sys/dev/usb/wlan/if_zydreg.h @@ -1249,7 +1249,8 @@ enum { }; struct zyd_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct usb_device *sc_udev; @@ -1260,13 +1261,13 @@ struct zyd_softc { #define ZYD_FLAG_INITONCE (1 << 1) #define ZYD_FLAG_INITDONE (1 << 2) #define ZYD_FLAG_DETACHED (1 << 3) +#define ZYD_FLAG_RUNNING (1 << 4) struct zyd_rf sc_rf; STAILQ_HEAD(, zyd_rq) sc_rtx; STAILQ_HEAD(, zyd_rq) sc_rqh; - uint8_t sc_bssid[IEEE80211_ADDR_LEN]; uint16_t sc_fwbase; uint8_t sc_regdomain; uint8_t sc_macrev; diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index b316d46dae74..f8af23138340 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -116,11 +116,9 @@ static struct ieee80211vap *wi_vap_create(struct ieee80211com *, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void wi_vap_delete(struct ieee80211vap *vap); -static void wi_stop_locked(struct wi_softc *sc, int disable); -static void wi_start_locked(struct ifnet *); -static void wi_start(struct ifnet *); -static int wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, - struct mbuf *m0); +static int wi_transmit(struct ieee80211com *, struct mbuf *); +static void wi_start(struct wi_softc *); +static int wi_start_tx(struct wi_softc *, struct wi_frame *, struct mbuf *); static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int); @@ -131,10 +129,8 @@ static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf); static int wi_reset(struct wi_softc *); static void wi_watchdog(void *); -static int wi_ioctl(struct ifnet *, u_long, caddr_t); +static void wi_parent(struct ieee80211com *); static void wi_media_status(struct ifnet *, struct ifmediareq *); -static uint64_t wi_get_counter(struct ifnet *, ift_counter); - static void wi_rx_intr(struct wi_softc *); static void wi_tx_intr(struct wi_softc *); static void wi_tx_ex_intr(struct wi_softc *); @@ -153,10 +149,10 @@ static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int); static int wi_cmd(struct wi_softc *, int, int, int, int); static int wi_seek_bap(struct wi_softc *, int, int); static int wi_read_bap(struct wi_softc *, int, int, void *, int); -static int wi_write_bap(struct wi_softc *, int, int, void *, int); +static int wi_write_bap(struct wi_softc *, int, int, const void *, int); static int wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int); static int wi_read_rid(struct wi_softc *, int, void *, int *); -static int wi_write_rid(struct wi_softc *, int, void *, int); +static int wi_write_rid(struct wi_softc *, int, const void *, int); static int wi_write_appie(struct wi_softc *, int, const struct ieee80211_appie *); static void wi_scan_start(struct ieee80211com *); @@ -237,8 +233,7 @@ int wi_attach(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; int i, nrates, buflen; u_int16_t val; u_int8_t ratebuf[2 + IEEE80211_RATE_SIZE]; @@ -249,15 +244,6 @@ wi_attach(device_t dev) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; int error; - uint8_t macaddr[IEEE80211_ADDR_LEN]; - - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc\n"); - wi_free(dev); - return ENOSPC; - } - ic = ifp->if_l2com; sc->sc_firmware_type = WI_NOTYPE; sc->wi_cmd_count = 500; @@ -309,6 +295,7 @@ wi_attach(device_t dev) mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* * Read the station address. @@ -317,12 +304,13 @@ wi_attach(device_t dev) * the probe to fail. */ buflen = IEEE80211_ADDR_LEN; - error = wi_read_rid(sc, WI_RID_MAC_NODE, macaddr, &buflen); + error = wi_read_rid(sc, WI_RID_MAC_NODE, &ic->ic_macaddr, &buflen); if (error != 0) { buflen = IEEE80211_ADDR_LEN; - error = wi_read_rid(sc, WI_RID_MAC_NODE, macaddr, &buflen); + error = wi_read_rid(sc, WI_RID_MAC_NODE, &ic->ic_macaddr, + &buflen); } - if (error || IEEE80211_ADDR_EQ(macaddr, empty_macaddr)) { + if (error || IEEE80211_ADDR_EQ(&ic->ic_macaddr, empty_macaddr)) { if (error != 0) device_printf(dev, "mac read failed %d\n", error); else { @@ -333,18 +321,6 @@ wi_attach(device_t dev) return (error); } - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = wi_ioctl; - ifp->if_start = wi_start; - ifp->if_init = wi_init; - ifp->if_get_counter = wi_get_counter; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_phytype = IEEE80211_T_DS; @@ -458,16 +434,17 @@ wi_attach(device_t dev) sc->sc_portnum = WI_DEFAULT_PORT; - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_raw_xmit = wi_raw_xmit; ic->ic_scan_start = wi_scan_start; ic->ic_scan_end = wi_scan_end; ic->ic_set_channel = wi_set_channel; - ic->ic_vap_create = wi_vap_create; ic->ic_vap_delete = wi_vap_delete; ic->ic_update_mcast = wi_update_mcast; ic->ic_update_promisc = wi_update_promisc; + ic->ic_transmit = wi_transmit; + ic->ic_parent = wi_parent; ieee80211_radiotap_attach(ic, &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), @@ -483,7 +460,6 @@ wi_attach(device_t dev) if (error) { device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); ieee80211_ifdetach(ic); - if_free(sc->sc_ifp); wi_free(dev); return error; } @@ -495,21 +471,20 @@ int wi_detach(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; WI_LOCK(sc); /* check if device was removed */ sc->wi_gone |= !bus_child_present(dev); - wi_stop_locked(sc, 0); + wi_stop(sc, 0); WI_UNLOCK(sc); ieee80211_ifdetach(ic); bus_teardown_intr(dev, sc->irq, sc->wi_intrhand); - if_free(sc->sc_ifp); wi_free(dev); + mbufq_drain(&sc->sc_snd); mtx_destroy(&sc->sc_mtx); return (0); } @@ -520,19 +495,16 @@ wi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct wi_softc *sc = ic->ic_ifp->if_softc; + struct wi_softc *sc = ic->ic_softc; struct wi_vap *wvp; struct ieee80211vap *vap; if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - wvp = (struct wi_vap *) malloc(sizeof(struct wi_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (wvp == NULL) - return NULL; + wvp = malloc(sizeof(struct wi_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &wvp->wv_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); vap->iv_max_aid = WI_MAX_AID; @@ -566,7 +538,7 @@ wi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, } /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status, mac); ic->ic_opmode = opmode; return vap; } @@ -585,7 +557,9 @@ wi_shutdown(device_t dev) { struct wi_softc *sc = device_get_softc(dev); + WI_LOCK(sc); wi_stop(sc, 1); + WI_UNLOCK(sc); return (0); } @@ -593,12 +567,12 @@ void wi_intr(void *arg) { struct wi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; u_int16_t status; WI_LOCK(sc); - if (sc->wi_gone || !sc->sc_enabled || (ifp->if_flags & IFF_UP) == 0) { + if (sc->wi_gone || !sc->sc_enabled || + (sc->sc_flags & WI_FLAGS_RUNNING) == 0) { CSR_WRITE_2(sc, WI_INT_EN, 0); CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); WI_UNLOCK(sc); @@ -617,9 +591,8 @@ wi_intr(void *arg) wi_tx_ex_intr(sc); if (status & WI_EV_INFO) wi_info_intr(sc); - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - wi_start_locked(ifp); + if (mbufq_first(&sc->sc_snd) != NULL) + wi_start(sc); /* Re-enable interrupts. */ CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); @@ -642,7 +615,7 @@ wi_enable(struct wi_softc *sc) static int wi_setup_locked(struct wi_softc *sc, int porttype, int mode, - uint8_t mac[IEEE80211_ADDR_LEN]) + const uint8_t mac[IEEE80211_ADDR_LEN]) { int i; @@ -676,26 +649,25 @@ wi_setup_locked(struct wi_softc *sc, int porttype, int mode, return 0; } -static void -wi_init_locked(struct wi_softc *sc) +void +wi_init(struct wi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int wasenabled; WI_LOCK_ASSERT(sc); wasenabled = sc->sc_enabled; if (wasenabled) - wi_stop_locked(sc, 1); + wi_stop(sc, 1); - if (wi_setup_locked(sc, sc->sc_porttype, 3, IF_LLADDR(ifp)) != 0) { - if_printf(ifp, "interface not running\n"); - wi_stop_locked(sc, 1); + if (wi_setup_locked(sc, sc->sc_porttype, 3, + sc->sc_ic.ic_macaddr) != 0) { + device_printf(sc->sc_dev, "interface not running\n"); + wi_stop(sc, 1); return; } - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + sc->sc_flags |= WI_FLAGS_RUNNING; callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc); @@ -703,24 +675,8 @@ wi_init_locked(struct wi_softc *sc) } void -wi_init(void *arg) +wi_stop(struct wi_softc *sc, int disable) { - struct wi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - WI_LOCK(sc); - wi_init_locked(sc); - WI_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - -static void -wi_stop_locked(struct wi_softc *sc, int disable) -{ - struct ifnet *ifp = sc->sc_ifp; WI_LOCK_ASSERT(sc); @@ -736,22 +692,13 @@ wi_stop_locked(struct wi_softc *sc, int disable) sc->sc_tx_timer = 0; sc->sc_false_syns = 0; - ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); -} - -void -wi_stop(struct wi_softc *sc, int disable) -{ - WI_LOCK(sc); - wi_stop_locked(sc, disable); - WI_UNLOCK(sc); + sc->sc_flags &= ~WI_FLAGS_RUNNING; } static void wi_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct wi_softc *sc = ifp->if_softc; + struct wi_softc *sc = ic->ic_softc; DPRINTF(("%s: channel %d, %sscanning\n", __func__, ieee80211_chan2ieee(ic, ic->ic_curchan), @@ -766,8 +713,7 @@ wi_set_channel(struct ieee80211com *ic) static void wi_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct wi_softc *sc = ifp->if_softc; + struct wi_softc *sc = ic->ic_softc; struct ieee80211_scan_state *ss = ic->ic_scan; DPRINTF(("%s\n", __func__)); @@ -790,8 +736,7 @@ wi_scan_start(struct ieee80211com *ic) static void wi_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct wi_softc *sc = ifp->if_softc; + struct wi_softc *sc = ic->ic_softc; DPRINTF(("%s: restore port type %d\n", __func__, sc->sc_porttype)); @@ -824,9 +769,8 @@ static int wi_newstate_sta(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; struct ieee80211_node *bss; - struct wi_softc *sc = ifp->if_softc; + struct wi_softc *sc = ic->ic_softc; DPRINTF(("%s: %s -> %s\n", __func__, ieee80211_state_name[vap->iv_state], @@ -894,9 +838,8 @@ static int wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; struct ieee80211_node *bss; - struct wi_softc *sc = ifp->if_softc; + struct wi_softc *sc = ic->ic_softc; int error; DPRINTF(("%s: %s -> %s\n", __func__, @@ -953,10 +896,30 @@ wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int ar return error; } -static void -wi_start_locked(struct ifnet *ifp) +static int +wi_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct wi_softc *sc = ic->ic_softc; + int error; + + WI_LOCK(sc); + if ((sc->sc_flags & WI_FLAGS_RUNNING) == 0) { + WI_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + WI_UNLOCK(sc); + return (error); + } + wi_start(sc); + WI_UNLOCK(sc); + return (0); +} + +static void +wi_start(struct wi_softc *sc) { - struct wi_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct ieee80211_frame *wh; struct mbuf *m0; @@ -972,15 +935,8 @@ wi_start_locked(struct ifnet *ifp) memset(&frmhdr, 0, sizeof(frmhdr)); cur = sc->sc_txnext; - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - if (sc->sc_txd[cur].d_len != 0) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } + while (sc->sc_txd[cur].d_len == 0 && + (m0 = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif; /* reconstruct 802.3 header */ @@ -1029,28 +985,16 @@ wi_start_locked(struct ifnet *ifp) m_adj(m0, sizeof(struct ieee80211_frame)); frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len); ieee80211_free_node(ni); - if (wi_start_tx(ifp, &frmhdr, m0)) + if (wi_start_tx(sc, &frmhdr, m0)) continue; sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf; - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); } } -static void -wi_start(struct ifnet *ifp) -{ - struct wi_softc *sc = ifp->if_softc; - - WI_LOCK(sc); - wi_start_locked(ifp); - WI_UNLOCK(sc); -} - static int -wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, struct mbuf *m0) +wi_start_tx(struct wi_softc *sc, struct wi_frame *frmhdr, struct mbuf *m0) { - struct wi_softc *sc = ifp->if_softc; int cur = sc->sc_txnext; int fid, off, error; @@ -1060,13 +1004,13 @@ wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, struct mbuf *m0) || wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0; m_freem(m0); if (error) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); return -1; } sc->sc_txd[cur].d_len = off; if (sc->sc_txcur == cur) { if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) { - if_printf(ifp, "xmit failed\n"); + device_printf(sc->sc_dev, "xmit failed\n"); sc->sc_txd[cur].d_len = 0; return -1; } @@ -1080,9 +1024,8 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; struct ieee80211vap *vap = ni->ni_vap; - struct wi_softc *sc = ifp->if_softc; + struct wi_softc *sc = ic->ic_softc; struct ieee80211_key *k; struct ieee80211_frame *wh; struct wi_frame frmhdr; @@ -1098,7 +1041,6 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, memset(&frmhdr, 0, sizeof(frmhdr)); cur = sc->sc_txnext; if (sc->sc_txd[cur].d_len != 0) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; rc = ENOBUFS; goto out; } @@ -1129,7 +1071,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, (caddr_t)&frmhdr.wi_whdr); m_adj(m0, sizeof(struct ieee80211_frame)); frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len); - if (wi_start_tx(ifp, &frmhdr, m0) < 0) { + if (wi_start_tx(sc, &frmhdr, m0) < 0) { m0 = NULL; rc = EIO; goto out; @@ -1160,7 +1102,7 @@ wi_reset(struct wi_softc *sc) } sc->sc_reset = 1; if (i == WI_INIT_TRIES) { - if_printf(sc->sc_ifp, "reset failed\n"); + device_printf(sc->sc_dev, "reset failed\n"); return error; } @@ -1178,7 +1120,6 @@ static void wi_watchdog(void *arg) { struct wi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; WI_LOCK_ASSERT(sc); @@ -1186,65 +1127,52 @@ wi_watchdog(void *arg) return; if (sc->sc_tx_timer && --sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - wi_init_locked(ifp->if_softc); + device_printf(sc->sc_dev, "device timeout\n"); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); + wi_init(sc); return; } callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc); } -static int -wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +wi_parent(struct ieee80211com *ic) { - struct wi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct wi_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - WI_LOCK(sc); - /* - * Can't do promisc and hostap at the same time. If all that's - * changing is the promisc flag, try to short-circuit a call to - * wi_init() by just setting PROMISC in the hardware. - */ - if (ifp->if_flags & IFF_UP) { - if (ic->ic_opmode != IEEE80211_M_HOSTAP && - ifp->if_drv_flags & IFF_DRV_RUNNING) { - if ((ifp->if_flags ^ sc->sc_if_flags) & IFF_PROMISC) { - wi_write_val(sc, WI_RID_PROMISC, - (ifp->if_flags & IFF_PROMISC) != 0); - } else { - wi_init_locked(sc); - startall = 1; - } + WI_LOCK(sc); + /* + * Can't do promisc and hostap at the same time. If all that's + * changing is the promisc flag, try to short-circuit a call to + * wi_init() by just setting PROMISC in the hardware. + */ + if (ic->ic_nrunning > 0) { + if (ic->ic_opmode != IEEE80211_M_HOSTAP && + sc->sc_flags & WI_FLAGS_RUNNING) { + if (ic->ic_promisc > 0 && + (sc->sc_flags & WI_FLAGS_PROMISC) == 0) { + wi_write_val(sc, WI_RID_PROMISC, 1); + sc->sc_flags |= WI_FLAGS_PROMISC; + } else if (ic->ic_promisc == 0 && + (sc->sc_flags & WI_FLAGS_PROMISC) != 0) { + wi_write_val(sc, WI_RID_PROMISC, 0); + sc->sc_flags &= ~WI_FLAGS_PROMISC; } else { - wi_init_locked(sc); + wi_init(sc); startall = 1; } } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - wi_stop_locked(sc, 1); - sc->wi_gone = 0; + wi_init(sc); + startall = 1; } - sc->sc_if_flags = ifp->if_flags; - WI_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; + } else if (sc->sc_flags & WI_FLAGS_RUNNING) { + wi_stop(sc, 1); + sc->wi_gone = 0; } - return error; + WI_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -1252,7 +1180,7 @@ wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) { struct ieee80211vap *vap = ifp->if_softc; struct ieee80211com *ic = vap->iv_ic; - struct wi_softc *sc = ic->ic_ifp->if_softc; + struct wi_softc *sc = ic->ic_softc; u_int16_t val; int rate, len; @@ -1280,8 +1208,7 @@ wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) static void wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni = vap->iv_bss; @@ -1295,7 +1222,7 @@ wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) * indicator of the firmware's BSSID. Damp spurious * change-of-BSSID indications. */ - if ((ifp->if_flags & IFF_PROMISC) != 0 && + if (ic->ic_promisc > 0 && !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns, WI_MAX_FALSE_SYNS)) return; @@ -1316,8 +1243,7 @@ wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) static __noinline void wi_rx_intr(struct wi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct wi_frame frmhdr; struct mbuf *m; struct ieee80211_frame *wh; @@ -1332,7 +1258,7 @@ wi_rx_intr(struct wi_softc *sc) /* First read in the frame header */ if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); DPRINTF(("wi_rx_intr: read fid %x failed\n", fid)); return; } @@ -1343,7 +1269,7 @@ wi_rx_intr(struct wi_softc *sc) status = le16toh(frmhdr.wi_status); if (status & WI_STAT_ERRSTAT) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status)); return; } @@ -1358,7 +1284,7 @@ wi_rx_intr(struct wi_softc *sc) if (off + len > MCLBYTES) { if (ic->ic_opmode != IEEE80211_M_MONITOR) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); DPRINTF(("wi_rx_intr: oversized packet\n")); return; } else @@ -1371,7 +1297,7 @@ wi_rx_intr(struct wi_softc *sc) m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); DPRINTF(("wi_rx_intr: MGET failed\n")); return; } @@ -1380,7 +1306,6 @@ wi_rx_intr(struct wi_softc *sc) wi_read_bap(sc, fid, sizeof(frmhdr), m->m_data + sizeof(struct ieee80211_frame), len); m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len; - m->m_pkthdr.rcvif = ifp; CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); @@ -1425,7 +1350,6 @@ wi_rx_intr(struct wi_softc *sc) static __noinline void wi_tx_ex_intr(struct wi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct wi_frame frmhdr; int fid; @@ -1440,7 +1364,7 @@ wi_tx_ex_intr(struct wi_softc *sc) */ if ((status & WI_TXSTAT_DISCONNECT) == 0) { if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) { - if_printf(ifp, "tx failed"); + device_printf(sc->sc_dev, "tx failed"); if (status & WI_TXSTAT_RET_ERR) printf(", retry limit exceeded"); if (status & WI_TXSTAT_AGED_ERR) @@ -1455,7 +1379,7 @@ wi_tx_ex_intr(struct wi_softc *sc) printf(", status=0x%x", status); printf("\n"); } - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); } else DPRINTF(("port disconnected\n")); } else @@ -1466,7 +1390,6 @@ wi_tx_ex_intr(struct wi_softc *sc) static __noinline void wi_tx_intr(struct wi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int fid, cur; if (sc->wi_gone) @@ -1477,19 +1400,17 @@ wi_tx_intr(struct wi_softc *sc) cur = sc->sc_txcur; if (sc->sc_txd[cur].d_fid != fid) { - if_printf(ifp, "bad alloc %x != %x, cur %d nxt %d\n", + device_printf(sc->sc_dev, "bad alloc %x != %x, cur %d nxt %d\n", fid, sc->sc_txd[cur].d_fid, cur, sc->sc_txnext); return; } sc->sc_tx_timer = 0; sc->sc_txd[cur].d_len = 0; sc->sc_txcur = cur = (cur + 1) % sc->sc_ntxbuf; - if (sc->sc_txd[cur].d_len == 0) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - else { + if (sc->sc_txd[cur].d_len != 0) { if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, sc->sc_txd[cur].d_fid, 0, 0)) { - if_printf(ifp, "xmit failed\n"); + device_printf(sc->sc_dev, "xmit failed\n"); sc->sc_txd[cur].d_len = 0; } else { sc->sc_tx_timer = 5; @@ -1500,7 +1421,7 @@ wi_tx_intr(struct wi_softc *sc) static __noinline void wi_info_intr(struct wi_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); int i, fid, len, off; u_int16_t ltbuf[2]; @@ -1574,32 +1495,15 @@ wi_info_intr(struct wi_softc *sc) CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO); } -static uint64_t -wi_get_counter(struct ifnet *ifp, ift_counter cnt) -{ - struct wi_softc *sc; - - sc = if_getsoftc(ifp); - - switch (cnt) { - case IFCOUNTER_COLLISIONS: - return (sc->sc_stats.wi_tx_single_retries + - sc->sc_stats.wi_tx_multi_retries + - sc->sc_stats.wi_tx_retry_limit); - default: - return (if_get_counter_default(ifp, cnt)); - } -} - static int wi_write_multi(struct wi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - int n; - struct ifmultiaddr *ifma; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap; struct wi_mcast mlist; + int n; - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { + if (ic->ic_allmulti > 0 || ic->ic_promisc > 0) { allmulti: memset(&mlist, 0, sizeof(mlist)); return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, @@ -1607,17 +1511,23 @@ wi_write_multi(struct wi_softc *sc) } n = 0; - if_maddr_rlock(ifp); - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - if (n >= 16) - goto allmulti; - IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], - (LLADDR((struct sockaddr_dl *)ifma->ifma_addr))); - n++; + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + struct ifnet *ifp; + struct ifmultiaddr *ifma; + + ifp = vap->iv_ifp; + if_maddr_rlock(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + if (n >= 16) + goto allmulti; + IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], + (LLADDR((struct sockaddr_dl *)ifma->ifma_addr))); + n++; + } + if_maddr_runlock(ifp); } - if_maddr_runlock(ifp); return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, IEEE80211_ADDR_LEN * n); } @@ -1638,7 +1548,7 @@ wi_update_promisc(struct ieee80211com *ic) /* XXX handle WEP special case handling? */ wi_write_val(sc, WI_RID_PROMISC, (ic->ic_opmode == IEEE80211_M_MONITOR || - (ic->ic_ifp->if_flags & IFF_PROMISC))); + (ic->ic_promisc > 0))); WI_UNLOCK(sc); } @@ -1937,7 +1847,7 @@ wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) } static int -wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) +wi_write_bap(struct wi_softc *sc, int id, int off, const void *buf, int buflen) { int error, cnt; @@ -1949,7 +1859,7 @@ wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) return error; } cnt = (buflen + 1) / 2; - CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt); + CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (const uint16_t *)buf, cnt); sc->sc_bap_off += cnt * 2; return 0; @@ -2039,7 +1949,7 @@ wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp) } static int -wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen) +wi_write_rid(struct wi_softc *sc, int rid, const void *buf, int buflen) { int error; u_int16_t ltbuf[2]; diff --git a/sys/dev/wi/if_wi_pccard.c b/sys/dev/wi/if_wi_pccard.c index fd70e77074a7..414dc20dba1b 100644 --- a/sys/dev/wi/if_wi_pccard.c +++ b/sys/dev/wi/if_wi_pccard.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/dev/wi/if_wi_pci.c b/sys/dev/wi/if_wi_pci.c index 198c599ef54a..b218c2479a69 100644 --- a/sys/dev/wi/if_wi_pci.c +++ b/sys/dev/wi/if_wi_pci.c @@ -238,7 +238,9 @@ wi_pci_suspend(device_t dev) { struct wi_softc *sc = device_get_softc(dev); + WI_LOCK(sc); wi_stop(sc, 1); + WI_UNLOCK(sc); return (0); } @@ -247,16 +249,15 @@ static int wi_pci_resume(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; - if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) + WI_LOCK(sc); + if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) { return (0); - - if (ifp->if_flags & IFF_UP) { - ifp->if_init(ifp->if_softc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ifp->if_start(ifp); + WI_UNLOCK(sc); } - + if (ic->ic_nrunning > 0) + wi_init(sc); + WI_UNLOCK(sc); return (0); } diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h index f163744ef834..9b668cc0e114 100644 --- a/sys/dev/wi/if_wivar.h +++ b/sys/dev/wi/if_wivar.h @@ -68,7 +68,8 @@ struct wi_vap { #define WI_VAP(vap) ((struct wi_vap *)(vap)) struct wi_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct mtx sc_mtx; struct callout sc_watchdog; @@ -107,7 +108,6 @@ struct wi_softc { int wi_cmd_count; int sc_flags; - int sc_if_flags; int sc_bap_id; int sc_bap_off; @@ -152,6 +152,8 @@ struct wi_softc { #define WI_FLAGS_HAS_ROAMING 0x0020 #define WI_FLAGS_HAS_FRAGTHR 0x0200 #define WI_FLAGS_HAS_DBMADJUST 0x0400 +#define WI_FLAGS_RUNNING 0x0800 +#define WI_FLAGS_PROMISC 0x1000 struct wi_card_ident { u_int16_t card_id; @@ -180,7 +182,7 @@ int wi_shutdown(device_t); int wi_alloc(device_t, int); void wi_free(device_t); extern devclass_t wi_devclass; -void wi_init(void *); void wi_intr(void *); int wi_mgmt_xmit(struct wi_softc *, caddr_t, int); void wi_stop(struct wi_softc *, int); +void wi_init(struct wi_softc *); diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index 34406059b437..01ce3e467695 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -205,12 +205,12 @@ static int wpi_tx_data_raw(struct wpi_softc *, struct mbuf *, const struct ieee80211_bpf_params *); static int wpi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void wpi_start(struct ifnet *); -static void wpi_start_task(void *, int); +static int wpi_transmit(struct ieee80211com *, struct mbuf *); +static void wpi_start(void *, int); static void wpi_watchdog_rfkill(void *); static void wpi_scan_timeout(void *); static void wpi_tx_timeout(void *); -static int wpi_ioctl(struct ifnet *, u_long, caddr_t); +static void wpi_parent(struct ieee80211com *); static int wpi_cmd(struct wpi_softc *, int, const void *, size_t, int); static int wpi_mrr_setup(struct wpi_softc *); static int wpi_add_node(struct wpi_softc *, struct ieee80211_node *); @@ -272,7 +272,7 @@ static int wpi_hw_init(struct wpi_softc *); static void wpi_hw_stop(struct wpi_softc *); static void wpi_radio_on(void *, int); static void wpi_radio_off(void *, int); -static void wpi_init(void *); +static int wpi_init(struct wpi_softc *); static void wpi_stop_locked(struct wpi_softc *); static void wpi_stop(struct wpi_softc *); static void wpi_scan_start(struct ieee80211com *); @@ -329,13 +329,11 @@ wpi_attach(device_t dev) { struct wpi_softc *sc = (struct wpi_softc *)device_get_softc(dev); struct ieee80211com *ic; - struct ifnet *ifp; int i, error, rid; #ifdef WPI_DEBUG int supportsa = 1; const struct wpi_ident *ident; #endif - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; @@ -445,14 +443,7 @@ wpi_attach(device_t dev) /* Clear pending interrupts. */ WPI_WRITE(sc, WPI_INT, 0xffffffff); - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not allocate ifnet structure\n"); - goto fail; - } - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; + ic = &sc->sc_ic; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -481,7 +472,7 @@ wpi_attach(device_t dev) * Read in the eeprom and also setup the channels for * net80211. We don't set the rates as net80211 does this for us */ - if ((error = wpi_read_eeprom(sc, macaddr)) != 0) { + if ((error = wpi_read_eeprom(sc, ic->ic_macaddr)) != 0) { device_printf(dev, "could not read EEPROM, error %d\n", error); goto fail; @@ -503,20 +494,12 @@ wpi_attach(device_t dev) } #endif - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = wpi_init; - ifp->if_ioctl = wpi_ioctl; - ifp->if_start = wpi_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_vap_create = wpi_vap_create; ic->ic_vap_delete = wpi_vap_delete; + ic->ic_parent = wpi_parent; ic->ic_raw_xmit = wpi_raw_xmit; + ic->ic_transmit = wpi_transmit; ic->ic_node_alloc = wpi_node_alloc; sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = wpi_node_free; @@ -543,7 +526,7 @@ wpi_attach(device_t dev) TASK_INIT(&sc->sc_reinittask, 0, wpi_hw_reset, sc); TASK_INIT(&sc->sc_radiooff_task, 0, wpi_radio_off, sc); TASK_INIT(&sc->sc_radioon_task, 0, wpi_radio_on, sc); - TASK_INIT(&sc->sc_start_task, 0, wpi_start_task, sc); + TASK_INIT(&sc->sc_start_task, 0, wpi_start, sc); sc->sc_tq = taskqueue_create("wpi_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->sc_tq); @@ -588,14 +571,13 @@ fail: wpi_detach(dev); static void wpi_radiotap_attach(struct wpi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct wpi_rx_radiotap_header *rxtap = &sc->sc_rxtap; + struct wpi_tx_radiotap_header *txtap = &sc->sc_txtap; + DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); - ieee80211_radiotap_attach(ic, - &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), - WPI_TX_RADIOTAP_PRESENT, - &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), - WPI_RX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(&sc->sc_ic, + &txtap->wt_ihdr, sizeof(*txtap), WPI_TX_RADIOTAP_PRESENT, + &rxtap->wr_ihdr, sizeof(*rxtap), WPI_RX_RADIOTAP_PRESENT); DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__); } @@ -646,12 +628,9 @@ wpi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - wvp = (struct wpi_vap *) malloc(sizeof(struct wpi_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (wvp == NULL) - return NULL; + wvp = malloc(sizeof(struct wpi_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &wvp->wv_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); if (opmode == IEEE80211_M_IBSS || opmode == IEEE80211_M_HOSTAP) { WPI_VAP_LOCK_INIT(wvp); @@ -671,7 +650,7 @@ wpi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* Complete setup. */ ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); + ieee80211_media_status, mac); ic->ic_opmode = opmode; return vap; } @@ -700,22 +679,21 @@ static int wpi_detach(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; int qid; DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); - if (ifp != NULL) { - ic = ifp->if_l2com; - + if (ic->ic_vap_create == wpi_vap_create) { ieee80211_draintask(ic, &sc->sc_radioon_task); ieee80211_draintask(ic, &sc->sc_start_task); wpi_stop(sc); - taskqueue_drain_all(sc->sc_tq); - taskqueue_free(sc->sc_tq); + if (sc->sc_tq != NULL) { + taskqueue_drain_all(sc->sc_tq); + taskqueue_free(sc->sc_tq); + } callout_drain(&sc->watchdog_rfkill); callout_drain(&sc->tx_timeout); @@ -748,9 +726,6 @@ wpi_detach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem), sc->mem); - if (ifp != NULL) - if_free(ifp); - DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__); WPI_TXQ_STATE_LOCK_DESTROY(sc); WPI_TXQ_LOCK_DESTROY(sc); @@ -774,7 +749,7 @@ static int wpi_suspend(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; ieee80211_suspend_all(ic); return 0; @@ -784,7 +759,7 @@ static int wpi_resume(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* Clear device-specific "PCI retry timeout" register (41h). */ pci_write_config(dev, 0x41, 0, 1); @@ -1191,6 +1166,7 @@ wpi_alloc_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring, int qid) ring->queued = 0; ring->cur = 0; ring->update = 0; + mbufq_init(&ring->snd, ifqmaxlen); DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); @@ -1318,6 +1294,7 @@ wpi_reset_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring) memset(ring->desc, 0, ring->desc_dma.size); bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, BUS_DMASYNC_PREWRITE); + mbufq_drain(&ring->snd); sc->qfullmsk &= ~(1 << ring->qid); ring->queued = 0; ring->cur = 0; @@ -1448,8 +1425,7 @@ wpi_eeprom_channel_flags(struct wpi_eeprom_chan *channel) static void wpi_read_eeprom_band(struct wpi_softc *sc, int n) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct wpi_eeprom_chan *channels = sc->eeprom_channels[n]; const struct wpi_chan_band *band = &wpi_bands[n]; struct ieee80211_channel *c; @@ -1506,8 +1482,7 @@ wpi_read_eeprom_band(struct wpi_softc *sc, int n) static int wpi_read_eeprom_channels(struct wpi_softc *sc, int n) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct wpi_chan_band *band = &wpi_bands[n]; int error; @@ -1549,8 +1524,7 @@ static int wpi_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, int nchan, struct ieee80211_channel chans[]) { - struct ifnet *ifp = ic->ic_ifp; - struct wpi_softc *sc = ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; int i; for (i = 0; i < nchan; i++) { @@ -1559,8 +1533,7 @@ wpi_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, channel = wpi_find_eeprom_channel(sc, c); if (channel == NULL) { - if_printf(ic->ic_ifp, - "%s: invalid channel %u freq %u/0x%x\n", + ic_printf(ic, "%s: invalid channel %u freq %u/0x%x\n", __func__, c->ic_ieee, c->ic_freq, c->ic_flags); return EINVAL; } @@ -1672,8 +1645,7 @@ wpi_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) static void wpi_node_free(struct ieee80211_node *ni) { - struct ieee80211com *ic = ni->ni_ic; - struct wpi_softc *sc = ic->ic_ifp->if_softc; + struct wpi_softc *sc = ni->ni_ic->ic_softc; struct wpi_node *wn = WPI_NODE(ni); if (wn->id != WPI_ID_UNDEFINED) { @@ -1700,7 +1672,7 @@ wpi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; - struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct wpi_softc *sc = vap->iv_ic->ic_softc; struct wpi_vap *wvp = WPI_VAP(vap); uint64_t ni_tstamp, rx_tstamp; @@ -1744,7 +1716,7 @@ wpi_restore_node(void *arg, struct ieee80211_node *ni) static void wpi_restore_node_table(struct wpi_softc *sc, struct wpi_vap *wvp) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* Set group keys once. */ WPI_NT_LOCK(sc); @@ -1763,12 +1735,20 @@ wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct wpi_vap *wvp = WPI_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct wpi_softc *sc = ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; int error = 0; DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); + WPI_TXQ_LOCK(sc); + if (nstate > IEEE80211_S_INIT && sc->sc_running == 0) { + DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__); + WPI_TXQ_UNLOCK(sc); + + return ENXIO; + } + WPI_TXQ_UNLOCK(sc); + DPRINTF(sc, WPI_DEBUG_STATE, "%s: %s -> %s\n", __func__, ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]); @@ -1937,8 +1917,7 @@ static void wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc, struct wpi_rx_data *data) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct wpi_rx_ring *ring = &sc->rxq; struct wpi_rx_stat *stat; struct wpi_rx_head *head; @@ -2019,7 +1998,6 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc, BUS_DMASYNC_PREWRITE); /* Finalize mbuf. */ - m->m_pkthdr.rcvif = ifp; m->m_data = (caddr_t)(head + 1); m->m_pkthdr.len = m->m_len = len; @@ -2073,7 +2051,7 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc, fail2: m_freem(m); -fail1: if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); +fail1: counter_u64_add(ic->ic_ierrors, 1); } static void @@ -2086,7 +2064,6 @@ wpi_rx_statistics(struct wpi_softc *sc, struct wpi_rx_desc *desc, static void wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc) { - struct ifnet *ifp = sc->sc_ifp; struct wpi_tx_ring *ring = &sc->txq[desc->qid & 0x3]; struct wpi_tx_data *data = &ring->data[desc->idx]; struct wpi_tx_stat *stat = (struct wpi_tx_stat *)(desc + 1); @@ -2119,14 +2096,11 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc) * Update rate control statistics for the node. */ if (status & WPI_TX_STATUS_FAIL) { - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); - } else { - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + } else ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); - } ieee80211_tx_complete(ni, m, (status & WPI_TX_STATUS_FAIL) != 0); @@ -2135,17 +2109,10 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc) if (ring->queued > 0) { callout_reset(&sc->tx_timeout, 5*hz, wpi_tx_timeout, sc); - if (sc->qfullmsk != 0 && - ring->queued < WPI_TX_RING_LOMARK) { + if ((sc->qfullmsk & (1 << ring->qid)) != 0 && + ring->queued < WPI_TX_RING_LOMARK) { sc->qfullmsk &= ~(1 << ring->qid); - IF_LOCK(&ifp->if_snd); - if (sc->qfullmsk == 0 && - (ifp->if_drv_flags & IFF_DRV_OACTIVE)) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); - ieee80211_runtask(ic, &sc->sc_start_task); - } else - IF_UNLOCK(&ifp->if_snd); + ieee80211_runtask(ic, &sc->sc_start_task); } } else callout_stop(&sc->tx_timeout); @@ -2203,8 +2170,7 @@ wpi_cmd_done(struct wpi_softc *sc, struct wpi_rx_desc *desc) static void wpi_notif_intr(struct wpi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t hw; @@ -2239,7 +2205,7 @@ wpi_notif_intr(struct wpi_softc *sc) /* An 802.11 frame has been received. */ wpi_rx_done(sc, desc, data); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if (sc->sc_running == 0) { /* wpi_stop() was called. */ return; } @@ -2328,6 +2294,7 @@ wpi_notif_intr(struct wpi_softc *sc) device_printf(sc->sc_dev, "microcontroller initialization failed\n"); wpi_stop_locked(sc); + return; } /* Save the address of the error log in SRAM. */ sc->errptr = le32toh(uc->errptr); @@ -2558,7 +2525,6 @@ static void wpi_intr(void *arg) { struct wpi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t r1, r2; WPI_LOCK(sc); @@ -2608,7 +2574,7 @@ wpi_intr(void *arg) done: /* Re-enable interrupts. */ - if (ifp->if_flags & IFF_UP) + if (sc->sc_running) WPI_WRITE(sc, WPI_INT_MASK, WPI_INT_MASK_DEF); end: WPI_UNLOCK(sc); @@ -2617,7 +2583,6 @@ end: WPI_UNLOCK(sc); static int wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf) { - struct ifnet *ifp = sc->sc_ifp; struct ieee80211_frame *wh; struct wpi_tx_cmd *cmd; struct wpi_tx_data *data; @@ -2633,7 +2598,7 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf) DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); - if (sc->txq_active == 0) { + if (sc->sc_running == 0) { /* wpi_stop() was called */ error = ENETDOWN; goto fail; @@ -2730,14 +2695,8 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf) if (ring->qid < WPI_CMD_QUEUE_NUM) { /* Mark TX ring as full if we reach a certain threshold. */ WPI_TXQ_STATE_LOCK(sc); - if (++ring->queued > WPI_TX_RING_HIMARK) { + if (++ring->queued > WPI_TX_RING_HIMARK) sc->qfullmsk |= 1 << ring->qid; - - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IF_UNLOCK(&ifp->if_snd); - } - callout_reset(&sc->tx_timeout, 5*hz, wpi_tx_timeout, sc); WPI_TXQ_STATE_UNLOCK(sc); } @@ -3031,24 +2990,47 @@ wpi_tx_data_raw(struct wpi_softc *sc, struct mbuf *m, return wpi_cmd2(sc, &tx_data); } +static __inline int +wpi_tx_ring_is_full(struct wpi_softc *sc, int ac) +{ + struct wpi_tx_ring *ring = &sc->txq[ac]; + int retval; + + WPI_TXQ_STATE_LOCK(sc); + retval = (ring->queued > WPI_TX_RING_HIMARK); + WPI_TXQ_STATE_UNLOCK(sc); + + return retval; +} + +static __inline void +wpi_handle_tx_failure(struct ieee80211_node *ni) +{ + /* NB: m is reclaimed on tx failure */ + if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); + ieee80211_free_node(ni); +} + static int wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct wpi_softc *sc = ifp->if_softc; - int error = 0; + struct wpi_softc *sc = ic->ic_softc; + int ac, error = 0; DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - ieee80211_free_node(ni); - m_freem(m); - return ENETDOWN; - } + ac = M_WME_GETAC(m); WPI_TX_LOCK(sc); + + if (sc->sc_running == 0 || wpi_tx_ring_is_full(sc, ac)) { + m_freem(m); + error = sc->sc_running ? ENOBUFS : ENETDOWN; + goto unlock; + } + if (params == NULL) { /* * Legacy path; interpret frame contents to decide @@ -3062,13 +3044,11 @@ wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, */ error = wpi_tx_data_raw(sc, m, ni, params); } - WPI_TX_UNLOCK(sc); + +unlock: WPI_TX_UNLOCK(sc); if (error != 0) { - /* NB: m is reclaimed on tx failure */ - ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - + wpi_handle_tx_failure(ni); DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__); return error; @@ -3079,57 +3059,88 @@ wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; } -/** - * Process data waiting to be sent on the IFNET output queue - */ -static void -wpi_start(struct ifnet *ifp) +static int +wpi_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct wpi_softc *sc = ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; struct ieee80211_node *ni; - struct mbuf *m; + struct mbufq *sndq; + int ac, error; WPI_TX_LOCK(sc); DPRINTF(sc, WPI_DEBUG_XMIT, "%s: called\n", __func__); - for (;;) { - IF_LOCK(&ifp->if_snd); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - (ifp->if_drv_flags & IFF_DRV_OACTIVE)) { - IF_UNLOCK(&ifp->if_snd); - break; - } - IF_UNLOCK(&ifp->if_snd); + /* Check if interface is up & running. */ + if (sc->sc_running == 0) { + error = ENXIO; + goto unlock; + } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; - if (wpi_tx_data(sc, m, ni) != 0) { - ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + /* Check for available space. */ + ac = M_WME_GETAC(m); + sndq = &sc->txq[ac].snd; + if (wpi_tx_ring_is_full(sc, ac) || mbufq_len(sndq) != 0) { + /* wpi_tx_done() will dequeue it. */ + error = mbufq_enqueue(sndq, m); + goto unlock; + } + + error = 0; + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + if (wpi_tx_data(sc, m, ni) != 0) { + wpi_handle_tx_failure(ni); + } + + DPRINTF(sc, WPI_DEBUG_XMIT, "%s: done\n", __func__); + +unlock: WPI_TX_UNLOCK(sc); + + return (error); +} + +/** + * Process data waiting to be sent on the output queue + */ +static void +wpi_start(void *arg0, int pending) +{ + struct wpi_softc *sc = arg0; + struct ieee80211_node *ni; + struct mbuf *m; + uint8_t i; + + WPI_TX_LOCK(sc); + if (sc->sc_running == 0) + goto unlock; + + DPRINTF(sc, WPI_DEBUG_XMIT, "%s: called\n", __func__); + + for (i = 0; i < WPI_CMD_QUEUE_NUM; i++) { + struct mbufq *sndq = &sc->txq[i].snd; + + for (;;) { + if (wpi_tx_ring_is_full(sc, i)) + break; + + if ((m = mbufq_dequeue(sndq)) == NULL) + break; + + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + if (wpi_tx_data(sc, m, ni) != 0) { + wpi_handle_tx_failure(ni); + } } } DPRINTF(sc, WPI_DEBUG_XMIT, "%s: done\n", __func__); - WPI_TX_UNLOCK(sc); -} - -static void -wpi_start_task(void *arg0, int pending) -{ - struct wpi_softc *sc = arg0; - struct ifnet *ifp = sc->sc_ifp; - - wpi_start(ifp); +unlock: WPI_TX_UNLOCK(sc); } static void wpi_watchdog_rfkill(void *arg) { struct wpi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; DPRINTF(sc, WPI_DEBUG_WATCHDOG, "RFkill Watchdog: tick\n"); @@ -3146,9 +3157,9 @@ static void wpi_scan_timeout(void *arg) { struct wpi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; - if_printf(ifp, "scan timeout\n"); + ic_printf(ic, "scan timeout\n"); taskqueue_enqueue(sc->sc_tq, &sc->sc_reinittask); } @@ -3156,44 +3167,28 @@ static void wpi_tx_timeout(void *arg) { struct wpi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = &sc->sc_ic; - if_printf(ifp, "device timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + ic_printf(ic, "device timeout\n"); taskqueue_enqueue(sc->sc_tq, &sc->sc_reinittask); } -static int -wpi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +wpi_parent(struct ieee80211com *ic) { - struct wpi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct wpi_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ifreq *ifr = (struct ifreq *) data; - int error = 0; - switch (cmd) { - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) { - wpi_init(sc); - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 && - vap != NULL) - ieee80211_stop(vap); - } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - wpi_stop(sc); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - default: - error = EINVAL; - break; - } - return error; + if (ic->ic_nrunning > 0) { + if (wpi_init(sc) == 0) { + ieee80211_notify_radio(ic, 1); + ieee80211_start_all(ic); + } else { + ieee80211_notify_radio(ic, 0); + ieee80211_stop(vap); + } + } else + wpi_stop(sc); } /* @@ -3215,9 +3210,13 @@ wpi_cmd(struct wpi_softc *sc, int code, const void *buf, size_t size, DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); - if (sc->txq_active == 0) { + if (sc->sc_running == 0) { /* wpi_stop() was called */ - error = 0; + if (code == WPI_CMD_SCAN) + error = ENETDOWN; + else + error = 0; + goto fail; } @@ -3283,10 +3282,7 @@ wpi_cmd(struct wpi_softc *sc, int code, const void *buf, size_t size, WPI_TXQ_UNLOCK(sc); - if (async) - return 0; - - return mtx_sleep(cmd, &sc->sc_mtx, PCATCH, "wpicmd", hz); + return async ? 0 : mtx_sleep(cmd, &sc->sc_mtx, PCATCH, "wpicmd", hz); fail: DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__); @@ -3301,8 +3297,7 @@ fail: DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__); static int wpi_mrr_setup(struct wpi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct wpi_mrr_setup mrr; int i, error; @@ -3399,14 +3394,13 @@ wpi_add_node(struct wpi_softc *sc, struct ieee80211_node *ni) static int wpi_add_broadcast_node(struct wpi_softc *sc, int async) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct wpi_node_info node; DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); memset(&node, 0, sizeof node); - IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr); + IEEE80211_ADDR_COPY(node.macaddr, ieee80211broadcastaddr); node.id = WPI_ID_BROADCAST; node.plcp = (ic->ic_curmode == IEEE80211_MODE_11A) ? wpi_ridx_to_plcp[WPI_RIDX_OFDM6] : wpi_ridx_to_plcp[WPI_RIDX_CCK1]; @@ -3492,7 +3486,7 @@ static int wpi_updateedca(struct ieee80211com *ic) { #define WPI_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */ - struct wpi_softc *sc = ic->ic_ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; struct wpi_edca_params cmd; int aci, error; @@ -3526,8 +3520,7 @@ wpi_updateedca(struct ieee80211com *ic) static void wpi_set_promisc(struct wpi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t promisc_filter; @@ -3535,7 +3528,7 @@ wpi_set_promisc(struct wpi_softc *sc) if (vap != NULL && vap->iv_opmode != IEEE80211_M_HOSTAP) promisc_filter |= WPI_FILTER_PROMISC; - if (ifp->if_flags & IFF_PROMISC) + if (ic->ic_promisc > 0) sc->rxon.filter |= htole32(promisc_filter); else sc->rxon.filter &= ~htole32(promisc_filter); @@ -3900,8 +3893,7 @@ wpi_send_rxon(struct wpi_softc *sc, int assoc, int async) static int wpi_config(struct wpi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_channel *c = ic->ic_curchan; int error; @@ -4011,7 +4003,7 @@ wpi_get_active_dwell_time(struct wpi_softc *sc, static uint16_t wpi_limit_dwell(struct wpi_softc *sc, uint16_t dwell_time) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); int bintval = 0; @@ -4068,8 +4060,7 @@ wpi_get_scan_pause_time(uint32_t time, uint16_t bintval) static int wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_scan_state *ss = ic->ic_scan; struct ieee80211vap *vap = ss->ss_vap; struct wpi_scan_hdr *hdr; @@ -4171,11 +4162,9 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c) 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, ifp->if_broadcastaddr); + IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr); IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr); - IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr); - *(uint16_t *)&wh->i_dur[0] = 0; /* filled by h/w */ - *(uint16_t *)&wh->i_seq[0] = 0; /* filled by h/w */ + IEEE80211_ADDR_COPY(wh->i_addr3, ieee80211broadcastaddr); frm = (uint8_t *)(wh + 1); frm = ieee80211_add_ssid(frm, NULL, 0); @@ -4206,7 +4195,6 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c) /* * Calculate the active/passive dwell times. */ - dwell_active = wpi_get_active_dwell_time(sc, c, nssid); dwell_passive = wpi_get_passive_dwell_time(sc, c); @@ -4324,7 +4312,7 @@ wpi_config_beacon(struct wpi_vap *wvp) struct ieee80211com *ic = wvp->wv_vap.iv_ic; struct ieee80211_beacon_offsets *bo = &wvp->wv_boff; struct wpi_buf *bcn = &wvp->wv_bcbuf; - struct wpi_softc *sc = ic->ic_ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; struct wpi_cmd_beacon *cmd = (struct wpi_cmd_beacon *)&bcn->data; struct ieee80211_tim_ie *tie; struct mbuf *m; @@ -4406,7 +4394,7 @@ wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni) static void wpi_update_beacon(struct ieee80211vap *vap, int item) { - struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct wpi_softc *sc = vap->iv_ic->ic_softc; struct wpi_vap *wvp = WPI_VAP(vap); struct wpi_buf *bcn = &wvp->wv_bcbuf; struct ieee80211_beacon_offsets *bo = &wvp->wv_boff; @@ -4448,7 +4436,7 @@ static void wpi_newassoc(struct ieee80211_node *ni, int isnew) { struct ieee80211vap *vap = ni->ni_vap; - struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct wpi_softc *sc = ni->ni_ic->ic_softc; struct wpi_node *wn = WPI_NODE(ni); int error; @@ -4575,7 +4563,7 @@ wpi_load_key(struct ieee80211_node *ni, const struct ieee80211_key *k) { const struct ieee80211_cipher *cip = k->wk_cipher; struct ieee80211vap *vap = ni->ni_vap; - struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct wpi_softc *sc = ni->ni_ic->ic_softc; struct wpi_node *wn = WPI_NODE(ni); struct wpi_node_info node; uint16_t kflags; @@ -4639,7 +4627,7 @@ wpi_load_key_cb(void *arg, struct ieee80211_node *ni) { const struct ieee80211_key *k = arg; struct ieee80211vap *vap = ni->ni_vap; - struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct wpi_softc *sc = ni->ni_ic->ic_softc; struct wpi_node *wn = WPI_NODE(ni); int error; @@ -4674,7 +4662,7 @@ static int wpi_del_key(struct ieee80211_node *ni, const struct ieee80211_key *k) { struct ieee80211vap *vap = ni->ni_vap; - struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct wpi_softc *sc = ni->ni_ic->ic_softc; struct wpi_node *wn = WPI_NODE(ni); struct wpi_node_info node; uint16_t kflags; @@ -4724,7 +4712,7 @@ wpi_del_key_cb(void *arg, struct ieee80211_node *ni) { const struct ieee80211_key *k = arg; struct ieee80211vap *vap = ni->ni_vap; - struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct wpi_softc *sc = ni->ni_ic->ic_softc; struct wpi_node *wn = WPI_NODE(ni); int error; @@ -4746,7 +4734,7 @@ wpi_process_key(struct ieee80211vap *vap, const struct ieee80211_key *k, int set) { struct ieee80211com *ic = vap->iv_ic; - struct wpi_softc *sc = ic->ic_ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; struct wpi_vap *wvp = WPI_VAP(vap); struct ieee80211_node *ni; int error, ni_ref = 0; @@ -5396,34 +5384,29 @@ static void wpi_radio_on(void *arg0, int pending) { struct wpi_softc *sc = arg0; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "RF switch: radio enabled\n"); - if (vap != NULL) { - wpi_init(sc); - ieee80211_init(vap); - } + WPI_LOCK(sc); + callout_stop(&sc->watchdog_rfkill); + WPI_UNLOCK(sc); - if (WPI_READ(sc, WPI_GP_CNTRL) & WPI_GP_CNTRL_RFKILL) { - WPI_LOCK(sc); - callout_stop(&sc->watchdog_rfkill); - WPI_UNLOCK(sc); - } + if (vap != NULL) + ieee80211_init(vap); } static void wpi_radio_off(void *arg0, int pending) { struct wpi_softc *sc = arg0; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "RF switch: radio disabled\n"); + ieee80211_notify_radio(ic, 0); wpi_stop(sc); if (vap != NULL) ieee80211_stop(vap); @@ -5433,19 +5416,16 @@ wpi_radio_off(void *arg0, int pending) WPI_UNLOCK(sc); } -static void -wpi_init(void *arg) +static int +wpi_init(struct wpi_softc *sc) { - struct wpi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - int error; + int error = 0; WPI_LOCK(sc); DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + if (sc->sc_running != 0) goto end; /* Check that the radio is not disabled by hardware switch. */ @@ -5454,6 +5434,7 @@ wpi_init(void *arg) "RF switch: radio disabled (%s)\n", __func__); callout_reset(&sc->watchdog_rfkill, hz, wpi_watchdog_rfkill, sc); + error = EINPROGRESS; goto end; } @@ -5462,9 +5443,11 @@ wpi_init(void *arg) device_printf(sc->sc_dev, "%s: could not read firmware, error %d\n", __func__, error); - goto fail; + goto end; } + sc->sc_running = 1; + /* Initialize hardware and upload firmware. */ error = wpi_hw_init(sc); wpi_unload_firmware(sc); @@ -5476,7 +5459,6 @@ wpi_init(void *arg) } /* Configure adapter now that it is ready. */ - sc->txq_active = 1; if ((error = wpi_config(sc)) != 0) { device_printf(sc->sc_dev, "%s: could not configure device, error %d\n", __func__, @@ -5484,34 +5466,34 @@ wpi_init(void *arg) goto fail; } - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - IF_UNLOCK(&ifp->if_snd); - DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__); WPI_UNLOCK(sc); - ieee80211_start_all(ic); - - return; + return 0; fail: wpi_stop_locked(sc); + end: DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__); WPI_UNLOCK(sc); + + return error; } static void wpi_stop_locked(struct wpi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; WPI_LOCK_ASSERT(sc); + if (sc->sc_running == 0) + return; + + WPI_TX_LOCK(sc); WPI_TXQ_LOCK(sc); - sc->txq_active = 0; + sc->sc_running = 0; WPI_TXQ_UNLOCK(sc); + WPI_TX_UNLOCK(sc); WPI_TXQ_STATE_LOCK(sc); callout_stop(&sc->tx_timeout); @@ -5522,10 +5504,6 @@ wpi_stop_locked(struct wpi_softc *sc) callout_stop(&sc->calib_to); WPI_RXON_UNLOCK(sc); - IF_LOCK(&ifp->if_snd); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - IF_UNLOCK(&ifp->if_snd); - /* Power OFF hardware. */ wpi_hw_stop(sc); } @@ -5544,7 +5522,7 @@ wpi_stop(struct wpi_softc *sc) static void wpi_scan_start(struct ieee80211com *ic) { - struct wpi_softc *sc = ic->ic_ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; wpi_set_led(sc, WPI_LED_LINK, 20, 2); } @@ -5555,8 +5533,7 @@ wpi_scan_start(struct ieee80211com *ic) static void wpi_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct wpi_softc *sc = ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); if (vap->iv_state == IEEE80211_S_RUN) @@ -5571,8 +5548,7 @@ static void wpi_set_channel(struct ieee80211com *ic) { const struct ieee80211_channel *c = ic->ic_curchan; - struct ifnet *ifp = ic->ic_ifp; - struct wpi_softc *sc = ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; int error; DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); @@ -5618,7 +5594,7 @@ wpi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) { struct ieee80211vap *vap = ss->ss_vap; struct ieee80211com *ic = vap->iv_ic; - struct wpi_softc *sc = ic->ic_ifp->if_softc; + struct wpi_softc *sc = ic->ic_softc; int error; WPI_RXON_LOCK(sc); @@ -5644,19 +5620,18 @@ static void wpi_hw_reset(void *arg, int pending) { struct wpi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); + ieee80211_notify_radio(ic, 0); if (vap != NULL && (ic->ic_flags & IEEE80211_F_SCAN)) ieee80211_cancel_scan(vap); wpi_stop(sc); - if (vap != NULL) + if (vap != NULL) { ieee80211_stop(vap); - wpi_init(sc); - if (vap != NULL) ieee80211_init(vap); + } } diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h index b7835281fb39..4e1baa5fdc50 100644 --- a/sys/dev/wpi/if_wpivar.h +++ b/sys/dev/wpi/if_wpivar.h @@ -72,6 +72,7 @@ struct wpi_tx_ring { struct wpi_tx_cmd *cmd; struct wpi_tx_data data[WPI_TX_RING_COUNT]; bus_dma_tag_t data_dmat; + struct mbufq snd; int qid; int queued; int cur; @@ -164,14 +165,15 @@ struct wpi_fw_info { struct wpi_softc { device_t sc_dev; - - struct ifnet *sc_ifp; int sc_debug; int sc_flags; #define WPI_PS_PATH (1 << 0) + int sc_running; struct mtx sc_mtx; + struct ieee80211com sc_ic; + struct mtx tx_mtx; /* Shared area. */ @@ -181,7 +183,6 @@ struct wpi_softc { struct wpi_tx_ring txq[WPI_NTXQUEUES]; struct mtx txq_mtx; struct mtx txq_state_mtx; - uint32_t txq_active; struct wpi_rx_ring rxq; uint64_t rx_tstamp; diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c index f6dbe77666f2..526ce54928d4 100644 --- a/sys/dev/wtap/if_wtap.c +++ b/sys/dev/wtap/if_wtap.c @@ -261,7 +261,7 @@ static int wtap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ieee80211com *ic = vap->iv_ic; - struct wtap_softc *sc = ic->ic_ifp->if_softc; + struct wtap_softc *sc = ic->ic_softc; struct wtap_vap *avp = WTAP_VAP(vap); struct ieee80211_node *ni = NULL; int error; @@ -318,7 +318,7 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct wtap_softc *sc = ic->ic_ifp->if_softc; + struct wtap_softc *sc = ic->ic_softc; struct ieee80211vap *vap; struct wtap_vap *avp; int error; @@ -326,15 +326,13 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], DWTAP_PRINTF("%s\n", __func__); - avp = malloc(sizeof(struct wtap_vap), M_80211_VAP, M_NOWAIT | M_ZERO); - if (avp == NULL) - return (NULL); + avp = malloc(sizeof(struct wtap_vap), M_80211_VAP, M_WAITOK | M_ZERO); avp->id = sc->id; avp->av_md = sc->sc_md; avp->av_bcinterval = msecs_to_ticks(BEACON_INTRERVAL + 100*sc->id); vap = (struct ieee80211vap *) avp; error = ieee80211_vap_setup(ic, vap, name, unit, IEEE80211_M_MBSS, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + flags | IEEE80211_CLONE_NOBEACONS, bssid); if (error) { free(avp, M_80211_VAP); return (NULL); @@ -351,9 +349,10 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], vap->iv_bmiss = wtap_bmiss; /* complete setup */ - ieee80211_vap_attach(vap, wtap_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, wtap_media_change, ieee80211_media_status, + mac); avp->av_dev = make_dev(&wtap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, - "%s", (const char *)ic->ic_ifp->if_xname); + "%s", (const char *)sc->name); /* TODO this is a hack to force it to choose the rate we want */ ni = ieee80211_ref_node(vap->iv_bss); @@ -374,148 +373,16 @@ wtap_vap_delete(struct ieee80211vap *vap) free((struct wtap_vap*) vap, M_80211_VAP); } -/* NB: This function is not used. - * I had the problem of the queue - * being empty all the time. - * Maybe I am setting the queue wrong? - */ static void -wtap_start(struct ifnet *ifp) +wtap_parent(struct ieee80211com *ic) { - struct ieee80211com *ic = ifp->if_l2com; - struct ifnet *icifp = ic->ic_ifp; - struct wtap_softc *sc = icifp->if_softc; - struct ieee80211_node *ni; - struct mbuf *m; + struct wtap_softc *sc = ic->ic_softc; - DWTAP_PRINTF("my_start, with id=%u\n", sc->id); - - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->up == 0) - return; - for (;;) { - if(IFQ_IS_EMPTY(&ifp->if_snd)){ - printf("queue empty, just trying to see " - "if the other queue is empty\n"); -#if 0 - printf("queue for id=1, %u\n", - IFQ_IS_EMPTY(&global_mscs[1]->ifp->if_snd)); - printf("queue for id=0, %u\n", - IFQ_IS_EMPTY(&global_mscs[0]->ifp->if_snd)); -#endif - break; - } - IFQ_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) { - printf("error dequeueing from ifp->snd\n"); - break; - } - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - /* - * Check for fragmentation. If this frame - * has been broken up verify we have enough - * buffers to send all the fragments so all - * go out or none... - */ -#if 0 - STAILQ_INIT(&frags); -#endif - if ((m->m_flags & M_FRAG)){ - printf("dont support frags\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - return; - } - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - if(wtap_raw_xmit(ni, m, NULL) < 0){ - printf("error raw_xmiting\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - return; - } - } -} - -static int -wtap_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ -#if 0 - DWTAP_PRINTF("%s\n", __func__); - uprintf("%s, command %lu\n", __func__, cmd); -#endif -#define IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct ieee80211com *ic = ifp->if_l2com; - struct wtap_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0; - - switch (cmd) { - case SIOCSIFFLAGS: - //printf("%s: %s\n", __func__, "SIOCSIFFLAGS"); - if (IS_RUNNING(ifp)) { - DWTAP_PRINTF("running\n"); -#if 0 - /* - * To avoid rescanning another access point, - * do not call ath_init() here. Instead, - * only reflect promisc mode settings. - */ - //ath_mode_init(sc); -#endif - } else if (ifp->if_flags & IFF_UP) { - DWTAP_PRINTF("up\n"); - sc->up = 1; -#if 0 - /* - * Beware of being called during attach/detach - * to reset promiscuous mode. In that case we - * will still be marked UP but not RUNNING. - * However trying to re-init the interface - * is the wrong thing to do as we've already - * torn down much of our state. There's - * probably a better way to deal with this. - */ - //if (!sc->sc_invalid) - // ath_init(sc); /* XXX lose error */ -#endif - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ieee80211_start_all(ic); - } else { - DWTAP_PRINTF("stoping\n"); -#if 0 - ath_stop_locked(ifp); -#ifdef notyet - /* XXX must wakeup in places like ath_vap_delete */ - if (!sc->sc_invalid) - ath_hal_setpower(sc->sc_ah, HAL_PM_FULL_SLEEP); -#endif -#endif - } - break; - case SIOCGIFMEDIA: - case SIOCSIFMEDIA: -#if 0 - DWTAP_PRINTF("%s: %s\n", __func__, "SIOCGIFMEDIA|SIOCSIFMEDIA"); -#endif - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: -#if 0 - DWTAP_PRINTF("%s: %s\n", __func__, "SIOCGIFADDR"); -#endif - error = ether_ioctl(ifp, cmd, data); - break; - default: - DWTAP_PRINTF("%s: %s [%lu]\n", __func__, "EINVAL", cmd); - error = EINVAL; - break; - } - return error; -#undef IS_RUNNING -} - -static void -wtap_init(void *arg){ - - DWTAP_PRINTF("%s\n", __func__); + if (ic->ic_nrunning > 0) { + sc->up = 1; + ieee80211_start_all(ic); + } else + sc->up = 0; } static void @@ -581,8 +448,7 @@ wtap_inject(struct wtap_softc *sc, struct mbuf *m) void wtap_rx_deliver(struct wtap_softc *sc, struct mbuf *m) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; int type; #if 0 @@ -591,11 +457,9 @@ wtap_rx_deliver(struct wtap_softc *sc, struct mbuf *m) DWTAP_PRINTF("[%d] receiving m=%p\n", sc->id, m); if (m == NULL) { /* NB: shouldn't happen */ - if_printf(ifp, "%s: no mbuf!\n", __func__); + ic_printf(ic, "%s: no mbuf!\n", __func__); } - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - ieee80211_dump_pkt(ic, mtod(m, caddr_t), 0,0,0); /* @@ -620,8 +484,7 @@ static void wtap_rx_proc(void *arg, int npending) { struct wtap_softc *sc = (struct wtap_softc *)arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mbuf *m; struct ieee80211_node *ni; int type; @@ -644,12 +507,10 @@ wtap_rx_proc(void *arg, int npending) m = bf->m; DWTAP_PRINTF("[%d] receiving m=%p\n", sc->id, bf->m); if (m == NULL) { /* NB: shouldn't happen */ - if_printf(ifp, "%s: no mbuf!\n", __func__); + ic_printf(ic, "%s: no mbuf!\n", __func__); free(bf, M_WTAP_RXBUF); return; } - - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); #if 0 ieee80211_dump_pkt(ic, mtod(m, caddr_t), 0,0,0); #endif @@ -716,7 +577,7 @@ wtap_update_promisc(struct ieee80211com *ic) } static int -wtap_if_transmit(struct ifnet *ifp, struct mbuf *m) +wtap_transmit(struct ieee80211com *ic, struct mbuf *m) { struct ieee80211_node *ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; @@ -753,7 +614,7 @@ static void wtap_node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct wtap_softc *sc = ic->ic_ifp->if_softc; + struct wtap_softc *sc = ic->ic_softc; DWTAP_PRINTF("%s\n", __func__); sc->sc_node_free(ni); @@ -762,41 +623,17 @@ wtap_node_free(struct ieee80211_node *ni) int32_t wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr) { - struct ifnet *ifp; - struct ieee80211com *ic; - char wtap_name[] = {'w','T','a','p',sc->id, - '_','t','a','s','k','q','\0'}; + struct ieee80211com *ic = &sc->sc_ic; DWTAP_PRINTF("%s\n", __func__); - ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - printf("can not if_alloc()\n"); - return -1; - } - ic = ifp->if_l2com; - if_initname(ifp, "wtap", sc->id); - - sc->sc_ifp = ifp; sc->up = 0; - STAILQ_INIT(&sc->sc_rxbuf); - sc->sc_tq = taskqueue_create(wtap_name, M_NOWAIT | M_ZERO, + sc->sc_tq = taskqueue_create("wtap_taskq", M_NOWAIT | M_ZERO, taskqueue_thread_enqueue, &sc->sc_tq); - taskqueue_start_threads(&sc->sc_tq, 1, PI_SOFT, "%s taskQ", - ifp->if_xname); + taskqueue_start_threads(&sc->sc_tq, 1, PI_SOFT, "%s taskQ", sc->name); TASK_INIT(&sc->sc_rxtask, 0, wtap_rx_proc, sc); - ifp->if_softc = sc; - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; - ifp->if_start = wtap_start; - ifp->if_ioctl = wtap_ioctl; - ifp->if_init = wtap_init; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = sc->name; ic->ic_phytype = IEEE80211_T_DS; @@ -815,17 +652,8 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr) ic->ic_channels[0].ic_flags = IEEE80211_CHAN_B; ic->ic_channels[0].ic_freq = 2412; - ieee80211_ifattach(ic, macaddr); - -#if 0 - /* new prototype hook-ups */ - msc->if_input = ifp->if_input; - ifp->if_input = myath_if_input; - msc->if_output = ifp->if_output; - ifp->if_output = myath_if_output; -#endif - sc->if_transmit = ifp->if_transmit; - ifp->if_transmit = wtap_if_transmit; + IEEE80211_ADDR_COPY(ic->ic_macaddr, macaddr); + ieee80211_ifattach(ic); /* override default methods */ ic->ic_newassoc = wtap_newassoc; @@ -835,15 +663,14 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr) ic->ic_raw_xmit = wtap_raw_xmit; ic->ic_update_mcast = wtap_update_mcast; ic->ic_update_promisc = wtap_update_promisc; + ic->ic_transmit = wtap_transmit; + ic->ic_parent = wtap_parent; sc->sc_node_alloc = ic->ic_node_alloc; ic->ic_node_alloc = wtap_node_alloc; sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = wtap_node_free; -#if 0 - ic->ic_node_getsignal = myath_node_getsignal; -#endif ic->ic_scan_start = wtap_scan_start; ic->ic_scan_end = wtap_scan_end; ic->ic_set_channel = wtap_set_channel; @@ -882,13 +709,11 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr) int32_t wtap_detach(struct wtap_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; DWTAP_PRINTF("%s\n", __func__); ieee80211_ageq_drain(&ic->ic_stageq); ieee80211_ifdetach(ic); - if_free(ifp); return 0; } diff --git a/sys/dev/wtap/if_wtapvar.h b/sys/dev/wtap/if_wtapvar.h index a886be93258b..04a1818d5c41 100644 --- a/sys/dev/wtap/if_wtapvar.h +++ b/sys/dev/wtap/if_wtapvar.h @@ -130,18 +130,14 @@ struct wtap_vap { struct taskqueue; struct wtap_softc { + struct ieee80211com sc_ic; char name[7]; /* wtapXX\0 */ int32_t id; int32_t up; - struct ifnet *sc_ifp; /* interface common */ struct wtap_medium *sc_md; /* interface medium */ struct ieee80211_node* (* sc_node_alloc) (struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN]); void (*sc_node_free)(struct ieee80211_node *); - int (*if_output) /* output routine (enqueue) */ - (struct ifnet *, struct mbuf *, struct sockaddr *, struct route *); - void (*if_input) (struct ifnet *, struct mbuf *);/* from h/w driver */ - int (*if_transmit)(struct ifnet *, struct mbuf *);/* output routine */ struct mtx sc_mtx; /* master lock (recursive) */ struct taskqueue *sc_tq; /* private task queue */ wtap_bufhead sc_rxbuf; /* receive buffer */ diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 3902227e8c43..39e03eaff93f 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -91,8 +92,6 @@ static void ieee80211_syncflag_ext_locked(struct ieee80211com *ic, int flag); static int ieee80211_media_setup(struct ieee80211com *ic, struct ifmedia *media, int caps, int addsta, ifm_change_cb_t media_change, ifm_stat_cb_t media_stat); -static void ieee80211com_media_status(struct ifnet *, struct ifmediareq *); -static int ieee80211com_media_change(struct ifnet *); static int media_status(enum ieee80211_opmode, const struct ieee80211_channel *); static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter); @@ -121,7 +120,7 @@ static const struct ieee80211_rateset ieee80211_rateset_11g = * all available channels as active, and pick * a default channel if not already specified. */ -static void +void ieee80211_chan_init(struct ieee80211com *ic) { #define DEFAULTRATES(m, def) do { \ @@ -238,29 +237,6 @@ null_update_promisc(struct ieee80211com *ic) ic_printf(ic, "need promiscuous mode update callback\n"); } -static int -null_transmit(struct ifnet *ifp, struct mbuf *m) -{ - m_freem(m); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - return EACCES; /* XXX EIO/EPERM? */ -} - -static int -null_output(struct ifnet *ifp, struct mbuf *m, - const struct sockaddr *dst, struct route *ro) -{ - if_printf(ifp, "discard raw packet\n"); - return null_transmit(ifp, m); -} - -static void -null_input(struct ifnet *ifp, struct mbuf *m) -{ - if_printf(ifp, "if_input should not be called\n"); - m_freem(m); -} - static void null_update_chw(struct ieee80211com *ic) { @@ -281,19 +257,43 @@ ic_printf(struct ieee80211com *ic, const char * fmt, ...) return (retval); } +static LIST_HEAD(, ieee80211com) ic_head = LIST_HEAD_INITIALIZER(ic_head); +static struct mtx ic_list_mtx; +MTX_SYSINIT(ic_list, &ic_list_mtx, "ieee80211com list", MTX_DEF); + +static int +sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS) +{ + struct ieee80211com *ic; + struct sbuf *sb; + char *sp; + int error; + + sb = sbuf_new_auto(); + sp = ""; + mtx_lock(&ic_list_mtx); + LIST_FOREACH(ic, &ic_head, ic_next) { + sbuf_printf(sb, "%s%s", sp, ic->ic_name); + sp = " "; + } + mtx_unlock(&ic_list_mtx); + sbuf_finish(sb); + error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1); + sbuf_delete(sb); + return (error); +} + +SYSCTL_PROC(_net_wlan, OID_AUTO, devices, + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, + sysctl_ieee80211coms, "A", "names of available 802.11 devices"); + /* * Attach/setup the common net80211 state. Called by * the driver on attach to prior to creating any vap's. */ void -ieee80211_ifattach(struct ieee80211com *ic, - const uint8_t macaddr[IEEE80211_ADDR_LEN]) +ieee80211_ifattach(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct sockaddr_dl *sdl; - struct ifaddr *ifa; - - KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type)); IEEE80211_LOCK_INIT(ic, ic->ic_name); IEEE80211_TX_LOCK_INIT(ic, ic->ic_name); @@ -311,7 +311,7 @@ ieee80211_ifattach(struct ieee80211com *ic, * available channels as active, and pick a default * channel if not already specified. */ - ieee80211_media_init(ic); + ieee80211_chan_init(ic); ic->ic_update_mcast = null_update_mcast; ic->ic_update_promisc = null_update_promisc; @@ -336,28 +336,9 @@ ieee80211_ifattach(struct ieee80211com *ic, ieee80211_sysctl_attach(ic); - ifp->if_addrlen = IEEE80211_ADDR_LEN; - ifp->if_hdrlen = 0; - - CURVNET_SET(vnet0); - - if_attach(ifp); - - ifp->if_mtu = IEEE80211_MTU_MAX; - ifp->if_broadcastaddr = ieee80211broadcastaddr; - ifp->if_output = null_output; - ifp->if_input = null_input; /* just in case */ - ifp->if_resolvemulti = NULL; /* NB: callers check */ - - ifa = ifaddr_byindex(ifp->if_index); - KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__)); - sdl = (struct sockaddr_dl *)ifa->ifa_addr; - sdl->sdl_type = IFT_ETHER; /* XXX IFT_IEEE80211? */ - sdl->sdl_alen = IEEE80211_ADDR_LEN; - IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr); - ifa_free(ifa); - - CURVNET_RESTORE(); + mtx_lock(&ic_list_mtx); + LIST_INSERT_HEAD(&ic_head, ic, ic_next); + mtx_unlock(&ic_list_mtx); } /* @@ -369,16 +350,11 @@ ieee80211_ifattach(struct ieee80211com *ic, void ieee80211_ifdetach(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; struct ieee80211vap *vap; - /* - * This detaches the main interface, but not the vaps. - * Each VAP may be in a separate VIMAGE. - */ - CURVNET_SET(ifp->if_vnet); - if_detach(ifp); - CURVNET_RESTORE(); + mtx_lock(&ic_list_mtx); + LIST_REMOVE(ic, ic_next); + mtx_unlock(&ic_list_mtx); /* * The VAP is responsible for setting and clearing @@ -402,8 +378,6 @@ ieee80211_ifdetach(struct ieee80211com *ic) ieee80211_power_detach(ic); ieee80211_node_detach(ic); - /* XXX VNET needed? */ - ifmedia_removeall(&ic->ic_media); counter_u64_free(ic->ic_ierrors); counter_u64_free(ic->ic_oerrors); @@ -412,6 +386,20 @@ ieee80211_ifdetach(struct ieee80211com *ic) IEEE80211_LOCK_DESTROY(ic); } +struct ieee80211com * +ieee80211_find_com(const char *name) +{ + struct ieee80211com *ic; + + mtx_lock(&ic_list_mtx); + LIST_FOREACH(ic, &ic_head, ic_next) + if (strcmp(ic->ic_name, name) == 0) + break; + mtx_unlock(&ic_list_mtx); + + return (ic); +} + /* * Default reset method for use with the ioctl support. This * method is invoked after any state change in the 802.11 @@ -460,8 +448,7 @@ ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt) int ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t macaddr[IEEE80211_ADDR_LEN]) + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN]) { struct ifnet *ifp; @@ -490,6 +477,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, vap->iv_htextcaps = ic->ic_htextcaps; vap->iv_opmode = opmode; vap->iv_caps |= ieee80211_opcap[opmode]; + vap->iv_myaddr = ic->ic_macaddr; switch (opmode) { case IEEE80211_M_WDS: /* @@ -556,8 +544,6 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, */ vap->iv_reset = default_reset; - IEEE80211_ADDR_COPY(vap->iv_myaddr, macaddr); - ieee80211_sysctl_vattach(vap); ieee80211_crypto_vattach(vap); ieee80211_node_vattach(vap); @@ -581,8 +567,8 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, * from this call the vap is ready for use. */ int -ieee80211_vap_attach(struct ieee80211vap *vap, - ifm_change_cb_t media_change, ifm_stat_cb_t media_stat) +ieee80211_vap_attach(struct ieee80211vap *vap, ifm_change_cb_t media_change, + ifm_stat_cb_t media_stat, const uint8_t macaddr[IEEE80211_ADDR_LEN]) { struct ifnet *ifp = vap->iv_ifp; struct ieee80211com *ic = vap->iv_ic; @@ -610,7 +596,8 @@ ieee80211_vap_attach(struct ieee80211vap *vap, if (maxrate) ifp->if_baudrate = IF_Mbps(maxrate); - ether_ifattach(ifp, vap->iv_myaddr); + ether_ifattach(ifp, macaddr); + vap->iv_myaddr = IF_LLADDR(ifp); /* hook output method setup by ether_ifattach */ vap->iv_output = ifp->if_output; ifp->if_output = ieee80211_output; @@ -626,8 +613,6 @@ ieee80211_vap_attach(struct ieee80211vap *vap, ieee80211_syncflag_locked(ic, IEEE80211_F_BURST); ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT); ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40); - ieee80211_syncifflag_locked(ic, IFF_PROMISC); - ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); IEEE80211_UNLOCK(ic); return 1; @@ -677,8 +662,10 @@ ieee80211_vap_detach(struct ieee80211vap *vap) ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40); /* NB: this handles the bpfdetach done below */ ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF); - ieee80211_syncifflag_locked(ic, IFF_PROMISC); - ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); + if (vap->iv_ifflags & IFF_PROMISC) + ieee80211_promisc(vap, false); + if (vap->iv_ifflags & IFF_ALLMULTI) + ieee80211_allmulti(vap, false); IEEE80211_UNLOCK(ic); ifmedia_removeall(&vap->iv_media); @@ -703,49 +690,57 @@ ieee80211_vap_detach(struct ieee80211vap *vap) } /* - * Synchronize flag bit state in the parent ifnet structure - * according to the state of all vap ifnet's. This is used, - * for example, to handle IFF_PROMISC and IFF_ALLMULTI. + * Count number of vaps in promisc, and issue promisc on + * parent respectively. */ void -ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag) +ieee80211_promisc(struct ieee80211vap *vap, bool on) { - struct ifnet *ifp = ic->ic_ifp; - struct ieee80211vap *vap; - int bit, oflags; + struct ieee80211com *ic = vap->iv_ic; - IEEE80211_LOCK_ASSERT(ic); + /* + * XXX the bridge sets PROMISC but we don't want to + * enable it on the device, discard here so all the + * drivers don't need to special-case it + */ + if (!(vap->iv_opmode == IEEE80211_M_MONITOR || + (vap->iv_opmode == IEEE80211_M_AHDEMO && + (vap->iv_caps & IEEE80211_C_TDMA) == 0))) + return; - bit = 0; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_ifp->if_flags & flag) { - /* - * XXX the bridge sets PROMISC but we don't want to - * enable it on the device, discard here so all the - * drivers don't need to special-case it - */ - if (flag == IFF_PROMISC && - !(vap->iv_opmode == IEEE80211_M_MONITOR || - (vap->iv_opmode == IEEE80211_M_AHDEMO && - (vap->iv_caps & IEEE80211_C_TDMA) == 0))) - continue; - bit = 1; - break; - } - oflags = ifp->if_flags; - if (bit) - ifp->if_flags |= flag; - else - ifp->if_flags &= ~flag; - if ((ifp->if_flags ^ oflags) & flag) { - /* XXX should we return 1/0 and let caller do this? */ - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if (flag == IFF_PROMISC) - ieee80211_runtask(ic, &ic->ic_promisc_task); - else if (flag == IFF_ALLMULTI) - ieee80211_runtask(ic, &ic->ic_mcast_task); - } + IEEE80211_LOCK(ic); + if (on) { + if (++ic->ic_promisc == 1) + ieee80211_runtask(ic, &ic->ic_promisc_task); + } else { + KASSERT(ic->ic_promisc > 0, ("%s: ic %p not promisc", + __func__, ic)); + if (--ic->ic_promisc == 0) + ieee80211_runtask(ic, &ic->ic_promisc_task); } + IEEE80211_UNLOCK(ic); +} + +/* + * Count number of vaps in allmulti, and issue allmulti on + * parent respectively. + */ +void +ieee80211_allmulti(struct ieee80211vap *vap, bool on) +{ + struct ieee80211com *ic = vap->iv_ic; + + IEEE80211_LOCK(ic); + if (on) { + if (++ic->ic_allmulti == 1) + ieee80211_runtask(ic, &ic->ic_mcast_task); + } else { + KASSERT(ic->ic_allmulti > 0, ("%s: ic %p not allmulti", + __func__, ic)); + if (--ic->ic_allmulti == 0) + ieee80211_runtask(ic, &ic->ic_mcast_task); + } + IEEE80211_UNLOCK(ic); } /* @@ -1234,39 +1229,6 @@ ieee80211_media_setup(struct ieee80211com *ic, return maxrate; } -void -ieee80211_media_init(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - int maxrate; - - /* NB: this works because the structure is initialized to zero */ - if (!LIST_EMPTY(&ic->ic_media.ifm_list)) { - /* - * We are re-initializing the channel list; clear - * the existing media state as the media routines - * don't suppress duplicates. - */ - ifmedia_removeall(&ic->ic_media); - } - ieee80211_chan_init(ic); - - /* - * Recalculate media settings in case new channel list changes - * the set of available modes. - */ - maxrate = ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, 1, - ieee80211com_media_change, ieee80211com_media_status); - /* NB: strip explicit mode; we're actually in autoselect */ - ifmedia_set(&ic->ic_media, - media_status(ic->ic_opmode, ic->ic_curchan) &~ - (IFM_MMASK | IFM_IEEE80211_TURBO)); - if (maxrate) - ifp->if_baudrate = IF_Mbps(maxrate); - - /* XXX need to propagate new media settings to vap's */ -} - /* XXX inline or eliminate? */ const struct ieee80211_rateset * ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c) @@ -1394,15 +1356,6 @@ media2mode(const struct ifmedia_entry *ime, uint32_t flags, uint16_t *mode) return 1; } -/* - * Handle a media change request on the underlying interface. - */ -int -ieee80211com_media_change(struct ifnet *ifp) -{ - return EINVAL; -} - /* * Handle a media change request on the vap interface. */ @@ -1480,23 +1433,6 @@ media_status(enum ieee80211_opmode opmode, const struct ieee80211_channel *chan) return status; } -static void -ieee80211com_media_status(struct ifnet *ifp, struct ifmediareq *imr) -{ - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap; - - imr->ifm_status = IFM_AVALID; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) - if (vap->iv_ifp->if_flags & IFF_UP) { - imr->ifm_status |= IFM_ACTIVE; - break; - } - imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan); - if (imr->ifm_status & IFM_ACTIVE) - imr->ifm_current = imr->ifm_active; -} - void ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr) { diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c index e646cf2b7417..ae4910c6ee0d 100644 --- a/sys/net80211/ieee80211_ddb.c +++ b/sys/net80211/ieee80211_ddb.c @@ -520,7 +520,7 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap); db_printf("\n"); - db_printf("\tifp %p(%s)", ic->ic_ifp, ic->ic_ifp->if_xname); + db_printf("\tsoftc %p", ic->ic_softc); db_printf("\tname %s", ic->ic_name); db_printf(" comlock %p", &ic->ic_comlock); db_printf("\n"); @@ -528,7 +528,6 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta, db_printf(" phytype %d", ic->ic_phytype); db_printf(" opmode %s", ieee80211_opmode_name[ic->ic_opmode]); db_printf("\n"); - db_printf("\tmedia %p", &ic->ic_media); db_printf(" inact %p", &ic->ic_inact); db_printf("\n"); diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index 3af75dfc78c0..9a8e94172030 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -69,58 +69,27 @@ static MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state"); static const char wlanname[] = "wlan"; static struct if_clone *wlan_cloner; -/* - * Allocate/free com structure in conjunction with ifnet; - * these routines are registered with if_register_com_alloc - * below and are called automatically by the ifnet code - * when the ifnet of the parent device is created. - */ -static void * -wlan_alloc(u_char type, struct ifnet *ifp) -{ - struct ieee80211com *ic; - - ic = IEEE80211_MALLOC(sizeof(struct ieee80211com), M_80211_COM, - IEEE80211_M_WAITOK | IEEE80211_M_ZERO); - ic->ic_ifp = ifp; - - return (ic); -} - -static void -wlan_free(void *ic, u_char type) -{ - IEEE80211_FREE(ic, M_80211_COM); -} - static int wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params) { struct ieee80211_clone_params cp; struct ieee80211vap *vap; struct ieee80211com *ic; - struct ifnet *ifp; int error; error = copyin(params, &cp, sizeof(cp)); if (error) return error; - ifp = ifunit(cp.icp_parent); - if (ifp == NULL) + ic = ieee80211_find_com(cp.icp_parent); + if (ic == NULL) return ENXIO; - /* XXX move printfs to DIAGNOSTIC before release */ - if (ifp->if_type != IFT_IEEE80211) { - if_printf(ifp, "%s: reject, not an 802.11 device\n", __func__); - return ENXIO; - } if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) { - if_printf(ifp, "%s: invalid opmode %d\n", - __func__, cp.icp_opmode); + ic_printf(ic, "%s: invalid opmode %d\n", __func__, + cp.icp_opmode); return EINVAL; } - ic = ifp->if_l2com; if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) { - if_printf(ifp, "%s mode not supported\n", + ic_printf(ic, "%s mode not supported\n", ieee80211_opmode_name[cp.icp_opmode]); return EOPNOTSUPP; } @@ -131,13 +100,13 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params) (1) #endif ) { - if_printf(ifp, "TDMA not supported\n"); + ic_printf(ic, "TDMA not supported\n"); return EOPNOTSUPP; } vap = ic->ic_vap_create(ic, wlanname, unit, cp.icp_opmode, cp.icp_flags, cp.icp_bssid, cp.icp_flags & IEEE80211_CLONE_MACADDR ? - cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp)); + cp.icp_macaddr : ic->ic_macaddr); return (vap == NULL ? EIO : 0); } @@ -528,17 +497,19 @@ ieee80211_process_callback(struct ieee80211_node *ni, * (the callers will first need modifying.) */ int -ieee80211_parent_xmitpkt(struct ieee80211com *ic, - struct mbuf *m) +ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m) { - struct ifnet *parent = ic->ic_ifp; + int error; + /* * Assert the IC TX lock is held - this enforces the * processing -> queuing order is maintained */ IEEE80211_TX_LOCK_ASSERT(ic); - - return (parent->if_transmit(parent, m)); + error = ic->ic_transmit(ic, m); + if (error) + m_freem(m); + return (error); } /* @@ -836,7 +807,6 @@ ieee80211_load_module(const char *modname) } static eventhandler_tag wlan_bpfevent; -static eventhandler_tag wlan_ifllevent; static void bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach) @@ -864,33 +834,6 @@ bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach) } } -static void -wlan_iflladdr(void *arg __unused, struct ifnet *ifp) -{ - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap, *next; - - if (ifp->if_type != IFT_IEEE80211 || ic == NULL) - return; - - IEEE80211_LOCK(ic); - TAILQ_FOREACH_SAFE(vap, &ic->ic_vaps, iv_next, next) { - /* - * If the MAC address has changed on the parent and it was - * copied to the vap on creation then re-sync. - */ - if (vap->iv_ic == ic && - (vap->iv_flags_ext & IEEE80211_FEXT_UNIQMAC) == 0) { - IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp)); - IEEE80211_UNLOCK(ic); - if_setlladdr(vap->iv_ifp, IF_LLADDR(ifp), - IEEE80211_ADDR_LEN); - IEEE80211_LOCK(ic); - } - } - IEEE80211_UNLOCK(ic); -} - /* * Module glue. * @@ -905,17 +848,12 @@ wlan_modevent(module_t mod, int type, void *unused) printf("wlan: <802.11 Link Layer>\n"); wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track, bpf_track, 0, EVENTHANDLER_PRI_ANY); - wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event, - wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY); wlan_cloner = if_clone_simple(wlanname, wlan_clone_create, wlan_clone_destroy, 0); - if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free); return 0; case MOD_UNLOAD: - if_deregister_com_alloc(IFT_IEEE80211); if_clone_detach(wlan_cloner); EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent); - EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent); return 0; } return EINVAL; diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 54ab39072ecc..1c7ddb9e15e4 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -1329,13 +1329,12 @@ static int setmlme_dropsta(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], struct mlmeop *mlmeop) { - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node_table *nt = &ic->ic_sta; + struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta; struct ieee80211_node *ni; int error = 0; /* NB: the broadcast address means do 'em all */ - if (!IEEE80211_ADDR_EQ(mac, ic->ic_ifp->if_broadcastaddr)) { + if (!IEEE80211_ADDR_EQ(mac, vap->iv_ifp->if_broadcastaddr)) { IEEE80211_NODE_LOCK(nt); ni = ieee80211_find_node_locked(nt, mac); IEEE80211_NODE_UNLOCK(nt); @@ -2529,14 +2528,9 @@ ieee80211_scanreq(struct ieee80211vap *vap, struct ieee80211_scan_req *sr) static __noinline int ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq) { - struct ieee80211com *ic = vap->iv_ic; struct ieee80211_scan_req sr; /* XXX off stack? */ int error; - /* NB: parent must be running */ - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return ENXIO; - if (ireq->i_len != sizeof(sr)) return EINVAL; error = copyin(ireq->i_data, &sr, sizeof(sr)); @@ -3300,41 +3294,6 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r return error; } -/* - * Rebuild the parent's multicast address list after an add/del - * of a multicast address for a vap. We have no way to tell - * what happened above to optimize the work so we purge the entire - * list and rebuild from scratch. This is way expensive. - * Note also the half-baked workaround for if_addmulti calling - * back to the parent device; there's no way to insert mcast - * entries quietly and/or cheaply. - */ -static void -ieee80211_ioctl_updatemulti(struct ieee80211com *ic) -{ - struct ifnet *parent = ic->ic_ifp; - struct ieee80211vap *vap; - void *ioctl; - - IEEE80211_LOCK(ic); - if_delallmulti(parent); - ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */ - parent->if_ioctl = NULL; - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { - struct ifnet *ifp = vap->iv_ifp; - struct ifmultiaddr *ifma; - - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - (void) if_addmulti(parent, ifma->ifma_addr, NULL); - } - } - parent->if_ioctl = ioctl; - ieee80211_runtask(ic, &ic->ic_mcast_task); - IEEE80211_UNLOCK(ic); -} - int ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { @@ -3347,8 +3306,11 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) switch (cmd) { case SIOCSIFFLAGS: IEEE80211_LOCK(ic); - ieee80211_syncifflag_locked(ic, IFF_PROMISC); - ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); + if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_PROMISC) + ieee80211_promisc(vap, ifp->if_flags & IFF_PROMISC); + if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_ALLMULTI) + ieee80211_allmulti(vap, ifp->if_flags & IFF_ALLMULTI); + vap->iv_ifflags = ifp->if_flags; if (ifp->if_flags & IFF_UP) { /* * Bring ourself up unless we're already operational. @@ -3371,7 +3333,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; case SIOCADDMULTI: case SIOCDELMULTI: - ieee80211_ioctl_updatemulti(ic); + ieee80211_runtask(ic, &ic->ic_mcast_task); break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: @@ -3427,17 +3389,16 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } break; - /* Pass NDIS ioctls up to the driver */ - case SIOCGDRVSPEC: - case SIOCSDRVSPEC: - case SIOCGPRIVATE_0: { - struct ifnet *parent = vap->iv_ic->ic_ifp; - error = parent->if_ioctl(parent, cmd, data); - break; - } default: + /* + * Pass unknown ioctls first to the driver, and if it + * returns ENOTTY, then to the generic Ethernet handler. + */ + if (ic->ic_ioctl != NULL && + (error = ic->ic_ioctl(ic, cmd, data)) != ENOTTY) + break; error = ether_ioctl(ifp, cmd, data); break; } - return error; + return (error); } diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index d11628df04ac..eb333da139cb 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -254,10 +254,6 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m, /* NB: IFQ_HANDOFF reclaims mbuf */ ieee80211_free_node(ni); if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - } else { - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - if_inc_counter(ifp, IFCOUNTER_OMCASTS, mcast); - if_inc_counter(ifp, IFCOUNTER_OBYTES, len); } ic->ic_lastdata = ticks; @@ -430,17 +426,6 @@ ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m) { struct ieee80211vap *vap = ifp->if_softc; struct ieee80211com *ic = vap->iv_ic; - struct ifnet *parent = ic->ic_ifp; - - /* NB: parent must be up and running */ - if (!IFNET_IS_UP_RUNNING(parent)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, - "%s: ignore queue, parent %s not up+running\n", - __func__, parent->if_xname); - m_freem(m); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - return (ENETDOWN); - } /* * No data frames go out unless we're running. @@ -507,6 +492,7 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = vap->iv_ic; + int error; /* * Set node - the caller has taken a reference, so ensure @@ -528,7 +514,10 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni, if (params) (void) ieee80211_add_xmit_params(m, params); - return (ic->ic_raw_xmit(ni, m, params)); + error = ic->ic_raw_xmit(ni, m, params); + if (error) + if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, 1); + return (error); } /* @@ -3457,6 +3446,15 @@ ieee80211_tx_complete(struct ieee80211_node *ni, struct mbuf *m, int status) { if (ni != NULL) { + struct ifnet *ifp = ni->ni_vap->iv_ifp; + + if (status == 0) { + if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + if (m->m_flags & M_MCAST) + if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1); + } else + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); if (m->m_flags & M_TXCB) ieee80211_process_callback(ni, m, status); ieee80211_free_node(ni); diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c index 91668cc7c0d2..2d216c2ac7c8 100644 --- a/sys/net80211/ieee80211_power.c +++ b/sys/net80211/ieee80211_power.c @@ -418,7 +418,6 @@ pwrsave_flushq(struct ieee80211_node *ni) struct ieee80211com *ic = ni->ni_ic; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_psq_head *qhead; - struct ifnet *parent, *ifp; struct mbuf *parent_q = NULL, *ifp_q = NULL; struct mbuf *m; @@ -429,59 +428,51 @@ pwrsave_flushq(struct ieee80211_node *ni) qhead = &psq->psq_head[0]; /* 802.11 frames */ if (qhead->head != NULL) { /* XXX could dispatch through vap and check M_ENCAP */ - parent = vap->iv_ic->ic_ifp; /* XXX need different driver interface */ /* XXX bypasses q max and OACTIVE */ parent_q = qhead->head; qhead->head = qhead->tail = NULL; qhead->len = 0; - } else - parent = NULL; + } qhead = &psq->psq_head[1]; /* 802.3 frames */ if (qhead->head != NULL) { - ifp = vap->iv_ifp; /* XXX need different driver interface */ /* XXX bypasses q max and OACTIVE */ ifp_q = qhead->head; qhead->head = qhead->tail = NULL; qhead->len = 0; - } else - ifp = NULL; + } psq->psq_len = 0; IEEE80211_PSQ_UNLOCK(psq); /* NB: do this outside the psq lock */ /* XXX packets might get reordered if parent is OACTIVE */ /* parent frames, should be encapsulated */ - if (parent != NULL) { - while (parent_q != NULL) { - m = parent_q; - parent_q = m->m_nextpkt; - m->m_nextpkt = NULL; - /* must be encapsulated */ - KASSERT((m->m_flags & M_ENCAP), - ("%s: parentq with non-M_ENCAP frame!\n", - __func__)); - /* - * For encaped frames, we need to free the node - * reference upon failure. - */ - if (ieee80211_parent_xmitpkt(ic, m) != 0) - ieee80211_free_node(ni); - } + while (parent_q != NULL) { + m = parent_q; + parent_q = m->m_nextpkt; + m->m_nextpkt = NULL; + /* must be encapsulated */ + KASSERT((m->m_flags & M_ENCAP), + ("%s: parentq with non-M_ENCAP frame!\n", + __func__)); + /* + * For encaped frames, we need to free the node + * reference upon failure. + */ + if (ieee80211_parent_xmitpkt(ic, m) != 0) + ieee80211_free_node(ni); } /* VAP frames, aren't encapsulated */ - if (ifp != NULL) { - while (ifp_q != NULL) { - m = ifp_q; - ifp_q = m->m_nextpkt; - m->m_nextpkt = NULL; - KASSERT((!(m->m_flags & M_ENCAP)), - ("%s: vapq with M_ENCAP frame!\n", __func__)); - (void) ieee80211_vap_xmitpkt(vap, m); - } + while (ifp_q != NULL) { + m = ifp_q; + ifp_q = m->m_nextpkt; + m->m_nextpkt = NULL; + KASSERT((!(m->m_flags & M_ENCAP)), + ("%s: vapq with M_ENCAP frame!\n", __func__)); + (void) ieee80211_vap_xmitpkt(vap, m); } } diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 01c60e1614e5..7adf0445d7fd 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -122,23 +122,23 @@ null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, void ieee80211_proto_attach(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; + uint8_t hdrlen; /* override the 802.3 setting */ - ifp->if_hdrlen = ic->ic_headroom + hdrlen = ic->ic_headroom + sizeof(struct ieee80211_qosframe_addr4) + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_EXTIVLEN; /* XXX no way to recalculate on ifdetach */ - if (ALIGN(ifp->if_hdrlen) > max_linkhdr) { + if (ALIGN(hdrlen) > max_linkhdr) { /* XXX sanity check... */ - max_linkhdr = ALIGN(ifp->if_hdrlen); + max_linkhdr = ALIGN(hdrlen); max_hdr = max_linkhdr + max_protohdr; max_datalen = MHLEN - max_hdr; } ic->ic_protmode = IEEE80211_PROT_CTSONLY; - TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ifp); + TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ic); TASK_INIT(&ic->ic_mcast_task, 0, update_mcast, ic); TASK_INIT(&ic->ic_promisc_task, 0, update_promisc, ic); TASK_INIT(&ic->ic_chan_task, 0, update_channel, ic); @@ -188,7 +188,10 @@ ieee80211_proto_vattach(struct ieee80211vap *vap) int i; /* override the 802.3 setting */ - ifp->if_hdrlen = ic->ic_ifp->if_hdrlen; + ifp->if_hdrlen = ic->ic_headroom + + sizeof(struct ieee80211_qosframe_addr4) + + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + + IEEE80211_WEP_EXTIVLEN; vap->iv_rtsthreshold = IEEE80211_RTS_DEFAULT; vap->iv_fragthreshold = IEEE80211_FRAG_DEFAULT; @@ -1155,9 +1158,9 @@ ieee80211_wme_updateparams(struct ieee80211vap *vap) static void parent_updown(void *arg, int npending) { - struct ifnet *parent = arg; + struct ieee80211com *ic = arg; - parent->if_ioctl(parent, SIOCSIFFLAGS, NULL); + ic->ic_parent(ic); } static void @@ -1224,7 +1227,6 @@ ieee80211_start_locked(struct ieee80211vap *vap) { struct ifnet *ifp = vap->iv_ifp; struct ieee80211com *ic = vap->iv_ic; - struct ifnet *parent = ic->ic_ifp; IEEE80211_LOCK_ASSERT(ic); @@ -1246,12 +1248,10 @@ ieee80211_start_locked(struct ieee80211vap *vap) * We are not running; if this we are the first vap * to be brought up auto-up the parent if necessary. */ - if (ic->ic_nrunning++ == 0 && - (parent->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if (ic->ic_nrunning++ == 0) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "%s: up parent %s\n", __func__, parent->if_xname); - parent->if_flags |= IFF_UP; + "%s: up parent %s\n", __func__, ic->ic_name); ieee80211_runtask(ic, &ic->ic_parent_task); return; } @@ -1260,8 +1260,7 @@ ieee80211_start_locked(struct ieee80211vap *vap) * If the parent is up and running, then kick the * 802.11 state machine as appropriate. */ - if ((parent->if_drv_flags & IFF_DRV_RUNNING) && - vap->iv_roaming != IEEE80211_ROAMING_MANUAL) { + if (vap->iv_roaming != IEEE80211_ROAMING_MANUAL) { if (vap->iv_opmode == IEEE80211_M_STA) { #if 0 /* XXX bypasses scan too easily; disable for now */ @@ -1344,7 +1343,6 @@ ieee80211_stop_locked(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = vap->iv_ifp; - struct ifnet *parent = ic->ic_ifp; IEEE80211_LOCK_ASSERT(ic); @@ -1354,12 +1352,10 @@ ieee80211_stop_locked(struct ieee80211vap *vap) ieee80211_new_state_locked(vap, IEEE80211_S_INIT, -1); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { ifp->if_drv_flags &= ~IFF_DRV_RUNNING; /* mark us stopped */ - if (--ic->ic_nrunning == 0 && - (parent->if_drv_flags & IFF_DRV_RUNNING)) { + if (--ic->ic_nrunning == 0) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "down parent %s\n", parent->if_xname); - parent->if_flags &= ~IFF_UP; + "down parent %s\n", ic->ic_name); ieee80211_runtask(ic, &ic->ic_parent_task); } } diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index a8123931588f..b5918b44a1cd 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -56,7 +56,8 @@ void ieee80211_proto_detach(struct ieee80211com *); void ieee80211_proto_vattach(struct ieee80211vap *); void ieee80211_proto_vdetach(struct ieee80211vap *); -void ieee80211_syncifflag_locked(struct ieee80211com *, int flag); +void ieee80211_promisc(struct ieee80211vap *, bool); +void ieee80211_allmulti(struct ieee80211vap *, bool); void ieee80211_syncflag(struct ieee80211vap *, int flag); void ieee80211_syncflag_ht(struct ieee80211vap *, int flag); void ieee80211_syncflag_ext(struct ieee80211vap *, int flag); diff --git a/sys/net80211/ieee80211_regdomain.c b/sys/net80211/ieee80211_regdomain.c index 9dfef2c5f168..efbe1a81fbc8 100644 --- a/sys/net80211/ieee80211_regdomain.c +++ b/sys/net80211/ieee80211_regdomain.c @@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$"); #include #include #include - #include #include @@ -487,7 +486,7 @@ ieee80211_setregdomain(struct ieee80211vap *vap, memset(&ic->ic_channels[ic->ic_nchans], 0, (IEEE80211_CHAN_MAX - ic->ic_nchans) * sizeof(struct ieee80211_channel)); - ieee80211_media_init(ic); + ieee80211_chan_init(ic); /* * Invalidate channel-related state. diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c index c0cbb7d2de4f..709710c1e9e4 100644 --- a/sys/net80211/ieee80211_scan_sta.c +++ b/sys/net80211/ieee80211_scan_sta.c @@ -1706,26 +1706,6 @@ static const struct ieee80211_scanner adhoc_default = { IEEE80211_SCANNER_ALG(ibss, IEEE80211_M_IBSS, adhoc_default); IEEE80211_SCANNER_ALG(ahdemo, IEEE80211_M_AHDEMO, adhoc_default); -static void -ap_force_promisc(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - - IEEE80211_LOCK(ic); - /* set interface into promiscuous mode */ - ifp->if_flags |= IFF_PROMISC; - ieee80211_runtask(ic, &ic->ic_promisc_task); - IEEE80211_UNLOCK(ic); -} - -static void -ap_reset_promisc(struct ieee80211com *ic) -{ - IEEE80211_LOCK(ic); - ieee80211_syncifflag_locked(ic, IFF_PROMISC); - IEEE80211_UNLOCK(ic); -} - static int ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) { @@ -1741,7 +1721,7 @@ ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) st->st_scangen++; st->st_newscan = 1; - ap_force_promisc(vap->iv_ic); + ieee80211_promisc(vap, true); return 0; } @@ -1751,7 +1731,7 @@ ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) static int ap_cancel(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) { - ap_reset_promisc(vap->iv_ic); + ieee80211_promisc(vap, false); return 0; } @@ -1825,7 +1805,7 @@ ap_end(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) return 0; } } - ap_reset_promisc(ic); + ieee80211_promisc(vap, false); if (ss->ss_flags & (IEEE80211_SCAN_NOPICK | IEEE80211_SCAN_NOJOIN)) { /* * Manual/background scan, don't select+join the diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 26238b88e4f1..a4507010f7fa 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -116,16 +116,15 @@ struct ieee80211_superg; struct ieee80211_frame; struct ieee80211com { - struct ifnet *ic_ifp; /* associated device */ void *ic_softc; /* driver softc */ const char *ic_name; /* usually device name */ ieee80211_com_lock_t ic_comlock; /* state update lock */ ieee80211_tx_lock_t ic_txlock; /* ic/vap TX lock */ + LIST_ENTRY(ieee80211com) ic_next; /* on global list */ TAILQ_HEAD(, ieee80211vap) ic_vaps; /* list of vap instances */ int ic_headroom; /* driver tx headroom needs */ enum ieee80211_phytype ic_phytype; /* XXX wrong for multi-mode */ enum ieee80211_opmode ic_opmode; /* operation mode */ - struct ifmedia ic_media; /* interface media config */ struct callout ic_inact; /* inactivity processing */ struct taskqueue *ic_tq; /* deferred state thread */ struct task ic_parent_task; /* deferred parent processing */ @@ -151,6 +150,7 @@ struct ieee80211com { uint8_t ic_allmulti; /* vap's needing all multicast*/ uint8_t ic_nrunning; /* vap's marked running */ uint8_t ic_curmode; /* current mode */ + uint8_t ic_macaddr[IEEE80211_ADDR_LEN]; uint16_t ic_bintval; /* beacon interval */ uint16_t ic_lintval; /* listen interval */ uint16_t ic_holdover; /* PM hold over duration */ @@ -241,6 +241,11 @@ struct ieee80211com { const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); void (*ic_vap_delete)(struct ieee80211vap *); + /* device specific ioctls */ + int (*ic_ioctl)(struct ieee80211com *, + u_long, void *); + /* start/stop device */ + void (*ic_parent)(struct ieee80211com *); /* operating mode attachment */ ieee80211vap_attach ic_vattach[IEEE80211_OPMODE_MAX]; /* return hardware/radio capabilities */ @@ -254,6 +259,9 @@ struct ieee80211com { int (*ic_set_quiet)(struct ieee80211_node *, u_int8_t *quiet_elm); + /* regular transmit */ + int (*ic_transmit)(struct ieee80211com *, + struct mbuf *); /* send/recv 802.11 management frame */ int (*ic_send_mgmt)(struct ieee80211_node *, int, int); @@ -351,14 +359,15 @@ struct ieee80211vap { TAILQ_ENTRY(ieee80211vap) iv_next; /* list of vap instances */ struct ieee80211com *iv_ic; /* back ptr to common state */ + const uint8_t *iv_myaddr; /* MAC address: ifp or ic */ uint32_t iv_debug; /* debug msg flags */ struct ieee80211_stats iv_stats; /* statistics */ - uint8_t iv_myaddr[IEEE80211_ADDR_LEN]; uint32_t iv_flags; /* state flags */ uint32_t iv_flags_ext; /* extended state flags */ uint32_t iv_flags_ht; /* HT state flags */ uint32_t iv_flags_ven; /* vendor state flags */ + uint32_t iv_ifflags; /* ifnet flags */ uint32_t iv_caps; /* capabilities */ uint32_t iv_htcaps; /* HT capabilities */ uint32_t iv_htextcaps; /* HT extended capabilities */ @@ -681,24 +690,24 @@ MALLOC_DECLARE(M_80211_VAP); "\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS" int ic_printf(struct ieee80211com *, const char *, ...) __printflike(2, 3); -void ieee80211_ifattach(struct ieee80211com *, - const uint8_t macaddr[IEEE80211_ADDR_LEN]); +void ieee80211_ifattach(struct ieee80211com *); void ieee80211_ifdetach(struct ieee80211com *); int ieee80211_vap_setup(struct ieee80211com *, struct ieee80211vap *, const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t macaddr[IEEE80211_ADDR_LEN]); + const uint8_t bssid[IEEE80211_ADDR_LEN]); int ieee80211_vap_attach(struct ieee80211vap *, - ifm_change_cb_t, ifm_stat_cb_t); + ifm_change_cb_t, ifm_stat_cb_t, + const uint8_t macaddr[IEEE80211_ADDR_LEN]); void ieee80211_vap_detach(struct ieee80211vap *); const struct ieee80211_rateset *ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *); void ieee80211_announce(struct ieee80211com *); void ieee80211_announce_channels(struct ieee80211com *); void ieee80211_drain(struct ieee80211com *); -void ieee80211_media_init(struct ieee80211com *); +void ieee80211_chan_init(struct ieee80211com *); struct ieee80211com *ieee80211_find_vap(const uint8_t mac[IEEE80211_ADDR_LEN]); +struct ieee80211com *ieee80211_find_com(const char *name); int ieee80211_media_change(struct ifnet *); void ieee80211_media_status(struct ifnet *, struct ifmediareq *); int ieee80211_ioctl(struct ifnet *, u_long, caddr_t); diff --git a/tools/tools/iwn/iwnstats/main.c b/tools/tools/iwn/iwnstats/main.c index 590c17854c13..89582aa995ed 100644 --- a/tools/tools/iwn/iwnstats/main.c +++ b/tools/tools/iwn/iwnstats/main.c @@ -50,7 +50,7 @@ #include "iwnstats.h" #include "iwn_ioctl.h" -#define IWN_DEFAULT_IF "iwn0" +#define IWN_DEFAULT_IF "wlan0" static struct iwnstats * iwnstats_new(const char *ifname) @@ -290,19 +290,6 @@ main(int argc, char *argv[]) if (ifname) free(ifname); ifname = strdup(optarg); - if (strncmp(ifname, "wlan", 4) == 0) { - free(ifname); - len = 0; - asprintf(&sysctlname, "net.wlan.%s.%%parent", ifname + 4); - ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0); - if (ret != 0) - err(1, "sysctl failed"); - ifname = calloc(len, 1); - ret = sysctlbyname(sysctlname, ifname, &len, NULL, 0); - if (ret != 0) - err(1, "sysctl failed"); - free(sysctlname); - } break; default: case '?': From cbaa6a0e0c5d5c6d9da63974d66631bbb15aa0a3 Mon Sep 17 00:00:00 2001 From: "Jason A. Harmening" Date: Fri, 7 Aug 2015 12:13:15 +0000 Subject: [PATCH 306/314] Create man page for pmap_quick_enter_page(9) and pmap_quick_remove_page(9) Reviewed by: kib, brueffer, wblock Approved by: kib (mentor) Differential Revision: https://reviews.freebsd.org/D3312 --- share/man/man9/Makefile | 2 + share/man/man9/pmap.9 | 2 + share/man/man9/pmap_quick_enter_page.9 | 103 +++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 share/man/man9/pmap_quick_enter_page.9 diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 695fa23cd2f3..521a710a2861 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -223,6 +223,7 @@ MAN= accept_filter.9 \ pmap_pinit.9 \ pmap_protect.9 \ pmap_qenter.9 \ + pmap_quick_enter_page.9 \ pmap_release.9 \ pmap_remove.9 \ pmap_resident_count.9 \ @@ -1265,6 +1266,7 @@ MLINKS+=pmap_is_modified.9 pmap_ts_referenced.9 MLINKS+=pmap_pinit.9 pmap_pinit0.9 \ pmap_pinit.9 pmap_pinit2.9 MLINKS+=pmap_qenter.9 pmap_qremove.9 +MLINKS+=pmap_quick_enter_page.9 pmap_quick_remove_page.9 MLINKS+=pmap_remove.9 pmap_remove_all.9 \ pmap_remove.9 pmap_remove_pages.9 MLINKS+=pmap_resident_count.9 pmap_wired_count.9 diff --git a/share/man/man9/pmap.9 b/share/man/man9/pmap.9 index 5d317805fe04..f7edc33b1513 100644 --- a/share/man/man9/pmap.9 +++ b/share/man/man9/pmap.9 @@ -111,6 +111,8 @@ operation. .Xr pmap_protect 9 , .Xr pmap_qenter 9 , .Xr pmap_qremove 9 , +.Xr pmap_quick_enter_page 9 , +.Xr pmap_quick_remove_page 9 , .Xr pmap_release 9 , .Xr pmap_remove 9 , .Xr pmap_remove_all 9 , diff --git a/share/man/man9/pmap_quick_enter_page.9 b/share/man/man9/pmap_quick_enter_page.9 new file mode 100644 index 000000000000..2089dd98a932 --- /dev/null +++ b/share/man/man9/pmap_quick_enter_page.9 @@ -0,0 +1,103 @@ +.\" +.\" Copyright (c) 2015 Jason A. Harmening +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$ +.\" +.Dd August 6, 2015 +.Dt PMAP_QUICK_ENTER_PAGE 9 +.Os +.Sh NAME +.Nm pmap_quick_enter_page , +.Nm pmap_quick_remove_page +.Nd manage fast, single-page kernel address space mappings +.Sh SYNOPSIS +.In sys/param.h +.In vm/vm.h +.In vm/pmap.h +.Ft vm_offset_t +.Fn pmap_quick_enter_page "vm_page_t m" +.Ft void +.Fn pmap_quick_remove_page "vm_offset_t kva" +.Sh DESCRIPTION +The +.Fn pmap_quick_enter_page +function accepts a single page +.Fa m , +and enters this page into a preallocated address in kernel virtual +address (KVA) space. +This function is intended for temporary mappings that will only +be used for a very short period, for example a copy operation on +the page contents. +.Pp +The +.Fn pmap_quick_remove_page +function removes a mapping previously created by +.Fn pmap_quick_enter_page +at +.Fa kva , +making the KVA frame used by +.Fn pmap_quick_enter_page +available for reuse. +.Pp +On many architectures, +.Fn pmap_quick_enter_page +uses a per-CPU pageframe. +In those cases, it must disable preemption on the local CPU. +The corresponding call to +.Fn pmap_quick_remove_page +then re-enables preemption. +It is therefore not safe for machine-independent code to sleep +or perform locking operations while holding these mappings. +Current implementations only guarantee the availability of a single +page for the calling thread, so calls to +.Fn pmap_quick_enter_page +must not be nested. +.Pp +.Fn pmap_quick_enter_page +and +.Fn pmap_quick_remove_page +do not sleep, and +.Fn pmap_quick_enter_page +always returns a valid address. +It is safe to use these functions under all types of locks except spin mutexes. +It is also safe to use them in all thread contexts except primary interrupt +context. +.Pp +The page +.Em must +not be swapped or otherwise reused while the mapping is active. +It must be either wired or held, or it must belong to an unmanaged +region such as I/O device memory. +.Sh RETURN VALUES +The +.Fn pmap_quick_enter_page +function returns the kernel virtual address +that is mapped to the page +.Fa m . +.Sh SEE ALSO +.Xr pmap 9 +.Sh AUTHORS +This manual page was written by +.An Jason A Harmening Aq Mt jah@FreeBSD.org . From 7a3151955b10f7d1e8b1d4f29b6e666423d8c574 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 7 Aug 2015 12:34:20 +0000 Subject: [PATCH 307/314] Fix !MWL_DEBUG build. --- sys/dev/mwl/if_mwl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c index 42264ac2ffe0..be80e465cd39 100644 --- a/sys/dev/mwl/if_mwl.c +++ b/sys/dev/mwl/if_mwl.c @@ -245,10 +245,10 @@ enum { static void mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix); static void mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix); #else -#define IFF_DUMPPKTS_RECV(sc, wh) do {} while (0) -#define IFF_DUMPPKTS_XMIT(sc) do {} while (0) -#define DPRINTF(sc, m, fmt, ...) do {} while (0) -#define KEYPRINTF(sc, k, mac) do {} while (0) +#define IFF_DUMPPKTS_RECV(sc, wh) 0 +#define IFF_DUMPPKTS_XMIT(sc) 0 +#define DPRINTF(sc, m, fmt, ...) do { (void )sc; } while (0) +#define KEYPRINTF(sc, k, mac) do { (void )sc; } while (0) #endif static MALLOC_DEFINE(M_MWLDEV, "mwldev", "mwl driver dma buffers"); From 3301406331c30f3138a805618227ee9a878890b7 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 7 Aug 2015 14:12:51 +0000 Subject: [PATCH 308/314] Add more ifdefs to fix build with GCC after r286406. --- sys/cam/ctl/ctl.c | 12 +++++++++++- sys/cam/ctl/ctl.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 0c27d90f2413..1b6c14928732 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -374,9 +374,11 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, debug, CTLFLAG_RWTUN, */ #define SCSI_EVPD_NUM_SUPPORTED_PAGES 10 +#ifdef notyet static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event, int param); static void ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest); +#endif static int ctl_init(void); void ctl_shutdown(void); static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td); @@ -444,7 +446,9 @@ static int ctl_scsiio_lun_check(struct ctl_lun *lun, const struct ctl_cmd_entry *entry, struct ctl_scsiio *ctsio); //static int ctl_check_rtr(union ctl_io *pending_io, struct ctl_softc *softc); +#ifdef notyet static void ctl_failover(void); +#endif static void ctl_clear_ua(struct ctl_softc *ctl_softc, uint32_t initidx, ctl_ua_type ua_type); static int ctl_scsiio_precheck(struct ctl_softc *ctl_softc, @@ -483,7 +487,9 @@ static void ctl_work_thread(void *arg); static void ctl_enqueue_incoming(union ctl_io *io); static void ctl_enqueue_rtr(union ctl_io *io); static void ctl_enqueue_done(union ctl_io *io); +#ifdef notyet static void ctl_enqueue_isc(union ctl_io *io); +#endif static const struct ctl_cmd_entry * ctl_get_cmd_entry(struct ctl_scsiio *ctsio, int *sa); static const struct ctl_cmd_entry * @@ -528,6 +534,7 @@ static struct ctl_frontend ioctl_frontend = .name = "ioctl", }; +#ifdef notyet static void ctl_isc_handler_finish_xfer(struct ctl_softc *ctl_softc, union ctl_ha_msg *msg_info) @@ -962,6 +969,7 @@ ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest) dest->scsiio.sense_len = src->scsi.sense_len; dest->io_hdr.status = src->hdr.status; } +#endif static void ctl_est_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua) @@ -11369,6 +11377,7 @@ ctl_failover_io(union ctl_io *io, int have_lock) ctl_done(io); } +#ifdef notyet static void ctl_failover(void) { @@ -11609,6 +11618,7 @@ ctl_failover(void) ctl_pause_rtr = 0; mtx_unlock(&softc->ctl_lock); } +#endif static void ctl_clear_ua(struct ctl_softc *ctl_softc, uint32_t initidx, @@ -14252,6 +14262,7 @@ ctl_enqueue_done(union ctl_io *io) wakeup(thr); } +#ifdef notyet static void ctl_enqueue_isc(union ctl_io *io) { @@ -14273,7 +14284,6 @@ ctl_init_isc_msg(void) printf("CTL: Still calling this thing\n"); } -#ifdef notyet /* * Init component * Initializes component into configuration defined by bootMode diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h index 2693419414ea..b1d9118c64b0 100644 --- a/sys/cam/ctl/ctl.h +++ b/sys/cam/ctl/ctl.h @@ -191,7 +191,9 @@ void ctl_data_submit_done(union ctl_io *io); void ctl_config_read_done(union ctl_io *io); void ctl_config_write_done(union ctl_io *io); void ctl_portDB_changed(int portnum); +#ifdef notyet void ctl_init_isc_msg(void); +#endif /* * KPI to manipulate LUN/port options From ebef81ecea932c2ddb2b39a061e3ad95effaabae Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 7 Aug 2015 14:38:26 +0000 Subject: [PATCH 309/314] Add unmapped I/O support to ata(4) driver. Main problem there was PIO mode support, that required KVA mapping. Handle that case using recently added pmap_quick_enter_page(9) KPI, mapping data pages to KVA one at a time. --- sys/dev/ata/ata-all.c | 2 +- sys/dev/ata/ata-lowlevel.c | 231 ++++++++++++++++++++++++++----------- 2 files changed, 165 insertions(+), 68 deletions(-) diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 19d6eb2cdb53..6e3f5fec65b6 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -1074,7 +1074,7 @@ ataaction(struct cam_sim *sim, union ccb *ccb) cpi->version_num = 1; /* XXX??? */ cpi->hba_inquiry = PI_SDTR_ABLE; cpi->target_sprt = 0; - cpi->hba_misc = PIM_SEQSCAN; + cpi->hba_misc = PIM_SEQSCAN | PIM_UNMAPPED; cpi->hba_eng_cnt = 0; if (ch->flags & ATA_NO_SLAVE) cpi->max_target = 0; diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index 459f98ccac5e..6b825c05e0d2 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -44,6 +45,12 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include + +#include +#include + /* prototypes */ static int ata_generic_status(device_t dev); static int ata_wait(struct ata_channel *ch, int unit, u_int8_t); @@ -811,86 +818,176 @@ ata_tf_write(struct ata_request *request) static void ata_pio_read(struct ata_request *request, int length) { - struct ata_channel *ch = device_get_softc(request->parent); - uint8_t *addr; - int size = min(request->transfersize, length); - int resid; - uint8_t buf[2] __aligned(sizeof(int16_t)); -#ifndef __NO_STRICT_ALIGNMENT - int i; -#endif + struct ata_channel *ch = device_get_softc(request->parent); + struct bio *bio; + uint8_t *addr; + vm_offset_t page; + int todo, done, off, moff, resid, size, i; + uint8_t buf[2] __aligned(2); - addr = (uint8_t *)request->data + request->donecount; - if (__predict_false(ch->flags & ATA_USE_16BIT || - (size % sizeof(int32_t)) || ((uintptr_t)addr % sizeof(int32_t)))) { + todo = min(request->transfersize, length); + page = done = resid = 0; + while (done < todo) { + size = todo - done; + + /* Prepare data address and limit size (if not sequential). */ + off = request->donecount + done; + if ((request->flags & ATA_R_DATA_IN_CCB) == 0 || + (request->ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) { + addr = (uint8_t *)request->data + off; + } else if ((request->ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_BIO) { + bio = (struct bio *)request->data; + if ((bio->bio_flags & BIO_UNMAPPED) == 0) { + addr = (uint8_t *)bio->bio_data + off; + } else { + moff = bio->bio_ma_offset + off; + page = pmap_quick_enter_page( + bio->bio_ma[moff / PAGE_SIZE]); + moff %= PAGE_SIZE; + size = min(size, PAGE_SIZE - moff); + addr = (void *)(page + moff); + } + } else + panic("ata_pio_read: Unsupported CAM data type %x\n", + (request->ccb->ccb_h.flags & CAM_DATA_MASK)); + + /* We may have extra byte already red but not stored. */ + if (resid) { + addr[0] = buf[1]; + addr++; + done++; + size--; + } + + /* Process main part of data. */ + resid = size % 2; + if (__predict_false((ch->flags & ATA_USE_16BIT) || + (size % 4) != 0 || ((uintptr_t)addr % 4) != 0)) { #ifndef __NO_STRICT_ALIGNMENT - if (__predict_false((uintptr_t)addr % sizeof(int16_t))) { - for (i = 0, resid = size & ~1; resid > 0; resid -= - sizeof(int16_t)) { - *(uint16_t *)&buf = ATA_IDX_INW_STRM(ch, ATA_DATA); - addr[i++] = buf[0]; - addr[i++] = buf[1]; - } - } else + if (__predict_false((uintptr_t)addr % 2)) { + for (i = 0; i + 1 < size; i += 2) { + *(uint16_t *)&buf = + ATA_IDX_INW_STRM(ch, ATA_DATA); + addr[i] = buf[0]; + addr[i + 1] = buf[1]; + } + } else #endif - ATA_IDX_INSW_STRM(ch, ATA_DATA, (void*)addr, size / - sizeof(int16_t)); - if (size & 1) { - *(uint16_t *)&buf = ATA_IDX_INW_STRM(ch, ATA_DATA); - (addr + (size & ~1))[0] = buf[0]; + ATA_IDX_INSW_STRM(ch, ATA_DATA, (void*)addr, + size / 2); + + /* If we have extra byte of data, leave it for later. */ + if (resid) { + *(uint16_t *)&buf = + ATA_IDX_INW_STRM(ch, ATA_DATA); + addr[size - 1] = buf[0]; + } + } else + ATA_IDX_INSL_STRM(ch, ATA_DATA, (void*)addr, size / 4); + + if (page) { + pmap_quick_remove_page(page); + page = 0; + } + done += size; } - } else - ATA_IDX_INSL_STRM(ch, ATA_DATA, (void*)addr, size / sizeof(int32_t)); - if (request->transfersize < length) { - device_printf(request->parent, "WARNING - %s read data overrun %d>%d\n", - ata_cmd2str(request), length, request->transfersize); - for (resid = request->transfersize + (size & 1); resid < length; - resid += sizeof(int16_t)) - ATA_IDX_INW(ch, ATA_DATA); - } + if (length > done) { + device_printf(request->parent, + "WARNING - %s read data overrun %d > %d\n", + ata_cmd2str(request), length, done); + for (i = done + resid; i < length; i += 2) + ATA_IDX_INW(ch, ATA_DATA); + } } static void ata_pio_write(struct ata_request *request, int length) { - struct ata_channel *ch = device_get_softc(request->parent); - uint8_t *addr; - int size = min(request->transfersize, length); - int resid; - uint8_t buf[2] __aligned(sizeof(int16_t)); -#ifndef __NO_STRICT_ALIGNMENT - int i; -#endif + struct ata_channel *ch = device_get_softc(request->parent); + struct bio *bio; + uint8_t *addr; + vm_offset_t page; + int todo, done, off, moff, resid, size, i; + uint8_t buf[2] __aligned(2); - size = min(request->transfersize, length); - addr = (uint8_t *)request->data + request->donecount; - if (__predict_false(ch->flags & ATA_USE_16BIT || - (size % sizeof(int32_t)) || ((uintptr_t)addr % sizeof(int32_t)))) { + todo = min(request->transfersize, length); + page = done = resid = 0; + while (done < todo) { + size = todo - done; + + /* Prepare data address and limit size (if not sequential). */ + off = request->donecount + done; + if ((request->flags & ATA_R_DATA_IN_CCB) == 0 || + (request->ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) { + addr = (uint8_t *)request->data + off; + } else if ((request->ccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_BIO) { + bio = (struct bio *)request->data; + if ((bio->bio_flags & BIO_UNMAPPED) == 0) { + addr = (uint8_t *)bio->bio_data + off; + } else { + moff = bio->bio_ma_offset + off; + page = pmap_quick_enter_page( + bio->bio_ma[moff / PAGE_SIZE]); + moff %= PAGE_SIZE; + size = min(size, PAGE_SIZE - moff); + addr = (void *)(page + moff); + } + } else + panic("ata_pio_write: Unsupported CAM data type %x\n", + (request->ccb->ccb_h.flags & CAM_DATA_MASK)); + + /* We may have extra byte to be written first. */ + if (resid) { + buf[1] = addr[0]; + ATA_IDX_OUTW_STRM(ch, ATA_DATA, *(uint16_t *)&buf); + addr++; + done++; + size--; + } + + /* Process main part of data. */ + resid = size % 2; + if (__predict_false((ch->flags & ATA_USE_16BIT) || + (size % 4) != 0 || ((uintptr_t)addr % 4) != 0)) { #ifndef __NO_STRICT_ALIGNMENT - if (__predict_false((uintptr_t)addr % sizeof(int16_t))) { - for (i = 0, resid = size & ~1; resid > 0; resid -= - sizeof(int16_t)) { - buf[0] = addr[i++]; - buf[1] = addr[i++]; - ATA_IDX_OUTW_STRM(ch, ATA_DATA, *(uint16_t *)&buf); - } - } else + if (__predict_false((uintptr_t)addr % 2)) { + for (i = 0; i + 1 < size; i += 2) { + buf[0] = addr[i]; + buf[1] = addr[i + 1]; + ATA_IDX_OUTW_STRM(ch, ATA_DATA, + *(uint16_t *)&buf); + } + } else #endif - ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)addr, size / - sizeof(int16_t)); - if (size & 1) { - buf[0] = (addr + (size & ~1))[0]; - ATA_IDX_OUTW_STRM(ch, ATA_DATA, *(uint16_t *)&buf); + ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)addr, + size / 2); + + /* If we have extra byte of data, save it for later. */ + if (resid) + buf[0] = addr[size - 1]; + } else + ATA_IDX_OUTSL_STRM(ch, ATA_DATA, + (void*)addr, size / sizeof(int32_t)); + + if (page) { + pmap_quick_remove_page(page); + page = 0; + } + done += size; } - } else - ATA_IDX_OUTSL_STRM(ch, ATA_DATA, (void*)addr, size / sizeof(int32_t)); - if (request->transfersize < length) { - device_printf(request->parent, "WARNING - %s write data underrun %d>%d\n", - ata_cmd2str(request), length, request->transfersize); - for (resid = request->transfersize + (size & 1); resid < length; - resid += sizeof(int16_t)) - ATA_IDX_OUTW(ch, ATA_DATA, 0); - } + /* We may have extra byte of data to be written. Pad it with zero. */ + if (resid) { + buf[1] = 0; + ATA_IDX_OUTW_STRM(ch, ATA_DATA, *(uint16_t *)&buf); + } + + if (length > done) { + device_printf(request->parent, + "WARNING - %s write data underrun %d > %d\n", + ata_cmd2str(request), length, done); + for (i = done + resid; i < length; i += 2) + ATA_IDX_OUTW(ch, ATA_DATA, 0); + } } From ad30bc5aec1877d7feb222c4cad449544a51ac01 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 7 Aug 2015 16:23:16 +0000 Subject: [PATCH 310/314] Fix mtx_assert() argument. --- sys/dev/usb/wlan/if_zyd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index 4c1c778472c6..a86ab8a3f061 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -2581,7 +2581,7 @@ zyd_start(struct zyd_softc *sc) struct ieee80211_node *ni; struct mbuf *m; - ZYD_LOCK_ASSERT(sc, MA_LOCKED); + ZYD_LOCK_ASSERT(sc, MA_OWNED); while (sc->tx_nfree > 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; From de9325262282ed4c304bb524e7ae0f73044a2eeb Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 7 Aug 2015 17:22:37 +0000 Subject: [PATCH 311/314] o Fix a typo. o Describe the file formats mkimg can create. --- usr.bin/mkimg/mkimg.1 | 84 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/usr.bin/mkimg/mkimg.1 b/usr.bin/mkimg/mkimg.1 index 3b1d63e94136..2738cd898774 100644 --- a/usr.bin/mkimg/mkimg.1 +++ b/usr.bin/mkimg/mkimg.1 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 22, 2015 +.Dd August 7, 2015 .Dt MKIMG 1 .Os .Sh NAME @@ -141,7 +141,7 @@ utility will create images that are identical. .Pp A set of long options exist to query about the .Nm -utilty itself. +utility itself. Options in this set should be given by themselves because the .Nm utility exits immediately after providing the requested information. @@ -165,6 +165,85 @@ run the .Nm utility without any arguments. This will print a usage message with all the necessary details. +.Sh DISK FORMATS +The +.Nm +utility supports a number of output file formats. +A short description of these is given below. +.Ss QCOW and QCOW2 +QCOW stands for "QEMU Copy On Write". +It's a sparse file format akin to VHD and VMDK and QCOW represents the +first version. +QCOW2 represents version 2 of the file format. +Version 2 is not backward compatible with version 1 and adds support for +snapshots among other things. +The QCOW file formats are natively supported by QEMU and Xen. +To write QCOW, specify +.Fl f Ar qcow +on the command line. +To write version 2 QCOW, specify +.Fl f Ar qcow2 +on the command line. +The preferred file extension is ".qcow" iand ".qcow2" for QCOW and QCOW2 +(resp.), but ".qcow" is sometimes used for version 2 files as well. +.Ss RAW file format +This file format is a sector by sector representation of an actual disk. +There is no extra information that describes or relates to the format +itself. The size of the file is the size of the (virtual) disk. +This file format is suitable for being copyied onto a disk with utilities +like +.Nm dd . +To write a raw disk file, either omit the +.Fl f +option, or specify +.Fl f Ar raw +on the command line. +The preferred file extension is one of ".img" or ".raw", but there's no +real convention for it. +.Ss Dynamic VHD and Fixed VHD +Microsoft's "Virtual Hard Disk" file formats. +The dynamic format is a sparse format akin to QCOW and VMDK. +The fixed format is effectively a raw format with a footer appended to the +file and as such it's often indistinguishable from the raw format. +The fixed file format has been added to support Microsoft's Azure platform +and due to inconsistencies in interpretation of the footer is not compatible +with utilities like +.Nm qemu +when it is specifically instructed to interpreted the file as a VHD file. +By default +.Nm qemu +will treat the file as a raw disk file, which mostly works fine. +To have +.Nm +create a dynamic VHD file, specify +.Fl f Ar vhd +on the command line. +To create a fixed VHD file for use by Azure, specify +.Fl f Ar vhdf +on the command line. +The preferred file extension is ".vhd". +.Ss VMDK +VMware's "Virtual Machine Disk" file format. +It's a sparse file format akin to QCOW and VHD and supported by many +virtualization solutions. +To create a VMDK file, specify +.Fl f Ar vmdk +on the command line. +The preferred file extension is ".vmdk". +.Pp +Not all virtualization solutions support all file formats, but often those +virtualization environments have utilities to convert from one format to +another. +Note however that conversion may require that the virtual disk size is +changed to match the constraints of the output format and this may invalidate +the contents of the disk image. +For example, the GUID Partition Table (GPT) scheme has a header in the last +sector on the disk. +When changing the disk size, the GPT must be changed so that the last header +is moved accordingly. +This is typically not part of the conversion process. +If possible, use an output format specifically for the environment in which +the file is intended to be used. .Sh ENVIRONMENT .Bl -tag -width "TMPDIR" -compact .It Ev TMPDIR @@ -235,6 +314,7 @@ utility supports assigning labels to the partitions specified. In the following example the file system partition is labeled as 'backup': .Dl % mkimg -s gpt -p freebsd-ufs/backup:=file-system.ufs -o gpt.img .Sh SEE ALSO +.Xr dd 1 , .Xr gpart 8 , .Xr makefs 8 , .Xr mdconfig 8 , From 881106317225f1ee9004c3df2261cd044dd9a492 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 7 Aug 2015 18:30:11 +0000 Subject: [PATCH 312/314] ipv4_is_zeronet() and ipv4_is_loopback() expect an address in network order, but IN_ZERONET and IN_LOOPBACK expect it in host order. Submitted by: Tao Liu MFC after: 1 week Sponsored by: EMC / Isilon Storage Division --- sys/ofed/include/linux/in.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/ofed/include/linux/in.h b/sys/ofed/include/linux/in.h index d3e8add794ea..102563f2abb5 100644 --- a/sys/ofed/include/linux/in.h +++ b/sys/ofed/include/linux/in.h @@ -37,7 +37,7 @@ #include #include -#define ipv4_is_zeronet IN_ZERONET -#define ipv4_is_loopback IN_LOOPBACK +#define ipv4_is_zeronet(be) IN_ZERONET(ntohl(be)) +#define ipv4_is_loopback(be) IN_LOOPBACK(ntohl(be)) #endif /* _LINUX_IN_H_ */ From 8f1d6b69150315ee24bee29a63dbb7a4f7048696 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Fri, 7 Aug 2015 18:40:44 +0000 Subject: [PATCH 313/314] Fix typo introduced in previous commit. Pointed out by: Nikolai Lifanov --- usr.bin/mkimg/mkimg.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/mkimg/mkimg.1 b/usr.bin/mkimg/mkimg.1 index 2738cd898774..b982791396d8 100644 --- a/usr.bin/mkimg/mkimg.1 +++ b/usr.bin/mkimg/mkimg.1 @@ -184,7 +184,7 @@ on the command line. To write version 2 QCOW, specify .Fl f Ar qcow2 on the command line. -The preferred file extension is ".qcow" iand ".qcow2" for QCOW and QCOW2 +The preferred file extension is ".qcow" and ".qcow2" for QCOW and QCOW2 (resp.), but ".qcow" is sometimes used for version 2 files as well. .Ss RAW file format This file format is a sector by sector representation of an actual disk. From 7e518a6648cd25343982e9ae18cf638ca8712d49 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 7 Aug 2015 19:56:22 +0000 Subject: [PATCH 314/314] - Use an explicit "depends_on module kernel" guard in DTrace libraries that reference types defined in the kernel. Otherwise dtrace(1) expects to find CTF definitions for all referenced types, which is not very reasonable when it is being used in a build environment. This was previously worked around by adding "-x nolibs" to dtrace -h or -G invocations, but as of r283025, dtrace(1) actually handles dependencies properly, so this is no longer necessary. - Remove "pragma ident" directives from DTrace libraries, as they're being phased out upstream as well. Submitted by: Krister Johansen [1] MFC after: 1 week Sponsored by: EMC / Isilon Storage Division --- cddl/lib/libdtrace/io.d | 3 +-- cddl/lib/libdtrace/ip.d | 1 + cddl/lib/libdtrace/nfs.d | 1 + cddl/lib/libdtrace/nfssrv.d | 3 ++- cddl/lib/libdtrace/psinfo.d | 2 ++ cddl/lib/libdtrace/regs_x86.d | 2 -- cddl/lib/libdtrace/sched.d | 4 +--- cddl/lib/libdtrace/siftr.d | 1 + cddl/lib/libdtrace/tcp.d | 1 + cddl/lib/libdtrace/udp.d | 1 + 10 files changed, 11 insertions(+), 8 deletions(-) diff --git a/cddl/lib/libdtrace/io.d b/cddl/lib/libdtrace/io.d index 18a54afdb937..41f7aa1533b8 100644 --- a/cddl/lib/libdtrace/io.d +++ b/cddl/lib/libdtrace/io.d @@ -25,8 +25,7 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - +#pragma D depends_on module kernel #pragma D depends_on provider io typedef struct devinfo { diff --git a/cddl/lib/libdtrace/ip.d b/cddl/lib/libdtrace/ip.d index a1a2996362fd..33fb007e6fff 100644 --- a/cddl/lib/libdtrace/ip.d +++ b/cddl/lib/libdtrace/ip.d @@ -25,6 +25,7 @@ * Copyright (c) 2013 Mark Johnston */ +#pragma D depends_on module kernel #pragma D depends_on provider ip /* diff --git a/cddl/lib/libdtrace/nfs.d b/cddl/lib/libdtrace/nfs.d index be342286f1b5..ae864ed363d2 100644 --- a/cddl/lib/libdtrace/nfs.d +++ b/cddl/lib/libdtrace/nfs.d @@ -30,6 +30,7 @@ #pragma D depends_on library ip.d #pragma D depends_on library net.d +#pragma D depends_on module kernel #pragma D depends_on module nfs typedef struct nfsv4opinfo { diff --git a/cddl/lib/libdtrace/nfssrv.d b/cddl/lib/libdtrace/nfssrv.d index 68ac08b58cde..37842f7963a1 100644 --- a/cddl/lib/libdtrace/nfssrv.d +++ b/cddl/lib/libdtrace/nfssrv.d @@ -30,7 +30,8 @@ #pragma D depends_on library ip.d #pragma D depends_on library net.d -#pragma D depends_on module nfs.d +#pragma D depends_on library nfs.d +#pragma D depends_on module kernel #pragma D depends_on module nfssrv #pragma D binding "1.5" translator diff --git a/cddl/lib/libdtrace/psinfo.d b/cddl/lib/libdtrace/psinfo.d index c2219f70a35d..1b13863df0e3 100644 --- a/cddl/lib/libdtrace/psinfo.d +++ b/cddl/lib/libdtrace/psinfo.d @@ -28,6 +28,8 @@ * Use is subject to license terms. */ +#pragma D depends_on module kernel + typedef struct psinfo { int pr_nlwp; /* number of threads */ pid_t pr_pid; /* unique process id */ diff --git a/cddl/lib/libdtrace/regs_x86.d b/cddl/lib/libdtrace/regs_x86.d index 7dce19717642..03528a6423d3 100644 --- a/cddl/lib/libdtrace/regs_x86.d +++ b/cddl/lib/libdtrace/regs_x86.d @@ -28,8 +28,6 @@ * Use is subject to license terms. */ -#pragma ident "@(#)regs.d.in 1.1 04/09/28 SMI" - inline int R_GS = 0; #pragma D binding "1.0" R_GS inline int R_FS = 1; diff --git a/cddl/lib/libdtrace/sched.d b/cddl/lib/libdtrace/sched.d index d91d3c5318f0..104fd571e4c0 100644 --- a/cddl/lib/libdtrace/sched.d +++ b/cddl/lib/libdtrace/sched.d @@ -27,9 +27,7 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#pragma D depends_on module unix +#pragma D depends_on module kernel #pragma D depends_on provider sched struct cpuinfo { diff --git a/cddl/lib/libdtrace/siftr.d b/cddl/lib/libdtrace/siftr.d index a6ff844901dc..37bc30ff3e06 100644 --- a/cddl/lib/libdtrace/siftr.d +++ b/cddl/lib/libdtrace/siftr.d @@ -21,6 +21,7 @@ * $FreeBSD$ */ +#pragma D depends_on module kernel #pragma D depends_on module siftr #pragma D depends_on provider tcp diff --git a/cddl/lib/libdtrace/tcp.d b/cddl/lib/libdtrace/tcp.d index 4b826f175572..8398cd3ec6ad 100644 --- a/cddl/lib/libdtrace/tcp.d +++ b/cddl/lib/libdtrace/tcp.d @@ -26,6 +26,7 @@ */ #pragma D depends_on library ip.d +#pragma D depends_on module kernel #pragma D depends_on provider tcp /* diff --git a/cddl/lib/libdtrace/udp.d b/cddl/lib/libdtrace/udp.d index 21538eb0ef3c..eeba58c8752f 100644 --- a/cddl/lib/libdtrace/udp.d +++ b/cddl/lib/libdtrace/udp.d @@ -26,6 +26,7 @@ */ #pragma D depends_on library ip.d +#pragma D depends_on module kernel #pragma D depends_on provider udp /*