1dc7e38acSHans Petter Selasky /*- 2a888087fSHans Petter Selasky * Copyright (c) 2015-2021 Mellanox Technologies. All rights reserved. 3ebdb7006SHans Petter Selasky * Copyright (c) 2022 NVIDIA corporation & affiliates. 4dc7e38acSHans Petter Selasky * 5dc7e38acSHans Petter Selasky * Redistribution and use in source and binary forms, with or without 6dc7e38acSHans Petter Selasky * modification, are permitted provided that the following conditions 7dc7e38acSHans Petter Selasky * are met: 8dc7e38acSHans Petter Selasky * 1. Redistributions of source code must retain the above copyright 9dc7e38acSHans Petter Selasky * notice, this list of conditions and the following disclaimer. 10dc7e38acSHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright 11dc7e38acSHans Petter Selasky * notice, this list of conditions and the following disclaimer in the 12dc7e38acSHans Petter Selasky * documentation and/or other materials provided with the distribution. 13dc7e38acSHans Petter Selasky * 14dc7e38acSHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 15dc7e38acSHans Petter Selasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16dc7e38acSHans Petter Selasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17dc7e38acSHans Petter Selasky * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18dc7e38acSHans Petter Selasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19dc7e38acSHans Petter Selasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20dc7e38acSHans Petter Selasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21dc7e38acSHans Petter Selasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22dc7e38acSHans Petter Selasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23dc7e38acSHans Petter Selasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24dc7e38acSHans Petter Selasky * SUCH DAMAGE. 25dc7e38acSHans Petter Selasky */ 26dc7e38acSHans Petter Selasky 27e23731dbSKonstantin Belousov #include "opt_ipsec.h" 287272f9cdSHans Petter Selasky #include "opt_kern_tls.h" 29b984b956SKonstantin Belousov #include "opt_rss.h" 30b984b956SKonstantin Belousov #include "opt_ratelimit.h" 317272f9cdSHans Petter Selasky 3289918a23SKonstantin Belousov #include <dev/mlx5/mlx5_en/en.h> 332787f8c3SKonstantin Belousov #include <dev/mlx5/mlx5_accel/ipsec.h> 34dc7e38acSHans Petter Selasky 35e12be321SConrad Meyer #include <sys/eventhandler.h> 36dc7e38acSHans Petter Selasky #include <sys/sockio.h> 37dc7e38acSHans Petter Selasky #include <machine/atomic.h> 38dc7e38acSHans Petter Selasky 3901651e96SHans Petter Selasky #include <net/debugnet.h> 401f628be8SAndrew Gallatin #include <netinet/tcp_ratelimit.h> 41e23731dbSKonstantin Belousov #include <netipsec/keydb.h> 42e23731dbSKonstantin Belousov #include <netipsec/ipsec_offload.h> 4301651e96SHans Petter Selasky 442f17f76aSHans Petter Selasky static int mlx5e_get_wqe_sz(struct mlx5e_priv *priv, u32 *wqe_sz, u32 *nsegs); 45c782ea8bSJohn Baldwin static if_snd_tag_query_t mlx5e_ul_snd_tag_query; 46c782ea8bSJohn Baldwin static if_snd_tag_free_t mlx5e_ul_snd_tag_free; 472f17f76aSHans Petter Selasky 48dc7e38acSHans Petter Selasky struct mlx5e_channel_param { 49dc7e38acSHans Petter Selasky struct mlx5e_rq_param rq; 50dc7e38acSHans Petter Selasky struct mlx5e_sq_param sq; 51dc7e38acSHans Petter Selasky struct mlx5e_cq_param rx_cq; 52dc7e38acSHans Petter Selasky struct mlx5e_cq_param tx_cq; 53dc7e38acSHans Petter Selasky }; 54dc7e38acSHans Petter Selasky 55ac87880aSHans Petter Selasky struct media { 56dc7e38acSHans Petter Selasky u32 subtype; 57dc7e38acSHans Petter Selasky u64 baudrate; 58ac87880aSHans Petter Selasky }; 59dc7e38acSHans Petter Selasky 60a888087fSHans Petter Selasky static const struct media mlx5e_mode_table[MLX5E_LINK_SPEEDS_NUMBER] = 61a888087fSHans Petter Selasky { 62a888087fSHans Petter Selasky [MLX5E_1000BASE_CX_SGMII] = { 63dc7e38acSHans Petter Selasky .subtype = IFM_1000_CX_SGMII, 64dc7e38acSHans Petter Selasky .baudrate = IF_Mbps(1000ULL), 65dc7e38acSHans Petter Selasky }, 66a888087fSHans Petter Selasky [MLX5E_1000BASE_KX] = { 67dc7e38acSHans Petter Selasky .subtype = IFM_1000_KX, 68dc7e38acSHans Petter Selasky .baudrate = IF_Mbps(1000ULL), 69dc7e38acSHans Petter Selasky }, 70a888087fSHans Petter Selasky [MLX5E_10GBASE_CX4] = { 71dc7e38acSHans Petter Selasky .subtype = IFM_10G_CX4, 72dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 73dc7e38acSHans Petter Selasky }, 74a888087fSHans Petter Selasky [MLX5E_10GBASE_KX4] = { 75dc7e38acSHans Petter Selasky .subtype = IFM_10G_KX4, 76dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 77dc7e38acSHans Petter Selasky }, 78a888087fSHans Petter Selasky [MLX5E_10GBASE_KR] = { 79dc7e38acSHans Petter Selasky .subtype = IFM_10G_KR, 80dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 81dc7e38acSHans Petter Selasky }, 82a888087fSHans Petter Selasky [MLX5E_20GBASE_KR2] = { 83dc7e38acSHans Petter Selasky .subtype = IFM_20G_KR2, 84dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(20ULL), 85dc7e38acSHans Petter Selasky }, 86a888087fSHans Petter Selasky [MLX5E_40GBASE_CR4] = { 87dc7e38acSHans Petter Selasky .subtype = IFM_40G_CR4, 88dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(40ULL), 89dc7e38acSHans Petter Selasky }, 90a888087fSHans Petter Selasky [MLX5E_40GBASE_KR4] = { 91dc7e38acSHans Petter Selasky .subtype = IFM_40G_KR4, 92dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(40ULL), 93dc7e38acSHans Petter Selasky }, 94a888087fSHans Petter Selasky [MLX5E_56GBASE_R4] = { 95dc7e38acSHans Petter Selasky .subtype = IFM_56G_R4, 96dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(56ULL), 97dc7e38acSHans Petter Selasky }, 98a888087fSHans Petter Selasky [MLX5E_10GBASE_CR] = { 99dc7e38acSHans Petter Selasky .subtype = IFM_10G_CR1, 100dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 101dc7e38acSHans Petter Selasky }, 102a888087fSHans Petter Selasky [MLX5E_10GBASE_SR] = { 103dc7e38acSHans Petter Selasky .subtype = IFM_10G_SR, 104dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 105dc7e38acSHans Petter Selasky }, 106a888087fSHans Petter Selasky [MLX5E_10GBASE_ER_LR] = { 107d9142151SHans Petter Selasky .subtype = IFM_10G_ER, 108dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 109dc7e38acSHans Petter Selasky }, 110a888087fSHans Petter Selasky [MLX5E_40GBASE_SR4] = { 111dc7e38acSHans Petter Selasky .subtype = IFM_40G_SR4, 112dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(40ULL), 113dc7e38acSHans Petter Selasky }, 114a888087fSHans Petter Selasky [MLX5E_40GBASE_LR4_ER4] = { 115dc7e38acSHans Petter Selasky .subtype = IFM_40G_LR4, 116dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(40ULL), 117dc7e38acSHans Petter Selasky }, 118a888087fSHans Petter Selasky [MLX5E_100GBASE_CR4] = { 119dc7e38acSHans Petter Selasky .subtype = IFM_100G_CR4, 120dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 121dc7e38acSHans Petter Selasky }, 122a888087fSHans Petter Selasky [MLX5E_100GBASE_SR4] = { 123dc7e38acSHans Petter Selasky .subtype = IFM_100G_SR4, 124dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 125dc7e38acSHans Petter Selasky }, 126a888087fSHans Petter Selasky [MLX5E_100GBASE_KR4] = { 127dc7e38acSHans Petter Selasky .subtype = IFM_100G_KR4, 128dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 129dc7e38acSHans Petter Selasky }, 130a888087fSHans Petter Selasky [MLX5E_100GBASE_LR4] = { 131dc7e38acSHans Petter Selasky .subtype = IFM_100G_LR4, 132dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 133dc7e38acSHans Petter Selasky }, 134a888087fSHans Petter Selasky [MLX5E_100BASE_TX] = { 135dc7e38acSHans Petter Selasky .subtype = IFM_100_TX, 136dc7e38acSHans Petter Selasky .baudrate = IF_Mbps(100ULL), 137dc7e38acSHans Petter Selasky }, 138a888087fSHans Petter Selasky [MLX5E_1000BASE_T] = { 139d9142151SHans Petter Selasky .subtype = IFM_1000_T, 140d9142151SHans Petter Selasky .baudrate = IF_Mbps(1000ULL), 141dc7e38acSHans Petter Selasky }, 142a888087fSHans Petter Selasky [MLX5E_10GBASE_T] = { 143dc7e38acSHans Petter Selasky .subtype = IFM_10G_T, 144dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 145dc7e38acSHans Petter Selasky }, 146a888087fSHans Petter Selasky [MLX5E_25GBASE_CR] = { 147dc7e38acSHans Petter Selasky .subtype = IFM_25G_CR, 148dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(25ULL), 149dc7e38acSHans Petter Selasky }, 150a888087fSHans Petter Selasky [MLX5E_25GBASE_KR] = { 151dc7e38acSHans Petter Selasky .subtype = IFM_25G_KR, 152dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(25ULL), 153dc7e38acSHans Petter Selasky }, 154a888087fSHans Petter Selasky [MLX5E_25GBASE_SR] = { 155dc7e38acSHans Petter Selasky .subtype = IFM_25G_SR, 156dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(25ULL), 157dc7e38acSHans Petter Selasky }, 158a888087fSHans Petter Selasky [MLX5E_50GBASE_CR2] = { 159dc7e38acSHans Petter Selasky .subtype = IFM_50G_CR2, 160dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(50ULL), 161dc7e38acSHans Petter Selasky }, 162a888087fSHans Petter Selasky [MLX5E_50GBASE_KR2] = { 163dc7e38acSHans Petter Selasky .subtype = IFM_50G_KR2, 164dc7e38acSHans Petter Selasky .baudrate = IF_Gbps(50ULL), 165dc7e38acSHans Petter Selasky }, 166a888087fSHans Petter Selasky [MLX5E_50GBASE_KR4] = { 16796dad2b7SKonstantin Belousov .subtype = IFM_50G_KR4, 16896dad2b7SKonstantin Belousov .baudrate = IF_Gbps(50ULL), 16996dad2b7SKonstantin Belousov }, 170dc7e38acSHans Petter Selasky }; 171dc7e38acSHans Petter Selasky 172a888087fSHans Petter Selasky static const struct media mlx5e_ext_mode_table[MLX5E_EXT_LINK_SPEEDS_NUMBER][MLX5E_CABLE_TYPE_NUMBER] = 173a888087fSHans Petter Selasky { 174a888087fSHans Petter Selasky /**/ 175a888087fSHans Petter Selasky [MLX5E_SGMII_100M][MLX5E_CABLE_TYPE_UNKNOWN] = { 176ac87880aSHans Petter Selasky .subtype = IFM_100_SGMII, 177ac87880aSHans Petter Selasky .baudrate = IF_Mbps(100), 178ac87880aSHans Petter Selasky }, 179a888087fSHans Petter Selasky 180a888087fSHans Petter Selasky /**/ 181a888087fSHans Petter Selasky [MLX5E_1000BASE_X_SGMII][MLX5E_CABLE_TYPE_UNKNOWN] = { 182ac87880aSHans Petter Selasky .subtype = IFM_1000_CX, 183ac87880aSHans Petter Selasky .baudrate = IF_Mbps(1000), 184ac87880aSHans Petter Selasky }, 185a888087fSHans Petter Selasky [MLX5E_1000BASE_X_SGMII][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 186ac87880aSHans Petter Selasky .subtype = IFM_1000_SX, 187ac87880aSHans Petter Selasky .baudrate = IF_Mbps(1000), 188ac87880aSHans Petter Selasky }, 189a888087fSHans Petter Selasky 190a888087fSHans Petter Selasky /**/ 191a888087fSHans Petter Selasky [MLX5E_5GBASE_R][MLX5E_CABLE_TYPE_UNKNOWN] = { 192ac87880aSHans Petter Selasky .subtype = IFM_5000_KR, 193ac87880aSHans Petter Selasky .baudrate = IF_Mbps(5000), 194ac87880aSHans Petter Selasky }, 195a888087fSHans Petter Selasky [MLX5E_5GBASE_R][MLX5E_CABLE_TYPE_TWISTED_PAIR] = { 196a888087fSHans Petter Selasky .subtype = IFM_5000_T, 197ac87880aSHans Petter Selasky .baudrate = IF_Mbps(5000), 198ac87880aSHans Petter Selasky }, 199a888087fSHans Petter Selasky 200a888087fSHans Petter Selasky /**/ 201a888087fSHans Petter Selasky [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_CABLE_TYPE_UNKNOWN] = { 202ac87880aSHans Petter Selasky .subtype = IFM_10G_KR, 203ac87880aSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 204ac87880aSHans Petter Selasky }, 205a888087fSHans Petter Selasky [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 206ac87880aSHans Petter Selasky .subtype = IFM_10G_CR1, 207ac87880aSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 208ac87880aSHans Petter Selasky }, 209a888087fSHans Petter Selasky [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 210a888087fSHans Petter Selasky .subtype = IFM_10G_SR, 211a888087fSHans Petter Selasky .baudrate = IF_Gbps(10ULL), 212ac87880aSHans Petter Selasky }, 213a888087fSHans Petter Selasky 214a888087fSHans Petter Selasky /**/ 215a888087fSHans Petter Selasky [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_CABLE_TYPE_UNKNOWN] = { 216ac87880aSHans Petter Selasky .subtype = IFM_40G_KR4, 217ac87880aSHans Petter Selasky .baudrate = IF_Gbps(40ULL), 218ac87880aSHans Petter Selasky }, 219a888087fSHans Petter Selasky [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 220a888087fSHans Petter Selasky .subtype = IFM_40G_CR4, 221ac87880aSHans Petter Selasky .baudrate = IF_Gbps(40ULL), 222ac87880aSHans Petter Selasky }, 223a888087fSHans Petter Selasky [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 224ac87880aSHans Petter Selasky .subtype = IFM_40G_SR4, 225ac87880aSHans Petter Selasky .baudrate = IF_Gbps(40ULL), 226ac87880aSHans Petter Selasky }, 227ac87880aSHans Petter Selasky 228a888087fSHans Petter Selasky /**/ 229a888087fSHans Petter Selasky [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_CABLE_TYPE_UNKNOWN] = { 230ac87880aSHans Petter Selasky .subtype = IFM_25G_KR, 231ac87880aSHans Petter Selasky .baudrate = IF_Gbps(25ULL), 232ac87880aSHans Petter Selasky }, 233a888087fSHans Petter Selasky [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 234a888087fSHans Petter Selasky .subtype = IFM_25G_CR, 235a888087fSHans Petter Selasky .baudrate = IF_Gbps(25ULL), 236a888087fSHans Petter Selasky }, 237a888087fSHans Petter Selasky [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 238ac87880aSHans Petter Selasky .subtype = IFM_25G_SR, 239ac87880aSHans Petter Selasky .baudrate = IF_Gbps(25ULL), 240ac87880aSHans Petter Selasky }, 241a888087fSHans Petter Selasky [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_CABLE_TYPE_TWISTED_PAIR] = { 242ac87880aSHans Petter Selasky .subtype = IFM_25G_T, 243ac87880aSHans Petter Selasky .baudrate = IF_Gbps(25ULL), 244ac87880aSHans Petter Selasky }, 245a888087fSHans Petter Selasky 246a888087fSHans Petter Selasky /**/ 247a888087fSHans Petter Selasky [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_CABLE_TYPE_UNKNOWN] = { 248ac87880aSHans Petter Selasky .subtype = IFM_50G_KR2, 249ac87880aSHans Petter Selasky .baudrate = IF_Gbps(50ULL), 250ac87880aSHans Petter Selasky }, 251a888087fSHans Petter Selasky [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 252a888087fSHans Petter Selasky .subtype = IFM_50G_CR2, 25396dad2b7SKonstantin Belousov .baudrate = IF_Gbps(50ULL), 25496dad2b7SKonstantin Belousov }, 255a888087fSHans Petter Selasky [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 256ac87880aSHans Petter Selasky .subtype = IFM_50G_SR2, 257ac87880aSHans Petter Selasky .baudrate = IF_Gbps(50ULL), 258ac87880aSHans Petter Selasky }, 259a888087fSHans Petter Selasky 260a888087fSHans Petter Selasky /**/ 261a888087fSHans Petter Selasky [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_CABLE_TYPE_UNKNOWN] = { 262ac87880aSHans Petter Selasky .subtype = IFM_50G_KR_PAM4, 263ac87880aSHans Petter Selasky .baudrate = IF_Gbps(50ULL), 264ac87880aSHans Petter Selasky }, 265a888087fSHans Petter Selasky [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 266a888087fSHans Petter Selasky .subtype = IFM_50G_CP, 267a888087fSHans Petter Selasky .baudrate = IF_Gbps(50ULL), 268ac87880aSHans Petter Selasky }, 269a888087fSHans Petter Selasky [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 270a888087fSHans Petter Selasky .subtype = IFM_50G_SR, 271a888087fSHans Petter Selasky .baudrate = IF_Gbps(50ULL), 272a888087fSHans Petter Selasky }, 273a888087fSHans Petter Selasky 274a888087fSHans Petter Selasky /**/ 275a888087fSHans Petter Selasky [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_CABLE_TYPE_UNKNOWN] = { 276ac87880aSHans Petter Selasky .subtype = IFM_100G_KR4, 277ac87880aSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 278ac87880aSHans Petter Selasky }, 279a888087fSHans Petter Selasky [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 280a888087fSHans Petter Selasky .subtype = IFM_100G_CR4, 281ac87880aSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 282ac87880aSHans Petter Selasky }, 283a888087fSHans Petter Selasky [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 284ac87880aSHans Petter Selasky .subtype = IFM_100G_SR4, 285ac87880aSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 286ac87880aSHans Petter Selasky }, 287a888087fSHans Petter Selasky 288a888087fSHans Petter Selasky /**/ 289a888087fSHans Petter Selasky [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_CABLE_TYPE_UNKNOWN] = { 290a888087fSHans Petter Selasky .subtype = IFM_100G_KR_PAM4, 291ac87880aSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 292ac87880aSHans Petter Selasky }, 293a888087fSHans Petter Selasky [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 294a888087fSHans Petter Selasky .subtype = IFM_100G_CR_PAM4, 295a888087fSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 296a888087fSHans Petter Selasky }, 297a888087fSHans Petter Selasky [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 298a888087fSHans Petter Selasky .subtype = IFM_100G_SR2, /* XXX */ 299a888087fSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 300a888087fSHans Petter Selasky }, 301a888087fSHans Petter Selasky 302a888087fSHans Petter Selasky /**/ 303a888087fSHans Petter Selasky [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_CABLE_TYPE_UNKNOWN] = { 304a888087fSHans Petter Selasky .subtype = IFM_100G_KR4, 305a888087fSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 306a888087fSHans Petter Selasky }, 307a888087fSHans Petter Selasky [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 308ac87880aSHans Petter Selasky .subtype = IFM_100G_CP2, 309ac87880aSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 310ac87880aSHans Petter Selasky }, 311a888087fSHans Petter Selasky [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 312a888087fSHans Petter Selasky .subtype = IFM_100G_SR2, 313ac87880aSHans Petter Selasky .baudrate = IF_Gbps(100ULL), 314ac87880aSHans Petter Selasky }, 315a888087fSHans Petter Selasky 316a888087fSHans Petter Selasky /**/ 317a888087fSHans Petter Selasky [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_CABLE_TYPE_UNKNOWN] = { 318a888087fSHans Petter Selasky .subtype = IFM_200G_KR4_PAM4, /* XXX */ 319ac87880aSHans Petter Selasky .baudrate = IF_Gbps(200ULL), 320ac87880aSHans Petter Selasky }, 321a888087fSHans Petter Selasky [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 322a888087fSHans Petter Selasky .subtype = IFM_200G_CR4_PAM4, /* XXX */ 323ac87880aSHans Petter Selasky .baudrate = IF_Gbps(200ULL), 324ac87880aSHans Petter Selasky }, 325a888087fSHans Petter Selasky [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 326a888087fSHans Petter Selasky .subtype = IFM_200G_SR4, /* XXX */ 327ac87880aSHans Petter Selasky .baudrate = IF_Gbps(200ULL), 328ac87880aSHans Petter Selasky }, 329a888087fSHans Petter Selasky 330a888087fSHans Petter Selasky /**/ 331a888087fSHans Petter Selasky [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_CABLE_TYPE_UNKNOWN] = { 332a888087fSHans Petter Selasky .subtype = IFM_200G_KR4_PAM4, 333ac87880aSHans Petter Selasky .baudrate = IF_Gbps(200ULL), 334ac87880aSHans Petter Selasky }, 335a888087fSHans Petter Selasky [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = { 336ac87880aSHans Petter Selasky .subtype = IFM_200G_CR4_PAM4, 337ac87880aSHans Petter Selasky .baudrate = IF_Gbps(200ULL), 338ac87880aSHans Petter Selasky }, 339a888087fSHans Petter Selasky [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = { 340a888087fSHans Petter Selasky .subtype = IFM_200G_SR4, 341ac87880aSHans Petter Selasky .baudrate = IF_Gbps(200ULL), 342ac87880aSHans Petter Selasky }, 343a888087fSHans Petter Selasky 344a888087fSHans Petter Selasky /**/ 345a888087fSHans Petter Selasky [MLX5E_400GAUI_8][MLX5E_CABLE_TYPE_UNKNOWN] = { 346a888087fSHans Petter Selasky .subtype = IFM_400G_LR8, /* XXX */ 347a888087fSHans Petter Selasky .baudrate = IF_Gbps(400ULL), 348a888087fSHans Petter Selasky }, 349a888087fSHans Petter Selasky 350a888087fSHans Petter Selasky /**/ 351a888087fSHans Petter Selasky [MLX5E_400GAUI_4_400GBASE_CR4_KR4][MLX5E_CABLE_TYPE_UNKNOWN] = { 352a888087fSHans Petter Selasky .subtype = IFM_400G_LR8, /* XXX */ 353a888087fSHans Petter Selasky .baudrate = IF_Gbps(400ULL), 354a888087fSHans Petter Selasky }, 355ac87880aSHans Petter Selasky }; 356ac87880aSHans Petter Selasky 357c782ea8bSJohn Baldwin static const struct if_snd_tag_sw mlx5e_ul_snd_tag_sw = { 358c782ea8bSJohn Baldwin .snd_tag_query = mlx5e_ul_snd_tag_query, 359c782ea8bSJohn Baldwin .snd_tag_free = mlx5e_ul_snd_tag_free, 360c782ea8bSJohn Baldwin .type = IF_SND_TAG_TYPE_UNLIMITED 361c782ea8bSJohn Baldwin }; 362c782ea8bSJohn Baldwin 36301651e96SHans Petter Selasky DEBUGNET_DEFINE(mlx5_en); 36401651e96SHans Petter Selasky 365dc7e38acSHans Petter Selasky MALLOC_DEFINE(M_MLX5EN, "MLX5EN", "MLX5 Ethernet"); 366dc7e38acSHans Petter Selasky 367dc7e38acSHans Petter Selasky static void 368dc7e38acSHans Petter Selasky mlx5e_update_carrier(struct mlx5e_priv *priv) 369dc7e38acSHans Petter Selasky { 370dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 371dc7e38acSHans Petter Selasky u32 out[MLX5_ST_SZ_DW(ptys_reg)]; 372dc7e38acSHans Petter Selasky u32 eth_proto_oper; 373dc7e38acSHans Petter Selasky int error; 374a888087fSHans Petter Selasky u8 i; 375a888087fSHans Petter Selasky u8 cable_type; 376dc7e38acSHans Petter Selasky u8 port_state; 37742390bb8SSlava Shwartsman u8 is_er_type; 378ac87880aSHans Petter Selasky bool ext; 379ac87880aSHans Petter Selasky struct media media_entry = {}; 380dc7e38acSHans Petter Selasky 381dc7e38acSHans Petter Selasky port_state = mlx5_query_vport_state(mdev, 382cb4e4a6eSHans Petter Selasky MLX5_QUERY_VPORT_STATE_IN_OP_MOD_VNIC_VPORT, 0); 383dc7e38acSHans Petter Selasky 384dc7e38acSHans Petter Selasky if (port_state == VPORT_STATE_UP) { 385dc7e38acSHans Petter Selasky priv->media_status_last |= IFM_ACTIVE; 386dc7e38acSHans Petter Selasky } else { 387dc7e38acSHans Petter Selasky priv->media_status_last &= ~IFM_ACTIVE; 388dc7e38acSHans Petter Selasky priv->media_active_last = IFM_ETHER; 389dc7e38acSHans Petter Selasky if_link_state_change(priv->ifp, LINK_STATE_DOWN); 390dc7e38acSHans Petter Selasky return; 391dc7e38acSHans Petter Selasky } 392dc7e38acSHans Petter Selasky 393ac87880aSHans Petter Selasky error = mlx5_query_port_ptys(mdev, out, sizeof(out), 394ac87880aSHans Petter Selasky MLX5_PTYS_EN, 1); 395dc7e38acSHans Petter Selasky if (error) { 396dc7e38acSHans Petter Selasky priv->media_active_last = IFM_ETHER; 3975dc00f00SJustin Hibbits if_setbaudrate(priv->ifp, 1); 3986b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, "query port ptys failed: 0x%x\n", 3996b4040d8SHans Petter Selasky error); 400dc7e38acSHans Petter Selasky return; 401dc7e38acSHans Petter Selasky } 402dc7e38acSHans Petter Selasky 403ac87880aSHans Petter Selasky ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); 404ac87880aSHans Petter Selasky eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, 405ac87880aSHans Petter Selasky eth_proto_oper); 40642390bb8SSlava Shwartsman 407ac87880aSHans Petter Selasky i = ilog2(eth_proto_oper); 40842390bb8SSlava Shwartsman 409a888087fSHans Petter Selasky if (ext) { 410a888087fSHans Petter Selasky error = mlx5_query_pddr_cable_type(mdev, 1, &cable_type); 411a888087fSHans Petter Selasky if (error != 0) { 412a888087fSHans Petter Selasky /* use fallback entry */ 413a888087fSHans Petter Selasky media_entry = mlx5e_ext_mode_table[i][MLX5E_CABLE_TYPE_UNKNOWN]; 414a888087fSHans Petter Selasky 415a888087fSHans Petter Selasky mlx5_en_err(priv->ifp, 416a888087fSHans Petter Selasky "query port pddr failed: %d\n", error); 417a888087fSHans Petter Selasky } else { 418a888087fSHans Petter Selasky media_entry = mlx5e_ext_mode_table[i][cable_type]; 419a888087fSHans Petter Selasky 420a888087fSHans Petter Selasky /* check if we should use fallback entry */ 421a888087fSHans Petter Selasky if (media_entry.subtype == 0) 422a888087fSHans Petter Selasky media_entry = mlx5e_ext_mode_table[i][MLX5E_CABLE_TYPE_UNKNOWN]; 423a888087fSHans Petter Selasky } 424a888087fSHans Petter Selasky } else { 425a888087fSHans Petter Selasky media_entry = mlx5e_mode_table[i]; 426ac87880aSHans Petter Selasky } 427ac87880aSHans Petter Selasky 428ac87880aSHans Petter Selasky if (media_entry.subtype == 0) { 4296b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 4306b4040d8SHans Petter Selasky "Could not find operational media subtype\n"); 431ac87880aSHans Petter Selasky return; 432ac87880aSHans Petter Selasky } 433ac87880aSHans Petter Selasky 434ac87880aSHans Petter Selasky switch (media_entry.subtype) { 43542390bb8SSlava Shwartsman case IFM_10G_ER: 43642390bb8SSlava Shwartsman error = mlx5_query_pddr_range_info(mdev, 1, &is_er_type); 43742390bb8SSlava Shwartsman if (error != 0) { 4386b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 4396b4040d8SHans Petter Selasky "query port pddr failed: %d\n", error); 44042390bb8SSlava Shwartsman } 44142390bb8SSlava Shwartsman if (error != 0 || is_er_type == 0) 442ac87880aSHans Petter Selasky media_entry.subtype = IFM_10G_LR; 44342390bb8SSlava Shwartsman break; 44442390bb8SSlava Shwartsman case IFM_40G_LR4: 44542390bb8SSlava Shwartsman error = mlx5_query_pddr_range_info(mdev, 1, &is_er_type); 44642390bb8SSlava Shwartsman if (error != 0) { 4476b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 4486b4040d8SHans Petter Selasky "query port pddr failed: %d\n", error); 44942390bb8SSlava Shwartsman } 45042390bb8SSlava Shwartsman if (error == 0 && is_er_type != 0) 451ac87880aSHans Petter Selasky media_entry.subtype = IFM_40G_ER4; 45242390bb8SSlava Shwartsman break; 45342390bb8SSlava Shwartsman } 454ac87880aSHans Petter Selasky priv->media_active_last = media_entry.subtype | IFM_ETHER | IFM_FDX; 4555dc00f00SJustin Hibbits if_setbaudrate(priv->ifp, media_entry.baudrate); 456ac87880aSHans Petter Selasky 457dc7e38acSHans Petter Selasky if_link_state_change(priv->ifp, LINK_STATE_UP); 458dc7e38acSHans Petter Selasky } 459dc7e38acSHans Petter Selasky 460dc7e38acSHans Petter Selasky static void 4615dc00f00SJustin Hibbits mlx5e_media_status(if_t dev, struct ifmediareq *ifmr) 462dc7e38acSHans Petter Selasky { 4635dc00f00SJustin Hibbits struct mlx5e_priv *priv = if_getsoftc(dev); 464dc7e38acSHans Petter Selasky 465dc7e38acSHans Petter Selasky ifmr->ifm_status = priv->media_status_last; 4660b8e170dSKonstantin Belousov ifmr->ifm_current = ifmr->ifm_active = priv->media_active_last | 4674d3b91a7SHans Petter Selasky (priv->params.rx_pauseframe_control ? IFM_ETH_RXPAUSE : 0) | 4684d3b91a7SHans Petter Selasky (priv->params.tx_pauseframe_control ? IFM_ETH_TXPAUSE : 0); 469dc7e38acSHans Petter Selasky 470dc7e38acSHans Petter Selasky } 471dc7e38acSHans Petter Selasky 472dc7e38acSHans Petter Selasky static u32 473ac87880aSHans Petter Selasky mlx5e_find_link_mode(u32 subtype, bool ext) 474dc7e38acSHans Petter Selasky { 475dc7e38acSHans Petter Selasky u32 link_mode = 0; 476dc7e38acSHans Petter Selasky 47742390bb8SSlava Shwartsman switch (subtype) { 478a888087fSHans Petter Selasky case 0: 479a888087fSHans Petter Selasky goto done; 48042390bb8SSlava Shwartsman case IFM_10G_LR: 48142390bb8SSlava Shwartsman subtype = IFM_10G_ER; 48242390bb8SSlava Shwartsman break; 48342390bb8SSlava Shwartsman case IFM_40G_ER4: 48442390bb8SSlava Shwartsman subtype = IFM_40G_LR4; 48542390bb8SSlava Shwartsman break; 486a888087fSHans Petter Selasky default: 487a888087fSHans Petter Selasky break; 48842390bb8SSlava Shwartsman } 48942390bb8SSlava Shwartsman 490a888087fSHans Petter Selasky if (ext) { 491a888087fSHans Petter Selasky for (unsigned i = 0; i != MLX5E_EXT_LINK_SPEEDS_NUMBER; i++) { 492a888087fSHans Petter Selasky for (unsigned j = 0; j != MLX5E_CABLE_TYPE_NUMBER; j++) { 493a888087fSHans Petter Selasky if (mlx5e_ext_mode_table[i][j].subtype == subtype) 494dc7e38acSHans Petter Selasky link_mode |= MLX5E_PROT_MASK(i); 495dc7e38acSHans Petter Selasky } 496ac87880aSHans Petter Selasky } 497a888087fSHans Petter Selasky } else { 498a888087fSHans Petter Selasky for (unsigned i = 0; i != MLX5E_LINK_SPEEDS_NUMBER; i++) { 499a888087fSHans Petter Selasky if (mlx5e_mode_table[i].subtype == subtype) 500a888087fSHans Petter Selasky link_mode |= MLX5E_PROT_MASK(i); 501ac87880aSHans Petter Selasky } 502a888087fSHans Petter Selasky } 503a888087fSHans Petter Selasky done: 504dc7e38acSHans Petter Selasky return (link_mode); 505dc7e38acSHans Petter Selasky } 506dc7e38acSHans Petter Selasky 507dc7e38acSHans Petter Selasky static int 50810b08045SHans Petter Selasky mlx5e_set_port_pause_and_pfc(struct mlx5e_priv *priv) 50910b08045SHans Petter Selasky { 51010b08045SHans Petter Selasky return (mlx5_set_port_pause_and_pfc(priv->mdev, 1, 51110b08045SHans Petter Selasky priv->params.rx_pauseframe_control, 51210b08045SHans Petter Selasky priv->params.tx_pauseframe_control, 51310b08045SHans Petter Selasky priv->params.rx_priority_flow_control, 51410b08045SHans Petter Selasky priv->params.tx_priority_flow_control)); 51510b08045SHans Petter Selasky } 51610b08045SHans Petter Selasky 51710b08045SHans Petter Selasky static int 51810b08045SHans Petter Selasky mlx5e_set_port_pfc(struct mlx5e_priv *priv) 51910b08045SHans Petter Selasky { 52010b08045SHans Petter Selasky int error; 52110b08045SHans Petter Selasky 52224385321SHans Petter Selasky if (priv->gone != 0) { 52324385321SHans Petter Selasky error = -ENXIO; 52424385321SHans Petter Selasky } else if (priv->params.rx_pauseframe_control || 52510b08045SHans Petter Selasky priv->params.tx_pauseframe_control) { 5266b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 5276b4040d8SHans Petter Selasky "Global pauseframes must be disabled before enabling PFC.\n"); 52810b08045SHans Petter Selasky error = -EINVAL; 52910b08045SHans Petter Selasky } else { 53010b08045SHans Petter Selasky error = mlx5e_set_port_pause_and_pfc(priv); 53110b08045SHans Petter Selasky } 53210b08045SHans Petter Selasky return (error); 53310b08045SHans Petter Selasky } 53410b08045SHans Petter Selasky 53510b08045SHans Petter Selasky static int 5365dc00f00SJustin Hibbits mlx5e_media_change(if_t dev) 537dc7e38acSHans Petter Selasky { 5385dc00f00SJustin Hibbits struct mlx5e_priv *priv = if_getsoftc(dev); 539dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 540dc7e38acSHans Petter Selasky u32 eth_proto_cap; 541dc7e38acSHans Petter Selasky u32 link_mode; 542ac87880aSHans Petter Selasky u32 out[MLX5_ST_SZ_DW(ptys_reg)]; 5434d3b91a7SHans Petter Selasky int was_opened; 544dc7e38acSHans Petter Selasky int locked; 545dc7e38acSHans Petter Selasky int error; 546ac87880aSHans Petter Selasky bool ext; 547dc7e38acSHans Petter Selasky 548dc7e38acSHans Petter Selasky locked = PRIV_LOCKED(priv); 549dc7e38acSHans Petter Selasky if (!locked) 550dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 551dc7e38acSHans Petter Selasky 552dc7e38acSHans Petter Selasky if (IFM_TYPE(priv->media.ifm_media) != IFM_ETHER) { 553dc7e38acSHans Petter Selasky error = EINVAL; 554dc7e38acSHans Petter Selasky goto done; 555dc7e38acSHans Petter Selasky } 556dc7e38acSHans Petter Selasky 557ac87880aSHans Petter Selasky error = mlx5_query_port_ptys(mdev, out, sizeof(out), 558ac87880aSHans Petter Selasky MLX5_PTYS_EN, 1); 5594d3b91a7SHans Petter Selasky if (error != 0) { 5606b4040d8SHans Petter Selasky mlx5_en_err(dev, "Query port media capability failed\n"); 561dc7e38acSHans Petter Selasky goto done; 562dc7e38acSHans Petter Selasky } 563ac87880aSHans Petter Selasky 564ac87880aSHans Petter Selasky ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); 565ac87880aSHans Petter Selasky link_mode = mlx5e_find_link_mode(IFM_SUBTYPE(priv->media.ifm_media), ext); 566ac87880aSHans Petter Selasky 567ac87880aSHans Petter Selasky /* query supported capabilities */ 568ac87880aSHans Petter Selasky eth_proto_cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, 569ac87880aSHans Petter Selasky eth_proto_capability); 570ac87880aSHans Petter Selasky 5714d3b91a7SHans Petter Selasky /* check for autoselect */ 5724d3b91a7SHans Petter Selasky if (IFM_SUBTYPE(priv->media.ifm_media) == IFM_AUTO) { 573dc7e38acSHans Petter Selasky link_mode = eth_proto_cap; 5744d3b91a7SHans Petter Selasky if (link_mode == 0) { 5756b4040d8SHans Petter Selasky mlx5_en_err(dev, "Port media capability is zero\n"); 5764d3b91a7SHans Petter Selasky error = EINVAL; 5774d3b91a7SHans Petter Selasky goto done; 5784d3b91a7SHans Petter Selasky } 5794d3b91a7SHans Petter Selasky } else { 580dc7e38acSHans Petter Selasky link_mode = link_mode & eth_proto_cap; 5814d3b91a7SHans Petter Selasky if (link_mode == 0) { 5826b4040d8SHans Petter Selasky mlx5_en_err(dev, "Not supported link mode requested\n"); 583dc7e38acSHans Petter Selasky error = EINVAL; 584dc7e38acSHans Petter Selasky goto done; 585dc7e38acSHans Petter Selasky } 5864d3b91a7SHans Petter Selasky } 58710b08045SHans Petter Selasky if (priv->media.ifm_media & (IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE)) { 58810b08045SHans Petter Selasky /* check if PFC is enabled */ 58910b08045SHans Petter Selasky if (priv->params.rx_priority_flow_control || 59010b08045SHans Petter Selasky priv->params.tx_priority_flow_control) { 5916b4040d8SHans Petter Selasky mlx5_en_err(dev, "PFC must be disabled before enabling global pauseframes.\n"); 59210b08045SHans Petter Selasky error = EINVAL; 59310b08045SHans Petter Selasky goto done; 59410b08045SHans Petter Selasky } 59510b08045SHans Petter Selasky } 5964d3b91a7SHans Petter Selasky /* update pauseframe control bits */ 5974d3b91a7SHans Petter Selasky priv->params.rx_pauseframe_control = 5984d3b91a7SHans Petter Selasky (priv->media.ifm_media & IFM_ETH_RXPAUSE) ? 1 : 0; 5994d3b91a7SHans Petter Selasky priv->params.tx_pauseframe_control = 6004d3b91a7SHans Petter Selasky (priv->media.ifm_media & IFM_ETH_TXPAUSE) ? 1 : 0; 6014d3b91a7SHans Petter Selasky 6024d3b91a7SHans Petter Selasky /* check if device is opened */ 6034d3b91a7SHans Petter Selasky was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); 6044d3b91a7SHans Petter Selasky 6054d3b91a7SHans Petter Selasky /* reconfigure the hardware */ 606dc7e38acSHans Petter Selasky mlx5_set_port_status(mdev, MLX5_PORT_DOWN); 607ac87880aSHans Petter Selasky mlx5_set_port_proto(mdev, link_mode, MLX5_PTYS_EN, ext); 60810b08045SHans Petter Selasky error = -mlx5e_set_port_pause_and_pfc(priv); 6094d3b91a7SHans Petter Selasky if (was_opened) 610dc7e38acSHans Petter Selasky mlx5_set_port_status(mdev, MLX5_PORT_UP); 611dc7e38acSHans Petter Selasky 612dc7e38acSHans Petter Selasky done: 613dc7e38acSHans Petter Selasky if (!locked) 614dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 615dc7e38acSHans Petter Selasky return (error); 616dc7e38acSHans Petter Selasky } 617dc7e38acSHans Petter Selasky 618dc7e38acSHans Petter Selasky static void 619dc7e38acSHans Petter Selasky mlx5e_update_carrier_work(struct work_struct *work) 620dc7e38acSHans Petter Selasky { 621dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv, 622dc7e38acSHans Petter Selasky update_carrier_work); 623dc7e38acSHans Petter Selasky 624dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 625dc7e38acSHans Petter Selasky if (test_bit(MLX5E_STATE_OPENED, &priv->state)) 626dc7e38acSHans Petter Selasky mlx5e_update_carrier(priv); 627dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 628dc7e38acSHans Petter Selasky } 629dc7e38acSHans Petter Selasky 6305f9484f3SHans Petter Selasky #define MLX5E_PCIE_PERF_GET_64(a,b,c,d,e,f) \ 6315f9484f3SHans Petter Selasky s_debug->c = MLX5_GET64(mpcnt_reg, out, counter_set.f.c); 6325f9484f3SHans Petter Selasky 6335f9484f3SHans Petter Selasky #define MLX5E_PCIE_PERF_GET_32(a,b,c,d,e,f) \ 6345f9484f3SHans Petter Selasky s_debug->c = MLX5_GET(mpcnt_reg, out, counter_set.f.c); 6355f9484f3SHans Petter Selasky 6365f9484f3SHans Petter Selasky static void 6375f9484f3SHans Petter Selasky mlx5e_update_pcie_counters(struct mlx5e_priv *priv) 6385f9484f3SHans Petter Selasky { 6395f9484f3SHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 6405f9484f3SHans Petter Selasky struct mlx5e_port_stats_debug *s_debug = &priv->stats.port_stats_debug; 6415f9484f3SHans Petter Selasky const unsigned sz = MLX5_ST_SZ_BYTES(mpcnt_reg); 6425f9484f3SHans Petter Selasky void *out; 6435f9484f3SHans Petter Selasky void *in; 6445f9484f3SHans Petter Selasky int err; 6455f9484f3SHans Petter Selasky 6465f9484f3SHans Petter Selasky /* allocate firmware request structures */ 6475f9484f3SHans Petter Selasky in = mlx5_vzalloc(sz); 6485f9484f3SHans Petter Selasky out = mlx5_vzalloc(sz); 6495f9484f3SHans Petter Selasky if (in == NULL || out == NULL) 6505f9484f3SHans Petter Selasky goto free_out; 6515f9484f3SHans Petter Selasky 6525f9484f3SHans Petter Selasky MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP); 6535f9484f3SHans Petter Selasky err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0); 6545f9484f3SHans Petter Selasky if (err != 0) 6555f9484f3SHans Petter Selasky goto free_out; 6565f9484f3SHans Petter Selasky 6575f9484f3SHans Petter Selasky MLX5E_PCIE_PERFORMANCE_COUNTERS_64(MLX5E_PCIE_PERF_GET_64) 6585f9484f3SHans Petter Selasky MLX5E_PCIE_PERFORMANCE_COUNTERS_32(MLX5E_PCIE_PERF_GET_32) 6595f9484f3SHans Petter Selasky 6605f9484f3SHans Petter Selasky MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_TIMERS_AND_STATES_COUNTERS_GROUP); 6615f9484f3SHans Petter Selasky err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0); 6625f9484f3SHans Petter Selasky if (err != 0) 6635f9484f3SHans Petter Selasky goto free_out; 6645f9484f3SHans Petter Selasky 6655f9484f3SHans Petter Selasky MLX5E_PCIE_TIMERS_AND_STATES_COUNTERS_32(MLX5E_PCIE_PERF_GET_32) 6665f9484f3SHans Petter Selasky 6675f9484f3SHans Petter Selasky MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_LANE_COUNTERS_GROUP); 6685f9484f3SHans Petter Selasky err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0); 6695f9484f3SHans Petter Selasky if (err != 0) 6705f9484f3SHans Petter Selasky goto free_out; 6715f9484f3SHans Petter Selasky 6725f9484f3SHans Petter Selasky MLX5E_PCIE_LANE_COUNTERS_32(MLX5E_PCIE_PERF_GET_32) 6735f9484f3SHans Petter Selasky 6745f9484f3SHans Petter Selasky free_out: 6755f9484f3SHans Petter Selasky /* free firmware request structures */ 6765f9484f3SHans Petter Selasky kvfree(in); 6775f9484f3SHans Petter Selasky kvfree(out); 6785f9484f3SHans Petter Selasky } 6795f9484f3SHans Petter Selasky 68043665913SHans Petter Selasky /* 68143665913SHans Petter Selasky * This function reads the physical port counters from the firmware 68243665913SHans Petter Selasky * using a pre-defined layout defined by various MLX5E_PPORT_XXX() 68343665913SHans Petter Selasky * macros. The output is converted from big-endian 64-bit values into 68443665913SHans Petter Selasky * host endian ones and stored in the "priv->stats.pport" structure. 68543665913SHans Petter Selasky */ 686dc7e38acSHans Petter Selasky static void 687dc7e38acSHans Petter Selasky mlx5e_update_pport_counters(struct mlx5e_priv *priv) 688dc7e38acSHans Petter Selasky { 689dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 690dc7e38acSHans Petter Selasky struct mlx5e_pport_stats *s = &priv->stats.pport; 691dc7e38acSHans Petter Selasky struct mlx5e_port_stats_debug *s_debug = &priv->stats.port_stats_debug; 692dc7e38acSHans Petter Selasky u32 *in; 693dc7e38acSHans Petter Selasky u32 *out; 69441aa095bSHans Petter Selasky const u64 *ptr; 695dc7e38acSHans Petter Selasky unsigned sz = MLX5_ST_SZ_BYTES(ppcnt_reg); 696dc7e38acSHans Petter Selasky unsigned x; 697dc7e38acSHans Petter Selasky unsigned y; 69810b08045SHans Petter Selasky unsigned z; 699dc7e38acSHans Petter Selasky 70043665913SHans Petter Selasky /* allocate firmware request structures */ 701dc7e38acSHans Petter Selasky in = mlx5_vzalloc(sz); 702dc7e38acSHans Petter Selasky out = mlx5_vzalloc(sz); 703dc7e38acSHans Petter Selasky if (in == NULL || out == NULL) 704dc7e38acSHans Petter Selasky goto free_out; 705dc7e38acSHans Petter Selasky 70643665913SHans Petter Selasky /* 70743665913SHans Petter Selasky * Get pointer to the 64-bit counter set which is located at a 70843665913SHans Petter Selasky * fixed offset in the output firmware request structure: 70943665913SHans Petter Selasky */ 71041aa095bSHans Petter Selasky ptr = (const uint64_t *)MLX5_ADDR_OF(ppcnt_reg, out, counter_set); 711dc7e38acSHans Petter Selasky 712dc7e38acSHans Petter Selasky MLX5_SET(ppcnt_reg, in, local_port, 1); 713dc7e38acSHans Petter Selasky 71443665913SHans Petter Selasky /* read IEEE802_3 counter group using predefined counter layout */ 715dc7e38acSHans Petter Selasky MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP); 716dc7e38acSHans Petter Selasky mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); 71710b08045SHans Petter Selasky for (x = 0, y = MLX5E_PPORT_PER_PRIO_STATS_NUM; 71810b08045SHans Petter Selasky x != MLX5E_PPORT_IEEE802_3_STATS_NUM; x++, y++) 719dc7e38acSHans Petter Selasky s->arg[y] = be64toh(ptr[x]); 720dc7e38acSHans Petter Selasky 72143665913SHans Petter Selasky /* read RFC2819 counter group using predefined counter layout */ 722dc7e38acSHans Petter Selasky MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2819_COUNTERS_GROUP); 723dc7e38acSHans Petter Selasky mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); 724dc7e38acSHans Petter Selasky for (x = 0; x != MLX5E_PPORT_RFC2819_STATS_NUM; x++, y++) 725dc7e38acSHans Petter Selasky s->arg[y] = be64toh(ptr[x]); 7265f9484f3SHans Petter Selasky 727dc7e38acSHans Petter Selasky for (y = 0; x != MLX5E_PPORT_RFC2819_STATS_NUM + 728dc7e38acSHans Petter Selasky MLX5E_PPORT_RFC2819_STATS_DEBUG_NUM; x++, y++) 729dc7e38acSHans Petter Selasky s_debug->arg[y] = be64toh(ptr[x]); 730dc7e38acSHans Petter Selasky 73143665913SHans Petter Selasky /* read RFC2863 counter group using predefined counter layout */ 732dc7e38acSHans Petter Selasky MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2863_COUNTERS_GROUP); 733dc7e38acSHans Petter Selasky mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); 734dc7e38acSHans Petter Selasky for (x = 0; x != MLX5E_PPORT_RFC2863_STATS_DEBUG_NUM; x++, y++) 735dc7e38acSHans Petter Selasky s_debug->arg[y] = be64toh(ptr[x]); 736dc7e38acSHans Petter Selasky 73743665913SHans Petter Selasky /* read physical layer stats counter group using predefined counter layout */ 738dc7e38acSHans Petter Selasky MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_COUNTERS_GROUP); 739dc7e38acSHans Petter Selasky mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); 740dc7e38acSHans Petter Selasky for (x = 0; x != MLX5E_PPORT_PHYSICAL_LAYER_STATS_DEBUG_NUM; x++, y++) 741dc7e38acSHans Petter Selasky s_debug->arg[y] = be64toh(ptr[x]); 74210b08045SHans Petter Selasky 743bcfad025SHans Petter Selasky /* read Extended Ethernet counter group using predefined counter layout */ 744bcfad025SHans Petter Selasky MLX5_SET(ppcnt_reg, in, grp, MLX5_ETHERNET_EXTENDED_COUNTERS_GROUP); 745bcfad025SHans Petter Selasky mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); 746bcfad025SHans Petter Selasky for (x = 0; x != MLX5E_PPORT_ETHERNET_EXTENDED_STATS_DEBUG_NUM; x++, y++) 747bcfad025SHans Petter Selasky s_debug->arg[y] = be64toh(ptr[x]); 748bcfad025SHans Petter Selasky 749c62f4d8dSHans Petter Selasky /* read Extended Statistical Group */ 750c62f4d8dSHans Petter Selasky if (MLX5_CAP_GEN(mdev, pcam_reg) && 751c62f4d8dSHans Petter Selasky MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group) && 752c62f4d8dSHans Petter Selasky MLX5_CAP_PCAM_FEATURE(mdev, per_lane_error_counters)) { 753c62f4d8dSHans Petter Selasky /* read Extended Statistical counter group using predefined counter layout */ 754c62f4d8dSHans Petter Selasky MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_STATISTICAL_GROUP); 755c62f4d8dSHans Petter Selasky mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); 756c62f4d8dSHans Petter Selasky 757c62f4d8dSHans Petter Selasky for (x = 0; x != MLX5E_PPORT_STATISTICAL_DEBUG_NUM; x++, y++) 758c62f4d8dSHans Petter Selasky s_debug->arg[y] = be64toh(ptr[x]); 759c62f4d8dSHans Petter Selasky } 760c62f4d8dSHans Petter Selasky 7615f9484f3SHans Petter Selasky /* read PCIE counters */ 7625f9484f3SHans Petter Selasky mlx5e_update_pcie_counters(priv); 7635f9484f3SHans Petter Selasky 76410b08045SHans Petter Selasky /* read per-priority counters */ 76510b08045SHans Petter Selasky MLX5_SET(ppcnt_reg, in, grp, MLX5_PER_PRIORITY_COUNTERS_GROUP); 76610b08045SHans Petter Selasky 76710b08045SHans Petter Selasky /* iterate all the priorities */ 76810b08045SHans Petter Selasky for (y = z = 0; z != MLX5E_PPORT_PER_PRIO_STATS_NUM_PRIO; z++) { 76910b08045SHans Petter Selasky MLX5_SET(ppcnt_reg, in, prio_tc, z); 77010b08045SHans Petter Selasky mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); 77110b08045SHans Petter Selasky 77210b08045SHans Petter Selasky /* read per priority stats counter group using predefined counter layout */ 77310b08045SHans Petter Selasky for (x = 0; x != (MLX5E_PPORT_PER_PRIO_STATS_NUM / 77410b08045SHans Petter Selasky MLX5E_PPORT_PER_PRIO_STATS_NUM_PRIO); x++, y++) 77510b08045SHans Petter Selasky s->arg[y] = be64toh(ptr[x]); 77610b08045SHans Petter Selasky } 777bcfad025SHans Petter Selasky 778dc7e38acSHans Petter Selasky free_out: 77943665913SHans Petter Selasky /* free firmware request structures */ 780dc7e38acSHans Petter Selasky kvfree(in); 781dc7e38acSHans Petter Selasky kvfree(out); 782dc7e38acSHans Petter Selasky } 783dc7e38acSHans Petter Selasky 784c29b90baSHans Petter Selasky static void 785c29b90baSHans Petter Selasky mlx5e_grp_vnic_env_update_stats(struct mlx5e_priv *priv) 786c29b90baSHans Petter Selasky { 787c29b90baSHans Petter Selasky u32 out[MLX5_ST_SZ_DW(query_vnic_env_out)] = {}; 788c29b90baSHans Petter Selasky u32 in[MLX5_ST_SZ_DW(query_vnic_env_in)] = {}; 789c29b90baSHans Petter Selasky 790c29b90baSHans Petter Selasky if (!MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard)) 791c29b90baSHans Petter Selasky return; 792c29b90baSHans Petter Selasky 793c29b90baSHans Petter Selasky MLX5_SET(query_vnic_env_in, in, opcode, 794c29b90baSHans Petter Selasky MLX5_CMD_OP_QUERY_VNIC_ENV); 795c29b90baSHans Petter Selasky MLX5_SET(query_vnic_env_in, in, op_mod, 0); 796c29b90baSHans Petter Selasky MLX5_SET(query_vnic_env_in, in, other_vport, 0); 797c29b90baSHans Petter Selasky 798c29b90baSHans Petter Selasky if (mlx5_cmd_exec(priv->mdev, in, sizeof(in), out, sizeof(out)) != 0) 799c29b90baSHans Petter Selasky return; 800c29b90baSHans Petter Selasky 801c29b90baSHans Petter Selasky priv->stats.vport.rx_steer_missed_packets = 802c29b90baSHans Petter Selasky MLX5_GET64(query_vnic_env_out, out, 803c29b90baSHans Petter Selasky vport_env.nic_receive_steering_discard); 804c29b90baSHans Petter Selasky } 805c29b90baSHans Petter Selasky 80643665913SHans Petter Selasky /* 80743665913SHans Petter Selasky * This function is called regularly to collect all statistics 80843665913SHans Petter Selasky * counters from the firmware. The values can be viewed through the 80943665913SHans Petter Selasky * sysctl interface. Execution is serialized using the priv's global 81043665913SHans Petter Selasky * configuration lock. 81143665913SHans Petter Selasky */ 812dc7e38acSHans Petter Selasky static void 813f0dcb8dfSHans Petter Selasky mlx5e_update_stats_locked(struct mlx5e_priv *priv) 814dc7e38acSHans Petter Selasky { 815dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 816dc7e38acSHans Petter Selasky struct mlx5e_vport_stats *s = &priv->stats.vport; 817dc7e38acSHans Petter Selasky struct mlx5e_sq_stats *sq_stats; 818dc7e38acSHans Petter Selasky u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)]; 819dc7e38acSHans Petter Selasky u32 *out; 820dc7e38acSHans Petter Selasky int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out); 821dc7e38acSHans Petter Selasky u64 tso_packets = 0; 822dc7e38acSHans Petter Selasky u64 tso_bytes = 0; 823dc7e38acSHans Petter Selasky u64 tx_queue_dropped = 0; 824dc7e38acSHans Petter Selasky u64 tx_defragged = 0; 825dc7e38acSHans Petter Selasky u64 tx_offload_none = 0; 826dc7e38acSHans Petter Selasky u64 lro_packets = 0; 827dc7e38acSHans Petter Selasky u64 lro_bytes = 0; 828dc7e38acSHans Petter Selasky u64 sw_lro_queued = 0; 829dc7e38acSHans Petter Selasky u64 sw_lro_flushed = 0; 830dc7e38acSHans Petter Selasky u64 rx_csum_none = 0; 831dc7e38acSHans Petter Selasky u64 rx_wqe_err = 0; 83294175bc9SHans Petter Selasky u64 rx_packets = 0; 83394175bc9SHans Petter Selasky u64 rx_bytes = 0; 83484d7b8e7SHans Petter Selasky u64 rx_decrypted_error = 0; 83584d7b8e7SHans Petter Selasky u64 rx_decrypted_ok = 0; 836ee090799SHans Petter Selasky u32 rx_out_of_buffer = 0; 83796425f44SHans Petter Selasky int error; 838dc7e38acSHans Petter Selasky int i; 839dc7e38acSHans Petter Selasky int j; 840dc7e38acSHans Petter Selasky 841dc7e38acSHans Petter Selasky out = mlx5_vzalloc(outlen); 842dc7e38acSHans Petter Selasky if (out == NULL) 843dc7e38acSHans Petter Selasky goto free_out; 844dc7e38acSHans Petter Selasky 845dc7e38acSHans Petter Selasky /* Collect firts the SW counters and then HW for consistency */ 846dc7e38acSHans Petter Selasky for (i = 0; i < priv->params.num_channels; i++) { 8473230c29dSSlava Shwartsman struct mlx5e_channel *pch = priv->channel + i; 8483230c29dSSlava Shwartsman struct mlx5e_rq *rq = &pch->rq; 8493230c29dSSlava Shwartsman struct mlx5e_rq_stats *rq_stats = &pch->rq.stats; 850dc7e38acSHans Petter Selasky 851dc7e38acSHans Petter Selasky /* collect stats from LRO */ 852dc7e38acSHans Petter Selasky rq_stats->sw_lro_queued = rq->lro.lro_queued; 853dc7e38acSHans Petter Selasky rq_stats->sw_lro_flushed = rq->lro.lro_flushed; 854dc7e38acSHans Petter Selasky sw_lro_queued += rq_stats->sw_lro_queued; 855dc7e38acSHans Petter Selasky sw_lro_flushed += rq_stats->sw_lro_flushed; 856dc7e38acSHans Petter Selasky lro_packets += rq_stats->lro_packets; 857dc7e38acSHans Petter Selasky lro_bytes += rq_stats->lro_bytes; 858dc7e38acSHans Petter Selasky rx_csum_none += rq_stats->csum_none; 859dc7e38acSHans Petter Selasky rx_wqe_err += rq_stats->wqe_err; 86094175bc9SHans Petter Selasky rx_packets += rq_stats->packets; 86194175bc9SHans Petter Selasky rx_bytes += rq_stats->bytes; 86284d7b8e7SHans Petter Selasky rx_decrypted_error += rq_stats->decrypted_error_packets; 86384d7b8e7SHans Petter Selasky rx_decrypted_ok += rq_stats->decrypted_ok_packets; 864dc7e38acSHans Petter Selasky 865dc7e38acSHans Petter Selasky for (j = 0; j < priv->num_tc; j++) { 8663230c29dSSlava Shwartsman sq_stats = &pch->sq[j].stats; 867dc7e38acSHans Petter Selasky 868dc7e38acSHans Petter Selasky tso_packets += sq_stats->tso_packets; 869dc7e38acSHans Petter Selasky tso_bytes += sq_stats->tso_bytes; 870dc7e38acSHans Petter Selasky tx_queue_dropped += sq_stats->dropped; 871bd88e5f2SHans Petter Selasky tx_queue_dropped += sq_stats->enobuf; 872dc7e38acSHans Petter Selasky tx_defragged += sq_stats->defragged; 873dc7e38acSHans Petter Selasky tx_offload_none += sq_stats->csum_offload_none; 874dc7e38acSHans Petter Selasky } 875dc7e38acSHans Petter Selasky } 876dc7e38acSHans Petter Selasky 8779e7fa1e6SHans Petter Selasky #ifdef RATELIMIT 8789e7fa1e6SHans Petter Selasky /* Collect statistics from all rate-limit queues */ 8799e7fa1e6SHans Petter Selasky for (j = 0; j < priv->rl.param.tx_worker_threads_def; j++) { 8809e7fa1e6SHans Petter Selasky struct mlx5e_rl_worker *rlw = priv->rl.workers + j; 8819e7fa1e6SHans Petter Selasky 8829e7fa1e6SHans Petter Selasky for (i = 0; i < priv->rl.param.tx_channels_per_worker_def; i++) { 8839e7fa1e6SHans Petter Selasky struct mlx5e_rl_channel *channel = rlw->channels + i; 8849e7fa1e6SHans Petter Selasky struct mlx5e_sq *sq = channel->sq; 8859e7fa1e6SHans Petter Selasky 8869e7fa1e6SHans Petter Selasky if (sq == NULL) 8879e7fa1e6SHans Petter Selasky continue; 8889e7fa1e6SHans Petter Selasky 8899e7fa1e6SHans Petter Selasky sq_stats = &sq->stats; 8909e7fa1e6SHans Petter Selasky 8919e7fa1e6SHans Petter Selasky tso_packets += sq_stats->tso_packets; 8929e7fa1e6SHans Petter Selasky tso_bytes += sq_stats->tso_bytes; 8939e7fa1e6SHans Petter Selasky tx_queue_dropped += sq_stats->dropped; 8949e7fa1e6SHans Petter Selasky tx_queue_dropped += sq_stats->enobuf; 8959e7fa1e6SHans Petter Selasky tx_defragged += sq_stats->defragged; 8969e7fa1e6SHans Petter Selasky tx_offload_none += sq_stats->csum_offload_none; 8979e7fa1e6SHans Petter Selasky } 8989e7fa1e6SHans Petter Selasky } 8999e7fa1e6SHans Petter Selasky #endif 9009e7fa1e6SHans Petter Selasky 901dc7e38acSHans Petter Selasky /* update counters */ 902dc7e38acSHans Petter Selasky s->tso_packets = tso_packets; 903dc7e38acSHans Petter Selasky s->tso_bytes = tso_bytes; 904dc7e38acSHans Petter Selasky s->tx_queue_dropped = tx_queue_dropped; 905dc7e38acSHans Petter Selasky s->tx_defragged = tx_defragged; 906dc7e38acSHans Petter Selasky s->lro_packets = lro_packets; 907dc7e38acSHans Petter Selasky s->lro_bytes = lro_bytes; 908dc7e38acSHans Petter Selasky s->sw_lro_queued = sw_lro_queued; 909dc7e38acSHans Petter Selasky s->sw_lro_flushed = sw_lro_flushed; 910dc7e38acSHans Petter Selasky s->rx_csum_none = rx_csum_none; 911dc7e38acSHans Petter Selasky s->rx_wqe_err = rx_wqe_err; 91294175bc9SHans Petter Selasky s->rx_packets = rx_packets; 91394175bc9SHans Petter Selasky s->rx_bytes = rx_bytes; 91484d7b8e7SHans Petter Selasky s->rx_decrypted_error_packets = rx_decrypted_error; 91584d7b8e7SHans Petter Selasky s->rx_decrypted_ok_packets = rx_decrypted_ok; 916dc7e38acSHans Petter Selasky 917c29b90baSHans Petter Selasky mlx5e_grp_vnic_env_update_stats(priv); 918c29b90baSHans Petter Selasky 919dc7e38acSHans Petter Selasky /* HW counters */ 920dc7e38acSHans Petter Selasky memset(in, 0, sizeof(in)); 921dc7e38acSHans Petter Selasky 922dc7e38acSHans Petter Selasky MLX5_SET(query_vport_counter_in, in, opcode, 923dc7e38acSHans Petter Selasky MLX5_CMD_OP_QUERY_VPORT_COUNTER); 924dc7e38acSHans Petter Selasky MLX5_SET(query_vport_counter_in, in, op_mod, 0); 925dc7e38acSHans Petter Selasky MLX5_SET(query_vport_counter_in, in, other_vport, 0); 926dc7e38acSHans Petter Selasky 927dc7e38acSHans Petter Selasky memset(out, 0, outlen); 928dc7e38acSHans Petter Selasky 929ee090799SHans Petter Selasky /* get number of out-of-buffer drops first */ 930f0dcb8dfSHans Petter Selasky if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0 && 931f0dcb8dfSHans Petter Selasky mlx5_vport_query_out_of_rx_buffer(mdev, priv->counter_set_id, 932f0dcb8dfSHans Petter Selasky &rx_out_of_buffer) == 0) { 933752b8aabSHans Petter Selasky s->rx_out_of_buffer = rx_out_of_buffer; 934f0dcb8dfSHans Petter Selasky } 935ee090799SHans Petter Selasky 936ee090799SHans Petter Selasky /* get port statistics */ 937f0dcb8dfSHans Petter Selasky if (mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen) == 0) { 938dc7e38acSHans Petter Selasky #define MLX5_GET_CTR(out, x) \ 939dc7e38acSHans Petter Selasky MLX5_GET64(query_vport_counter_out, out, x) 940dc7e38acSHans Petter Selasky 941dc7e38acSHans Petter Selasky s->rx_error_packets = 942dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, received_errors.packets); 943dc7e38acSHans Petter Selasky s->rx_error_bytes = 944dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, received_errors.octets); 945dc7e38acSHans Petter Selasky s->tx_error_packets = 946dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, transmit_errors.packets); 947dc7e38acSHans Petter Selasky s->tx_error_bytes = 948dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, transmit_errors.octets); 949dc7e38acSHans Petter Selasky 950dc7e38acSHans Petter Selasky s->rx_unicast_packets = 951dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, received_eth_unicast.packets); 952dc7e38acSHans Petter Selasky s->rx_unicast_bytes = 953dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, received_eth_unicast.octets); 954dc7e38acSHans Petter Selasky s->tx_unicast_packets = 955dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, transmitted_eth_unicast.packets); 956dc7e38acSHans Petter Selasky s->tx_unicast_bytes = 957dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, transmitted_eth_unicast.octets); 958dc7e38acSHans Petter Selasky 959dc7e38acSHans Petter Selasky s->rx_multicast_packets = 960dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, received_eth_multicast.packets); 961dc7e38acSHans Petter Selasky s->rx_multicast_bytes = 962dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, received_eth_multicast.octets); 963dc7e38acSHans Petter Selasky s->tx_multicast_packets = 964dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, transmitted_eth_multicast.packets); 965dc7e38acSHans Petter Selasky s->tx_multicast_bytes = 966dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, transmitted_eth_multicast.octets); 967dc7e38acSHans Petter Selasky 968dc7e38acSHans Petter Selasky s->rx_broadcast_packets = 969dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, received_eth_broadcast.packets); 970dc7e38acSHans Petter Selasky s->rx_broadcast_bytes = 971dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, received_eth_broadcast.octets); 972dc7e38acSHans Petter Selasky s->tx_broadcast_packets = 973dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, transmitted_eth_broadcast.packets); 974dc7e38acSHans Petter Selasky s->tx_broadcast_bytes = 975dc7e38acSHans Petter Selasky MLX5_GET_CTR(out, transmitted_eth_broadcast.octets); 976dc7e38acSHans Petter Selasky 977f0dcb8dfSHans Petter Selasky s->tx_packets = s->tx_unicast_packets + 978f0dcb8dfSHans Petter Selasky s->tx_multicast_packets + s->tx_broadcast_packets; 979f0dcb8dfSHans Petter Selasky s->tx_bytes = s->tx_unicast_bytes + s->tx_multicast_bytes + 980dc7e38acSHans Petter Selasky s->tx_broadcast_bytes; 981dc7e38acSHans Petter Selasky 982dc7e38acSHans Petter Selasky /* Update calculated offload counters */ 983dc7e38acSHans Petter Selasky s->tx_csum_offload = s->tx_packets - tx_offload_none; 984dc7e38acSHans Petter Selasky s->rx_csum_good = s->rx_packets - s->rx_csum_none; 985f0dcb8dfSHans Petter Selasky } 986dc7e38acSHans Petter Selasky 9878b483546SHans Petter Selasky /* Get physical port counters */ 988ee090799SHans Petter Selasky mlx5e_update_pport_counters(priv); 989ee090799SHans Petter Selasky 990c66537d7SHans Petter Selasky s->tx_jumbo_packets = 991c66537d7SHans Petter Selasky priv->stats.port_stats_debug.tx_stat_p1519to2047octets + 992c66537d7SHans Petter Selasky priv->stats.port_stats_debug.tx_stat_p2048to4095octets + 993c66537d7SHans Petter Selasky priv->stats.port_stats_debug.tx_stat_p4096to8191octets + 994c66537d7SHans Petter Selasky priv->stats.port_stats_debug.tx_stat_p8192to10239octets; 995c66537d7SHans Petter Selasky 996dc7e38acSHans Petter Selasky free_out: 997dc7e38acSHans Petter Selasky kvfree(out); 99866d53750SHans Petter Selasky 99966d53750SHans Petter Selasky /* Update diagnostics, if any */ 100066d53750SHans Petter Selasky if (priv->params_ethtool.diag_pci_enable || 100166d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable) { 100296425f44SHans Petter Selasky error = mlx5_core_get_diagnostics_full(mdev, 100366d53750SHans Petter Selasky priv->params_ethtool.diag_pci_enable ? &priv->params_pci : NULL, 100466d53750SHans Petter Selasky priv->params_ethtool.diag_general_enable ? &priv->params_general : NULL); 100566d53750SHans Petter Selasky if (error != 0) 10066b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 10076b4040d8SHans Petter Selasky "Failed reading diagnostics: %d\n", error); 100866d53750SHans Petter Selasky } 100996425f44SHans Petter Selasky 101096425f44SHans Petter Selasky /* Update FEC, if any */ 101196425f44SHans Petter Selasky error = mlx5e_fec_update(priv); 101296425f44SHans Petter Selasky if (error != 0 && error != EOPNOTSUPP) { 101396425f44SHans Petter Selasky mlx5_en_err(priv->ifp, 101496425f44SHans Petter Selasky "Updating FEC failed: %d\n", error); 101596425f44SHans Petter Selasky } 1016decb087cSHans Petter Selasky 1017decb087cSHans Petter Selasky /* Update temperature, if any */ 1018decb087cSHans Petter Selasky if (priv->params_ethtool.hw_num_temp != 0) { 1019decb087cSHans Petter Selasky error = mlx5e_hw_temperature_update(priv); 1020decb087cSHans Petter Selasky if (error != 0 && error != EOPNOTSUPP) { 1021decb087cSHans Petter Selasky mlx5_en_err(priv->ifp, 1022decb087cSHans Petter Selasky "Updating temperature failed: %d\n", error); 1023decb087cSHans Petter Selasky } 1024decb087cSHans Petter Selasky } 1025f0dcb8dfSHans Petter Selasky } 1026f0dcb8dfSHans Petter Selasky 1027f0dcb8dfSHans Petter Selasky static void 1028f0dcb8dfSHans Petter Selasky mlx5e_update_stats_work(struct work_struct *work) 1029f0dcb8dfSHans Petter Selasky { 1030f0dcb8dfSHans Petter Selasky struct mlx5e_priv *priv; 1031f0dcb8dfSHans Petter Selasky 1032f0dcb8dfSHans Petter Selasky priv = container_of(work, struct mlx5e_priv, update_stats_work); 1033f0dcb8dfSHans Petter Selasky PRIV_LOCK(priv); 10340cf6ff0aSKonstantin Belousov if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0 && 10350cf6ff0aSKonstantin Belousov !test_bit(MLX5_INTERFACE_STATE_TEARDOWN, &priv->mdev->intf_state)) 1036f0dcb8dfSHans Petter Selasky mlx5e_update_stats_locked(priv); 1037dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 1038dc7e38acSHans Petter Selasky } 1039dc7e38acSHans Petter Selasky 1040dc7e38acSHans Petter Selasky static void 1041dc7e38acSHans Petter Selasky mlx5e_update_stats(void *arg) 1042dc7e38acSHans Petter Selasky { 1043dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg; 1044dc7e38acSHans Petter Selasky 104517778156SHans Petter Selasky queue_work(priv->wq, &priv->update_stats_work); 1046dc7e38acSHans Petter Selasky 104739b0f9c3SHans Petter Selasky callout_reset(&priv->watchdog, hz / 4, &mlx5e_update_stats, priv); 1048dc7e38acSHans Petter Selasky } 1049dc7e38acSHans Petter Selasky 1050dc7e38acSHans Petter Selasky static void 1051dc7e38acSHans Petter Selasky mlx5e_async_event_sub(struct mlx5e_priv *priv, 1052dc7e38acSHans Petter Selasky enum mlx5_dev_event event) 1053dc7e38acSHans Petter Selasky { 1054dc7e38acSHans Petter Selasky switch (event) { 1055dc7e38acSHans Petter Selasky case MLX5_DEV_EVENT_PORT_UP: 1056dc7e38acSHans Petter Selasky case MLX5_DEV_EVENT_PORT_DOWN: 105717778156SHans Petter Selasky queue_work(priv->wq, &priv->update_carrier_work); 1058dc7e38acSHans Petter Selasky break; 1059dc7e38acSHans Petter Selasky 1060dc7e38acSHans Petter Selasky default: 1061dc7e38acSHans Petter Selasky break; 1062dc7e38acSHans Petter Selasky } 1063dc7e38acSHans Petter Selasky } 1064dc7e38acSHans Petter Selasky 1065dc7e38acSHans Petter Selasky static void 1066dc7e38acSHans Petter Selasky mlx5e_async_event(struct mlx5_core_dev *mdev, void *vpriv, 1067dc7e38acSHans Petter Selasky enum mlx5_dev_event event, unsigned long param) 1068dc7e38acSHans Petter Selasky { 1069dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = vpriv; 1070dc7e38acSHans Petter Selasky 1071dc7e38acSHans Petter Selasky mtx_lock(&priv->async_events_mtx); 1072dc7e38acSHans Petter Selasky if (test_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state)) 1073dc7e38acSHans Petter Selasky mlx5e_async_event_sub(priv, event); 1074dc7e38acSHans Petter Selasky mtx_unlock(&priv->async_events_mtx); 1075dc7e38acSHans Petter Selasky } 1076dc7e38acSHans Petter Selasky 1077dc7e38acSHans Petter Selasky static void 1078dc7e38acSHans Petter Selasky mlx5e_enable_async_events(struct mlx5e_priv *priv) 1079dc7e38acSHans Petter Selasky { 1080dc7e38acSHans Petter Selasky set_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state); 1081dc7e38acSHans Petter Selasky } 1082dc7e38acSHans Petter Selasky 1083dc7e38acSHans Petter Selasky static void 1084dc7e38acSHans Petter Selasky mlx5e_disable_async_events(struct mlx5e_priv *priv) 1085dc7e38acSHans Petter Selasky { 1086dc7e38acSHans Petter Selasky mtx_lock(&priv->async_events_mtx); 1087dc7e38acSHans Petter Selasky clear_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state); 1088dc7e38acSHans Petter Selasky mtx_unlock(&priv->async_events_mtx); 1089dc7e38acSHans Petter Selasky } 1090dc7e38acSHans Petter Selasky 1091ef23f141SKonstantin Belousov static void mlx5e_calibration_callout(void *arg); 1092ef23f141SKonstantin Belousov static int mlx5e_calibration_duration = 20; 1093ef23f141SKonstantin Belousov static int mlx5e_fast_calibration = 1; 1094ef23f141SKonstantin Belousov static int mlx5e_normal_calibration = 30; 1095ef23f141SKonstantin Belousov 10967029da5cSPawel Biernacki static SYSCTL_NODE(_hw_mlx5, OID_AUTO, calibr, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 1097db0ac6deSCy Schubert "MLX5 timestamp calibration parameters"); 1098ef23f141SKonstantin Belousov 1099ef23f141SKonstantin Belousov SYSCTL_INT(_hw_mlx5_calibr, OID_AUTO, duration, CTLFLAG_RWTUN, 1100ef23f141SKonstantin Belousov &mlx5e_calibration_duration, 0, 1101ef23f141SKonstantin Belousov "Duration of initial calibration"); 1102ef23f141SKonstantin Belousov SYSCTL_INT(_hw_mlx5_calibr, OID_AUTO, fast, CTLFLAG_RWTUN, 1103ef23f141SKonstantin Belousov &mlx5e_fast_calibration, 0, 1104ef23f141SKonstantin Belousov "Recalibration interval during initial calibration"); 1105ef23f141SKonstantin Belousov SYSCTL_INT(_hw_mlx5_calibr, OID_AUTO, normal, CTLFLAG_RWTUN, 1106ef23f141SKonstantin Belousov &mlx5e_normal_calibration, 0, 1107ef23f141SKonstantin Belousov "Recalibration interval during normal operations"); 1108ef23f141SKonstantin Belousov 1109ef23f141SKonstantin Belousov /* 1110ef23f141SKonstantin Belousov * Ignites the calibration process. 1111ef23f141SKonstantin Belousov */ 1112ef23f141SKonstantin Belousov static void 1113ef23f141SKonstantin Belousov mlx5e_reset_calibration_callout(struct mlx5e_priv *priv) 1114ef23f141SKonstantin Belousov { 1115ef23f141SKonstantin Belousov 1116ef23f141SKonstantin Belousov if (priv->clbr_done == 0) 1117ef23f141SKonstantin Belousov mlx5e_calibration_callout(priv); 1118ef23f141SKonstantin Belousov else 11190eb2dcd3SKonstantin Belousov callout_reset_sbt_curcpu(&priv->tstmp_clbr, (priv->clbr_done < 1120ef23f141SKonstantin Belousov mlx5e_calibration_duration ? mlx5e_fast_calibration : 11210eb2dcd3SKonstantin Belousov mlx5e_normal_calibration) * SBT_1S, 0, 11220eb2dcd3SKonstantin Belousov mlx5e_calibration_callout, priv, C_DIRECT_EXEC); 1123ef23f141SKonstantin Belousov } 1124ef23f141SKonstantin Belousov 1125ef23f141SKonstantin Belousov static uint64_t 1126ef23f141SKonstantin Belousov mlx5e_timespec2usec(const struct timespec *ts) 1127ef23f141SKonstantin Belousov { 1128ef23f141SKonstantin Belousov 1129ef23f141SKonstantin Belousov return ((uint64_t)ts->tv_sec * 1000000000 + ts->tv_nsec); 1130ef23f141SKonstantin Belousov } 1131ef23f141SKonstantin Belousov 1132ef23f141SKonstantin Belousov static uint64_t 1133ef23f141SKonstantin Belousov mlx5e_hw_clock(struct mlx5e_priv *priv) 1134ef23f141SKonstantin Belousov { 1135ef23f141SKonstantin Belousov struct mlx5_init_seg *iseg; 1136ef23f141SKonstantin Belousov uint32_t hw_h, hw_h1, hw_l; 1137ef23f141SKonstantin Belousov 1138ef23f141SKonstantin Belousov iseg = priv->mdev->iseg; 1139ef23f141SKonstantin Belousov do { 1140ef23f141SKonstantin Belousov hw_h = ioread32be(&iseg->internal_timer_h); 1141ef23f141SKonstantin Belousov hw_l = ioread32be(&iseg->internal_timer_l); 1142ef23f141SKonstantin Belousov hw_h1 = ioread32be(&iseg->internal_timer_h); 1143ef23f141SKonstantin Belousov } while (hw_h1 != hw_h); 1144ef23f141SKonstantin Belousov return (((uint64_t)hw_h << 32) | hw_l); 1145ef23f141SKonstantin Belousov } 1146ef23f141SKonstantin Belousov 1147ef23f141SKonstantin Belousov /* 1148ef23f141SKonstantin Belousov * The calibration callout, it runs either in the context of the 1149ef23f141SKonstantin Belousov * thread which enables calibration, or in callout. It takes the 1150ef23f141SKonstantin Belousov * snapshot of system and adapter clocks, then advances the pointers to 1151ef23f141SKonstantin Belousov * the calibration point to allow rx path to read the consistent data 1152ef23f141SKonstantin Belousov * lockless. 1153ef23f141SKonstantin Belousov */ 1154ef23f141SKonstantin Belousov static void 1155ef23f141SKonstantin Belousov mlx5e_calibration_callout(void *arg) 1156ef23f141SKonstantin Belousov { 1157ef23f141SKonstantin Belousov struct mlx5e_priv *priv; 1158ef23f141SKonstantin Belousov struct mlx5e_clbr_point *next, *curr; 1159ef23f141SKonstantin Belousov struct timespec ts; 1160ef23f141SKonstantin Belousov int clbr_curr_next; 1161ef23f141SKonstantin Belousov 1162ef23f141SKonstantin Belousov priv = arg; 1163ef23f141SKonstantin Belousov curr = &priv->clbr_points[priv->clbr_curr]; 1164ef23f141SKonstantin Belousov clbr_curr_next = priv->clbr_curr + 1; 1165ef23f141SKonstantin Belousov if (clbr_curr_next >= nitems(priv->clbr_points)) 1166ef23f141SKonstantin Belousov clbr_curr_next = 0; 1167ef23f141SKonstantin Belousov next = &priv->clbr_points[clbr_curr_next]; 1168ef23f141SKonstantin Belousov 1169ef23f141SKonstantin Belousov next->base_prev = curr->base_curr; 1170ef23f141SKonstantin Belousov next->clbr_hw_prev = curr->clbr_hw_curr; 1171ef23f141SKonstantin Belousov 1172ef23f141SKonstantin Belousov next->clbr_hw_curr = mlx5e_hw_clock(priv); 1173945f3984SHans Petter Selasky if (((next->clbr_hw_curr - curr->clbr_hw_curr) >> MLX5E_TSTMP_PREC) == 1174ef23f141SKonstantin Belousov 0) { 1175945f3984SHans Petter Selasky if (priv->clbr_done != 0) { 11766b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 11776b4040d8SHans Petter Selasky "HW failed tstmp frozen %#jx %#jx, disabling\n", 1178945f3984SHans Petter Selasky next->clbr_hw_curr, curr->clbr_hw_prev); 1179ef23f141SKonstantin Belousov priv->clbr_done = 0; 1180945f3984SHans Petter Selasky } 1181945f3984SHans Petter Selasky atomic_store_rel_int(&curr->clbr_gen, 0); 1182ef23f141SKonstantin Belousov return; 1183ef23f141SKonstantin Belousov } 1184ef23f141SKonstantin Belousov 1185ef23f141SKonstantin Belousov nanouptime(&ts); 1186ef23f141SKonstantin Belousov next->base_curr = mlx5e_timespec2usec(&ts); 1187ef23f141SKonstantin Belousov 1188ef23f141SKonstantin Belousov curr->clbr_gen = 0; 1189ef23f141SKonstantin Belousov atomic_thread_fence_rel(); 1190ef23f141SKonstantin Belousov priv->clbr_curr = clbr_curr_next; 1191ef23f141SKonstantin Belousov atomic_store_rel_int(&next->clbr_gen, ++(priv->clbr_gen)); 1192ef23f141SKonstantin Belousov 1193ef23f141SKonstantin Belousov if (priv->clbr_done < mlx5e_calibration_duration) 1194ef23f141SKonstantin Belousov priv->clbr_done++; 1195ef23f141SKonstantin Belousov mlx5e_reset_calibration_callout(priv); 1196ef23f141SKonstantin Belousov } 1197ef23f141SKonstantin Belousov 1198dc7e38acSHans Petter Selasky static const char *mlx5e_rq_stats_desc[] = { 1199dc7e38acSHans Petter Selasky MLX5E_RQ_STATS(MLX5E_STATS_DESC) 1200dc7e38acSHans Petter Selasky }; 1201dc7e38acSHans Petter Selasky 1202dc7e38acSHans Petter Selasky static int 1203dc7e38acSHans Petter Selasky mlx5e_create_rq(struct mlx5e_channel *c, 1204dc7e38acSHans Petter Selasky struct mlx5e_rq_param *param, 1205dc7e38acSHans Petter Selasky struct mlx5e_rq *rq) 1206dc7e38acSHans Petter Selasky { 1207dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = c->priv; 1208dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 1209dc7e38acSHans Petter Selasky char buffer[16]; 1210dc7e38acSHans Petter Selasky void *rqc = param->rqc; 1211dc7e38acSHans Petter Selasky void *rqc_wq = MLX5_ADDR_OF(rqc, rqc, wq); 1212dc7e38acSHans Petter Selasky int wq_sz; 1213dc7e38acSHans Petter Selasky int err; 1214dc7e38acSHans Petter Selasky int i; 12152f17f76aSHans Petter Selasky u32 nsegs, wqe_sz; 12162f17f76aSHans Petter Selasky 12172f17f76aSHans Petter Selasky err = mlx5e_get_wqe_sz(priv, &wqe_sz, &nsegs); 12182f17f76aSHans Petter Selasky if (err != 0) 12192f17f76aSHans Petter Selasky goto done; 1220dc7e38acSHans Petter Selasky 1221dc7e38acSHans Petter Selasky /* Create DMA descriptor TAG */ 1222dc7e38acSHans Petter Selasky if ((err = -bus_dma_tag_create( 1223dc7e38acSHans Petter Selasky bus_get_dma_tag(mdev->pdev->dev.bsddev), 1224dc7e38acSHans Petter Selasky 1, /* any alignment */ 1225dc7e38acSHans Petter Selasky 0, /* no boundary */ 1226dc7e38acSHans Petter Selasky BUS_SPACE_MAXADDR, /* lowaddr */ 1227dc7e38acSHans Petter Selasky BUS_SPACE_MAXADDR, /* highaddr */ 1228dc7e38acSHans Petter Selasky NULL, NULL, /* filter, filterarg */ 12292f17f76aSHans Petter Selasky nsegs * MLX5E_MAX_RX_BYTES, /* maxsize */ 12302f17f76aSHans Petter Selasky nsegs, /* nsegments */ 12312f17f76aSHans Petter Selasky nsegs * MLX5E_MAX_RX_BYTES, /* maxsegsize */ 1232dc7e38acSHans Petter Selasky 0, /* flags */ 1233dc7e38acSHans Petter Selasky NULL, NULL, /* lockfunc, lockfuncarg */ 1234dc7e38acSHans Petter Selasky &rq->dma_tag))) 1235dc7e38acSHans Petter Selasky goto done; 1236dc7e38acSHans Petter Selasky 1237dc7e38acSHans Petter Selasky err = mlx5_wq_ll_create(mdev, ¶m->wq, rqc_wq, &rq->wq, 1238dc7e38acSHans Petter Selasky &rq->wq_ctrl); 1239dc7e38acSHans Petter Selasky if (err) 1240dc7e38acSHans Petter Selasky goto err_free_dma_tag; 1241dc7e38acSHans Petter Selasky 1242dc7e38acSHans Petter Selasky rq->wq.db = &rq->wq.db[MLX5_RCV_DBR]; 1243dc7e38acSHans Petter Selasky 12442f17f76aSHans Petter Selasky err = mlx5e_get_wqe_sz(priv, &rq->wqe_sz, &rq->nsegs); 12452f17f76aSHans Petter Selasky if (err != 0) 1246dc7e38acSHans Petter Selasky goto err_rq_wq_destroy; 1247dc7e38acSHans Petter Selasky 1248dc7e38acSHans Petter Selasky wq_sz = mlx5_wq_ll_get_size(&rq->wq); 124957d5dd79SHans Petter Selasky 1250fb3bc596SJohn Baldwin err = -tcp_lro_init_args(&rq->lro, priv->ifp, TCP_LRO_ENTRIES, wq_sz); 125157d5dd79SHans Petter Selasky if (err) 125257d5dd79SHans Petter Selasky goto err_rq_wq_destroy; 125357d5dd79SHans Petter Selasky 12547c3eff94SHans Petter Selasky rq->mbuf = malloc_domainset(wq_sz * sizeof(rq->mbuf[0]), M_MLX5EN, 12557c3eff94SHans Petter Selasky mlx5_dev_domainset(mdev), M_WAITOK | M_ZERO); 1256dc7e38acSHans Petter Selasky for (i = 0; i != wq_sz; i++) { 1257dc7e38acSHans Petter Selasky struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(&rq->wq, i); 12582f17f76aSHans Petter Selasky int j; 1259dc7e38acSHans Petter Selasky 1260dc7e38acSHans Petter Selasky err = -bus_dmamap_create(rq->dma_tag, 0, &rq->mbuf[i].dma_map); 1261dc7e38acSHans Petter Selasky if (err != 0) { 1262dc7e38acSHans Petter Selasky while (i--) 1263dc7e38acSHans Petter Selasky bus_dmamap_destroy(rq->dma_tag, rq->mbuf[i].dma_map); 1264dc7e38acSHans Petter Selasky goto err_rq_mbuf_free; 1265dc7e38acSHans Petter Selasky } 12662f17f76aSHans Petter Selasky 12672f17f76aSHans Petter Selasky /* set value for constant fields */ 12682f17f76aSHans Petter Selasky for (j = 0; j < rq->nsegs; j++) 1269a2d65bfdSHans Petter Selasky wqe->data[j].lkey = cpu_to_be32(priv->mr.key); 1270dc7e38acSHans Petter Selasky } 1271dc7e38acSHans Petter Selasky 1272423530beSHans Petter Selasky INIT_WORK(&rq->dim.work, mlx5e_dim_work); 1273423530beSHans Petter Selasky if (priv->params.rx_cq_moderation_mode < 2) { 1274423530beSHans Petter Selasky rq->dim.mode = NET_DIM_CQ_PERIOD_MODE_DISABLED; 1275423530beSHans Petter Selasky } else { 1276423530beSHans Petter Selasky void *cqc = container_of(param, 1277423530beSHans Petter Selasky struct mlx5e_channel_param, rq)->rx_cq.cqc; 1278423530beSHans Petter Selasky 1279423530beSHans Petter Selasky switch (MLX5_GET(cqc, cqc, cq_period_mode)) { 1280423530beSHans Petter Selasky case MLX5_CQ_PERIOD_MODE_START_FROM_EQE: 1281423530beSHans Petter Selasky rq->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE; 1282423530beSHans Petter Selasky break; 1283423530beSHans Petter Selasky case MLX5_CQ_PERIOD_MODE_START_FROM_CQE: 1284423530beSHans Petter Selasky rq->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE; 1285423530beSHans Petter Selasky break; 1286423530beSHans Petter Selasky default: 1287423530beSHans Petter Selasky rq->dim.mode = NET_DIM_CQ_PERIOD_MODE_DISABLED; 1288423530beSHans Petter Selasky break; 1289423530beSHans Petter Selasky } 1290423530beSHans Petter Selasky } 1291423530beSHans Petter Selasky 1292fb3bc596SJohn Baldwin rq->ifp = priv->ifp; 1293dc7e38acSHans Petter Selasky rq->channel = c; 1294dc7e38acSHans Petter Selasky rq->ix = c->ix; 1295dc7e38acSHans Petter Selasky 1296dc7e38acSHans Petter Selasky snprintf(buffer, sizeof(buffer), "rxstat%d", c->ix); 1297dc7e38acSHans Petter Selasky mlx5e_create_stats(&rq->stats.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 1298dc7e38acSHans Petter Selasky buffer, mlx5e_rq_stats_desc, MLX5E_RQ_STATS_NUM, 1299dc7e38acSHans Petter Selasky rq->stats.arg); 1300dc7e38acSHans Petter Selasky return (0); 1301dc7e38acSHans Petter Selasky 1302dc7e38acSHans Petter Selasky err_rq_mbuf_free: 1303dc7e38acSHans Petter Selasky free(rq->mbuf, M_MLX5EN); 130457d5dd79SHans Petter Selasky tcp_lro_free(&rq->lro); 1305dc7e38acSHans Petter Selasky err_rq_wq_destroy: 1306dc7e38acSHans Petter Selasky mlx5_wq_destroy(&rq->wq_ctrl); 1307dc7e38acSHans Petter Selasky err_free_dma_tag: 1308dc7e38acSHans Petter Selasky bus_dma_tag_destroy(rq->dma_tag); 1309dc7e38acSHans Petter Selasky done: 1310dc7e38acSHans Petter Selasky return (err); 1311dc7e38acSHans Petter Selasky } 1312dc7e38acSHans Petter Selasky 1313dc7e38acSHans Petter Selasky static void 1314dc7e38acSHans Petter Selasky mlx5e_destroy_rq(struct mlx5e_rq *rq) 1315dc7e38acSHans Petter Selasky { 1316dc7e38acSHans Petter Selasky int wq_sz; 1317dc7e38acSHans Petter Selasky int i; 1318dc7e38acSHans Petter Selasky 1319dc7e38acSHans Petter Selasky /* destroy all sysctl nodes */ 1320dc7e38acSHans Petter Selasky sysctl_ctx_free(&rq->stats.ctx); 1321dc7e38acSHans Petter Selasky 1322dc7e38acSHans Petter Selasky /* free leftover LRO packets, if any */ 1323dc7e38acSHans Petter Selasky tcp_lro_free(&rq->lro); 132457d5dd79SHans Petter Selasky 1325dc7e38acSHans Petter Selasky wq_sz = mlx5_wq_ll_get_size(&rq->wq); 1326dc7e38acSHans Petter Selasky for (i = 0; i != wq_sz; i++) { 1327dc7e38acSHans Petter Selasky if (rq->mbuf[i].mbuf != NULL) { 1328d00f3505SKonstantin Belousov if (rq->mbuf[i].ipsec_mtag != NULL) 1329d00f3505SKonstantin Belousov m_tag_free(&rq->mbuf[i].ipsec_mtag->tag); 1330c0cea51bSHans Petter Selasky bus_dmamap_unload(rq->dma_tag, rq->mbuf[i].dma_map); 1331dc7e38acSHans Petter Selasky m_freem(rq->mbuf[i].mbuf); 1332dc7e38acSHans Petter Selasky } 1333dc7e38acSHans Petter Selasky bus_dmamap_destroy(rq->dma_tag, rq->mbuf[i].dma_map); 1334dc7e38acSHans Petter Selasky } 1335dc7e38acSHans Petter Selasky free(rq->mbuf, M_MLX5EN); 1336dc7e38acSHans Petter Selasky mlx5_wq_destroy(&rq->wq_ctrl); 133776a35558SHans Petter Selasky bus_dma_tag_destroy(rq->dma_tag); 1338dc7e38acSHans Petter Selasky } 1339dc7e38acSHans Petter Selasky 1340dc7e38acSHans Petter Selasky static int 1341dc7e38acSHans Petter Selasky mlx5e_enable_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param) 1342dc7e38acSHans Petter Selasky { 1343dc7e38acSHans Petter Selasky struct mlx5e_channel *c = rq->channel; 1344dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = c->priv; 1345dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 1346dc7e38acSHans Petter Selasky void *in; 1347dc7e38acSHans Petter Selasky void *rqc; 1348dc7e38acSHans Petter Selasky void *wq; 1349dc7e38acSHans Petter Selasky int inlen; 1350dc7e38acSHans Petter Selasky int err; 13514fb0a74eSHans Petter Selasky u8 ts_format; 1352dc7e38acSHans Petter Selasky 1353dc7e38acSHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(create_rq_in) + 1354dc7e38acSHans Petter Selasky sizeof(u64) * rq->wq_ctrl.buf.npages; 1355dc7e38acSHans Petter Selasky in = mlx5_vzalloc(inlen); 1356dc7e38acSHans Petter Selasky if (in == NULL) 1357dc7e38acSHans Petter Selasky return (-ENOMEM); 1358dc7e38acSHans Petter Selasky 13594fb0a74eSHans Petter Selasky ts_format = mlx5_get_rq_default_ts(mdev); 1360dc7e38acSHans Petter Selasky rqc = MLX5_ADDR_OF(create_rq_in, in, ctx); 1361dc7e38acSHans Petter Selasky wq = MLX5_ADDR_OF(rqc, rqc, wq); 1362dc7e38acSHans Petter Selasky 1363dc7e38acSHans Petter Selasky memcpy(rqc, param->rqc, sizeof(param->rqc)); 1364dc7e38acSHans Petter Selasky 1365dc7e38acSHans Petter Selasky MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST); 13664fb0a74eSHans Petter Selasky MLX5_SET(rqc, rqc, ts_format, ts_format); 1367dc7e38acSHans Petter Selasky MLX5_SET(rqc, rqc, flush_in_error_en, 1); 1368dc7e38acSHans Petter Selasky if (priv->counter_set_id >= 0) 1369dc7e38acSHans Petter Selasky MLX5_SET(rqc, rqc, counter_set_id, priv->counter_set_id); 1370dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, log_wq_pg_sz, rq->wq_ctrl.buf.page_shift - 1371d735d604SHans Petter Selasky MLX5_ADAPTER_PAGE_SHIFT); 1372dc7e38acSHans Petter Selasky MLX5_SET64(wq, wq, dbr_addr, rq->wq_ctrl.db.dma); 1373dc7e38acSHans Petter Selasky 1374dc7e38acSHans Petter Selasky mlx5_fill_page_array(&rq->wq_ctrl.buf, 1375dc7e38acSHans Petter Selasky (__be64 *) MLX5_ADDR_OF(wq, wq, pas)); 1376dc7e38acSHans Petter Selasky 1377dc7e38acSHans Petter Selasky err = mlx5_core_create_rq(mdev, in, inlen, &rq->rqn); 1378dc7e38acSHans Petter Selasky 1379dc7e38acSHans Petter Selasky kvfree(in); 1380dc7e38acSHans Petter Selasky 1381dc7e38acSHans Petter Selasky return (err); 1382dc7e38acSHans Petter Selasky } 1383dc7e38acSHans Petter Selasky 1384dc7e38acSHans Petter Selasky static int 1385dc7e38acSHans Petter Selasky mlx5e_modify_rq(struct mlx5e_rq *rq, int curr_state, int next_state) 1386dc7e38acSHans Petter Selasky { 1387dc7e38acSHans Petter Selasky struct mlx5e_channel *c = rq->channel; 1388dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = c->priv; 1389dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 1390dc7e38acSHans Petter Selasky 1391dc7e38acSHans Petter Selasky void *in; 1392dc7e38acSHans Petter Selasky void *rqc; 1393dc7e38acSHans Petter Selasky int inlen; 1394dc7e38acSHans Petter Selasky int err; 1395dc7e38acSHans Petter Selasky 1396dc7e38acSHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(modify_rq_in); 1397dc7e38acSHans Petter Selasky in = mlx5_vzalloc(inlen); 1398dc7e38acSHans Petter Selasky if (in == NULL) 1399dc7e38acSHans Petter Selasky return (-ENOMEM); 1400dc7e38acSHans Petter Selasky 1401dc7e38acSHans Petter Selasky rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); 1402dc7e38acSHans Petter Selasky 1403dc7e38acSHans Petter Selasky MLX5_SET(modify_rq_in, in, rqn, rq->rqn); 1404dc7e38acSHans Petter Selasky MLX5_SET(modify_rq_in, in, rq_state, curr_state); 1405dc7e38acSHans Petter Selasky MLX5_SET(rqc, rqc, state, next_state); 1406dc7e38acSHans Petter Selasky 1407dc7e38acSHans Petter Selasky err = mlx5_core_modify_rq(mdev, in, inlen); 1408dc7e38acSHans Petter Selasky 1409dc7e38acSHans Petter Selasky kvfree(in); 1410dc7e38acSHans Petter Selasky 1411dc7e38acSHans Petter Selasky return (err); 1412dc7e38acSHans Petter Selasky } 1413dc7e38acSHans Petter Selasky 1414dc7e38acSHans Petter Selasky static void 1415dc7e38acSHans Petter Selasky mlx5e_disable_rq(struct mlx5e_rq *rq) 1416dc7e38acSHans Petter Selasky { 1417dc7e38acSHans Petter Selasky struct mlx5e_channel *c = rq->channel; 1418dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = c->priv; 1419dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 1420dc7e38acSHans Petter Selasky 1421dc7e38acSHans Petter Selasky mlx5_core_destroy_rq(mdev, rq->rqn); 1422dc7e38acSHans Petter Selasky } 1423dc7e38acSHans Petter Selasky 1424dc7e38acSHans Petter Selasky static int 1425dc7e38acSHans Petter Selasky mlx5e_open_rq(struct mlx5e_channel *c, 1426dc7e38acSHans Petter Selasky struct mlx5e_rq_param *param, 1427dc7e38acSHans Petter Selasky struct mlx5e_rq *rq) 1428dc7e38acSHans Petter Selasky { 1429dc7e38acSHans Petter Selasky int err; 1430dc7e38acSHans Petter Selasky 1431dc7e38acSHans Petter Selasky err = mlx5e_create_rq(c, param, rq); 1432dc7e38acSHans Petter Selasky if (err) 1433dc7e38acSHans Petter Selasky return (err); 1434dc7e38acSHans Petter Selasky 14357800af35SHans Petter Selasky /* set CQN in RQ parameters */ 14367800af35SHans Petter Selasky MLX5_SET(rqc, param->rqc, cqn, c->rq.cq.mcq.cqn); 14377800af35SHans Petter Selasky 1438dc7e38acSHans Petter Selasky err = mlx5e_enable_rq(rq, param); 1439dc7e38acSHans Petter Selasky if (err) 1440dc7e38acSHans Petter Selasky goto err_destroy_rq; 1441dc7e38acSHans Petter Selasky 1442dc7e38acSHans Petter Selasky err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY); 1443dc7e38acSHans Petter Selasky if (err) 1444dc7e38acSHans Petter Selasky goto err_disable_rq; 1445dc7e38acSHans Petter Selasky 1446dc7e38acSHans Petter Selasky c->rq.enabled = 1; 1447dc7e38acSHans Petter Selasky 1448dc7e38acSHans Petter Selasky return (0); 1449dc7e38acSHans Petter Selasky 1450dc7e38acSHans Petter Selasky err_disable_rq: 1451dc7e38acSHans Petter Selasky mlx5e_disable_rq(rq); 1452dc7e38acSHans Petter Selasky err_destroy_rq: 1453dc7e38acSHans Petter Selasky mlx5e_destroy_rq(rq); 1454dc7e38acSHans Petter Selasky 1455dc7e38acSHans Petter Selasky return (err); 1456dc7e38acSHans Petter Selasky } 1457dc7e38acSHans Petter Selasky 1458dc7e38acSHans Petter Selasky static void 1459dc7e38acSHans Petter Selasky mlx5e_close_rq(struct mlx5e_rq *rq) 1460dc7e38acSHans Petter Selasky { 14616f4cab6cSHans Petter Selasky mtx_lock(&rq->mtx); 1462dc7e38acSHans Petter Selasky rq->enabled = 0; 14636f4cab6cSHans Petter Selasky callout_stop(&rq->watchdog); 14646f4cab6cSHans Petter Selasky mtx_unlock(&rq->mtx); 14656f4cab6cSHans Petter Selasky 1466dc7e38acSHans Petter Selasky mlx5e_modify_rq(rq, MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_ERR); 1467dc7e38acSHans Petter Selasky } 1468dc7e38acSHans Petter Selasky 1469dc7e38acSHans Petter Selasky static void 1470dc7e38acSHans Petter Selasky mlx5e_close_rq_wait(struct mlx5e_rq *rq) 1471dc7e38acSHans Petter Selasky { 1472c0cea51bSHans Petter Selasky 1473dc7e38acSHans Petter Selasky mlx5e_disable_rq(rq); 147491f13f83SHans Petter Selasky mlx5e_close_cq(&rq->cq); 147591f13f83SHans Petter Selasky cancel_work_sync(&rq->dim.work); 1476dc7e38acSHans Petter Selasky mlx5e_destroy_rq(rq); 1477dc7e38acSHans Petter Selasky } 1478dc7e38acSHans Petter Selasky 147927b778aeSHans Petter Selasky /* 148027b778aeSHans Petter Selasky * What is a drop RQ and why is it needed? 148127b778aeSHans Petter Selasky * 148227b778aeSHans Petter Selasky * The RSS indirection table, also called the RQT, selects the 148327b778aeSHans Petter Selasky * destination RQ based on the receive queue number, RQN. The RQT is 148427b778aeSHans Petter Selasky * frequently referred to by flow steering rules to distribute traffic 148527b778aeSHans Petter Selasky * among multiple RQs. The problem is that the RQs cannot be destroyed 148627b778aeSHans Petter Selasky * before the RQT referring them is destroyed too. Further, TLS RX 148727b778aeSHans Petter Selasky * rules may still be referring to the RQT even if the link went 148827b778aeSHans Petter Selasky * down. Because there is no magic RQN for dropping packets, we create 148927b778aeSHans Petter Selasky * a dummy RQ, also called drop RQ, which sole purpose is to drop all 149027b778aeSHans Petter Selasky * received packets. When the link goes down this RQN is filled in all 149127b778aeSHans Petter Selasky * RQT entries, of the main RQT, so the real RQs which are about to be 149227b778aeSHans Petter Selasky * destroyed can be released and the TLS RX rules can be sustained. 149327b778aeSHans Petter Selasky */ 149427b778aeSHans Petter Selasky static void 149527b778aeSHans Petter Selasky mlx5e_open_drop_rq_comp(struct mlx5_core_cq *mcq __unused, struct mlx5_eqe *eqe __unused) 149627b778aeSHans Petter Selasky { 149727b778aeSHans Petter Selasky } 149827b778aeSHans Petter Selasky 149927b778aeSHans Petter Selasky static int 150027b778aeSHans Petter Selasky mlx5e_open_drop_rq(struct mlx5e_priv *priv, 150127b778aeSHans Petter Selasky struct mlx5e_rq *drop_rq) 150227b778aeSHans Petter Selasky { 150327b778aeSHans Petter Selasky struct mlx5e_cq_param param_cq = {}; 150427b778aeSHans Petter Selasky struct mlx5e_rq_param param_rq = {}; 150527b778aeSHans Petter Selasky void *rqc_wq = MLX5_ADDR_OF(rqc, param_rq.rqc, wq); 150627b778aeSHans Petter Selasky int err; 150727b778aeSHans Petter Selasky 150803567b0dSHans Petter Selasky /* set channel pointer */ 150903567b0dSHans Petter Selasky drop_rq->channel = priv->channel; 151003567b0dSHans Petter Selasky 151127b778aeSHans Petter Selasky /* set basic CQ parameters needed */ 151227b778aeSHans Petter Selasky MLX5_SET(cqc, param_cq.cqc, log_cq_size, 0); 151327b778aeSHans Petter Selasky MLX5_SET(cqc, param_cq.cqc, uar_page, priv->mdev->priv.uar->index); 151427b778aeSHans Petter Selasky 151527b778aeSHans Petter Selasky /* open receive completion queue */ 151627b778aeSHans Petter Selasky err = mlx5e_open_cq(priv, ¶m_cq, &drop_rq->cq, 151727b778aeSHans Petter Selasky &mlx5e_open_drop_rq_comp, 0); 151827b778aeSHans Petter Selasky if (err) 151927b778aeSHans Petter Selasky goto err_done; 152027b778aeSHans Petter Selasky 152127b778aeSHans Petter Selasky /* set basic WQ parameters needed */ 152227b778aeSHans Petter Selasky MLX5_SET(wq, rqc_wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST); 152327b778aeSHans Petter Selasky MLX5_SET(wq, rqc_wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN); 152427b778aeSHans Petter Selasky MLX5_SET(wq, rqc_wq, log_wq_stride, ilog2(sizeof(struct mlx5e_rx_wqe) + sizeof(struct mlx5_wqe_data_seg))); 152527b778aeSHans Petter Selasky MLX5_SET(wq, rqc_wq, log_wq_sz, 0); 152627b778aeSHans Petter Selasky MLX5_SET(wq, rqc_wq, pd, priv->pdn); 152727b778aeSHans Petter Selasky 152827b778aeSHans Petter Selasky param_rq.wq.linear = 1; 152927b778aeSHans Petter Selasky 153027b778aeSHans Petter Selasky err = mlx5_wq_ll_create(priv->mdev, ¶m_rq.wq, rqc_wq, &drop_rq->wq, 153127b778aeSHans Petter Selasky &drop_rq->wq_ctrl); 153227b778aeSHans Petter Selasky if (err) 153327b778aeSHans Petter Selasky goto err_close_cq; 153427b778aeSHans Petter Selasky 15357800af35SHans Petter Selasky /* set CQN in RQ parameters */ 15367800af35SHans Petter Selasky MLX5_SET(rqc, param_rq.rqc, cqn, drop_rq->cq.mcq.cqn); 15377800af35SHans Petter Selasky 153827b778aeSHans Petter Selasky err = mlx5e_enable_rq(drop_rq, ¶m_rq); 153927b778aeSHans Petter Selasky if (err) 154027b778aeSHans Petter Selasky goto err_wq_destroy; 154127b778aeSHans Petter Selasky 154227b778aeSHans Petter Selasky err = mlx5e_modify_rq(drop_rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY); 154327b778aeSHans Petter Selasky if (err) 154427b778aeSHans Petter Selasky goto err_disable_rq; 154527b778aeSHans Petter Selasky 154627b778aeSHans Petter Selasky return (err); 154727b778aeSHans Petter Selasky 154827b778aeSHans Petter Selasky err_disable_rq: 154927b778aeSHans Petter Selasky mlx5e_disable_rq(drop_rq); 155027b778aeSHans Petter Selasky err_wq_destroy: 155127b778aeSHans Petter Selasky mlx5_wq_destroy(&drop_rq->wq_ctrl); 155227b778aeSHans Petter Selasky err_close_cq: 155327b778aeSHans Petter Selasky mlx5e_close_cq(&drop_rq->cq); 155427b778aeSHans Petter Selasky err_done: 155527b778aeSHans Petter Selasky return (err); 155627b778aeSHans Petter Selasky } 155727b778aeSHans Petter Selasky 155827b778aeSHans Petter Selasky static void 155927b778aeSHans Petter Selasky mlx5e_close_drop_rq(struct mlx5e_rq *drop_rq) 156027b778aeSHans Petter Selasky { 156127b778aeSHans Petter Selasky mlx5e_modify_rq(drop_rq, MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_ERR); 156227b778aeSHans Petter Selasky mlx5e_disable_rq(drop_rq); 156327b778aeSHans Petter Selasky mlx5_wq_destroy(&drop_rq->wq_ctrl); 156427b778aeSHans Petter Selasky mlx5e_close_cq(&drop_rq->cq); 156527b778aeSHans Petter Selasky } 156627b778aeSHans Petter Selasky 15677b4e6e4aSHans Petter Selasky void 1568dc7e38acSHans Petter Selasky mlx5e_free_sq_db(struct mlx5e_sq *sq) 1569dc7e38acSHans Petter Selasky { 1570dc7e38acSHans Petter Selasky int wq_sz = mlx5_wq_cyc_get_size(&sq->wq); 1571dc7e38acSHans Petter Selasky int x; 1572dc7e38acSHans Petter Selasky 15738b1b42c1SHans Petter Selasky for (x = 0; x != wq_sz; x++) { 15748b1b42c1SHans Petter Selasky if (sq->mbuf[x].mbuf != NULL) { 15758b1b42c1SHans Petter Selasky bus_dmamap_unload(sq->dma_tag, sq->mbuf[x].dma_map); 15768b1b42c1SHans Petter Selasky m_freem(sq->mbuf[x].mbuf); 15778b1b42c1SHans Petter Selasky } 1578ebdb7006SHans Petter Selasky if (sq->mbuf[x].mst != NULL) { 1579ebdb7006SHans Petter Selasky m_snd_tag_rele(sq->mbuf[x].mst); 1580ebdb7006SHans Petter Selasky sq->mbuf[x].mst = NULL; 1581ebdb7006SHans Petter Selasky } 1582dc7e38acSHans Petter Selasky bus_dmamap_destroy(sq->dma_tag, sq->mbuf[x].dma_map); 15838b1b42c1SHans Petter Selasky } 1584dc7e38acSHans Petter Selasky free(sq->mbuf, M_MLX5EN); 1585dc7e38acSHans Petter Selasky } 1586dc7e38acSHans Petter Selasky 15877b4e6e4aSHans Petter Selasky int 1588dc7e38acSHans Petter Selasky mlx5e_alloc_sq_db(struct mlx5e_sq *sq) 1589dc7e38acSHans Petter Selasky { 1590dc7e38acSHans Petter Selasky int wq_sz = mlx5_wq_cyc_get_size(&sq->wq); 1591dc7e38acSHans Petter Selasky int err; 1592dc7e38acSHans Petter Selasky int x; 1593dc7e38acSHans Petter Selasky 15947c3eff94SHans Petter Selasky sq->mbuf = malloc_domainset(wq_sz * sizeof(sq->mbuf[0]), M_MLX5EN, 15957c3eff94SHans Petter Selasky mlx5_dev_domainset(sq->priv->mdev), M_WAITOK | M_ZERO); 1596dc7e38acSHans Petter Selasky 1597dc7e38acSHans Petter Selasky /* Create DMA descriptor MAPs */ 1598dc7e38acSHans Petter Selasky for (x = 0; x != wq_sz; x++) { 1599dc7e38acSHans Petter Selasky err = -bus_dmamap_create(sq->dma_tag, 0, &sq->mbuf[x].dma_map); 1600dc7e38acSHans Petter Selasky if (err != 0) { 1601dc7e38acSHans Petter Selasky while (x--) 1602dc7e38acSHans Petter Selasky bus_dmamap_destroy(sq->dma_tag, sq->mbuf[x].dma_map); 1603dc7e38acSHans Petter Selasky free(sq->mbuf, M_MLX5EN); 1604dc7e38acSHans Petter Selasky return (err); 1605dc7e38acSHans Petter Selasky } 1606dc7e38acSHans Petter Selasky } 1607dc7e38acSHans Petter Selasky return (0); 1608dc7e38acSHans Petter Selasky } 1609dc7e38acSHans Petter Selasky 1610dc7e38acSHans Petter Selasky static const char *mlx5e_sq_stats_desc[] = { 1611dc7e38acSHans Petter Selasky MLX5E_SQ_STATS(MLX5E_STATS_DESC) 1612dc7e38acSHans Petter Selasky }; 1613dc7e38acSHans Petter Selasky 16143e581cabSSlava Shwartsman void 16153e581cabSSlava Shwartsman mlx5e_update_sq_inline(struct mlx5e_sq *sq) 16163e581cabSSlava Shwartsman { 16173e581cabSSlava Shwartsman sq->max_inline = sq->priv->params.tx_max_inline; 16183e581cabSSlava Shwartsman sq->min_inline_mode = sq->priv->params.tx_min_inline_mode; 16193e581cabSSlava Shwartsman 16203e581cabSSlava Shwartsman /* 16213e581cabSSlava Shwartsman * Check if trust state is DSCP or if inline mode is NONE which 16223e581cabSSlava Shwartsman * indicates CX-5 or newer hardware. 16233e581cabSSlava Shwartsman */ 16243e581cabSSlava Shwartsman if (sq->priv->params_ethtool.trust_state != MLX5_QPTS_TRUST_PCP || 16253e581cabSSlava Shwartsman sq->min_inline_mode == MLX5_INLINE_MODE_NONE) { 16263e581cabSSlava Shwartsman if (MLX5_CAP_ETH(sq->priv->mdev, wqe_vlan_insert)) 16273e581cabSSlava Shwartsman sq->min_insert_caps = MLX5E_INSERT_VLAN | MLX5E_INSERT_NON_VLAN; 16283e581cabSSlava Shwartsman else 16293e581cabSSlava Shwartsman sq->min_insert_caps = MLX5E_INSERT_NON_VLAN; 16303e581cabSSlava Shwartsman } else { 16313e581cabSSlava Shwartsman sq->min_insert_caps = 0; 16323e581cabSSlava Shwartsman } 16333e581cabSSlava Shwartsman } 16343e581cabSSlava Shwartsman 16353e581cabSSlava Shwartsman static void 16363e581cabSSlava Shwartsman mlx5e_refresh_sq_inline_sub(struct mlx5e_priv *priv, struct mlx5e_channel *c) 16373e581cabSSlava Shwartsman { 16383e581cabSSlava Shwartsman int i; 16393e581cabSSlava Shwartsman 1640eeb1ff98SHans Petter Selasky for (i = 0; i != priv->num_tc; i++) { 16413e581cabSSlava Shwartsman mtx_lock(&c->sq[i].lock); 16423e581cabSSlava Shwartsman mlx5e_update_sq_inline(&c->sq[i]); 16433e581cabSSlava Shwartsman mtx_unlock(&c->sq[i].lock); 16443e581cabSSlava Shwartsman } 16453e581cabSSlava Shwartsman } 16463e581cabSSlava Shwartsman 16473e581cabSSlava Shwartsman void 16483e581cabSSlava Shwartsman mlx5e_refresh_sq_inline(struct mlx5e_priv *priv) 16493e581cabSSlava Shwartsman { 16503e581cabSSlava Shwartsman int i; 16513e581cabSSlava Shwartsman 16523e581cabSSlava Shwartsman /* check if channels are closed */ 16533e581cabSSlava Shwartsman if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0) 16543e581cabSSlava Shwartsman return; 16553e581cabSSlava Shwartsman 16563e581cabSSlava Shwartsman for (i = 0; i < priv->params.num_channels; i++) 16573230c29dSSlava Shwartsman mlx5e_refresh_sq_inline_sub(priv, &priv->channel[i]); 16583e581cabSSlava Shwartsman } 16593e581cabSSlava Shwartsman 1660dc7e38acSHans Petter Selasky static int 1661dc7e38acSHans Petter Selasky mlx5e_create_sq(struct mlx5e_channel *c, 1662dc7e38acSHans Petter Selasky int tc, 1663dc7e38acSHans Petter Selasky struct mlx5e_sq_param *param, 1664dc7e38acSHans Petter Selasky struct mlx5e_sq *sq) 1665dc7e38acSHans Petter Selasky { 1666dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = c->priv; 1667dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 1668dc7e38acSHans Petter Selasky char buffer[16]; 1669dc7e38acSHans Petter Selasky void *sqc = param->sqc; 1670dc7e38acSHans Petter Selasky void *sqc_wq = MLX5_ADDR_OF(sqc, sqc, wq); 1671dc7e38acSHans Petter Selasky int err; 1672dc7e38acSHans Petter Selasky 1673dc7e38acSHans Petter Selasky /* Create DMA descriptor TAG */ 1674dc7e38acSHans Petter Selasky if ((err = -bus_dma_tag_create( 1675dc7e38acSHans Petter Selasky bus_get_dma_tag(mdev->pdev->dev.bsddev), 1676dc7e38acSHans Petter Selasky 1, /* any alignment */ 1677dc7e38acSHans Petter Selasky 0, /* no boundary */ 1678dc7e38acSHans Petter Selasky BUS_SPACE_MAXADDR, /* lowaddr */ 1679dc7e38acSHans Petter Selasky BUS_SPACE_MAXADDR, /* highaddr */ 1680dc7e38acSHans Petter Selasky NULL, NULL, /* filter, filterarg */ 1681dc7e38acSHans Petter Selasky MLX5E_MAX_TX_PAYLOAD_SIZE, /* maxsize */ 1682dc7e38acSHans Petter Selasky MLX5E_MAX_TX_MBUF_FRAGS, /* nsegments */ 1683dc7e38acSHans Petter Selasky MLX5E_MAX_TX_MBUF_SIZE, /* maxsegsize */ 1684dc7e38acSHans Petter Selasky 0, /* flags */ 1685dc7e38acSHans Petter Selasky NULL, NULL, /* lockfunc, lockfuncarg */ 1686dc7e38acSHans Petter Selasky &sq->dma_tag))) 1687dc7e38acSHans Petter Selasky goto done; 1688dc7e38acSHans Petter Selasky 16897c3eff94SHans Petter Selasky sq->mkey_be = cpu_to_be32(priv->mr.key); 16907c3eff94SHans Petter Selasky sq->ifp = priv->ifp; 16917c3eff94SHans Petter Selasky sq->priv = priv; 16927c3eff94SHans Petter Selasky sq->tc = tc; 16937c3eff94SHans Petter Selasky 1694dc7e38acSHans Petter Selasky err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, 1695dc7e38acSHans Petter Selasky &sq->wq_ctrl); 1696dc7e38acSHans Petter Selasky if (err) 1697f8f5b459SHans Petter Selasky goto err_free_dma_tag; 1698dc7e38acSHans Petter Selasky 1699dc7e38acSHans Petter Selasky sq->wq.db = &sq->wq.db[MLX5_SND_DBR]; 1700dc7e38acSHans Petter Selasky 1701dc7e38acSHans Petter Selasky err = mlx5e_alloc_sq_db(sq); 1702dc7e38acSHans Petter Selasky if (err) 1703dc7e38acSHans Petter Selasky goto err_sq_wq_destroy; 1704dc7e38acSHans Petter Selasky 17053e581cabSSlava Shwartsman mlx5e_update_sq_inline(sq); 1706dc7e38acSHans Petter Selasky 1707dc7e38acSHans Petter Selasky snprintf(buffer, sizeof(buffer), "txstat%dtc%d", c->ix, tc); 1708dc7e38acSHans Petter Selasky mlx5e_create_stats(&sq->stats.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 1709dc7e38acSHans Petter Selasky buffer, mlx5e_sq_stats_desc, MLX5E_SQ_STATS_NUM, 1710dc7e38acSHans Petter Selasky sq->stats.arg); 1711dc7e38acSHans Petter Selasky 1712dc7e38acSHans Petter Selasky return (0); 1713dc7e38acSHans Petter Selasky 1714dc7e38acSHans Petter Selasky err_sq_wq_destroy: 1715dc7e38acSHans Petter Selasky mlx5_wq_destroy(&sq->wq_ctrl); 1716dc7e38acSHans Petter Selasky 1717dc7e38acSHans Petter Selasky err_free_dma_tag: 1718dc7e38acSHans Petter Selasky bus_dma_tag_destroy(sq->dma_tag); 1719dc7e38acSHans Petter Selasky done: 1720dc7e38acSHans Petter Selasky return (err); 1721dc7e38acSHans Petter Selasky } 1722dc7e38acSHans Petter Selasky 1723dc7e38acSHans Petter Selasky static void 1724dc7e38acSHans Petter Selasky mlx5e_destroy_sq(struct mlx5e_sq *sq) 1725dc7e38acSHans Petter Selasky { 1726dc7e38acSHans Petter Selasky /* destroy all sysctl nodes */ 1727dc7e38acSHans Petter Selasky sysctl_ctx_free(&sq->stats.ctx); 1728dc7e38acSHans Petter Selasky 1729dc7e38acSHans Petter Selasky mlx5e_free_sq_db(sq); 1730dc7e38acSHans Petter Selasky mlx5_wq_destroy(&sq->wq_ctrl); 173176a35558SHans Petter Selasky bus_dma_tag_destroy(sq->dma_tag); 1732dc7e38acSHans Petter Selasky } 1733dc7e38acSHans Petter Selasky 17347b4e6e4aSHans Petter Selasky int 17357b4e6e4aSHans Petter Selasky mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param, 17369dfa2148SHans Petter Selasky const struct mlx5_sq_bfreg *bfreg, int tis_num) 1737dc7e38acSHans Petter Selasky { 1738dc7e38acSHans Petter Selasky void *in; 1739dc7e38acSHans Petter Selasky void *sqc; 1740dc7e38acSHans Petter Selasky void *wq; 1741dc7e38acSHans Petter Selasky int inlen; 1742dc7e38acSHans Petter Selasky int err; 17434fb0a74eSHans Petter Selasky u8 ts_format; 1744dc7e38acSHans Petter Selasky 1745dc7e38acSHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(create_sq_in) + 1746dc7e38acSHans Petter Selasky sizeof(u64) * sq->wq_ctrl.buf.npages; 1747dc7e38acSHans Petter Selasky in = mlx5_vzalloc(inlen); 1748dc7e38acSHans Petter Selasky if (in == NULL) 1749dc7e38acSHans Petter Selasky return (-ENOMEM); 1750dc7e38acSHans Petter Selasky 17519dfa2148SHans Petter Selasky sq->uar_map = bfreg->map; 17529dfa2148SHans Petter Selasky 17534fb0a74eSHans Petter Selasky ts_format = mlx5_get_sq_default_ts(sq->priv->mdev); 1754dc7e38acSHans Petter Selasky sqc = MLX5_ADDR_OF(create_sq_in, in, ctx); 1755dc7e38acSHans Petter Selasky wq = MLX5_ADDR_OF(sqc, sqc, wq); 1756dc7e38acSHans Petter Selasky 1757dc7e38acSHans Petter Selasky memcpy(sqc, param->sqc, sizeof(param->sqc)); 1758dc7e38acSHans Petter Selasky 17597b4e6e4aSHans Petter Selasky MLX5_SET(sqc, sqc, tis_num_0, tis_num); 176098626886SHans Petter Selasky MLX5_SET(sqc, sqc, cqn, sq->cq.mcq.cqn); 1761dc7e38acSHans Petter Selasky MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST); 17624fb0a74eSHans Petter Selasky MLX5_SET(sqc, sqc, ts_format, ts_format); 1763dc7e38acSHans Petter Selasky MLX5_SET(sqc, sqc, tis_lst_sz, 1); 1764dc7e38acSHans Petter Selasky MLX5_SET(sqc, sqc, flush_in_error_en, 1); 17655e12b3bbSKonstantin Belousov MLX5_SET(sqc, sqc, allow_swp, 1); 1766dc7e38acSHans Petter Selasky 1767dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC); 17689dfa2148SHans Petter Selasky MLX5_SET(wq, wq, uar_page, bfreg->index); 1769dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, log_wq_pg_sz, sq->wq_ctrl.buf.page_shift - 1770d735d604SHans Petter Selasky MLX5_ADAPTER_PAGE_SHIFT); 1771dc7e38acSHans Petter Selasky MLX5_SET64(wq, wq, dbr_addr, sq->wq_ctrl.db.dma); 1772dc7e38acSHans Petter Selasky 1773dc7e38acSHans Petter Selasky mlx5_fill_page_array(&sq->wq_ctrl.buf, 1774dc7e38acSHans Petter Selasky (__be64 *) MLX5_ADDR_OF(wq, wq, pas)); 1775dc7e38acSHans Petter Selasky 177698626886SHans Petter Selasky err = mlx5_core_create_sq(sq->priv->mdev, in, inlen, &sq->sqn); 1777dc7e38acSHans Petter Selasky 1778dc7e38acSHans Petter Selasky kvfree(in); 1779dc7e38acSHans Petter Selasky 1780dc7e38acSHans Petter Selasky return (err); 1781dc7e38acSHans Petter Selasky } 1782dc7e38acSHans Petter Selasky 17837b4e6e4aSHans Petter Selasky int 1784dc7e38acSHans Petter Selasky mlx5e_modify_sq(struct mlx5e_sq *sq, int curr_state, int next_state) 1785dc7e38acSHans Petter Selasky { 1786dc7e38acSHans Petter Selasky void *in; 1787dc7e38acSHans Petter Selasky void *sqc; 1788dc7e38acSHans Petter Selasky int inlen; 1789dc7e38acSHans Petter Selasky int err; 1790dc7e38acSHans Petter Selasky 1791dc7e38acSHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(modify_sq_in); 1792dc7e38acSHans Petter Selasky in = mlx5_vzalloc(inlen); 1793dc7e38acSHans Petter Selasky if (in == NULL) 1794dc7e38acSHans Petter Selasky return (-ENOMEM); 1795dc7e38acSHans Petter Selasky 1796dc7e38acSHans Petter Selasky sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx); 1797dc7e38acSHans Petter Selasky 1798dc7e38acSHans Petter Selasky MLX5_SET(modify_sq_in, in, sqn, sq->sqn); 1799dc7e38acSHans Petter Selasky MLX5_SET(modify_sq_in, in, sq_state, curr_state); 1800dc7e38acSHans Petter Selasky MLX5_SET(sqc, sqc, state, next_state); 1801dc7e38acSHans Petter Selasky 180298626886SHans Petter Selasky err = mlx5_core_modify_sq(sq->priv->mdev, in, inlen); 1803dc7e38acSHans Petter Selasky 1804dc7e38acSHans Petter Selasky kvfree(in); 1805dc7e38acSHans Petter Selasky 1806dc7e38acSHans Petter Selasky return (err); 1807dc7e38acSHans Petter Selasky } 1808dc7e38acSHans Petter Selasky 18097b4e6e4aSHans Petter Selasky void 1810dc7e38acSHans Petter Selasky mlx5e_disable_sq(struct mlx5e_sq *sq) 1811dc7e38acSHans Petter Selasky { 1812dc7e38acSHans Petter Selasky 181398626886SHans Petter Selasky mlx5_core_destroy_sq(sq->priv->mdev, sq->sqn); 1814dc7e38acSHans Petter Selasky } 1815dc7e38acSHans Petter Selasky 1816dc7e38acSHans Petter Selasky static int 1817dc7e38acSHans Petter Selasky mlx5e_open_sq(struct mlx5e_channel *c, 1818dc7e38acSHans Petter Selasky int tc, 1819dc7e38acSHans Petter Selasky struct mlx5e_sq_param *param, 1820dc7e38acSHans Petter Selasky struct mlx5e_sq *sq) 1821dc7e38acSHans Petter Selasky { 1822dc7e38acSHans Petter Selasky int err; 1823dc7e38acSHans Petter Selasky 1824eeb1ff98SHans Petter Selasky sq->cev_factor = c->priv->params_ethtool.tx_completion_fact; 1825eeb1ff98SHans Petter Selasky 1826eeb1ff98SHans Petter Selasky /* ensure the TX completion event factor is not zero */ 1827eeb1ff98SHans Petter Selasky if (sq->cev_factor == 0) 1828eeb1ff98SHans Petter Selasky sq->cev_factor = 1; 1829eeb1ff98SHans Petter Selasky 1830dc7e38acSHans Petter Selasky err = mlx5e_create_sq(c, tc, param, sq); 1831dc7e38acSHans Petter Selasky if (err) 1832dc7e38acSHans Petter Selasky return (err); 1833dc7e38acSHans Petter Selasky 18349dfa2148SHans Petter Selasky err = mlx5e_enable_sq(sq, param, &c->bfreg, c->priv->tisn[tc]); 1835dc7e38acSHans Petter Selasky if (err) 1836dc7e38acSHans Petter Selasky goto err_destroy_sq; 1837dc7e38acSHans Petter Selasky 1838dc7e38acSHans Petter Selasky err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RST, MLX5_SQC_STATE_RDY); 1839dc7e38acSHans Petter Selasky if (err) 1840dc7e38acSHans Petter Selasky goto err_disable_sq; 1841dc7e38acSHans Petter Selasky 18423230c29dSSlava Shwartsman WRITE_ONCE(sq->running, 1); 18433230c29dSSlava Shwartsman 1844dc7e38acSHans Petter Selasky return (0); 1845dc7e38acSHans Petter Selasky 1846dc7e38acSHans Petter Selasky err_disable_sq: 1847dc7e38acSHans Petter Selasky mlx5e_disable_sq(sq); 1848dc7e38acSHans Petter Selasky err_destroy_sq: 1849dc7e38acSHans Petter Selasky mlx5e_destroy_sq(sq); 1850dc7e38acSHans Petter Selasky 1851dc7e38acSHans Petter Selasky return (err); 1852dc7e38acSHans Petter Selasky } 1853dc7e38acSHans Petter Selasky 1854dc7e38acSHans Petter Selasky static void 1855376bcf63SHans Petter Selasky mlx5e_sq_send_nops_locked(struct mlx5e_sq *sq, int can_sleep) 1856dc7e38acSHans Petter Selasky { 1857376bcf63SHans Petter Selasky /* fill up remainder with NOPs */ 1858376bcf63SHans Petter Selasky while (sq->cev_counter != 0) { 1859376bcf63SHans Petter Selasky while (!mlx5e_sq_has_room_for(sq, 1)) { 1860376bcf63SHans Petter Selasky if (can_sleep != 0) { 1861376bcf63SHans Petter Selasky mtx_unlock(&sq->lock); 1862376bcf63SHans Petter Selasky msleep(4); 1863376bcf63SHans Petter Selasky mtx_lock(&sq->lock); 1864376bcf63SHans Petter Selasky } else { 1865376bcf63SHans Petter Selasky goto done; 1866376bcf63SHans Petter Selasky } 1867376bcf63SHans Petter Selasky } 1868af89c4afSHans Petter Selasky /* send a single NOP */ 1869af89c4afSHans Petter Selasky mlx5e_send_nop(sq, 1); 18709cb83c46SHans Petter Selasky atomic_thread_fence_rel(); 1871376bcf63SHans Petter Selasky } 1872376bcf63SHans Petter Selasky done: 18732d5e5a0dSHans Petter Selasky mlx5e_tx_notify_hw(sq, false); 1874376bcf63SHans Petter Selasky } 1875dc7e38acSHans Petter Selasky 1876376bcf63SHans Petter Selasky void 1877376bcf63SHans Petter Selasky mlx5e_sq_cev_timeout(void *arg) 1878376bcf63SHans Petter Selasky { 1879376bcf63SHans Petter Selasky struct mlx5e_sq *sq = arg; 1880376bcf63SHans Petter Selasky 1881376bcf63SHans Petter Selasky mtx_assert(&sq->lock, MA_OWNED); 1882376bcf63SHans Petter Selasky 1883376bcf63SHans Petter Selasky /* check next state */ 1884376bcf63SHans Petter Selasky switch (sq->cev_next_state) { 1885376bcf63SHans Petter Selasky case MLX5E_CEV_STATE_SEND_NOPS: 1886376bcf63SHans Petter Selasky /* fill TX ring with NOPs, if any */ 1887376bcf63SHans Petter Selasky mlx5e_sq_send_nops_locked(sq, 0); 1888376bcf63SHans Petter Selasky 1889376bcf63SHans Petter Selasky /* check if completed */ 1890376bcf63SHans Petter Selasky if (sq->cev_counter == 0) { 1891376bcf63SHans Petter Selasky sq->cev_next_state = MLX5E_CEV_STATE_INITIAL; 1892376bcf63SHans Petter Selasky return; 1893376bcf63SHans Petter Selasky } 1894376bcf63SHans Petter Selasky break; 1895376bcf63SHans Petter Selasky default: 1896376bcf63SHans Petter Selasky /* send NOPs on next timeout */ 1897376bcf63SHans Petter Selasky sq->cev_next_state = MLX5E_CEV_STATE_SEND_NOPS; 1898376bcf63SHans Petter Selasky break; 1899376bcf63SHans Petter Selasky } 1900376bcf63SHans Petter Selasky 1901376bcf63SHans Petter Selasky /* restart timer */ 1902376bcf63SHans Petter Selasky callout_reset_curcpu(&sq->cev_callout, hz, mlx5e_sq_cev_timeout, sq); 1903dc7e38acSHans Petter Selasky } 1904dc7e38acSHans Petter Selasky 19057b4e6e4aSHans Petter Selasky void 19067b4e6e4aSHans Petter Selasky mlx5e_drain_sq(struct mlx5e_sq *sq) 1907dc7e38acSHans Petter Selasky { 19083dfa7645SHans Petter Selasky int error; 1909c0cea51bSHans Petter Selasky struct mlx5_core_dev *mdev= sq->priv->mdev; 19103dfa7645SHans Petter Selasky 19113dfa7645SHans Petter Selasky /* 19123dfa7645SHans Petter Selasky * Check if already stopped. 19133dfa7645SHans Petter Selasky * 19143230c29dSSlava Shwartsman * NOTE: Serialization of this function is managed by the 19153230c29dSSlava Shwartsman * caller ensuring the priv's state lock is locked or in case 19163230c29dSSlava Shwartsman * of rate limit support, a single thread manages drain and 19173230c29dSSlava Shwartsman * resume of SQs. The "running" variable can therefore safely 19183230c29dSSlava Shwartsman * be read without any locks. 19193dfa7645SHans Petter Selasky */ 19203230c29dSSlava Shwartsman if (READ_ONCE(sq->running) == 0) 19213dfa7645SHans Petter Selasky return; 1922376bcf63SHans Petter Selasky 19233dfa7645SHans Petter Selasky /* don't put more packets into the SQ */ 19243230c29dSSlava Shwartsman WRITE_ONCE(sq->running, 0); 19253230c29dSSlava Shwartsman 19263230c29dSSlava Shwartsman /* serialize access to DMA rings */ 19273230c29dSSlava Shwartsman mtx_lock(&sq->lock); 19283dfa7645SHans Petter Selasky 1929376bcf63SHans Petter Selasky /* teardown event factor timer, if any */ 1930376bcf63SHans Petter Selasky sq->cev_next_state = MLX5E_CEV_STATE_HOLD_NOPS; 1931376bcf63SHans Petter Selasky callout_stop(&sq->cev_callout); 1932376bcf63SHans Petter Selasky 1933376bcf63SHans Petter Selasky /* send dummy NOPs in order to flush the transmit ring */ 1934376bcf63SHans Petter Selasky mlx5e_sq_send_nops_locked(sq, 1); 1935376bcf63SHans Petter Selasky mtx_unlock(&sq->lock); 1936376bcf63SHans Petter Selasky 19373dfa7645SHans Petter Selasky /* wait till SQ is empty or link is down */ 19383dfa7645SHans Petter Selasky mtx_lock(&sq->lock); 19393dfa7645SHans Petter Selasky while (sq->cc != sq->pc && 1940c0cea51bSHans Petter Selasky (sq->priv->media_status_last & IFM_ACTIVE) != 0 && 19414692d980SHans Petter Selasky mdev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR && 19424692d980SHans Petter Selasky pci_channel_offline(mdev->pdev) == 0) { 19433dfa7645SHans Petter Selasky mtx_unlock(&sq->lock); 19443dfa7645SHans Petter Selasky msleep(1); 1945f34f0a65SHans Petter Selasky sq->cq.mcq.comp(&sq->cq.mcq, NULL); 19463dfa7645SHans Petter Selasky mtx_lock(&sq->lock); 19473dfa7645SHans Petter Selasky } 19483dfa7645SHans Petter Selasky mtx_unlock(&sq->lock); 19493dfa7645SHans Petter Selasky 1950376bcf63SHans Petter Selasky /* error out remaining requests */ 19513dfa7645SHans Petter Selasky error = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RDY, MLX5_SQC_STATE_ERR); 19523dfa7645SHans Petter Selasky if (error != 0) { 19536b4040d8SHans Petter Selasky mlx5_en_err(sq->ifp, 19543dfa7645SHans Petter Selasky "mlx5e_modify_sq() from RDY to ERR failed: %d\n", error); 19553dfa7645SHans Petter Selasky } 1956376bcf63SHans Petter Selasky 1957dc7e38acSHans Petter Selasky /* wait till SQ is empty */ 1958376bcf63SHans Petter Selasky mtx_lock(&sq->lock); 1959c0cea51bSHans Petter Selasky while (sq->cc != sq->pc && 19604692d980SHans Petter Selasky mdev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR && 19614692d980SHans Petter Selasky pci_channel_offline(mdev->pdev) == 0) { 1962376bcf63SHans Petter Selasky mtx_unlock(&sq->lock); 19633dfa7645SHans Petter Selasky msleep(1); 1964f34f0a65SHans Petter Selasky sq->cq.mcq.comp(&sq->cq.mcq, NULL); 1965376bcf63SHans Petter Selasky mtx_lock(&sq->lock); 1966dc7e38acSHans Petter Selasky } 1967376bcf63SHans Petter Selasky mtx_unlock(&sq->lock); 19687b4e6e4aSHans Petter Selasky } 1969dc7e38acSHans Petter Selasky 19707b4e6e4aSHans Petter Selasky static void 19717b4e6e4aSHans Petter Selasky mlx5e_close_sq_wait(struct mlx5e_sq *sq) 19727b4e6e4aSHans Petter Selasky { 19737b4e6e4aSHans Petter Selasky 19747b4e6e4aSHans Petter Selasky mlx5e_drain_sq(sq); 1975dc7e38acSHans Petter Selasky mlx5e_disable_sq(sq); 1976dc7e38acSHans Petter Selasky mlx5e_destroy_sq(sq); 1977dc7e38acSHans Petter Selasky } 1978dc7e38acSHans Petter Selasky 1979dc7e38acSHans Petter Selasky static int 1980941cd5d1SHans Petter Selasky mlx5e_create_cq(struct mlx5e_priv *priv, 1981dc7e38acSHans Petter Selasky struct mlx5e_cq_param *param, 1982dc7e38acSHans Petter Selasky struct mlx5e_cq *cq, 1983941cd5d1SHans Petter Selasky mlx5e_cq_comp_t *comp, 1984941cd5d1SHans Petter Selasky int eq_ix) 1985dc7e38acSHans Petter Selasky { 1986dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 1987dc7e38acSHans Petter Selasky struct mlx5_core_cq *mcq = &cq->mcq; 1988dc7e38acSHans Petter Selasky int eqn_not_used; 1989dc7e38acSHans Petter Selasky int irqn; 1990dc7e38acSHans Petter Selasky int err; 1991dc7e38acSHans Petter Selasky u32 i; 1992dc7e38acSHans Petter Selasky 199353784e36SHans Petter Selasky err = mlx5_vector2eqn(mdev, eq_ix, &eqn_not_used, &irqn); 199453784e36SHans Petter Selasky if (err) 199553784e36SHans Petter Selasky return (err); 199653784e36SHans Petter Selasky 1997dc7e38acSHans Petter Selasky err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq, 1998dc7e38acSHans Petter Selasky &cq->wq_ctrl); 1999dc7e38acSHans Petter Selasky if (err) 2000dc7e38acSHans Petter Selasky return (err); 2001dc7e38acSHans Petter Selasky 2002dc7e38acSHans Petter Selasky mcq->cqe_sz = 64; 2003dc7e38acSHans Petter Selasky mcq->set_ci_db = cq->wq_ctrl.db.db; 2004dc7e38acSHans Petter Selasky mcq->arm_db = cq->wq_ctrl.db.db + 1; 2005dc7e38acSHans Petter Selasky *mcq->set_ci_db = 0; 2006dc7e38acSHans Petter Selasky *mcq->arm_db = 0; 2007941cd5d1SHans Petter Selasky mcq->vector = eq_ix; 2008dc7e38acSHans Petter Selasky mcq->comp = comp; 2009dc7e38acSHans Petter Selasky mcq->event = mlx5e_cq_error_event; 2010dc7e38acSHans Petter Selasky mcq->irqn = irqn; 2011dc7e38acSHans Petter Selasky 2012dc7e38acSHans Petter Selasky for (i = 0; i < mlx5_cqwq_get_size(&cq->wq); i++) { 2013dc7e38acSHans Petter Selasky struct mlx5_cqe64 *cqe = mlx5_cqwq_get_wqe(&cq->wq, i); 2014dc7e38acSHans Petter Selasky 2015dc7e38acSHans Petter Selasky cqe->op_own = 0xf1; 2016dc7e38acSHans Petter Selasky } 2017dc7e38acSHans Petter Selasky 201898626886SHans Petter Selasky cq->priv = priv; 2019dc7e38acSHans Petter Selasky 2020dc7e38acSHans Petter Selasky return (0); 2021dc7e38acSHans Petter Selasky } 2022dc7e38acSHans Petter Selasky 2023dc7e38acSHans Petter Selasky static void 2024dc7e38acSHans Petter Selasky mlx5e_destroy_cq(struct mlx5e_cq *cq) 2025dc7e38acSHans Petter Selasky { 2026dc7e38acSHans Petter Selasky mlx5_wq_destroy(&cq->wq_ctrl); 2027dc7e38acSHans Petter Selasky } 2028dc7e38acSHans Petter Selasky 2029dc7e38acSHans Petter Selasky static int 2030941cd5d1SHans Petter Selasky mlx5e_enable_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param, int eq_ix) 2031dc7e38acSHans Petter Selasky { 2032dc7e38acSHans Petter Selasky struct mlx5_core_cq *mcq = &cq->mcq; 2033ffdb195fSHans Petter Selasky u32 out[MLX5_ST_SZ_DW(create_cq_out)]; 2034dc7e38acSHans Petter Selasky void *in; 2035dc7e38acSHans Petter Selasky void *cqc; 2036dc7e38acSHans Petter Selasky int inlen; 2037dc7e38acSHans Petter Selasky int irqn_not_used; 2038dc7e38acSHans Petter Selasky int eqn; 2039dc7e38acSHans Petter Selasky int err; 2040dc7e38acSHans Petter Selasky 2041dc7e38acSHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(create_cq_in) + 2042dc7e38acSHans Petter Selasky sizeof(u64) * cq->wq_ctrl.buf.npages; 2043dc7e38acSHans Petter Selasky in = mlx5_vzalloc(inlen); 2044dc7e38acSHans Petter Selasky if (in == NULL) 2045dc7e38acSHans Petter Selasky return (-ENOMEM); 2046dc7e38acSHans Petter Selasky 2047dc7e38acSHans Petter Selasky cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context); 2048dc7e38acSHans Petter Selasky 2049dc7e38acSHans Petter Selasky memcpy(cqc, param->cqc, sizeof(param->cqc)); 2050dc7e38acSHans Petter Selasky 2051dc7e38acSHans Petter Selasky mlx5_fill_page_array(&cq->wq_ctrl.buf, 2052dc7e38acSHans Petter Selasky (__be64 *) MLX5_ADDR_OF(create_cq_in, in, pas)); 2053dc7e38acSHans Petter Selasky 2054941cd5d1SHans Petter Selasky mlx5_vector2eqn(cq->priv->mdev, eq_ix, &eqn, &irqn_not_used); 2055dc7e38acSHans Petter Selasky 2056dc7e38acSHans Petter Selasky MLX5_SET(cqc, cqc, c_eqn, eqn); 2057dc7e38acSHans Petter Selasky MLX5_SET(cqc, cqc, log_page_size, cq->wq_ctrl.buf.page_shift - 2058d735d604SHans Petter Selasky MLX5_ADAPTER_PAGE_SHIFT); 2059dc7e38acSHans Petter Selasky MLX5_SET64(cqc, cqc, dbr_addr, cq->wq_ctrl.db.dma); 2060dc7e38acSHans Petter Selasky 2061ffdb195fSHans Petter Selasky err = mlx5_core_create_cq(cq->priv->mdev, mcq, in, inlen, out, sizeof(out)); 2062dc7e38acSHans Petter Selasky 2063dc7e38acSHans Petter Selasky kvfree(in); 2064dc7e38acSHans Petter Selasky 2065dc7e38acSHans Petter Selasky if (err) 2066dc7e38acSHans Petter Selasky return (err); 2067dc7e38acSHans Petter Selasky 2068e5d6b589SHans Petter Selasky mlx5e_cq_arm(cq, MLX5_GET_DOORBELL_LOCK(&cq->priv->doorbell_lock)); 2069dc7e38acSHans Petter Selasky 2070dc7e38acSHans Petter Selasky return (0); 2071dc7e38acSHans Petter Selasky } 2072dc7e38acSHans Petter Selasky 2073dc7e38acSHans Petter Selasky static void 2074dc7e38acSHans Petter Selasky mlx5e_disable_cq(struct mlx5e_cq *cq) 2075dc7e38acSHans Petter Selasky { 2076dc7e38acSHans Petter Selasky 207798626886SHans Petter Selasky mlx5_core_destroy_cq(cq->priv->mdev, &cq->mcq); 2078dc7e38acSHans Petter Selasky } 2079dc7e38acSHans Petter Selasky 208028f22cceSHans Petter Selasky int 2081941cd5d1SHans Petter Selasky mlx5e_open_cq(struct mlx5e_priv *priv, 2082dc7e38acSHans Petter Selasky struct mlx5e_cq_param *param, 2083dc7e38acSHans Petter Selasky struct mlx5e_cq *cq, 2084dc7e38acSHans Petter Selasky mlx5e_cq_comp_t *comp, 2085941cd5d1SHans Petter Selasky int eq_ix) 2086dc7e38acSHans Petter Selasky { 2087dc7e38acSHans Petter Selasky int err; 2088dc7e38acSHans Petter Selasky 2089941cd5d1SHans Petter Selasky err = mlx5e_create_cq(priv, param, cq, comp, eq_ix); 2090dc7e38acSHans Petter Selasky if (err) 2091dc7e38acSHans Petter Selasky return (err); 2092dc7e38acSHans Petter Selasky 2093941cd5d1SHans Petter Selasky err = mlx5e_enable_cq(cq, param, eq_ix); 2094dc7e38acSHans Petter Selasky if (err) 2095dc7e38acSHans Petter Selasky goto err_destroy_cq; 2096dc7e38acSHans Petter Selasky 2097dc7e38acSHans Petter Selasky return (0); 2098dc7e38acSHans Petter Selasky 2099dc7e38acSHans Petter Selasky err_destroy_cq: 2100dc7e38acSHans Petter Selasky mlx5e_destroy_cq(cq); 2101dc7e38acSHans Petter Selasky 2102dc7e38acSHans Petter Selasky return (err); 2103dc7e38acSHans Petter Selasky } 2104dc7e38acSHans Petter Selasky 210528f22cceSHans Petter Selasky void 2106dc7e38acSHans Petter Selasky mlx5e_close_cq(struct mlx5e_cq *cq) 2107dc7e38acSHans Petter Selasky { 2108dc7e38acSHans Petter Selasky mlx5e_disable_cq(cq); 2109dc7e38acSHans Petter Selasky mlx5e_destroy_cq(cq); 2110dc7e38acSHans Petter Selasky } 2111dc7e38acSHans Petter Selasky 2112dc7e38acSHans Petter Selasky static int 2113dc7e38acSHans Petter Selasky mlx5e_open_tx_cqs(struct mlx5e_channel *c, 2114dc7e38acSHans Petter Selasky struct mlx5e_channel_param *cparam) 2115dc7e38acSHans Petter Selasky { 2116dc7e38acSHans Petter Selasky int err; 2117dc7e38acSHans Petter Selasky int tc; 2118dc7e38acSHans Petter Selasky 2119eeb1ff98SHans Petter Selasky for (tc = 0; tc < c->priv->num_tc; tc++) { 2120dc7e38acSHans Petter Selasky /* open completion queue */ 2121941cd5d1SHans Petter Selasky err = mlx5e_open_cq(c->priv, &cparam->tx_cq, &c->sq[tc].cq, 2122941cd5d1SHans Petter Selasky &mlx5e_tx_cq_comp, c->ix); 2123dc7e38acSHans Petter Selasky if (err) 2124dc7e38acSHans Petter Selasky goto err_close_tx_cqs; 2125dc7e38acSHans Petter Selasky } 2126dc7e38acSHans Petter Selasky return (0); 2127dc7e38acSHans Petter Selasky 2128dc7e38acSHans Petter Selasky err_close_tx_cqs: 2129dc7e38acSHans Petter Selasky for (tc--; tc >= 0; tc--) 2130dc7e38acSHans Petter Selasky mlx5e_close_cq(&c->sq[tc].cq); 2131dc7e38acSHans Petter Selasky 2132dc7e38acSHans Petter Selasky return (err); 2133dc7e38acSHans Petter Selasky } 2134dc7e38acSHans Petter Selasky 2135dc7e38acSHans Petter Selasky static void 2136dc7e38acSHans Petter Selasky mlx5e_close_tx_cqs(struct mlx5e_channel *c) 2137dc7e38acSHans Petter Selasky { 2138dc7e38acSHans Petter Selasky int tc; 2139dc7e38acSHans Petter Selasky 2140eeb1ff98SHans Petter Selasky for (tc = 0; tc < c->priv->num_tc; tc++) 2141dc7e38acSHans Petter Selasky mlx5e_close_cq(&c->sq[tc].cq); 2142dc7e38acSHans Petter Selasky } 2143dc7e38acSHans Petter Selasky 2144dc7e38acSHans Petter Selasky static int 2145dc7e38acSHans Petter Selasky mlx5e_open_sqs(struct mlx5e_channel *c, 2146dc7e38acSHans Petter Selasky struct mlx5e_channel_param *cparam) 2147dc7e38acSHans Petter Selasky { 2148dc7e38acSHans Petter Selasky int err; 2149dc7e38acSHans Petter Selasky int tc; 2150dc7e38acSHans Petter Selasky 2151eeb1ff98SHans Petter Selasky for (tc = 0; tc < c->priv->num_tc; tc++) { 2152dc7e38acSHans Petter Selasky err = mlx5e_open_sq(c, tc, &cparam->sq, &c->sq[tc]); 2153dc7e38acSHans Petter Selasky if (err) 2154dc7e38acSHans Petter Selasky goto err_close_sqs; 2155dc7e38acSHans Petter Selasky } 2156dc7e38acSHans Petter Selasky 2157dc7e38acSHans Petter Selasky return (0); 2158dc7e38acSHans Petter Selasky 2159dc7e38acSHans Petter Selasky err_close_sqs: 2160376bcf63SHans Petter Selasky for (tc--; tc >= 0; tc--) 2161dc7e38acSHans Petter Selasky mlx5e_close_sq_wait(&c->sq[tc]); 2162dc7e38acSHans Petter Selasky 2163dc7e38acSHans Petter Selasky return (err); 2164dc7e38acSHans Petter Selasky } 2165dc7e38acSHans Petter Selasky 2166dc7e38acSHans Petter Selasky static void 2167dc7e38acSHans Petter Selasky mlx5e_close_sqs_wait(struct mlx5e_channel *c) 2168dc7e38acSHans Petter Selasky { 2169dc7e38acSHans Petter Selasky int tc; 2170dc7e38acSHans Petter Selasky 2171eeb1ff98SHans Petter Selasky for (tc = 0; tc < c->priv->num_tc; tc++) 2172dc7e38acSHans Petter Selasky mlx5e_close_sq_wait(&c->sq[tc]); 2173dc7e38acSHans Petter Selasky } 2174dc7e38acSHans Petter Selasky 2175dc7e38acSHans Petter Selasky static void 2176eeb1ff98SHans Petter Selasky mlx5e_chan_static_init(struct mlx5e_priv *priv, struct mlx5e_channel *c, int ix) 2177dc7e38acSHans Petter Selasky { 2178dc7e38acSHans Petter Selasky int tc; 2179dc7e38acSHans Petter Selasky 2180eeb1ff98SHans Petter Selasky /* setup priv and channel number */ 2181eeb1ff98SHans Petter Selasky c->priv = priv; 2182eeb1ff98SHans Petter Selasky c->ix = ix; 2183eeb1ff98SHans Petter Selasky 2184eeb1ff98SHans Petter Selasky /* setup send tag */ 2185c782ea8bSJohn Baldwin m_snd_tag_init(&c->tag, c->priv->ifp, &mlx5e_ul_snd_tag_sw); 2186eeb1ff98SHans Petter Selasky 2187c84e0068SHans Petter Selasky init_completion(&c->completion); 2188c84e0068SHans Petter Selasky 2189dc7e38acSHans Petter Selasky mtx_init(&c->rq.mtx, "mlx5rx", MTX_NETWORK_LOCK, MTX_DEF); 2190dc7e38acSHans Petter Selasky 21916f4cab6cSHans Petter Selasky callout_init_mtx(&c->rq.watchdog, &c->rq.mtx, 0); 21926f4cab6cSHans Petter Selasky 2193eeb1ff98SHans Petter Selasky for (tc = 0; tc != MLX5E_MAX_TX_NUM_TC; tc++) { 2194376bcf63SHans Petter Selasky struct mlx5e_sq *sq = c->sq + tc; 2195376bcf63SHans Petter Selasky 2196b98ba640SHans Petter Selasky mtx_init(&sq->lock, "mlx5tx", 2197b98ba640SHans Petter Selasky MTX_NETWORK_LOCK " TX", MTX_DEF); 2198b98ba640SHans Petter Selasky mtx_init(&sq->comp_lock, "mlx5comp", 2199b98ba640SHans Petter Selasky MTX_NETWORK_LOCK " TX", MTX_DEF); 2200376bcf63SHans Petter Selasky 2201376bcf63SHans Petter Selasky callout_init_mtx(&sq->cev_callout, &sq->lock, 0); 2202dc7e38acSHans Petter Selasky } 220369426357SHans Petter Selasky 220469426357SHans Petter Selasky mlx5e_iq_static_init(&c->iq); 2205dc7e38acSHans Petter Selasky } 2206dc7e38acSHans Petter Selasky 2207dc7e38acSHans Petter Selasky static void 2208c84e0068SHans Petter Selasky mlx5e_chan_wait_for_completion(struct mlx5e_channel *c) 2209c84e0068SHans Petter Selasky { 2210c84e0068SHans Petter Selasky 221156fb710fSJohn Baldwin m_snd_tag_rele(&c->tag); 2212c84e0068SHans Petter Selasky wait_for_completion(&c->completion); 2213c84e0068SHans Petter Selasky } 2214c84e0068SHans Petter Selasky 2215c84e0068SHans Petter Selasky static void 2216c84e0068SHans Petter Selasky mlx5e_priv_wait_for_completion(struct mlx5e_priv *priv, const uint32_t channels) 2217c84e0068SHans Petter Selasky { 2218c84e0068SHans Petter Selasky uint32_t x; 2219c84e0068SHans Petter Selasky 2220c84e0068SHans Petter Selasky for (x = 0; x != channels; x++) 2221c84e0068SHans Petter Selasky mlx5e_chan_wait_for_completion(&priv->channel[x]); 2222c84e0068SHans Petter Selasky } 2223c84e0068SHans Petter Selasky 2224c84e0068SHans Petter Selasky static void 2225eeb1ff98SHans Petter Selasky mlx5e_chan_static_destroy(struct mlx5e_channel *c) 2226dc7e38acSHans Petter Selasky { 2227dc7e38acSHans Petter Selasky int tc; 2228dc7e38acSHans Petter Selasky 2229eeb1ff98SHans Petter Selasky callout_drain(&c->rq.watchdog); 2230eeb1ff98SHans Petter Selasky 2231dc7e38acSHans Petter Selasky mtx_destroy(&c->rq.mtx); 2232dc7e38acSHans Petter Selasky 2233eeb1ff98SHans Petter Selasky for (tc = 0; tc != MLX5E_MAX_TX_NUM_TC; tc++) { 2234eeb1ff98SHans Petter Selasky callout_drain(&c->sq[tc].cev_callout); 2235dc7e38acSHans Petter Selasky mtx_destroy(&c->sq[tc].lock); 2236dc7e38acSHans Petter Selasky mtx_destroy(&c->sq[tc].comp_lock); 2237dc7e38acSHans Petter Selasky } 223869426357SHans Petter Selasky 223969426357SHans Petter Selasky mlx5e_iq_static_destroy(&c->iq); 2240dc7e38acSHans Petter Selasky } 2241dc7e38acSHans Petter Selasky 2242dc7e38acSHans Petter Selasky static int 2243eeb1ff98SHans Petter Selasky mlx5e_open_channel(struct mlx5e_priv *priv, 2244dc7e38acSHans Petter Selasky struct mlx5e_channel_param *cparam, 22453230c29dSSlava Shwartsman struct mlx5e_channel *c) 2246dc7e38acSHans Petter Selasky { 2247e4881300SHans Petter Selasky struct epoch_tracker et; 2248eeb1ff98SHans Petter Selasky int i, err; 2249dc7e38acSHans Petter Selasky 22504a87beecSGordon Bergling /* zero non-persistent data */ 2251eeb1ff98SHans Petter Selasky MLX5E_ZERO(&c->rq, mlx5e_rq_zero_start); 2252eeb1ff98SHans Petter Selasky for (i = 0; i != priv->num_tc; i++) 2253eeb1ff98SHans Petter Selasky MLX5E_ZERO(&c->sq[i], mlx5e_sq_zero_start); 225469426357SHans Petter Selasky MLX5E_ZERO(&c->iq, mlx5e_iq_zero_start); 2255dc7e38acSHans Petter Selasky 2256dc7e38acSHans Petter Selasky /* open transmit completion queue */ 2257dc7e38acSHans Petter Selasky err = mlx5e_open_tx_cqs(c, cparam); 2258dc7e38acSHans Petter Selasky if (err) 2259dc7e38acSHans Petter Selasky goto err_free; 2260dc7e38acSHans Petter Selasky 2261dc7e38acSHans Petter Selasky /* open receive completion queue */ 2262941cd5d1SHans Petter Selasky err = mlx5e_open_cq(c->priv, &cparam->rx_cq, &c->rq.cq, 2263941cd5d1SHans Petter Selasky &mlx5e_rx_cq_comp, c->ix); 2264dc7e38acSHans Petter Selasky if (err) 2265dc7e38acSHans Petter Selasky goto err_close_tx_cqs; 2266dc7e38acSHans Petter Selasky 2267dc7e38acSHans Petter Selasky err = mlx5e_open_sqs(c, cparam); 2268dc7e38acSHans Petter Selasky if (err) 2269dc7e38acSHans Petter Selasky goto err_close_rx_cq; 2270dc7e38acSHans Petter Selasky 227169426357SHans Petter Selasky err = mlx5e_iq_open(c, &cparam->sq, &cparam->tx_cq, &c->iq); 2272dc7e38acSHans Petter Selasky if (err) 2273dc7e38acSHans Petter Selasky goto err_close_sqs; 2274dc7e38acSHans Petter Selasky 227569426357SHans Petter Selasky err = mlx5e_open_rq(c, &cparam->rq, &c->rq); 227669426357SHans Petter Selasky if (err) 227769426357SHans Petter Selasky goto err_close_iq; 227869426357SHans Petter Selasky 2279dc7e38acSHans Petter Selasky /* poll receive queue initially */ 2280e4881300SHans Petter Selasky NET_EPOCH_ENTER(et); 2281f34f0a65SHans Petter Selasky c->rq.cq.mcq.comp(&c->rq.cq.mcq, NULL); 2282e4881300SHans Petter Selasky NET_EPOCH_EXIT(et); 2283dc7e38acSHans Petter Selasky 2284dc7e38acSHans Petter Selasky return (0); 2285dc7e38acSHans Petter Selasky 228669426357SHans Petter Selasky err_close_iq: 228769426357SHans Petter Selasky mlx5e_iq_close(&c->iq); 228869426357SHans Petter Selasky 2289dc7e38acSHans Petter Selasky err_close_sqs: 2290dc7e38acSHans Petter Selasky mlx5e_close_sqs_wait(c); 2291dc7e38acSHans Petter Selasky 2292dc7e38acSHans Petter Selasky err_close_rx_cq: 2293dc7e38acSHans Petter Selasky mlx5e_close_cq(&c->rq.cq); 2294dc7e38acSHans Petter Selasky 2295dc7e38acSHans Petter Selasky err_close_tx_cqs: 2296dc7e38acSHans Petter Selasky mlx5e_close_tx_cqs(c); 2297dc7e38acSHans Petter Selasky 2298dc7e38acSHans Petter Selasky err_free: 2299dc7e38acSHans Petter Selasky return (err); 2300dc7e38acSHans Petter Selasky } 2301dc7e38acSHans Petter Selasky 2302dc7e38acSHans Petter Selasky static void 23033230c29dSSlava Shwartsman mlx5e_close_channel(struct mlx5e_channel *c) 2304dc7e38acSHans Petter Selasky { 2305dc7e38acSHans Petter Selasky mlx5e_close_rq(&c->rq); 2306dc7e38acSHans Petter Selasky } 2307dc7e38acSHans Petter Selasky 2308dc7e38acSHans Petter Selasky static void 23093230c29dSSlava Shwartsman mlx5e_close_channel_wait(struct mlx5e_channel *c) 2310dc7e38acSHans Petter Selasky { 2311dc7e38acSHans Petter Selasky mlx5e_close_rq_wait(&c->rq); 231269426357SHans Petter Selasky mlx5e_iq_close(&c->iq); 2313dc7e38acSHans Petter Selasky mlx5e_close_sqs_wait(c); 2314dc7e38acSHans Petter Selasky mlx5e_close_tx_cqs(c); 2315dc7e38acSHans Petter Selasky } 2316dc7e38acSHans Petter Selasky 23172f17f76aSHans Petter Selasky static int 23182f17f76aSHans Petter Selasky mlx5e_get_wqe_sz(struct mlx5e_priv *priv, u32 *wqe_sz, u32 *nsegs) 23192f17f76aSHans Petter Selasky { 23202f17f76aSHans Petter Selasky u32 r, n; 23212f17f76aSHans Petter Selasky 23222f17f76aSHans Petter Selasky r = priv->params.hw_lro_en ? priv->params.lro_wqe_sz : 23235dc00f00SJustin Hibbits MLX5E_SW2MB_MTU(if_getmtu(priv->ifp)); 23242f17f76aSHans Petter Selasky if (r > MJUM16BYTES) 23252f17f76aSHans Petter Selasky return (-ENOMEM); 23262f17f76aSHans Petter Selasky 23272f17f76aSHans Petter Selasky if (r > MJUM9BYTES) 23282f17f76aSHans Petter Selasky r = MJUM16BYTES; 23292f17f76aSHans Petter Selasky else if (r > MJUMPAGESIZE) 23302f17f76aSHans Petter Selasky r = MJUM9BYTES; 23312f17f76aSHans Petter Selasky else if (r > MCLBYTES) 23322f17f76aSHans Petter Selasky r = MJUMPAGESIZE; 23332f17f76aSHans Petter Selasky else 23342f17f76aSHans Petter Selasky r = MCLBYTES; 23352f17f76aSHans Petter Selasky 23362f17f76aSHans Petter Selasky /* 23372f17f76aSHans Petter Selasky * n + 1 must be a power of two, because stride size must be. 23382f17f76aSHans Petter Selasky * Stride size is 16 * (n + 1), as the first segment is 23392f17f76aSHans Petter Selasky * control. 23402f17f76aSHans Petter Selasky */ 2341dc048255SDoug Moore n = roundup_pow_of_two(1 + howmany(r, MLX5E_MAX_RX_BYTES)) - 1; 23428b825a18SHans Petter Selasky if (n > MLX5E_MAX_BUSDMA_RX_SEGS) 23438b825a18SHans Petter Selasky return (-ENOMEM); 23448b825a18SHans Petter Selasky 23452f17f76aSHans Petter Selasky *wqe_sz = r; 23462f17f76aSHans Petter Selasky *nsegs = n; 23472f17f76aSHans Petter Selasky return (0); 23482f17f76aSHans Petter Selasky } 23492f17f76aSHans Petter Selasky 2350dc7e38acSHans Petter Selasky static void 2351dc7e38acSHans Petter Selasky mlx5e_build_rq_param(struct mlx5e_priv *priv, 2352dc7e38acSHans Petter Selasky struct mlx5e_rq_param *param) 2353dc7e38acSHans Petter Selasky { 2354dc7e38acSHans Petter Selasky void *rqc = param->rqc; 2355dc7e38acSHans Petter Selasky void *wq = MLX5_ADDR_OF(rqc, rqc, wq); 23562f17f76aSHans Petter Selasky u32 wqe_sz, nsegs; 2357dc7e38acSHans Petter Selasky 23582f17f76aSHans Petter Selasky mlx5e_get_wqe_sz(priv, &wqe_sz, &nsegs); 2359dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST); 2360dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN); 23612f17f76aSHans Petter Selasky MLX5_SET(wq, wq, log_wq_stride, ilog2(sizeof(struct mlx5e_rx_wqe) + 23622f17f76aSHans Petter Selasky nsegs * sizeof(struct mlx5_wqe_data_seg))); 2363dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, log_wq_sz, priv->params.log_rq_size); 2364dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, pd, priv->pdn); 2365dc7e38acSHans Petter Selasky 2366dc7e38acSHans Petter Selasky param->wq.linear = 1; 2367dc7e38acSHans Petter Selasky } 2368dc7e38acSHans Petter Selasky 2369dc7e38acSHans Petter Selasky static void 2370dc7e38acSHans Petter Selasky mlx5e_build_sq_param(struct mlx5e_priv *priv, 2371dc7e38acSHans Petter Selasky struct mlx5e_sq_param *param) 2372dc7e38acSHans Petter Selasky { 2373dc7e38acSHans Petter Selasky void *sqc = param->sqc; 2374dc7e38acSHans Petter Selasky void *wq = MLX5_ADDR_OF(sqc, sqc, wq); 2375dc7e38acSHans Petter Selasky 2376dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, log_wq_sz, priv->params.log_sq_size); 2377dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, log_wq_stride, ilog2(MLX5_SEND_WQE_BB)); 2378dc7e38acSHans Petter Selasky MLX5_SET(wq, wq, pd, priv->pdn); 2379dc7e38acSHans Petter Selasky 2380dc7e38acSHans Petter Selasky param->wq.linear = 1; 2381dc7e38acSHans Petter Selasky } 2382dc7e38acSHans Petter Selasky 2383dc7e38acSHans Petter Selasky static void 2384dc7e38acSHans Petter Selasky mlx5e_build_common_cq_param(struct mlx5e_priv *priv, 2385dc7e38acSHans Petter Selasky struct mlx5e_cq_param *param) 2386dc7e38acSHans Petter Selasky { 2387dc7e38acSHans Petter Selasky void *cqc = param->cqc; 2388dc7e38acSHans Petter Selasky 2389f8f5b459SHans Petter Selasky MLX5_SET(cqc, cqc, uar_page, priv->mdev->priv.uar->index); 2390dc7e38acSHans Petter Selasky } 2391dc7e38acSHans Petter Selasky 2392dc7e38acSHans Petter Selasky static void 2393423530beSHans Petter Selasky mlx5e_get_default_profile(struct mlx5e_priv *priv, int mode, struct net_dim_cq_moder *ptr) 2394423530beSHans Petter Selasky { 2395423530beSHans Petter Selasky 2396423530beSHans Petter Selasky *ptr = net_dim_get_profile(mode, MLX5E_DIM_DEFAULT_PROFILE); 2397423530beSHans Petter Selasky 2398423530beSHans Petter Selasky /* apply LRO restrictions */ 2399423530beSHans Petter Selasky if (priv->params.hw_lro_en && 2400423530beSHans Petter Selasky ptr->pkts > MLX5E_DIM_MAX_RX_CQ_MODERATION_PKTS_WITH_LRO) { 2401423530beSHans Petter Selasky ptr->pkts = MLX5E_DIM_MAX_RX_CQ_MODERATION_PKTS_WITH_LRO; 2402423530beSHans Petter Selasky } 2403423530beSHans Petter Selasky } 2404423530beSHans Petter Selasky 2405423530beSHans Petter Selasky static void 2406dc7e38acSHans Petter Selasky mlx5e_build_rx_cq_param(struct mlx5e_priv *priv, 2407dc7e38acSHans Petter Selasky struct mlx5e_cq_param *param) 2408dc7e38acSHans Petter Selasky { 2409423530beSHans Petter Selasky struct net_dim_cq_moder curr; 2410dc7e38acSHans Petter Selasky void *cqc = param->cqc; 2411dc7e38acSHans Petter Selasky 241290cc1c77SHans Petter Selasky /* 2413a005c157SHans Petter Selasky * We use MLX5_CQE_FORMAT_HASH because the RX hash mini CQE 2414a005c157SHans Petter Selasky * format is more beneficial for FreeBSD use case. 2415a005c157SHans Petter Selasky * 2416a005c157SHans Petter Selasky * Adding support for MLX5_CQE_FORMAT_CSUM will require changes 2417a005c157SHans Petter Selasky * in mlx5e_decompress_cqe. 241890cc1c77SHans Petter Selasky */ 241990cc1c77SHans Petter Selasky if (priv->params.cqe_zipping_en) { 2420a005c157SHans Petter Selasky MLX5_SET(cqc, cqc, mini_cqe_res_format, MLX5_CQE_FORMAT_HASH); 242190cc1c77SHans Petter Selasky MLX5_SET(cqc, cqc, cqe_compression_en, 1); 242290cc1c77SHans Petter Selasky } 242390cc1c77SHans Petter Selasky 2424dc7e38acSHans Petter Selasky MLX5_SET(cqc, cqc, log_cq_size, priv->params.log_rq_size); 2425dc7e38acSHans Petter Selasky 2426941cd5d1SHans Petter Selasky switch (priv->params.rx_cq_moderation_mode) { 2427941cd5d1SHans Petter Selasky case 0: 2428423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_period, priv->params.rx_cq_moderation_usec); 2429423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_max_count, priv->params.rx_cq_moderation_pkts); 2430941cd5d1SHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE); 2431941cd5d1SHans Petter Selasky break; 2432423530beSHans Petter Selasky case 1: 2433423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_period, priv->params.rx_cq_moderation_usec); 2434423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_max_count, priv->params.rx_cq_moderation_pkts); 2435941cd5d1SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe)) 2436941cd5d1SHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_CQE); 2437941cd5d1SHans Petter Selasky else 2438941cd5d1SHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE); 2439941cd5d1SHans Petter Selasky break; 2440423530beSHans Petter Selasky case 2: 2441423530beSHans Petter Selasky mlx5e_get_default_profile(priv, NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE, &curr); 2442423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_period, curr.usec); 2443423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_max_count, curr.pkts); 2444423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE); 2445423530beSHans Petter Selasky break; 2446423530beSHans Petter Selasky case 3: 2447423530beSHans Petter Selasky mlx5e_get_default_profile(priv, NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE, &curr); 2448423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_period, curr.usec); 2449423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_max_count, curr.pkts); 2450423530beSHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe)) 2451423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_CQE); 2452423530beSHans Petter Selasky else 2453423530beSHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE); 2454423530beSHans Petter Selasky break; 2455423530beSHans Petter Selasky default: 2456423530beSHans Petter Selasky break; 2457941cd5d1SHans Petter Selasky } 2458941cd5d1SHans Petter Selasky 2459423530beSHans Petter Selasky mlx5e_dim_build_cq_param(priv, param); 2460423530beSHans Petter Selasky 2461dc7e38acSHans Petter Selasky mlx5e_build_common_cq_param(priv, param); 2462dc7e38acSHans Petter Selasky } 2463dc7e38acSHans Petter Selasky 2464dc7e38acSHans Petter Selasky static void 2465dc7e38acSHans Petter Selasky mlx5e_build_tx_cq_param(struct mlx5e_priv *priv, 2466dc7e38acSHans Petter Selasky struct mlx5e_cq_param *param) 2467dc7e38acSHans Petter Selasky { 2468dc7e38acSHans Petter Selasky void *cqc = param->cqc; 2469dc7e38acSHans Petter Selasky 2470dc7e38acSHans Petter Selasky MLX5_SET(cqc, cqc, log_cq_size, priv->params.log_sq_size); 2471dc7e38acSHans Petter Selasky MLX5_SET(cqc, cqc, cq_period, priv->params.tx_cq_moderation_usec); 2472dc7e38acSHans Petter Selasky MLX5_SET(cqc, cqc, cq_max_count, priv->params.tx_cq_moderation_pkts); 2473dc7e38acSHans Petter Selasky 2474941cd5d1SHans Petter Selasky switch (priv->params.tx_cq_moderation_mode) { 2475941cd5d1SHans Petter Selasky case 0: 2476941cd5d1SHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE); 2477941cd5d1SHans Petter Selasky break; 2478941cd5d1SHans Petter Selasky default: 2479941cd5d1SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe)) 2480941cd5d1SHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_CQE); 2481941cd5d1SHans Petter Selasky else 2482941cd5d1SHans Petter Selasky MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE); 2483941cd5d1SHans Petter Selasky break; 2484941cd5d1SHans Petter Selasky } 2485941cd5d1SHans Petter Selasky 2486dc7e38acSHans Petter Selasky mlx5e_build_common_cq_param(priv, param); 2487dc7e38acSHans Petter Selasky } 2488dc7e38acSHans Petter Selasky 2489dc7e38acSHans Petter Selasky static void 2490dc7e38acSHans Petter Selasky mlx5e_build_channel_param(struct mlx5e_priv *priv, 2491dc7e38acSHans Petter Selasky struct mlx5e_channel_param *cparam) 2492dc7e38acSHans Petter Selasky { 2493dc7e38acSHans Petter Selasky memset(cparam, 0, sizeof(*cparam)); 2494dc7e38acSHans Petter Selasky 2495dc7e38acSHans Petter Selasky mlx5e_build_rq_param(priv, &cparam->rq); 2496dc7e38acSHans Petter Selasky mlx5e_build_sq_param(priv, &cparam->sq); 2497dc7e38acSHans Petter Selasky mlx5e_build_rx_cq_param(priv, &cparam->rx_cq); 2498dc7e38acSHans Petter Selasky mlx5e_build_tx_cq_param(priv, &cparam->tx_cq); 2499dc7e38acSHans Petter Selasky } 2500dc7e38acSHans Petter Selasky 2501dc7e38acSHans Petter Selasky static int 2502dc7e38acSHans Petter Selasky mlx5e_open_channels(struct mlx5e_priv *priv) 2503dc7e38acSHans Petter Selasky { 2504eeb1ff98SHans Petter Selasky struct mlx5e_channel_param *cparam; 2505dc7e38acSHans Petter Selasky int err; 2506dc7e38acSHans Petter Selasky int i; 2507dc7e38acSHans Petter Selasky 2508eeb1ff98SHans Petter Selasky cparam = malloc(sizeof(*cparam), M_MLX5EN, M_WAITOK); 2509eeb1ff98SHans Petter Selasky 2510eeb1ff98SHans Petter Selasky mlx5e_build_channel_param(priv, cparam); 2511dc7e38acSHans Petter Selasky for (i = 0; i < priv->params.num_channels; i++) { 2512eeb1ff98SHans Petter Selasky err = mlx5e_open_channel(priv, cparam, &priv->channel[i]); 2513dc7e38acSHans Petter Selasky if (err) 2514dc7e38acSHans Petter Selasky goto err_close_channels; 2515c8d16d1eSHans Petter Selasky 2516c8d16d1eSHans Petter Selasky /* Bind interrupt vectors, if any. */ 2517c8d16d1eSHans Petter Selasky if (priv->params_ethtool.irq_cpu_base > -1) { 2518c8d16d1eSHans Petter Selasky cpuset_t cpuset; 2519c8d16d1eSHans Petter Selasky int cpu; 2520c8d16d1eSHans Petter Selasky int irq; 2521c8d16d1eSHans Petter Selasky int eqn; 2522c8d16d1eSHans Petter Selasky int nirq; 2523c8d16d1eSHans Petter Selasky 2524c8d16d1eSHans Petter Selasky err = mlx5_vector2eqn(priv->mdev, i, 2525c8d16d1eSHans Petter Selasky &eqn, &nirq); 2526c8d16d1eSHans Petter Selasky 2527c8d16d1eSHans Petter Selasky /* error here is non-fatal */ 2528c8d16d1eSHans Petter Selasky if (err != 0) 2529c8d16d1eSHans Petter Selasky continue; 2530c8d16d1eSHans Petter Selasky 2531c8d16d1eSHans Petter Selasky irq = priv->mdev->priv.msix_arr[nirq].vector; 2532c8d16d1eSHans Petter Selasky cpu = (unsigned)(priv->params_ethtool.irq_cpu_base + 2533c8d16d1eSHans Petter Selasky i * priv->params_ethtool.irq_cpu_stride) % (unsigned)mp_ncpus; 2534c8d16d1eSHans Petter Selasky 2535c8d16d1eSHans Petter Selasky CPU_ZERO(&cpuset); 2536c8d16d1eSHans Petter Selasky CPU_SET(cpu, &cpuset); 2537c8d16d1eSHans Petter Selasky intr_setaffinity(irq, CPU_WHICH_INTRHANDLER, &cpuset); 2538c8d16d1eSHans Petter Selasky } 2539dc7e38acSHans Petter Selasky } 2540eeb1ff98SHans Petter Selasky free(cparam, M_MLX5EN); 2541dc7e38acSHans Petter Selasky return (0); 2542dc7e38acSHans Petter Selasky 2543dc7e38acSHans Petter Selasky err_close_channels: 25443230c29dSSlava Shwartsman while (i--) { 2545dc7e38acSHans Petter Selasky mlx5e_close_channel(&priv->channel[i]); 2546dc7e38acSHans Petter Selasky mlx5e_close_channel_wait(&priv->channel[i]); 2547dc7e38acSHans Petter Selasky } 2548eeb1ff98SHans Petter Selasky free(cparam, M_MLX5EN); 2549dc7e38acSHans Petter Selasky return (err); 2550dc7e38acSHans Petter Selasky } 2551dc7e38acSHans Petter Selasky 2552dc7e38acSHans Petter Selasky static void 2553dc7e38acSHans Petter Selasky mlx5e_close_channels(struct mlx5e_priv *priv) 2554dc7e38acSHans Petter Selasky { 2555dc7e38acSHans Petter Selasky int i; 2556dc7e38acSHans Petter Selasky 2557dc7e38acSHans Petter Selasky for (i = 0; i < priv->params.num_channels; i++) 2558dc7e38acSHans Petter Selasky mlx5e_close_channel(&priv->channel[i]); 2559dc7e38acSHans Petter Selasky for (i = 0; i < priv->params.num_channels; i++) 2560dc7e38acSHans Petter Selasky mlx5e_close_channel_wait(&priv->channel[i]); 2561dc7e38acSHans Petter Selasky } 2562dc7e38acSHans Petter Selasky 2563dc7e38acSHans Petter Selasky static int 2564f03f517bSHans Petter Selasky mlx5e_refresh_sq_params(struct mlx5e_priv *priv, struct mlx5e_sq *sq) 2565f03f517bSHans Petter Selasky { 2566d2bf00a9SHans Petter Selasky 2567d2bf00a9SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify)) { 2568d2bf00a9SHans Petter Selasky uint8_t cq_mode; 2569d2bf00a9SHans Petter Selasky 2570d2bf00a9SHans Petter Selasky switch (priv->params.tx_cq_moderation_mode) { 2571d2bf00a9SHans Petter Selasky case 0: 2572423530beSHans Petter Selasky case 2: 2573d2bf00a9SHans Petter Selasky cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE; 2574d2bf00a9SHans Petter Selasky break; 2575d2bf00a9SHans Petter Selasky default: 2576d2bf00a9SHans Petter Selasky cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE; 2577d2bf00a9SHans Petter Selasky break; 2578d2bf00a9SHans Petter Selasky } 2579d2bf00a9SHans Petter Selasky 2580d2bf00a9SHans Petter Selasky return (mlx5_core_modify_cq_moderation_mode(priv->mdev, &sq->cq.mcq, 2581d2bf00a9SHans Petter Selasky priv->params.tx_cq_moderation_usec, 2582d2bf00a9SHans Petter Selasky priv->params.tx_cq_moderation_pkts, 2583d2bf00a9SHans Petter Selasky cq_mode)); 2584d2bf00a9SHans Petter Selasky } 2585d2bf00a9SHans Petter Selasky 2586f03f517bSHans Petter Selasky return (mlx5_core_modify_cq_moderation(priv->mdev, &sq->cq.mcq, 2587f03f517bSHans Petter Selasky priv->params.tx_cq_moderation_usec, 2588f03f517bSHans Petter Selasky priv->params.tx_cq_moderation_pkts)); 2589f03f517bSHans Petter Selasky } 2590f03f517bSHans Petter Selasky 2591f03f517bSHans Petter Selasky static int 2592f03f517bSHans Petter Selasky mlx5e_refresh_rq_params(struct mlx5e_priv *priv, struct mlx5e_rq *rq) 2593f03f517bSHans Petter Selasky { 2594d2bf00a9SHans Petter Selasky 2595d2bf00a9SHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify)) { 2596d2bf00a9SHans Petter Selasky uint8_t cq_mode; 2597423530beSHans Petter Selasky uint8_t dim_mode; 2598d2bf00a9SHans Petter Selasky int retval; 2599d2bf00a9SHans Petter Selasky 2600d2bf00a9SHans Petter Selasky switch (priv->params.rx_cq_moderation_mode) { 2601d2bf00a9SHans Petter Selasky case 0: 2602423530beSHans Petter Selasky case 2: 2603d2bf00a9SHans Petter Selasky cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE; 2604423530beSHans Petter Selasky dim_mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE; 2605d2bf00a9SHans Petter Selasky break; 2606d2bf00a9SHans Petter Selasky default: 2607d2bf00a9SHans Petter Selasky cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE; 2608423530beSHans Petter Selasky dim_mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE; 2609d2bf00a9SHans Petter Selasky break; 2610d2bf00a9SHans Petter Selasky } 2611d2bf00a9SHans Petter Selasky 2612423530beSHans Petter Selasky /* tear down dynamic interrupt moderation */ 2613423530beSHans Petter Selasky mtx_lock(&rq->mtx); 2614423530beSHans Petter Selasky rq->dim.mode = NET_DIM_CQ_PERIOD_MODE_DISABLED; 2615423530beSHans Petter Selasky mtx_unlock(&rq->mtx); 2616423530beSHans Petter Selasky 2617423530beSHans Petter Selasky /* wait for dynamic interrupt moderation work task, if any */ 2618423530beSHans Petter Selasky cancel_work_sync(&rq->dim.work); 2619423530beSHans Petter Selasky 2620423530beSHans Petter Selasky if (priv->params.rx_cq_moderation_mode >= 2) { 2621423530beSHans Petter Selasky struct net_dim_cq_moder curr; 2622423530beSHans Petter Selasky 2623423530beSHans Petter Selasky mlx5e_get_default_profile(priv, dim_mode, &curr); 2624423530beSHans Petter Selasky 2625423530beSHans Petter Selasky retval = mlx5_core_modify_cq_moderation_mode(priv->mdev, &rq->cq.mcq, 2626423530beSHans Petter Selasky curr.usec, curr.pkts, cq_mode); 2627423530beSHans Petter Selasky 2628423530beSHans Petter Selasky /* set dynamic interrupt moderation mode and zero defaults */ 2629423530beSHans Petter Selasky mtx_lock(&rq->mtx); 2630423530beSHans Petter Selasky rq->dim.mode = dim_mode; 2631423530beSHans Petter Selasky rq->dim.state = 0; 2632423530beSHans Petter Selasky rq->dim.profile_ix = MLX5E_DIM_DEFAULT_PROFILE; 2633423530beSHans Petter Selasky mtx_unlock(&rq->mtx); 2634423530beSHans Petter Selasky } else { 2635d2bf00a9SHans Petter Selasky retval = mlx5_core_modify_cq_moderation_mode(priv->mdev, &rq->cq.mcq, 2636d2bf00a9SHans Petter Selasky priv->params.rx_cq_moderation_usec, 2637d2bf00a9SHans Petter Selasky priv->params.rx_cq_moderation_pkts, 2638d2bf00a9SHans Petter Selasky cq_mode); 2639423530beSHans Petter Selasky } 2640d2bf00a9SHans Petter Selasky return (retval); 2641d2bf00a9SHans Petter Selasky } 2642d2bf00a9SHans Petter Selasky 2643f03f517bSHans Petter Selasky return (mlx5_core_modify_cq_moderation(priv->mdev, &rq->cq.mcq, 2644f03f517bSHans Petter Selasky priv->params.rx_cq_moderation_usec, 2645f03f517bSHans Petter Selasky priv->params.rx_cq_moderation_pkts)); 2646f03f517bSHans Petter Selasky } 2647f03f517bSHans Petter Selasky 2648f03f517bSHans Petter Selasky static int 2649f03f517bSHans Petter Selasky mlx5e_refresh_channel_params_sub(struct mlx5e_priv *priv, struct mlx5e_channel *c) 2650f03f517bSHans Petter Selasky { 2651f03f517bSHans Petter Selasky int err; 2652f03f517bSHans Petter Selasky int i; 2653f03f517bSHans Petter Selasky 2654f03f517bSHans Petter Selasky err = mlx5e_refresh_rq_params(priv, &c->rq); 2655f03f517bSHans Petter Selasky if (err) 2656f03f517bSHans Petter Selasky goto done; 2657f03f517bSHans Petter Selasky 2658eeb1ff98SHans Petter Selasky for (i = 0; i != priv->num_tc; i++) { 2659f03f517bSHans Petter Selasky err = mlx5e_refresh_sq_params(priv, &c->sq[i]); 2660f03f517bSHans Petter Selasky if (err) 2661f03f517bSHans Petter Selasky goto done; 2662f03f517bSHans Petter Selasky } 2663f03f517bSHans Petter Selasky done: 2664f03f517bSHans Petter Selasky return (err); 2665f03f517bSHans Petter Selasky } 2666f03f517bSHans Petter Selasky 2667f03f517bSHans Petter Selasky int 2668f03f517bSHans Petter Selasky mlx5e_refresh_channel_params(struct mlx5e_priv *priv) 2669f03f517bSHans Petter Selasky { 2670f03f517bSHans Petter Selasky int i; 2671f03f517bSHans Petter Selasky 26723230c29dSSlava Shwartsman /* check if channels are closed */ 26733230c29dSSlava Shwartsman if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0) 2674f03f517bSHans Petter Selasky return (EINVAL); 2675f03f517bSHans Petter Selasky 2676f03f517bSHans Petter Selasky for (i = 0; i < priv->params.num_channels; i++) { 2677f03f517bSHans Petter Selasky int err; 2678f03f517bSHans Petter Selasky 26793230c29dSSlava Shwartsman err = mlx5e_refresh_channel_params_sub(priv, &priv->channel[i]); 2680f03f517bSHans Petter Selasky if (err) 2681f03f517bSHans Petter Selasky return (err); 2682f03f517bSHans Petter Selasky } 2683f03f517bSHans Petter Selasky return (0); 2684f03f517bSHans Petter Selasky } 2685f03f517bSHans Petter Selasky 2686f03f517bSHans Petter Selasky static int 2687dc7e38acSHans Petter Selasky mlx5e_open_tis(struct mlx5e_priv *priv, int tc) 2688dc7e38acSHans Petter Selasky { 2689dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 2690dc7e38acSHans Petter Selasky u32 in[MLX5_ST_SZ_DW(create_tis_in)]; 2691dc7e38acSHans Petter Selasky void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx); 2692dc7e38acSHans Petter Selasky 2693dc7e38acSHans Petter Selasky memset(in, 0, sizeof(in)); 2694dc7e38acSHans Petter Selasky 2695dc7e38acSHans Petter Selasky MLX5_SET(tisc, tisc, prio, tc); 2696dc7e38acSHans Petter Selasky MLX5_SET(tisc, tisc, transport_domain, priv->tdn); 2697dc7e38acSHans Petter Selasky 2698dc7e38acSHans Petter Selasky return (mlx5_core_create_tis(mdev, in, sizeof(in), &priv->tisn[tc])); 2699dc7e38acSHans Petter Selasky } 2700dc7e38acSHans Petter Selasky 2701dc7e38acSHans Petter Selasky static void 2702dc7e38acSHans Petter Selasky mlx5e_close_tis(struct mlx5e_priv *priv, int tc) 2703dc7e38acSHans Petter Selasky { 2704b633e08cSHans Petter Selasky mlx5_core_destroy_tis(priv->mdev, priv->tisn[tc], 0); 2705dc7e38acSHans Petter Selasky } 2706dc7e38acSHans Petter Selasky 2707dc7e38acSHans Petter Selasky static int 2708dc7e38acSHans Petter Selasky mlx5e_open_tises(struct mlx5e_priv *priv) 2709dc7e38acSHans Petter Selasky { 2710dc7e38acSHans Petter Selasky int num_tc = priv->num_tc; 2711dc7e38acSHans Petter Selasky int err; 2712dc7e38acSHans Petter Selasky int tc; 2713dc7e38acSHans Petter Selasky 2714dc7e38acSHans Petter Selasky for (tc = 0; tc < num_tc; tc++) { 2715dc7e38acSHans Petter Selasky err = mlx5e_open_tis(priv, tc); 2716dc7e38acSHans Petter Selasky if (err) 2717dc7e38acSHans Petter Selasky goto err_close_tises; 2718dc7e38acSHans Petter Selasky } 2719dc7e38acSHans Petter Selasky 2720dc7e38acSHans Petter Selasky return (0); 2721dc7e38acSHans Petter Selasky 2722dc7e38acSHans Petter Selasky err_close_tises: 2723dc7e38acSHans Petter Selasky for (tc--; tc >= 0; tc--) 2724dc7e38acSHans Petter Selasky mlx5e_close_tis(priv, tc); 2725dc7e38acSHans Petter Selasky 2726dc7e38acSHans Petter Selasky return (err); 2727dc7e38acSHans Petter Selasky } 2728dc7e38acSHans Petter Selasky 2729dc7e38acSHans Petter Selasky static void 2730dc7e38acSHans Petter Selasky mlx5e_close_tises(struct mlx5e_priv *priv) 2731dc7e38acSHans Petter Selasky { 2732dc7e38acSHans Petter Selasky int num_tc = priv->num_tc; 2733dc7e38acSHans Petter Selasky int tc; 2734dc7e38acSHans Petter Selasky 2735dc7e38acSHans Petter Selasky for (tc = 0; tc < num_tc; tc++) 2736dc7e38acSHans Petter Selasky mlx5e_close_tis(priv, tc); 2737dc7e38acSHans Petter Selasky } 2738dc7e38acSHans Petter Selasky 2739dc7e38acSHans Petter Selasky static int 27408e332232SHans Petter Selasky mlx5e_open_default_rqt(struct mlx5e_priv *priv, u32 *prqtn, int sz) 2741dc7e38acSHans Petter Selasky { 2742dc7e38acSHans Petter Selasky u32 *in; 2743dc7e38acSHans Petter Selasky void *rqtc; 2744dc7e38acSHans Petter Selasky int inlen; 2745dc7e38acSHans Petter Selasky int err; 2746dc7e38acSHans Petter Selasky int i; 2747dc7e38acSHans Petter Selasky 2748dc7e38acSHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * sz; 2749dc7e38acSHans Petter Selasky in = mlx5_vzalloc(inlen); 2750dc7e38acSHans Petter Selasky if (in == NULL) 2751dc7e38acSHans Petter Selasky return (-ENOMEM); 2752dc7e38acSHans Petter Selasky rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context); 2753dc7e38acSHans Petter Selasky 2754dc7e38acSHans Petter Selasky MLX5_SET(rqtc, rqtc, rqt_actual_size, sz); 2755dc7e38acSHans Petter Selasky MLX5_SET(rqtc, rqtc, rqt_max_size, sz); 2756dc7e38acSHans Petter Selasky 275733a6a7a7SHans Petter Selasky for (i = 0; i != sz; i++) 275833a6a7a7SHans Petter Selasky MLX5_SET(rqtc, rqtc, rq_num[i], priv->drop_rq.rqn); 275933a6a7a7SHans Petter Selasky 27608e332232SHans Petter Selasky err = mlx5_core_create_rqt(priv->mdev, in, inlen, prqtn); 276133a6a7a7SHans Petter Selasky kvfree(in); 276233a6a7a7SHans Petter Selasky 276333a6a7a7SHans Petter Selasky return (err); 276433a6a7a7SHans Petter Selasky } 276533a6a7a7SHans Petter Selasky 276633a6a7a7SHans Petter Selasky static int 27678e332232SHans Petter Selasky mlx5e_open_rqts(struct mlx5e_priv *priv) 27688e332232SHans Petter Selasky { 27698e332232SHans Petter Selasky int err; 27708e332232SHans Petter Selasky int i; 27718e332232SHans Petter Selasky 27728e332232SHans Petter Selasky err = mlx5e_open_default_rqt(priv, &priv->rqtn, 27738e332232SHans Petter Selasky 1 << priv->params.rx_hash_log_tbl_sz); 27748e332232SHans Petter Selasky if (err) 27758e332232SHans Petter Selasky goto err_default; 27768e332232SHans Petter Selasky 27778e332232SHans Petter Selasky for (i = 0; i != priv->mdev->priv.eq_table.num_comp_vectors; i++) { 27788e332232SHans Petter Selasky err = mlx5e_open_default_rqt(priv, &priv->channel[i].rqtn, 1); 27798e332232SHans Petter Selasky if (err) 27808e332232SHans Petter Selasky goto err_channel; 27818e332232SHans Petter Selasky } 27828e332232SHans Petter Selasky return (0); 27838e332232SHans Petter Selasky 27848e332232SHans Petter Selasky err_channel: 27858e332232SHans Petter Selasky while (i--) 27868e332232SHans Petter Selasky mlx5_core_destroy_rqt(priv->mdev, priv->channel[i].rqtn, 0); 27878e332232SHans Petter Selasky 27888e332232SHans Petter Selasky mlx5_core_destroy_rqt(priv->mdev, priv->rqtn, 0); 27898e332232SHans Petter Selasky 27908e332232SHans Petter Selasky err_default: 27918e332232SHans Petter Selasky return (err); 27928e332232SHans Petter Selasky } 27938e332232SHans Petter Selasky 27948e332232SHans Petter Selasky static void 27958e332232SHans Petter Selasky mlx5e_close_rqts(struct mlx5e_priv *priv) 27968e332232SHans Petter Selasky { 27978e332232SHans Petter Selasky int i; 27988e332232SHans Petter Selasky 27998e332232SHans Petter Selasky for (i = 0; i != priv->mdev->priv.eq_table.num_comp_vectors; i++) 28008e332232SHans Petter Selasky mlx5_core_destroy_rqt(priv->mdev, priv->channel[i].rqtn, 0); 28018e332232SHans Petter Selasky 28028e332232SHans Petter Selasky mlx5_core_destroy_rqt(priv->mdev, priv->rqtn, 0); 28038e332232SHans Petter Selasky } 28048e332232SHans Petter Selasky 28058e332232SHans Petter Selasky static int 280633a6a7a7SHans Petter Selasky mlx5e_activate_rqt(struct mlx5e_priv *priv) 280733a6a7a7SHans Petter Selasky { 280833a6a7a7SHans Petter Selasky u32 *in; 280933a6a7a7SHans Petter Selasky void *rqtc; 281033a6a7a7SHans Petter Selasky int inlen; 281133a6a7a7SHans Petter Selasky int err; 281233a6a7a7SHans Petter Selasky int sz; 281333a6a7a7SHans Petter Selasky int i; 281433a6a7a7SHans Petter Selasky 281533a6a7a7SHans Petter Selasky sz = 1 << priv->params.rx_hash_log_tbl_sz; 281633a6a7a7SHans Petter Selasky 281733a6a7a7SHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + sizeof(u32) * sz; 281833a6a7a7SHans Petter Selasky in = mlx5_vzalloc(inlen); 281933a6a7a7SHans Petter Selasky if (in == NULL) 282033a6a7a7SHans Petter Selasky return (-ENOMEM); 282133a6a7a7SHans Petter Selasky 282233a6a7a7SHans Petter Selasky rqtc = MLX5_ADDR_OF(modify_rqt_in, in, ctx); 282333a6a7a7SHans Petter Selasky 282433a6a7a7SHans Petter Selasky MLX5_SET(rqtc, rqtc, rqt_actual_size, sz); 282533a6a7a7SHans Petter Selasky MLX5_SET(modify_rqt_in, in, bitmask.rqn_list, 1); 282633a6a7a7SHans Petter Selasky 282733a6a7a7SHans Petter Selasky for (i = 0; i != sz; i++) { 28288e332232SHans Petter Selasky int ix; 2829278ce1c9SHans Petter Selasky #ifdef RSS 28308e332232SHans Petter Selasky ix = rss_get_indirection_to_bucket(i); 28318e332232SHans Petter Selasky #else 28328e332232SHans Petter Selasky ix = i; 2833278ce1c9SHans Petter Selasky #endif 2834278ce1c9SHans Petter Selasky /* ensure we don't overflow */ 2835278ce1c9SHans Petter Selasky ix %= priv->params.num_channels; 283616ae32f9SHans Petter Selasky 283716ae32f9SHans Petter Selasky /* apply receive side scaling stride, if any */ 283816ae32f9SHans Petter Selasky ix -= ix % (int)priv->params.channels_rsss; 283916ae32f9SHans Petter Selasky 28403230c29dSSlava Shwartsman MLX5_SET(rqtc, rqtc, rq_num[i], priv->channel[ix].rq.rqn); 2841dc7e38acSHans Petter Selasky } 2842dc7e38acSHans Petter Selasky 284333a6a7a7SHans Petter Selasky err = mlx5_core_modify_rqt(priv->mdev, priv->rqtn, in, inlen); 28448e332232SHans Petter Selasky if (err) 28458e332232SHans Petter Selasky goto err_modify; 2846dc7e38acSHans Petter Selasky 28478e332232SHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + sizeof(u32); 28488e332232SHans Petter Selasky 28498e332232SHans Petter Selasky MLX5_SET(rqtc, rqtc, rqt_actual_size, 1); 28508e332232SHans Petter Selasky 28518e332232SHans Petter Selasky for (i = 0; i != priv->mdev->priv.eq_table.num_comp_vectors; i++) { 28528e332232SHans Petter Selasky int ix; 28538e332232SHans Petter Selasky #ifdef RSS 28548e332232SHans Petter Selasky ix = rss_get_indirection_to_bucket(i); 28558e332232SHans Petter Selasky #else 28568e332232SHans Petter Selasky ix = i; 28578e332232SHans Petter Selasky #endif 28588e332232SHans Petter Selasky /* ensure we don't overflow */ 28598e332232SHans Petter Selasky ix %= priv->params.num_channels; 28608e332232SHans Petter Selasky 28618e332232SHans Petter Selasky /* apply receive side scaling stride, if any */ 28628e332232SHans Petter Selasky ix -= ix % (int)priv->params.channels_rsss; 28638e332232SHans Petter Selasky 28648e332232SHans Petter Selasky MLX5_SET(rqtc, rqtc, rq_num[0], priv->channel[ix].rq.rqn); 28658e332232SHans Petter Selasky 28668e332232SHans Petter Selasky err = mlx5_core_modify_rqt(priv->mdev, priv->channel[i].rqtn, in, inlen); 28678e332232SHans Petter Selasky if (err) 28688e332232SHans Petter Selasky goto err_modify; 28698e332232SHans Petter Selasky } 28708e332232SHans Petter Selasky 28718e332232SHans Petter Selasky err_modify: 28728e332232SHans Petter Selasky kvfree(in); 2873dc7e38acSHans Petter Selasky return (err); 2874dc7e38acSHans Petter Selasky } 2875dc7e38acSHans Petter Selasky 287633a6a7a7SHans Petter Selasky static int 287733a6a7a7SHans Petter Selasky mlx5e_deactivate_rqt(struct mlx5e_priv *priv) 2878dc7e38acSHans Petter Selasky { 287933a6a7a7SHans Petter Selasky u32 *in; 288033a6a7a7SHans Petter Selasky void *rqtc; 288133a6a7a7SHans Petter Selasky int inlen; 288233a6a7a7SHans Petter Selasky int err; 288333a6a7a7SHans Petter Selasky int sz; 288433a6a7a7SHans Petter Selasky int i; 2885dc7e38acSHans Petter Selasky 288633a6a7a7SHans Petter Selasky sz = 1 << priv->params.rx_hash_log_tbl_sz; 2887dc7e38acSHans Petter Selasky 288833a6a7a7SHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + sizeof(u32) * sz; 288933a6a7a7SHans Petter Selasky in = mlx5_vzalloc(inlen); 289033a6a7a7SHans Petter Selasky if (in == NULL) 289133a6a7a7SHans Petter Selasky return (-ENOMEM); 289233a6a7a7SHans Petter Selasky 289333a6a7a7SHans Petter Selasky rqtc = MLX5_ADDR_OF(modify_rqt_in, in, ctx); 289433a6a7a7SHans Petter Selasky 289533a6a7a7SHans Petter Selasky MLX5_SET(rqtc, rqtc, rqt_actual_size, sz); 289633a6a7a7SHans Petter Selasky MLX5_SET(modify_rqt_in, in, bitmask.rqn_list, 1); 289733a6a7a7SHans Petter Selasky 289833a6a7a7SHans Petter Selasky for (i = 0; i != sz; i++) 289933a6a7a7SHans Petter Selasky MLX5_SET(rqtc, rqtc, rq_num[i], priv->drop_rq.rqn); 290033a6a7a7SHans Petter Selasky 290133a6a7a7SHans Petter Selasky err = mlx5_core_modify_rqt(priv->mdev, priv->rqtn, in, inlen); 29028e332232SHans Petter Selasky if (err) 29038e332232SHans Petter Selasky goto err_modify; 290433a6a7a7SHans Petter Selasky 29058e332232SHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + sizeof(u32); 29068e332232SHans Petter Selasky 29078e332232SHans Petter Selasky MLX5_SET(rqtc, rqtc, rqt_actual_size, 1); 29088e332232SHans Petter Selasky 29098e332232SHans Petter Selasky for (i = 0; i != priv->mdev->priv.eq_table.num_comp_vectors; i++) { 29108e332232SHans Petter Selasky MLX5_SET(rqtc, rqtc, rq_num[0], priv->drop_rq.rqn); 29118e332232SHans Petter Selasky 29128e332232SHans Petter Selasky err = mlx5_core_modify_rqt(priv->mdev, priv->channel[i].rqtn, in, inlen); 29138e332232SHans Petter Selasky if (err) 29148e332232SHans Petter Selasky goto err_modify; 29158e332232SHans Petter Selasky } 29168e332232SHans Petter Selasky 29178e332232SHans Petter Selasky err_modify: 29188e332232SHans Petter Selasky kvfree(in); 291933a6a7a7SHans Petter Selasky return (err); 2920dc7e38acSHans Petter Selasky } 2921dc7e38acSHans Petter Selasky 2922a00718e1SHans Petter Selasky #define MLX5E_RSS_KEY_SIZE (10 * 4) /* bytes */ 2923a00718e1SHans Petter Selasky 2924a00718e1SHans Petter Selasky static void 2925a00718e1SHans Petter Selasky mlx5e_get_rss_key(void *key_ptr) 2926a00718e1SHans Petter Selasky { 2927a00718e1SHans Petter Selasky #ifdef RSS 2928a00718e1SHans Petter Selasky rss_getkey(key_ptr); 2929a00718e1SHans Petter Selasky #else 2930a00718e1SHans Petter Selasky static const u32 rsskey[] = { 2931a00718e1SHans Petter Selasky cpu_to_be32(0xD181C62C), 2932a00718e1SHans Petter Selasky cpu_to_be32(0xF7F4DB5B), 2933a00718e1SHans Petter Selasky cpu_to_be32(0x1983A2FC), 2934a00718e1SHans Petter Selasky cpu_to_be32(0x943E1ADB), 2935a00718e1SHans Petter Selasky cpu_to_be32(0xD9389E6B), 2936a00718e1SHans Petter Selasky cpu_to_be32(0xD1039C2C), 2937a00718e1SHans Petter Selasky cpu_to_be32(0xA74499AD), 2938a00718e1SHans Petter Selasky cpu_to_be32(0x593D56D9), 2939a00718e1SHans Petter Selasky cpu_to_be32(0xF3253C06), 2940a00718e1SHans Petter Selasky cpu_to_be32(0x2ADC1FFC), 2941a00718e1SHans Petter Selasky }; 2942a00718e1SHans Petter Selasky CTASSERT(sizeof(rsskey) == MLX5E_RSS_KEY_SIZE); 2943a00718e1SHans Petter Selasky memcpy(key_ptr, rsskey, MLX5E_RSS_KEY_SIZE); 2944a00718e1SHans Petter Selasky #endif 2945a00718e1SHans Petter Selasky } 2946a00718e1SHans Petter Selasky 2947dc7e38acSHans Petter Selasky static void 2948fba6942fSKonstantin Belousov mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, int tt, bool inner_vxlan) 2949dc7e38acSHans Petter Selasky { 2950dc7e38acSHans Petter Selasky void *hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer); 2951fba6942fSKonstantin Belousov void *hfsi = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_inner); 2952fba6942fSKonstantin Belousov void *hfs = inner_vxlan ? hfsi : hfso; 2953dc7e38acSHans Petter Selasky __be32 *hkey; 2954dc7e38acSHans Petter Selasky 2955dc7e38acSHans Petter Selasky MLX5_SET(tirc, tirc, transport_domain, priv->tdn); 2956dc7e38acSHans Petter Selasky 2957dc7e38acSHans Petter Selasky #define ROUGH_MAX_L2_L3_HDR_SZ 256 2958dc7e38acSHans Petter Selasky 2959dc7e38acSHans Petter Selasky #define MLX5_HASH_IP (MLX5_HASH_FIELD_SEL_SRC_IP |\ 2960dc7e38acSHans Petter Selasky MLX5_HASH_FIELD_SEL_DST_IP) 2961dc7e38acSHans Petter Selasky 2962dc7e38acSHans Petter Selasky #define MLX5_HASH_ALL (MLX5_HASH_FIELD_SEL_SRC_IP |\ 2963dc7e38acSHans Petter Selasky MLX5_HASH_FIELD_SEL_DST_IP |\ 2964dc7e38acSHans Petter Selasky MLX5_HASH_FIELD_SEL_L4_SPORT |\ 2965dc7e38acSHans Petter Selasky MLX5_HASH_FIELD_SEL_L4_DPORT) 2966dc7e38acSHans Petter Selasky 2967dc7e38acSHans Petter Selasky #define MLX5_HASH_IP_IPSEC_SPI (MLX5_HASH_FIELD_SEL_SRC_IP |\ 2968dc7e38acSHans Petter Selasky MLX5_HASH_FIELD_SEL_DST_IP |\ 2969dc7e38acSHans Petter Selasky MLX5_HASH_FIELD_SEL_IPSEC_SPI) 2970dc7e38acSHans Petter Selasky 2971dc7e38acSHans Petter Selasky if (priv->params.hw_lro_en) { 2972dc7e38acSHans Petter Selasky MLX5_SET(tirc, tirc, lro_enable_mask, 2973dc7e38acSHans Petter Selasky MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO | 2974dc7e38acSHans Petter Selasky MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO); 2975dc7e38acSHans Petter Selasky MLX5_SET(tirc, tirc, lro_max_msg_sz, 2976dc7e38acSHans Petter Selasky (priv->params.lro_wqe_sz - 2977dc7e38acSHans Petter Selasky ROUGH_MAX_L2_L3_HDR_SZ) >> 8); 2978dc7e38acSHans Petter Selasky /* TODO: add the option to choose timer value dynamically */ 2979dc7e38acSHans Petter Selasky MLX5_SET(tirc, tirc, lro_timeout_period_usecs, 2980dc7e38acSHans Petter Selasky MLX5_CAP_ETH(priv->mdev, 2981dc7e38acSHans Petter Selasky lro_timer_supported_periods[2])); 2982dc7e38acSHans Petter Selasky } 2983278ce1c9SHans Petter Selasky 298448acda2bSKonstantin Belousov if (inner_vxlan) 2985fba6942fSKonstantin Belousov MLX5_SET(tirc, tirc, tunneled_offload_en, 1); 2986fba6942fSKonstantin Belousov 298706c2bd18SHans Petter Selasky /* 298806c2bd18SHans Petter Selasky * All packets must go through the indirection table, RQT, 298906c2bd18SHans Petter Selasky * because it is not possible to modify the RQN of the TIR 299006c2bd18SHans Petter Selasky * for direct dispatchment after it is created, typically 299106c2bd18SHans Petter Selasky * when the link goes up and down. 299206c2bd18SHans Petter Selasky */ 2993dc7e38acSHans Petter Selasky MLX5_SET(tirc, tirc, disp_type, 2994dc7e38acSHans Petter Selasky MLX5_TIRC_DISP_TYPE_INDIRECT); 2995dc7e38acSHans Petter Selasky MLX5_SET(tirc, tirc, indirect_table, 2996dc7e38acSHans Petter Selasky priv->rqtn); 2997dc7e38acSHans Petter Selasky MLX5_SET(tirc, tirc, rx_hash_fn, 2998dc7e38acSHans Petter Selasky MLX5_TIRC_RX_HASH_FN_HASH_TOEPLITZ); 2999dc7e38acSHans Petter Selasky hkey = (__be32 *) MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key); 3000a00718e1SHans Petter Selasky 3001a00718e1SHans Petter Selasky CTASSERT(MLX5_FLD_SZ_BYTES(tirc, rx_hash_toeplitz_key) >= 3002a00718e1SHans Petter Selasky MLX5E_RSS_KEY_SIZE); 3003278ce1c9SHans Petter Selasky #ifdef RSS 3004278ce1c9SHans Petter Selasky /* 3005278ce1c9SHans Petter Selasky * The FreeBSD RSS implementation does currently not 3006278ce1c9SHans Petter Selasky * support symmetric Toeplitz hashes: 3007278ce1c9SHans Petter Selasky */ 3008278ce1c9SHans Petter Selasky MLX5_SET(tirc, tirc, rx_hash_symmetric, 0); 3009278ce1c9SHans Petter Selasky #else 3010278ce1c9SHans Petter Selasky MLX5_SET(tirc, tirc, rx_hash_symmetric, 1); 3011278ce1c9SHans Petter Selasky #endif 3012a00718e1SHans Petter Selasky mlx5e_get_rss_key(hkey); 3013dc7e38acSHans Petter Selasky 3014dc7e38acSHans Petter Selasky switch (tt) { 3015dc7e38acSHans Petter Selasky case MLX5E_TT_IPV4_TCP: 3016fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3017dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV4); 3018fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l4_prot_type, 3019dc7e38acSHans Petter Selasky MLX5_L4_PROT_TYPE_TCP); 3020278ce1c9SHans Petter Selasky #ifdef RSS 3021278ce1c9SHans Petter Selasky if (!(rss_gethashconfig() & RSS_HASHTYPE_RSS_TCP_IPV4)) { 3022fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3023278ce1c9SHans Petter Selasky MLX5_HASH_IP); 3024278ce1c9SHans Petter Selasky } else 3025278ce1c9SHans Petter Selasky #endif 3026fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3027dc7e38acSHans Petter Selasky MLX5_HASH_ALL); 3028dc7e38acSHans Petter Selasky break; 3029dc7e38acSHans Petter Selasky 3030dc7e38acSHans Petter Selasky case MLX5E_TT_IPV6_TCP: 3031fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3032dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV6); 3033fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l4_prot_type, 3034dc7e38acSHans Petter Selasky MLX5_L4_PROT_TYPE_TCP); 3035278ce1c9SHans Petter Selasky #ifdef RSS 3036278ce1c9SHans Petter Selasky if (!(rss_gethashconfig() & RSS_HASHTYPE_RSS_TCP_IPV6)) { 3037fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3038278ce1c9SHans Petter Selasky MLX5_HASH_IP); 3039278ce1c9SHans Petter Selasky } else 3040278ce1c9SHans Petter Selasky #endif 3041fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3042dc7e38acSHans Petter Selasky MLX5_HASH_ALL); 3043dc7e38acSHans Petter Selasky break; 3044dc7e38acSHans Petter Selasky 3045dc7e38acSHans Petter Selasky case MLX5E_TT_IPV4_UDP: 3046fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3047dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV4); 3048fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l4_prot_type, 3049dc7e38acSHans Petter Selasky MLX5_L4_PROT_TYPE_UDP); 3050278ce1c9SHans Petter Selasky #ifdef RSS 3051278ce1c9SHans Petter Selasky if (!(rss_gethashconfig() & RSS_HASHTYPE_RSS_UDP_IPV4)) { 3052fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3053278ce1c9SHans Petter Selasky MLX5_HASH_IP); 3054278ce1c9SHans Petter Selasky } else 3055278ce1c9SHans Petter Selasky #endif 3056fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3057dc7e38acSHans Petter Selasky MLX5_HASH_ALL); 3058dc7e38acSHans Petter Selasky break; 3059dc7e38acSHans Petter Selasky 3060dc7e38acSHans Petter Selasky case MLX5E_TT_IPV6_UDP: 3061fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3062dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV6); 3063fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l4_prot_type, 3064dc7e38acSHans Petter Selasky MLX5_L4_PROT_TYPE_UDP); 3065278ce1c9SHans Petter Selasky #ifdef RSS 3066278ce1c9SHans Petter Selasky if (!(rss_gethashconfig() & RSS_HASHTYPE_RSS_UDP_IPV6)) { 3067fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3068278ce1c9SHans Petter Selasky MLX5_HASH_IP); 3069278ce1c9SHans Petter Selasky } else 3070278ce1c9SHans Petter Selasky #endif 3071fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3072dc7e38acSHans Petter Selasky MLX5_HASH_ALL); 3073dc7e38acSHans Petter Selasky break; 3074dc7e38acSHans Petter Selasky 3075dc7e38acSHans Petter Selasky case MLX5E_TT_IPV4_IPSEC_AH: 3076fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3077dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV4); 3078fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3079dc7e38acSHans Petter Selasky MLX5_HASH_IP_IPSEC_SPI); 3080dc7e38acSHans Petter Selasky break; 3081dc7e38acSHans Petter Selasky 3082dc7e38acSHans Petter Selasky case MLX5E_TT_IPV6_IPSEC_AH: 3083fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3084dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV6); 3085fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3086dc7e38acSHans Petter Selasky MLX5_HASH_IP_IPSEC_SPI); 3087dc7e38acSHans Petter Selasky break; 3088dc7e38acSHans Petter Selasky 3089dc7e38acSHans Petter Selasky case MLX5E_TT_IPV4_IPSEC_ESP: 3090fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3091dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV4); 3092fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3093dc7e38acSHans Petter Selasky MLX5_HASH_IP_IPSEC_SPI); 3094dc7e38acSHans Petter Selasky break; 3095dc7e38acSHans Petter Selasky 3096dc7e38acSHans Petter Selasky case MLX5E_TT_IPV6_IPSEC_ESP: 3097fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3098dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV6); 3099fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3100dc7e38acSHans Petter Selasky MLX5_HASH_IP_IPSEC_SPI); 3101dc7e38acSHans Petter Selasky break; 3102dc7e38acSHans Petter Selasky 3103dc7e38acSHans Petter Selasky case MLX5E_TT_IPV4: 3104fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3105dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV4); 3106fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3107dc7e38acSHans Petter Selasky MLX5_HASH_IP); 3108dc7e38acSHans Petter Selasky break; 3109dc7e38acSHans Petter Selasky 3110dc7e38acSHans Petter Selasky case MLX5E_TT_IPV6: 3111fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, l3_prot_type, 3112dc7e38acSHans Petter Selasky MLX5_L3_PROT_TYPE_IPV6); 3113fba6942fSKonstantin Belousov MLX5_SET(rx_hash_field_select, hfs, selected_fields, 3114dc7e38acSHans Petter Selasky MLX5_HASH_IP); 3115dc7e38acSHans Petter Selasky break; 3116dc7e38acSHans Petter Selasky 3117dc7e38acSHans Petter Selasky default: 3118dc7e38acSHans Petter Selasky break; 3119dc7e38acSHans Petter Selasky } 3120dc7e38acSHans Petter Selasky } 3121dc7e38acSHans Petter Selasky 3122dc7e38acSHans Petter Selasky static int 3123fba6942fSKonstantin Belousov mlx5e_open_tir(struct mlx5e_priv *priv, int tt, bool inner_vxlan) 3124dc7e38acSHans Petter Selasky { 3125dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 3126dc7e38acSHans Petter Selasky u32 *in; 3127dc7e38acSHans Petter Selasky void *tirc; 3128dc7e38acSHans Petter Selasky int inlen; 3129dc7e38acSHans Petter Selasky int err; 3130dc7e38acSHans Petter Selasky 3131dc7e38acSHans Petter Selasky inlen = MLX5_ST_SZ_BYTES(create_tir_in); 3132dc7e38acSHans Petter Selasky in = mlx5_vzalloc(inlen); 3133dc7e38acSHans Petter Selasky if (in == NULL) 3134dc7e38acSHans Petter Selasky return (-ENOMEM); 3135dc7e38acSHans Petter Selasky tirc = MLX5_ADDR_OF(create_tir_in, in, tir_context); 3136dc7e38acSHans Petter Selasky 3137fba6942fSKonstantin Belousov mlx5e_build_tir_ctx(priv, tirc, tt, inner_vxlan); 3138dc7e38acSHans Petter Selasky 3139fba6942fSKonstantin Belousov err = mlx5_core_create_tir(mdev, in, inlen, inner_vxlan ? 3140fba6942fSKonstantin Belousov &priv->tirn_inner_vxlan[tt] : &priv->tirn[tt]); 3141dc7e38acSHans Petter Selasky 3142dc7e38acSHans Petter Selasky kvfree(in); 3143dc7e38acSHans Petter Selasky 3144dc7e38acSHans Petter Selasky return (err); 3145dc7e38acSHans Petter Selasky } 3146dc7e38acSHans Petter Selasky 3147dc7e38acSHans Petter Selasky static void 3148fba6942fSKonstantin Belousov mlx5e_close_tir(struct mlx5e_priv *priv, int tt, bool inner_vxlan) 3149dc7e38acSHans Petter Selasky { 3150fba6942fSKonstantin Belousov mlx5_core_destroy_tir(priv->mdev, inner_vxlan ? 3151b633e08cSHans Petter Selasky priv->tirn_inner_vxlan[tt] : priv->tirn[tt], 0); 3152dc7e38acSHans Petter Selasky } 3153dc7e38acSHans Petter Selasky 3154dc7e38acSHans Petter Selasky static int 3155e059c120SHans Petter Selasky mlx5e_open_tirs(struct mlx5e_priv *priv) 3156dc7e38acSHans Petter Selasky { 3157dc7e38acSHans Petter Selasky int err; 3158dc7e38acSHans Petter Selasky int i; 3159dc7e38acSHans Petter Selasky 3160e059c120SHans Petter Selasky for (i = 0; i != 2 * MLX5E_NUM_TT; i++) { 3161e059c120SHans Petter Selasky err = mlx5e_open_tir(priv, i / 2, (i % 2) ? true : false); 3162dc7e38acSHans Petter Selasky if (err) 3163dc7e38acSHans Petter Selasky goto err_close_tirs; 3164dc7e38acSHans Petter Selasky } 3165dc7e38acSHans Petter Selasky 3166dc7e38acSHans Petter Selasky return (0); 3167dc7e38acSHans Petter Selasky 3168dc7e38acSHans Petter Selasky err_close_tirs: 3169dc7e38acSHans Petter Selasky for (i--; i >= 0; i--) 3170e059c120SHans Petter Selasky mlx5e_close_tir(priv, i / 2, (i % 2) ? true : false); 3171dc7e38acSHans Petter Selasky 3172dc7e38acSHans Petter Selasky return (err); 3173dc7e38acSHans Petter Selasky } 3174dc7e38acSHans Petter Selasky 3175dc7e38acSHans Petter Selasky static void 3176e059c120SHans Petter Selasky mlx5e_close_tirs(struct mlx5e_priv *priv) 3177dc7e38acSHans Petter Selasky { 3178dc7e38acSHans Petter Selasky int i; 3179dc7e38acSHans Petter Selasky 3180e059c120SHans Petter Selasky for (i = 0; i != 2 * MLX5E_NUM_TT; i++) 3181e059c120SHans Petter Selasky mlx5e_close_tir(priv, i / 2, (i % 2) ? true : false); 3182dc7e38acSHans Petter Selasky } 3183dc7e38acSHans Petter Selasky 3184dc7e38acSHans Petter Selasky /* 3185dc7e38acSHans Petter Selasky * SW MTU does not include headers, 3186dc7e38acSHans Petter Selasky * HW MTU includes all headers and checksums. 3187dc7e38acSHans Petter Selasky */ 3188dc7e38acSHans Petter Selasky static int 31895dc00f00SJustin Hibbits mlx5e_set_dev_port_mtu(if_t ifp, int sw_mtu) 3190dc7e38acSHans Petter Selasky { 31915dc00f00SJustin Hibbits struct mlx5e_priv *priv = if_getsoftc(ifp); 3192dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 3193dc7e38acSHans Petter Selasky int hw_mtu; 3194dc7e38acSHans Petter Selasky int err; 3195dc7e38acSHans Petter Selasky 31961eb09ad4SHans Petter Selasky hw_mtu = MLX5E_SW2HW_MTU(sw_mtu); 31971eb09ad4SHans Petter Selasky 31981eb09ad4SHans Petter Selasky err = mlx5_set_port_mtu(mdev, hw_mtu); 31992a5ac376SHans Petter Selasky if (err) { 32006b4040d8SHans Petter Selasky mlx5_en_err(ifp, "mlx5_set_port_mtu failed setting %d, err=%d\n", 32016b4040d8SHans Petter Selasky sw_mtu, err); 3202dc7e38acSHans Petter Selasky return (err); 32032a5ac376SHans Petter Selasky } 320453d7bb46SHans Petter Selasky 32051eb09ad4SHans Petter Selasky /* Update vport context MTU */ 32061eb09ad4SHans Petter Selasky err = mlx5_set_vport_mtu(mdev, hw_mtu); 32071eb09ad4SHans Petter Selasky if (err) { 32086b4040d8SHans Petter Selasky mlx5_en_err(ifp, 32096b4040d8SHans Petter Selasky "Failed updating vport context with MTU size, err=%d\n", 32106b4040d8SHans Petter Selasky err); 32111eb09ad4SHans Petter Selasky } 32121eb09ad4SHans Petter Selasky 32135dc00f00SJustin Hibbits if_setmtu(ifp, sw_mtu); 32141eb09ad4SHans Petter Selasky 32151eb09ad4SHans Petter Selasky err = mlx5_query_vport_mtu(mdev, &hw_mtu); 32161eb09ad4SHans Petter Selasky if (err || !hw_mtu) { 32171eb09ad4SHans Petter Selasky /* fallback to port oper mtu */ 3218dc7e38acSHans Petter Selasky err = mlx5_query_port_oper_mtu(mdev, &hw_mtu); 32191eb09ad4SHans Petter Selasky } 3220431fe474SHans Petter Selasky if (err) { 32216b4040d8SHans Petter Selasky mlx5_en_err(ifp, 32226b4040d8SHans Petter Selasky "Query port MTU, after setting new MTU value, failed\n"); 322353d7bb46SHans Petter Selasky return (err); 3224431fe474SHans Petter Selasky } else if (MLX5E_HW2SW_MTU(hw_mtu) < sw_mtu) { 3225431fe474SHans Petter Selasky err = -E2BIG, 32266b4040d8SHans Petter Selasky mlx5_en_err(ifp, 32276b4040d8SHans Petter Selasky "Port MTU %d is smaller than ifp mtu %d\n", 32286b4040d8SHans Petter Selasky hw_mtu, sw_mtu); 3229431fe474SHans Petter Selasky } else if (MLX5E_HW2SW_MTU(hw_mtu) > sw_mtu) { 3230431fe474SHans Petter Selasky err = -EINVAL; 32316b4040d8SHans Petter Selasky mlx5_en_err(ifp, 32326b4040d8SHans Petter Selasky "Port MTU %d is bigger than ifp mtu %d\n", 32336b4040d8SHans Petter Selasky hw_mtu, sw_mtu); 3234dc7e38acSHans Petter Selasky } 323553d7bb46SHans Petter Selasky priv->params_ethtool.hw_mtu = hw_mtu; 323653d7bb46SHans Petter Selasky 32377272f9cdSHans Petter Selasky /* compute MSB */ 32387272f9cdSHans Petter Selasky while (hw_mtu & (hw_mtu - 1)) 32397272f9cdSHans Petter Selasky hw_mtu &= (hw_mtu - 1); 32407272f9cdSHans Petter Selasky priv->params_ethtool.hw_mtu_msb = hw_mtu; 32417272f9cdSHans Petter Selasky 3242431fe474SHans Petter Selasky return (err); 3243dc7e38acSHans Petter Selasky } 3244dc7e38acSHans Petter Selasky 3245dc7e38acSHans Petter Selasky int 32465dc00f00SJustin Hibbits mlx5e_open_locked(if_t ifp) 3247dc7e38acSHans Petter Selasky { 32485dc00f00SJustin Hibbits struct mlx5e_priv *priv = if_getsoftc(ifp); 3249dc7e38acSHans Petter Selasky int err; 3250cb4e4a6eSHans Petter Selasky u16 set_id; 3251dc7e38acSHans Petter Selasky 3252dc7e38acSHans Petter Selasky /* check if already opened */ 3253dc7e38acSHans Petter Selasky if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0) 3254dc7e38acSHans Petter Selasky return (0); 3255dc7e38acSHans Petter Selasky 3256278ce1c9SHans Petter Selasky #ifdef RSS 3257278ce1c9SHans Petter Selasky if (rss_getnumbuckets() > priv->params.num_channels) { 32586b4040d8SHans Petter Selasky mlx5_en_info(ifp, 32596b4040d8SHans Petter Selasky "NOTE: There are more RSS buckets(%u) than channels(%u) available\n", 32606b4040d8SHans Petter Selasky rss_getnumbuckets(), priv->params.num_channels); 3261278ce1c9SHans Petter Selasky } 3262278ce1c9SHans Petter Selasky #endif 3263dc7e38acSHans Petter Selasky err = mlx5e_open_tises(priv); 3264dc7e38acSHans Petter Selasky if (err) { 32656b4040d8SHans Petter Selasky mlx5_en_err(ifp, "mlx5e_open_tises failed, %d\n", err); 3266dc7e38acSHans Petter Selasky return (err); 3267dc7e38acSHans Petter Selasky } 3268cb4e4a6eSHans Petter Selasky err = mlx5_vport_alloc_q_counter(priv->mdev, 3269cb4e4a6eSHans Petter Selasky MLX5_INTERFACE_PROTOCOL_ETH, &set_id); 3270dc7e38acSHans Petter Selasky if (err) { 32716b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 32726b4040d8SHans Petter Selasky "mlx5_vport_alloc_q_counter failed: %d\n", err); 3273dc7e38acSHans Petter Selasky goto err_close_tises; 3274dc7e38acSHans Petter Selasky } 3275cb4e4a6eSHans Petter Selasky /* store counter set ID */ 3276cb4e4a6eSHans Petter Selasky priv->counter_set_id = set_id; 3277cb4e4a6eSHans Petter Selasky 3278dc7e38acSHans Petter Selasky err = mlx5e_open_channels(priv); 3279dc7e38acSHans Petter Selasky if (err) { 32806b4040d8SHans Petter Selasky mlx5_en_err(ifp, 32816b4040d8SHans Petter Selasky "mlx5e_open_channels failed, %d\n", err); 3282dc7e38acSHans Petter Selasky goto err_dalloc_q_counter; 3283dc7e38acSHans Petter Selasky } 328433a6a7a7SHans Petter Selasky err = mlx5e_activate_rqt(priv); 3285dc7e38acSHans Petter Selasky if (err) { 328633a6a7a7SHans Petter Selasky mlx5_en_err(ifp, "mlx5e_activate_rqt failed, %d\n", err); 3287dc7e38acSHans Petter Selasky goto err_close_channels; 3288dc7e38acSHans Petter Selasky } 3289e059c120SHans Petter Selasky 3290dc7e38acSHans Petter Selasky set_bit(MLX5E_STATE_OPENED, &priv->state); 3291dc7e38acSHans Petter Selasky 3292dc7e38acSHans Petter Selasky mlx5e_update_carrier(priv); 3293dc7e38acSHans Petter Selasky 3294dc7e38acSHans Petter Selasky return (0); 3295dc7e38acSHans Petter Selasky 3296dc7e38acSHans Petter Selasky err_close_channels: 3297dc7e38acSHans Petter Selasky mlx5e_close_channels(priv); 3298dc7e38acSHans Petter Selasky 3299dc7e38acSHans Petter Selasky err_dalloc_q_counter: 3300cb4e4a6eSHans Petter Selasky mlx5_vport_dealloc_q_counter(priv->mdev, 3301cb4e4a6eSHans Petter Selasky MLX5_INTERFACE_PROTOCOL_ETH, priv->counter_set_id); 3302dc7e38acSHans Petter Selasky 3303dc7e38acSHans Petter Selasky err_close_tises: 3304dc7e38acSHans Petter Selasky mlx5e_close_tises(priv); 3305dc7e38acSHans Petter Selasky 3306dc7e38acSHans Petter Selasky return (err); 3307dc7e38acSHans Petter Selasky } 3308dc7e38acSHans Petter Selasky 3309dc7e38acSHans Petter Selasky static void 3310dc7e38acSHans Petter Selasky mlx5e_open(void *arg) 3311dc7e38acSHans Petter Selasky { 3312dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg; 3313dc7e38acSHans Petter Selasky 3314dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 3315dc7e38acSHans Petter Selasky if (mlx5_set_port_status(priv->mdev, MLX5_PORT_UP)) 33166b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 33176b4040d8SHans Petter Selasky "Setting port status to up failed\n"); 3318dc7e38acSHans Petter Selasky 3319dc7e38acSHans Petter Selasky mlx5e_open_locked(priv->ifp); 33205dc00f00SJustin Hibbits if_setdrvflagbits(priv->ifp, IFF_DRV_RUNNING, 0); 3321dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 3322dc7e38acSHans Petter Selasky } 3323dc7e38acSHans Petter Selasky 3324dc7e38acSHans Petter Selasky int 33255dc00f00SJustin Hibbits mlx5e_close_locked(if_t ifp) 3326dc7e38acSHans Petter Selasky { 33275dc00f00SJustin Hibbits struct mlx5e_priv *priv = if_getsoftc(ifp); 3328dc7e38acSHans Petter Selasky 3329dc7e38acSHans Petter Selasky /* check if already closed */ 3330dc7e38acSHans Petter Selasky if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0) 3331dc7e38acSHans Petter Selasky return (0); 3332dc7e38acSHans Petter Selasky 3333dc7e38acSHans Petter Selasky clear_bit(MLX5E_STATE_OPENED, &priv->state); 3334dc7e38acSHans Petter Selasky 3335dc7e38acSHans Petter Selasky if_link_state_change(priv->ifp, LINK_STATE_DOWN); 3336e059c120SHans Petter Selasky 333733a6a7a7SHans Petter Selasky mlx5e_deactivate_rqt(priv); 3338dc7e38acSHans Petter Selasky mlx5e_close_channels(priv); 3339cb4e4a6eSHans Petter Selasky mlx5_vport_dealloc_q_counter(priv->mdev, 3340cb4e4a6eSHans Petter Selasky MLX5_INTERFACE_PROTOCOL_ETH, priv->counter_set_id); 3341dc7e38acSHans Petter Selasky mlx5e_close_tises(priv); 3342dc7e38acSHans Petter Selasky 3343dc7e38acSHans Petter Selasky return (0); 3344dc7e38acSHans Petter Selasky } 3345dc7e38acSHans Petter Selasky 3346dc7e38acSHans Petter Selasky static uint64_t 33475dc00f00SJustin Hibbits mlx5e_get_counter(if_t ifp, ift_counter cnt) 3348dc7e38acSHans Petter Selasky { 33495dc00f00SJustin Hibbits struct mlx5e_priv *priv = if_getsoftc(ifp); 3350dc7e38acSHans Petter Selasky u64 retval; 3351dc7e38acSHans Petter Selasky 3352dc7e38acSHans Petter Selasky /* PRIV_LOCK(priv); XXX not allowed */ 3353dc7e38acSHans Petter Selasky switch (cnt) { 3354dc7e38acSHans Petter Selasky case IFCOUNTER_IPACKETS: 3355dc7e38acSHans Petter Selasky retval = priv->stats.vport.rx_packets; 3356dc7e38acSHans Petter Selasky break; 3357dc7e38acSHans Petter Selasky case IFCOUNTER_IERRORS: 33580b9cdc8eSHans Petter Selasky retval = priv->stats.pport.in_range_len_errors + 33598b483546SHans Petter Selasky priv->stats.pport.out_of_range_len + 33608b483546SHans Petter Selasky priv->stats.pport.too_long_errors + 33610b9cdc8eSHans Petter Selasky priv->stats.pport.check_seq_err + 33620b9cdc8eSHans Petter Selasky priv->stats.pport.alignment_err; 3363dc7e38acSHans Petter Selasky break; 3364ee090799SHans Petter Selasky case IFCOUNTER_IQDROPS: 33650b9cdc8eSHans Petter Selasky retval = priv->stats.vport.rx_out_of_buffer; 3366ee090799SHans Petter Selasky break; 3367dc7e38acSHans Petter Selasky case IFCOUNTER_OPACKETS: 3368dc7e38acSHans Petter Selasky retval = priv->stats.vport.tx_packets; 3369dc7e38acSHans Petter Selasky break; 3370dc7e38acSHans Petter Selasky case IFCOUNTER_OERRORS: 33710b9cdc8eSHans Petter Selasky retval = priv->stats.port_stats_debug.out_discards; 3372dc7e38acSHans Petter Selasky break; 3373dc7e38acSHans Petter Selasky case IFCOUNTER_IBYTES: 3374dc7e38acSHans Petter Selasky retval = priv->stats.vport.rx_bytes; 3375dc7e38acSHans Petter Selasky break; 3376dc7e38acSHans Petter Selasky case IFCOUNTER_OBYTES: 3377dc7e38acSHans Petter Selasky retval = priv->stats.vport.tx_bytes; 3378dc7e38acSHans Petter Selasky break; 3379dc7e38acSHans Petter Selasky case IFCOUNTER_IMCASTS: 3380dc7e38acSHans Petter Selasky retval = priv->stats.vport.rx_multicast_packets; 3381dc7e38acSHans Petter Selasky break; 3382dc7e38acSHans Petter Selasky case IFCOUNTER_OMCASTS: 3383dc7e38acSHans Petter Selasky retval = priv->stats.vport.tx_multicast_packets; 3384dc7e38acSHans Petter Selasky break; 3385dc7e38acSHans Petter Selasky case IFCOUNTER_OQDROPS: 3386dc7e38acSHans Petter Selasky retval = priv->stats.vport.tx_queue_dropped; 3387dc7e38acSHans Petter Selasky break; 33888b483546SHans Petter Selasky case IFCOUNTER_COLLISIONS: 33898b483546SHans Petter Selasky retval = priv->stats.pport.collisions; 33908b483546SHans Petter Selasky break; 3391dc7e38acSHans Petter Selasky default: 3392dc7e38acSHans Petter Selasky retval = if_get_counter_default(ifp, cnt); 3393dc7e38acSHans Petter Selasky break; 3394dc7e38acSHans Petter Selasky } 3395dc7e38acSHans Petter Selasky /* PRIV_UNLOCK(priv); XXX not allowed */ 3396dc7e38acSHans Petter Selasky return (retval); 3397dc7e38acSHans Petter Selasky } 3398dc7e38acSHans Petter Selasky 3399dc7e38acSHans Petter Selasky static void 34005dc00f00SJustin Hibbits mlx5e_set_rx_mode(if_t ifp) 3401dc7e38acSHans Petter Selasky { 34025dc00f00SJustin Hibbits struct mlx5e_priv *priv = if_getsoftc(ifp); 3403dc7e38acSHans Petter Selasky 340417778156SHans Petter Selasky queue_work(priv->wq, &priv->set_rx_mode_work); 3405dc7e38acSHans Petter Selasky } 3406dc7e38acSHans Petter Selasky 3407cca0dc49SKonstantin Belousov static bool 3408cca0dc49SKonstantin Belousov mlx5e_is_ipsec_capable(struct mlx5_core_dev *mdev) 3409cca0dc49SKonstantin Belousov { 3410cca0dc49SKonstantin Belousov #ifdef IPSEC_OFFLOAD 3411cca0dc49SKonstantin Belousov if ((mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_PACKET_OFFLOAD) != 0) 3412cca0dc49SKonstantin Belousov return (true); 3413cca0dc49SKonstantin Belousov #endif 3414cca0dc49SKonstantin Belousov return (false); 3415cca0dc49SKonstantin Belousov } 3416cca0dc49SKonstantin Belousov 3417cca0dc49SKonstantin Belousov static bool 3418cca0dc49SKonstantin Belousov mlx5e_is_ratelimit_capable(struct mlx5_core_dev *mdev) 3419cca0dc49SKonstantin Belousov { 3420cca0dc49SKonstantin Belousov #ifdef RATELIMIT 3421cca0dc49SKonstantin Belousov if (MLX5_CAP_GEN(mdev, qos) && 3422cca0dc49SKonstantin Belousov MLX5_CAP_QOS(mdev, packet_pacing)) 3423cca0dc49SKonstantin Belousov return (true); 3424cca0dc49SKonstantin Belousov #endif 3425cca0dc49SKonstantin Belousov return (false); 3426cca0dc49SKonstantin Belousov } 3427cca0dc49SKonstantin Belousov 3428cca0dc49SKonstantin Belousov static bool 3429cca0dc49SKonstantin Belousov mlx5e_is_tlstx_capable(struct mlx5_core_dev *mdev) 3430cca0dc49SKonstantin Belousov { 3431cca0dc49SKonstantin Belousov #ifdef KERN_TLS 3432cca0dc49SKonstantin Belousov if (MLX5_CAP_GEN(mdev, tls_tx) != 0 && 3433cca0dc49SKonstantin Belousov MLX5_CAP_GEN(mdev, log_max_dek) != 0) 3434cca0dc49SKonstantin Belousov return (true); 3435cca0dc49SKonstantin Belousov #endif 3436cca0dc49SKonstantin Belousov return (false); 3437cca0dc49SKonstantin Belousov } 3438cca0dc49SKonstantin Belousov 3439cca0dc49SKonstantin Belousov static bool 3440cca0dc49SKonstantin Belousov mlx5e_is_tlsrx_capable(struct mlx5_core_dev *mdev) 3441cca0dc49SKonstantin Belousov { 3442cca0dc49SKonstantin Belousov #ifdef KERN_TLS 3443cca0dc49SKonstantin Belousov if (MLX5_CAP_GEN(mdev, tls_rx) != 0 && 3444cca0dc49SKonstantin Belousov MLX5_CAP_GEN(mdev, log_max_dek) != 0 && 3445cca0dc49SKonstantin Belousov MLX5_CAP_FLOWTABLE_NIC_RX(mdev, 3446cca0dc49SKonstantin Belousov ft_field_support.outer_ip_version) != 0) 3447cca0dc49SKonstantin Belousov return (true); 3448cca0dc49SKonstantin Belousov #endif 3449cca0dc49SKonstantin Belousov return (false); 3450cca0dc49SKonstantin Belousov } 3451cca0dc49SKonstantin Belousov 3452dc7e38acSHans Petter Selasky static int 34535dc00f00SJustin Hibbits mlx5e_ioctl(if_t ifp, u_long command, caddr_t data) 3454dc7e38acSHans Petter Selasky { 3455dc7e38acSHans Petter Selasky struct mlx5e_priv *priv; 3456dc7e38acSHans Petter Selasky struct ifreq *ifr; 34572ea114b3SKonstantin Belousov struct ifdownreason *ifdr; 3458dc7e38acSHans Petter Selasky struct ifi2creq i2c; 3459a00718e1SHans Petter Selasky struct ifrsskey *ifrk; 3460a00718e1SHans Petter Selasky struct ifrsshash *ifrh; 3461d5d69490SHans Petter Selasky struct siocsifcapnv_driver_data *drv_ioctl_data, drv_ioctl_data_d; 3462dc7e38acSHans Petter Selasky int error = 0; 3463d5d69490SHans Petter Selasky int mask; 3464dc7e38acSHans Petter Selasky int size_read = 0; 3465ecb4fcc4SHans Petter Selasky int module_status; 3466dc7e38acSHans Petter Selasky int module_num; 3467dc7e38acSHans Petter Selasky int max_mtu; 34684fbd91a5SHans Petter Selasky uint8_t read_addr; 3469dc7e38acSHans Petter Selasky 34705dc00f00SJustin Hibbits priv = if_getsoftc(ifp); 3471dc7e38acSHans Petter Selasky 3472dc7e38acSHans Petter Selasky /* check if detaching */ 3473dc7e38acSHans Petter Selasky if (priv == NULL || priv->gone != 0) 3474dc7e38acSHans Petter Selasky return (ENXIO); 3475dc7e38acSHans Petter Selasky 3476dc7e38acSHans Petter Selasky switch (command) { 3477dc7e38acSHans Petter Selasky case SIOCSIFMTU: 3478dc7e38acSHans Petter Selasky ifr = (struct ifreq *)data; 3479dc7e38acSHans Petter Selasky 3480dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 3481dc7e38acSHans Petter Selasky mlx5_query_port_max_mtu(priv->mdev, &max_mtu); 3482dc7e38acSHans Petter Selasky 3483dc7e38acSHans Petter Selasky if (ifr->ifr_mtu >= MLX5E_MTU_MIN && 3484dc7e38acSHans Petter Selasky ifr->ifr_mtu <= MIN(MLX5E_MTU_MAX, max_mtu)) { 3485dc7e38acSHans Petter Selasky int was_opened; 3486dc7e38acSHans Petter Selasky 3487dc7e38acSHans Petter Selasky was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); 3488dc7e38acSHans Petter Selasky if (was_opened) 3489dc7e38acSHans Petter Selasky mlx5e_close_locked(ifp); 3490dc7e38acSHans Petter Selasky 3491dc7e38acSHans Petter Selasky /* set new MTU */ 3492dc7e38acSHans Petter Selasky mlx5e_set_dev_port_mtu(ifp, ifr->ifr_mtu); 3493dc7e38acSHans Petter Selasky 3494dc7e38acSHans Petter Selasky if (was_opened) 3495dc7e38acSHans Petter Selasky mlx5e_open_locked(ifp); 3496dc7e38acSHans Petter Selasky } else { 3497dc7e38acSHans Petter Selasky error = EINVAL; 34986b4040d8SHans Petter Selasky mlx5_en_err(ifp, 34996b4040d8SHans Petter Selasky "Invalid MTU value. Min val: %d, Max val: %d\n", 3500dc7e38acSHans Petter Selasky MLX5E_MTU_MIN, MIN(MLX5E_MTU_MAX, max_mtu)); 3501dc7e38acSHans Petter Selasky } 3502dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 3503dc7e38acSHans Petter Selasky break; 3504dc7e38acSHans Petter Selasky case SIOCSIFFLAGS: 35055dc00f00SJustin Hibbits if ((if_getflags(ifp) & IFF_UP) && 35065dc00f00SJustin Hibbits (if_getdrvflags(ifp) & IFF_DRV_RUNNING)) { 3507dc7e38acSHans Petter Selasky mlx5e_set_rx_mode(ifp); 3508dc7e38acSHans Petter Selasky break; 3509dc7e38acSHans Petter Selasky } 3510dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 35115dc00f00SJustin Hibbits if (if_getflags(ifp) & IFF_UP) { 35125dc00f00SJustin Hibbits if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) { 3513dc7e38acSHans Petter Selasky if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0) 3514dc7e38acSHans Petter Selasky mlx5e_open_locked(ifp); 35155dc00f00SJustin Hibbits if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0); 3516dc7e38acSHans Petter Selasky mlx5_set_port_status(priv->mdev, MLX5_PORT_UP); 3517dc7e38acSHans Petter Selasky } 3518dc7e38acSHans Petter Selasky } else { 35195dc00f00SJustin Hibbits if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { 3520dc7e38acSHans Petter Selasky mlx5_set_port_status(priv->mdev, 3521dc7e38acSHans Petter Selasky MLX5_PORT_DOWN); 3522dc7e38acSHans Petter Selasky if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0) 3523dc7e38acSHans Petter Selasky mlx5e_close_locked(ifp); 3524dc7e38acSHans Petter Selasky mlx5e_update_carrier(priv); 35255dc00f00SJustin Hibbits if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING); 3526dc7e38acSHans Petter Selasky } 3527dc7e38acSHans Petter Selasky } 3528dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 3529dc7e38acSHans Petter Selasky break; 3530dc7e38acSHans Petter Selasky case SIOCADDMULTI: 3531dc7e38acSHans Petter Selasky case SIOCDELMULTI: 3532dc7e38acSHans Petter Selasky mlx5e_set_rx_mode(ifp); 3533dc7e38acSHans Petter Selasky break; 3534dc7e38acSHans Petter Selasky case SIOCSIFMEDIA: 3535dc7e38acSHans Petter Selasky case SIOCGIFMEDIA: 3536dc7e38acSHans Petter Selasky case SIOCGIFXMEDIA: 3537dc7e38acSHans Petter Selasky ifr = (struct ifreq *)data; 3538dc7e38acSHans Petter Selasky error = ifmedia_ioctl(ifp, ifr, &priv->media, command); 3539dc7e38acSHans Petter Selasky break; 3540f7ea1995SKonstantin Belousov case SIOCGIFCAPNV: 3541f7ea1995SKonstantin Belousov error = 0; 3542f7ea1995SKonstantin Belousov break; 3543dc7e38acSHans Petter Selasky case SIOCSIFCAP: 3544dc7e38acSHans Petter Selasky ifr = (struct ifreq *)data; 3545f7ea1995SKonstantin Belousov drv_ioctl_data = &drv_ioctl_data_d; 3546f7ea1995SKonstantin Belousov drv_ioctl_data->reqcap = ifr->ifr_reqcap; 3547dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 35485dc00f00SJustin Hibbits drv_ioctl_data->reqcap2 = if_getcapenable2(ifp); 3549f7ea1995SKonstantin Belousov drv_ioctl_data->nvcap = NULL; 3550f7ea1995SKonstantin Belousov goto siocsifcap_driver; 3551f7ea1995SKonstantin Belousov case SIOCSIFCAPNV: 3552f7ea1995SKonstantin Belousov drv_ioctl_data = (struct siocsifcapnv_driver_data *)data; 3553f7ea1995SKonstantin Belousov PRIV_LOCK(priv); 3554f7ea1995SKonstantin Belousov siocsifcap_driver: 3555*4cc5d081SKonstantin Belousov if (!mlx5e_is_tlstx_capable(priv->mdev)) { 3556*4cc5d081SKonstantin Belousov drv_ioctl_data->reqcap &= ~(IFCAP_TXTLS4 | 3557*4cc5d081SKonstantin Belousov IFCAP_TXTLS6); 3558*4cc5d081SKonstantin Belousov } 3559*4cc5d081SKonstantin Belousov if (!mlx5e_is_tlsrx_capable(priv->mdev)) { 3560*4cc5d081SKonstantin Belousov drv_ioctl_data->reqcap &= ~( 3561*4cc5d081SKonstantin Belousov IFCAP2_BIT(IFCAP2_RXTLS4) | 3562*4cc5d081SKonstantin Belousov IFCAP2_BIT(IFCAP2_RXTLS6)); 3563*4cc5d081SKonstantin Belousov } 3564*4cc5d081SKonstantin Belousov if (!mlx5e_is_ipsec_capable(priv->mdev)) { 3565*4cc5d081SKonstantin Belousov drv_ioctl_data->reqcap &= 3566*4cc5d081SKonstantin Belousov ~IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD); 3567*4cc5d081SKonstantin Belousov } 3568*4cc5d081SKonstantin Belousov if (!mlx5e_is_ratelimit_capable(priv->mdev)) { 3569*4cc5d081SKonstantin Belousov drv_ioctl_data->reqcap &= ~(IFCAP_TXTLS_RTLMT | 3570*4cc5d081SKonstantin Belousov IFCAP_TXRTLMT); 3571*4cc5d081SKonstantin Belousov } 3572*4cc5d081SKonstantin Belousov 35735dc00f00SJustin Hibbits mask = drv_ioctl_data->reqcap ^ if_getcapenable(ifp); 3574dc7e38acSHans Petter Selasky 3575dc7e38acSHans Petter Selasky if (mask & IFCAP_TXCSUM) { 35765dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_TXCSUM); 35775dc00f00SJustin Hibbits if_togglehwassist(ifp, (CSUM_TCP | CSUM_UDP | CSUM_IP)); 3578dc7e38acSHans Petter Selasky 35795dc00f00SJustin Hibbits if (IFCAP_TSO4 & if_getcapenable(ifp) && 35805dc00f00SJustin Hibbits !(IFCAP_TXCSUM & if_getcapenable(ifp))) { 3581cbb9ccf7SRyan Moeller mask &= ~IFCAP_TSO4; 35825dc00f00SJustin Hibbits if_setcapenablebit(ifp, 0, IFCAP_TSO4); 35835dc00f00SJustin Hibbits if_sethwassistbits(ifp, 0, CSUM_IP_TSO); 35846b4040d8SHans Petter Selasky mlx5_en_err(ifp, 3585dc7e38acSHans Petter Selasky "tso4 disabled due to -txcsum.\n"); 3586dc7e38acSHans Petter Selasky } 3587dc7e38acSHans Petter Selasky } 3588dc7e38acSHans Petter Selasky if (mask & IFCAP_TXCSUM_IPV6) { 35895dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_TXCSUM_IPV6); 35905dc00f00SJustin Hibbits if_togglehwassist(ifp, (CSUM_UDP_IPV6 | CSUM_TCP_IPV6)); 3591dc7e38acSHans Petter Selasky 35925dc00f00SJustin Hibbits if (IFCAP_TSO6 & if_getcapenable(ifp) && 35935dc00f00SJustin Hibbits !(IFCAP_TXCSUM_IPV6 & if_getcapenable(ifp))) { 3594cbb9ccf7SRyan Moeller mask &= ~IFCAP_TSO6; 35955dc00f00SJustin Hibbits if_setcapenablebit(ifp, 0, IFCAP_TSO6); 35965dc00f00SJustin Hibbits if_sethwassistbits(ifp, 0, CSUM_IP6_TSO); 35976b4040d8SHans Petter Selasky mlx5_en_err(ifp, 3598dc7e38acSHans Petter Selasky "tso6 disabled due to -txcsum6.\n"); 3599dc7e38acSHans Petter Selasky } 3600dc7e38acSHans Petter Selasky } 36013f43ada9SGleb Smirnoff if (mask & IFCAP_MEXTPG) 36025dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_MEXTPG); 36037272f9cdSHans Petter Selasky if (mask & IFCAP_TXTLS4) 36045dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_TXTLS4); 36057272f9cdSHans Petter Selasky if (mask & IFCAP_TXTLS6) 36065dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_TXTLS6); 3607521eac97SJohn Baldwin #ifdef RATELIMIT 3608521eac97SJohn Baldwin if (mask & IFCAP_TXTLS_RTLMT) 36095dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_TXTLS_RTLMT); 3610521eac97SJohn Baldwin #endif 3611dc7e38acSHans Petter Selasky if (mask & IFCAP_RXCSUM) 36125dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_RXCSUM); 3613dc7e38acSHans Petter Selasky if (mask & IFCAP_RXCSUM_IPV6) 36145dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_RXCSUM_IPV6); 3615dc7e38acSHans Petter Selasky if (mask & IFCAP_TSO4) { 36165dc00f00SJustin Hibbits if (!(IFCAP_TSO4 & if_getcapenable(ifp)) && 36175dc00f00SJustin Hibbits !(IFCAP_TXCSUM & if_getcapenable(ifp))) { 36186b4040d8SHans Petter Selasky mlx5_en_err(ifp, "enable txcsum first.\n"); 3619dc7e38acSHans Petter Selasky error = EAGAIN; 3620dc7e38acSHans Petter Selasky goto out; 3621dc7e38acSHans Petter Selasky } 36225dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_TSO4); 36235dc00f00SJustin Hibbits if_togglehwassist(ifp, CSUM_IP_TSO); 3624dc7e38acSHans Petter Selasky } 3625dc7e38acSHans Petter Selasky if (mask & IFCAP_TSO6) { 36265dc00f00SJustin Hibbits if (!(IFCAP_TSO6 & if_getcapenable(ifp)) && 36275dc00f00SJustin Hibbits !(IFCAP_TXCSUM_IPV6 & if_getcapenable(ifp))) { 36286b4040d8SHans Petter Selasky mlx5_en_err(ifp, "enable txcsum6 first.\n"); 3629dc7e38acSHans Petter Selasky error = EAGAIN; 3630dc7e38acSHans Petter Selasky goto out; 3631dc7e38acSHans Petter Selasky } 36325dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_TSO6); 36335dc00f00SJustin Hibbits if_togglehwassist(ifp, CSUM_IP6_TSO); 3634dc7e38acSHans Petter Selasky } 3635064009e7SHans Petter Selasky if (mask & IFCAP_VLAN_HWTSO) 36365dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_VLAN_HWTSO); 3637dc7e38acSHans Petter Selasky if (mask & IFCAP_VLAN_HWFILTER) { 36385dc00f00SJustin Hibbits if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER) 3639dc7e38acSHans Petter Selasky mlx5e_disable_vlan_filter(priv); 3640dc7e38acSHans Petter Selasky else 3641dc7e38acSHans Petter Selasky mlx5e_enable_vlan_filter(priv); 3642dc7e38acSHans Petter Selasky 36435dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_VLAN_HWFILTER); 3644dc7e38acSHans Petter Selasky } 3645dc7e38acSHans Petter Selasky if (mask & IFCAP_VLAN_HWTAGGING) 36465dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_VLAN_HWTAGGING); 3647dc7e38acSHans Petter Selasky if (mask & IFCAP_WOL_MAGIC) 36485dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_WOL_MAGIC); 3649bf202a8dSKonstantin Belousov if (mask & IFCAP_VXLAN_HWCSUM) { 3650e059c120SHans Petter Selasky const bool was_enabled = 36515dc00f00SJustin Hibbits (if_getcapenable(ifp) & IFCAP_VXLAN_HWCSUM) != 0; 3652e059c120SHans Petter Selasky if (was_enabled) 3653e059c120SHans Petter Selasky mlx5e_del_all_vxlan_rules(priv); 36545dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_VXLAN_HWCSUM); 36555dc00f00SJustin Hibbits if_togglehwassist(ifp, CSUM_INNER_IP | CSUM_INNER_IP_UDP | 3656bf202a8dSKonstantin Belousov CSUM_INNER_IP_TCP | CSUM_INNER_IP6_UDP | 36575dc00f00SJustin Hibbits CSUM_INNER_IP6_TCP); 3658e059c120SHans Petter Selasky if (!was_enabled) { 3659e059c120SHans Petter Selasky int err = mlx5e_add_all_vxlan_rules(priv); 3660e059c120SHans Petter Selasky if (err != 0) { 3661e059c120SHans Petter Selasky mlx5_en_err(ifp, 3662e059c120SHans Petter Selasky "mlx5e_add_all_vxlan_rules() failed, %d (ignored)\n", err); 3663e059c120SHans Petter Selasky } 3664e059c120SHans Petter Selasky } 3665bf202a8dSKonstantin Belousov } 3666bf202a8dSKonstantin Belousov if (mask & IFCAP_VXLAN_HWTSO) { 36675dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_VXLAN_HWTSO); 36685dc00f00SJustin Hibbits if_togglehwassist(ifp, CSUM_INNER_IP_TSO | 36695dc00f00SJustin Hibbits CSUM_INNER_IP6_TSO); 3670bf202a8dSKonstantin Belousov } 3671dc7e38acSHans Petter Selasky 3672dc7e38acSHans Petter Selasky VLAN_CAPABILITIES(ifp); 3673dc7e38acSHans Petter Selasky /* turn off LRO means also turn of HW LRO - if it's on */ 3674dc7e38acSHans Petter Selasky if (mask & IFCAP_LRO) { 3675dc7e38acSHans Petter Selasky int was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state); 3676dc7e38acSHans Petter Selasky bool need_restart = false; 3677dc7e38acSHans Petter Selasky 36785dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_LRO); 367971defedaSSlava Shwartsman 368071defedaSSlava Shwartsman /* figure out if updating HW LRO is needed */ 36815dc00f00SJustin Hibbits if (!(if_getcapenable(ifp) & IFCAP_LRO)) { 3682dc7e38acSHans Petter Selasky if (priv->params.hw_lro_en) { 3683dc7e38acSHans Petter Selasky priv->params.hw_lro_en = false; 3684dc7e38acSHans Petter Selasky need_restart = true; 368571defedaSSlava Shwartsman } 368671defedaSSlava Shwartsman } else { 368771defedaSSlava Shwartsman if (priv->params.hw_lro_en == false && 368871defedaSSlava Shwartsman priv->params_ethtool.hw_lro != 0) { 368971defedaSSlava Shwartsman priv->params.hw_lro_en = true; 369071defedaSSlava Shwartsman need_restart = true; 3691dc7e38acSHans Petter Selasky } 3692dc7e38acSHans Petter Selasky } 3693dc7e38acSHans Petter Selasky if (was_opened && need_restart) { 3694dc7e38acSHans Petter Selasky mlx5e_close_locked(ifp); 3695dc7e38acSHans Petter Selasky mlx5e_open_locked(ifp); 3696dc7e38acSHans Petter Selasky } 3697dc7e38acSHans Petter Selasky } 3698ef23f141SKonstantin Belousov if (mask & IFCAP_HWRXTSTMP) { 36995dc00f00SJustin Hibbits if_togglecapenable(ifp, IFCAP_HWRXTSTMP); 37005dc00f00SJustin Hibbits if (if_getcapenable(ifp) & IFCAP_HWRXTSTMP) { 3701ef23f141SKonstantin Belousov if (priv->clbr_done == 0) 3702ef23f141SKonstantin Belousov mlx5e_reset_calibration_callout(priv); 3703ef23f141SKonstantin Belousov } else { 3704ef23f141SKonstantin Belousov callout_drain(&priv->tstmp_clbr); 3705ef23f141SKonstantin Belousov priv->clbr_done = 0; 3706ef23f141SKonstantin Belousov } 3707ef23f141SKonstantin Belousov } 37085dc00f00SJustin Hibbits mask = drv_ioctl_data->reqcap2 ^ if_getcapenable2(ifp); 370901143ba1SKonstantin Belousov if ((mask & IFCAP2_BIT(IFCAP2_RXTLS4)) != 0) 37105dc00f00SJustin Hibbits if_togglecapenable2(ifp, IFCAP2_BIT(IFCAP2_RXTLS4)); 371101143ba1SKonstantin Belousov if ((mask & IFCAP2_BIT(IFCAP2_RXTLS6)) != 0) 37125dc00f00SJustin Hibbits if_togglecapenable2(ifp, IFCAP2_BIT(IFCAP2_RXTLS6)); 3713e23731dbSKonstantin Belousov #ifdef IPSEC_OFFLOAD 3714e23731dbSKonstantin Belousov if ((mask & IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD)) != 0) { 3715e23731dbSKonstantin Belousov bool was_enabled = (if_getcapenable2(ifp) & 3716e23731dbSKonstantin Belousov IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD)) != 0; 3717e23731dbSKonstantin Belousov mlx5e_close_locked(ifp); 3718e23731dbSKonstantin Belousov if (was_enabled) 3719e23731dbSKonstantin Belousov ipsec_accel_on_ifdown(priv->ifp); 3720e23731dbSKonstantin Belousov if_togglecapenable2(ifp, 3721e23731dbSKonstantin Belousov IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD)); 3722e23731dbSKonstantin Belousov mlx5e_open_locked(ifp); 3723e23731dbSKonstantin Belousov } 3724e23731dbSKonstantin Belousov #endif 3725dc7e38acSHans Petter Selasky out: 3726dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 3727dc7e38acSHans Petter Selasky break; 3728dc7e38acSHans Petter Selasky 3729dc7e38acSHans Petter Selasky case SIOCGI2C: 3730dc7e38acSHans Petter Selasky ifr = (struct ifreq *)data; 3731dc7e38acSHans Petter Selasky 3732bb3853c6SHans Petter Selasky /* 3733bb3853c6SHans Petter Selasky * Copy from the user-space address ifr_data to the 3734bb3853c6SHans Petter Selasky * kernel-space address i2c 3735bb3853c6SHans Petter Selasky */ 3736541d96aaSBrooks Davis error = copyin(ifr_data_get_ptr(ifr), &i2c, sizeof(i2c)); 3737dc7e38acSHans Petter Selasky if (error) 3738dc7e38acSHans Petter Selasky break; 3739dc7e38acSHans Petter Selasky 3740dc7e38acSHans Petter Selasky if (i2c.len > sizeof(i2c.data)) { 3741dc7e38acSHans Petter Selasky error = EINVAL; 3742dc7e38acSHans Petter Selasky break; 3743dc7e38acSHans Petter Selasky } 3744dc7e38acSHans Petter Selasky 3745dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 3746dc7e38acSHans Petter Selasky /* Get module_num which is required for the query_eeprom */ 3747dc7e38acSHans Petter Selasky error = mlx5_query_module_num(priv->mdev, &module_num); 3748dc7e38acSHans Petter Selasky if (error) { 37496b4040d8SHans Petter Selasky mlx5_en_err(ifp, 37506b4040d8SHans Petter Selasky "Query module num failed, eeprom reading is not supported\n"); 375183c5d190SHans Petter Selasky error = EINVAL; 3752dc7e38acSHans Petter Selasky goto err_i2c; 3753dc7e38acSHans Petter Selasky } 375421dd6527SHans Petter Selasky /* Check if module is present before doing an access */ 3755ecb4fcc4SHans Petter Selasky module_status = mlx5_query_module_status(priv->mdev, module_num); 3756111b57c3SHans Petter Selasky if (module_status != MLX5_MODULE_STATUS_PLUGGED_ENABLED) { 37572204a482SKonstantin Belousov if (bootverbose) 3758c097967bSKonstantin Belousov mlx5_en_err(ifp, 37592204a482SKonstantin Belousov "Query module %d status: not plugged (%d), " 37602204a482SKonstantin Belousov "eeprom reading is not supported\n", 3761c097967bSKonstantin Belousov module_num, module_status); 376221dd6527SHans Petter Selasky error = EINVAL; 376321dd6527SHans Petter Selasky goto err_i2c; 376421dd6527SHans Petter Selasky } 3765dc7e38acSHans Petter Selasky /* 37664fbd91a5SHans Petter Selasky * Currently 0XA0 and 0xA2 are the only addresses permitted. 37674fbd91a5SHans Petter Selasky * The internal conversion is as follows: 3768dc7e38acSHans Petter Selasky */ 37694fbd91a5SHans Petter Selasky if (i2c.dev_addr == 0xA0) 3770048ddb58SHans Petter Selasky read_addr = MLX5_I2C_ADDR_LOW; 37714fbd91a5SHans Petter Selasky else if (i2c.dev_addr == 0xA2) 3772048ddb58SHans Petter Selasky read_addr = MLX5_I2C_ADDR_HIGH; 37734fbd91a5SHans Petter Selasky else { 37746b4040d8SHans Petter Selasky mlx5_en_err(ifp, 37756b4040d8SHans Petter Selasky "Query eeprom failed, Invalid Address: %X\n", 37766b4040d8SHans Petter Selasky i2c.dev_addr); 37774fbd91a5SHans Petter Selasky error = EINVAL; 37784fbd91a5SHans Petter Selasky goto err_i2c; 37794fbd91a5SHans Petter Selasky } 3780dc7e38acSHans Petter Selasky error = mlx5_query_eeprom(priv->mdev, 3781048ddb58SHans Petter Selasky read_addr, MLX5_EEPROM_LOW_PAGE, 3782dc7e38acSHans Petter Selasky (uint32_t)i2c.offset, (uint32_t)i2c.len, module_num, 3783dc7e38acSHans Petter Selasky (uint32_t *)i2c.data, &size_read); 3784dc7e38acSHans Petter Selasky if (error) { 37856b4040d8SHans Petter Selasky mlx5_en_err(ifp, 37866b4040d8SHans Petter Selasky "Query eeprom failed, eeprom reading is not supported\n"); 378783c5d190SHans Petter Selasky error = EINVAL; 3788dc7e38acSHans Petter Selasky goto err_i2c; 3789dc7e38acSHans Petter Selasky } 3790dc7e38acSHans Petter Selasky 3791dc7e38acSHans Petter Selasky if (i2c.len > MLX5_EEPROM_MAX_BYTES) { 3792dc7e38acSHans Petter Selasky error = mlx5_query_eeprom(priv->mdev, 3793048ddb58SHans Petter Selasky read_addr, MLX5_EEPROM_LOW_PAGE, 3794dc7e38acSHans Petter Selasky (uint32_t)(i2c.offset + size_read), 3795dc7e38acSHans Petter Selasky (uint32_t)(i2c.len - size_read), module_num, 3796dc7e38acSHans Petter Selasky (uint32_t *)(i2c.data + size_read), &size_read); 3797dc7e38acSHans Petter Selasky } 3798dc7e38acSHans Petter Selasky if (error) { 37996b4040d8SHans Petter Selasky mlx5_en_err(ifp, 38006b4040d8SHans Petter Selasky "Query eeprom failed, eeprom reading is not supported\n"); 380183c5d190SHans Petter Selasky error = EINVAL; 3802dc7e38acSHans Petter Selasky goto err_i2c; 3803dc7e38acSHans Petter Selasky } 3804dc7e38acSHans Petter Selasky 3805541d96aaSBrooks Davis error = copyout(&i2c, ifr_data_get_ptr(ifr), sizeof(i2c)); 3806dc7e38acSHans Petter Selasky err_i2c: 3807dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 3808dc7e38acSHans Petter Selasky break; 38092ea114b3SKonstantin Belousov case SIOCGIFDOWNREASON: 38102ea114b3SKonstantin Belousov ifdr = (struct ifdownreason *)data; 38112ea114b3SKonstantin Belousov bzero(ifdr->ifdr_msg, sizeof(ifdr->ifdr_msg)); 38122ea114b3SKonstantin Belousov PRIV_LOCK(priv); 38132ea114b3SKonstantin Belousov error = -mlx5_query_pddr_troubleshooting_info(priv->mdev, NULL, 38142ea114b3SKonstantin Belousov ifdr->ifdr_msg, sizeof(ifdr->ifdr_msg)); 38152ea114b3SKonstantin Belousov PRIV_UNLOCK(priv); 38162ea114b3SKonstantin Belousov if (error == 0) 38172ea114b3SKonstantin Belousov ifdr->ifdr_reason = IFDR_REASON_MSG; 38182ea114b3SKonstantin Belousov break; 3819dc7e38acSHans Petter Selasky 3820a00718e1SHans Petter Selasky case SIOCGIFRSSKEY: 3821a00718e1SHans Petter Selasky ifrk = (struct ifrsskey *)data; 3822a00718e1SHans Petter Selasky ifrk->ifrk_func = RSS_FUNC_TOEPLITZ; 3823a00718e1SHans Petter Selasky ifrk->ifrk_keylen = MLX5E_RSS_KEY_SIZE; 3824a00718e1SHans Petter Selasky CTASSERT(sizeof(ifrk->ifrk_key) >= MLX5E_RSS_KEY_SIZE); 3825a00718e1SHans Petter Selasky mlx5e_get_rss_key(ifrk->ifrk_key); 3826a00718e1SHans Petter Selasky break; 3827a00718e1SHans Petter Selasky 3828a00718e1SHans Petter Selasky case SIOCGIFRSSHASH: 3829a00718e1SHans Petter Selasky ifrh = (struct ifrsshash *)data; 3830a00718e1SHans Petter Selasky ifrh->ifrh_func = RSS_FUNC_TOEPLITZ; 3831a00718e1SHans Petter Selasky ifrh->ifrh_types = 3832a00718e1SHans Petter Selasky RSS_TYPE_IPV4 | 3833a00718e1SHans Petter Selasky RSS_TYPE_TCP_IPV4 | 3834a00718e1SHans Petter Selasky RSS_TYPE_UDP_IPV4 | 3835a00718e1SHans Petter Selasky RSS_TYPE_IPV6 | 3836a00718e1SHans Petter Selasky RSS_TYPE_TCP_IPV6 | 3837a00718e1SHans Petter Selasky RSS_TYPE_UDP_IPV6; 3838a00718e1SHans Petter Selasky break; 3839a00718e1SHans Petter Selasky 3840dc7e38acSHans Petter Selasky default: 3841dc7e38acSHans Petter Selasky error = ether_ioctl(ifp, command, data); 3842dc7e38acSHans Petter Selasky break; 3843dc7e38acSHans Petter Selasky } 3844dc7e38acSHans Petter Selasky return (error); 3845dc7e38acSHans Petter Selasky } 3846dc7e38acSHans Petter Selasky 3847dc7e38acSHans Petter Selasky static int 3848dc7e38acSHans Petter Selasky mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev) 3849dc7e38acSHans Petter Selasky { 3850dc7e38acSHans Petter Selasky /* 3851dc7e38acSHans Petter Selasky * TODO: uncoment once FW really sets all these bits if 3852dc7e38acSHans Petter Selasky * (!mdev->caps.eth.rss_ind_tbl_cap || !mdev->caps.eth.csum_cap || 3853dc7e38acSHans Petter Selasky * !mdev->caps.eth.max_lso_cap || !mdev->caps.eth.vlan_cap || 3854dc7e38acSHans Petter Selasky * !(mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_SCQE_BRK_MOD)) return 3855dc7e38acSHans Petter Selasky * -ENOTSUPP; 3856dc7e38acSHans Petter Selasky */ 3857dc7e38acSHans Petter Selasky 3858dc7e38acSHans Petter Selasky /* TODO: add more must-to-have features */ 3859dc7e38acSHans Petter Selasky 3860f5344e83SHans Petter Selasky if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH) 3861f5344e83SHans Petter Selasky return (-ENODEV); 3862f5344e83SHans Petter Selasky 3863dc7e38acSHans Petter Selasky return (0); 3864dc7e38acSHans Petter Selasky } 3865dc7e38acSHans Petter Selasky 386605399002SHans Petter Selasky static u16 386705399002SHans Petter Selasky mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev) 386805399002SHans Petter Selasky { 38699c9b7340SHans Petter Selasky const int min_size = ETHER_VLAN_ENCAP_LEN + ETHER_HDR_LEN; 38709c9b7340SHans Petter Selasky const int max_size = MLX5E_MAX_TX_INLINE; 38719c9b7340SHans Petter Selasky const int bf_buf_size = 38729c9b7340SHans Petter Selasky ((1U << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2U) - 38739c9b7340SHans Petter Selasky (sizeof(struct mlx5e_tx_wqe) - 2); 387405399002SHans Petter Selasky 38759c9b7340SHans Petter Selasky /* verify against driver limits */ 38769c9b7340SHans Petter Selasky if (bf_buf_size > max_size) 38779c9b7340SHans Petter Selasky return (max_size); 38789c9b7340SHans Petter Selasky else if (bf_buf_size < min_size) 38799c9b7340SHans Petter Selasky return (min_size); 38809c9b7340SHans Petter Selasky else 38813e581cabSSlava Shwartsman return (bf_buf_size); 388205399002SHans Petter Selasky } 388305399002SHans Petter Selasky 38843e581cabSSlava Shwartsman static int 3885dc7e38acSHans Petter Selasky mlx5e_build_ifp_priv(struct mlx5_core_dev *mdev, 3886dc7e38acSHans Petter Selasky struct mlx5e_priv *priv, 3887dc7e38acSHans Petter Selasky int num_comp_vectors) 3888dc7e38acSHans Petter Selasky { 38893e581cabSSlava Shwartsman int err; 38903e581cabSSlava Shwartsman 3891dc7e38acSHans Petter Selasky /* 3892dc7e38acSHans Petter Selasky * TODO: Consider link speed for setting "log_sq_size", 3893dc7e38acSHans Petter Selasky * "log_rq_size" and "cq_moderation_xxx": 3894dc7e38acSHans Petter Selasky */ 3895dc7e38acSHans Petter Selasky priv->params.log_sq_size = 3896dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE; 3897dc7e38acSHans Petter Selasky priv->params.log_rq_size = 3898dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE; 3899dc7e38acSHans Petter Selasky priv->params.rx_cq_moderation_usec = 3900dc7e38acSHans Petter Selasky MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ? 3901dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE : 3902dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC; 3903dc7e38acSHans Petter Selasky priv->params.rx_cq_moderation_mode = 3904dc7e38acSHans Petter Selasky MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ? 1 : 0; 3905dc7e38acSHans Petter Selasky priv->params.rx_cq_moderation_pkts = 3906dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS; 3907dc7e38acSHans Petter Selasky priv->params.tx_cq_moderation_usec = 3908dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC; 3909dc7e38acSHans Petter Selasky priv->params.tx_cq_moderation_pkts = 3910dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS; 3911dc7e38acSHans Petter Selasky priv->params.rx_hash_log_tbl_sz = 3912dc7e38acSHans Petter Selasky (order_base_2(num_comp_vectors) > 3913dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ) ? 3914dc7e38acSHans Petter Selasky order_base_2(num_comp_vectors) : 3915dc7e38acSHans Petter Selasky MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ; 3916dc7e38acSHans Petter Selasky priv->params.num_tc = 1; 3917dc7e38acSHans Petter Selasky priv->params.default_vlan_prio = 0; 3918dc7e38acSHans Petter Selasky priv->counter_set_id = -1; 391905399002SHans Petter Selasky priv->params.tx_max_inline = mlx5e_get_max_inline_cap(mdev); 39203e581cabSSlava Shwartsman 39213e581cabSSlava Shwartsman err = mlx5_query_min_inline(mdev, &priv->params.tx_min_inline_mode); 39223e581cabSSlava Shwartsman if (err) 39233e581cabSSlava Shwartsman return (err); 3924dc7e38acSHans Petter Selasky 3925dc7e38acSHans Petter Selasky /* 3926bb3853c6SHans Petter Selasky * hw lro is currently defaulted to off. when it won't anymore we 3927bb3853c6SHans Petter Selasky * will consider the HW capability: "!!MLX5_CAP_ETH(mdev, lro_cap)" 3928dc7e38acSHans Petter Selasky */ 3929dc7e38acSHans Petter Selasky priv->params.hw_lro_en = false; 3930dc7e38acSHans Petter Selasky priv->params.lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; 3931dc7e38acSHans Petter Selasky 3932d52ffcb7SHans Petter Selasky /* 39336bd4bb9bSHans Petter Selasky * CQE zipping is off, because the per-packet 32-bit Toeplitz hash 39346bd4bb9bSHans Petter Selasky * is then not supported. The 32-bit Toeplitz hash is needed to 39356bd4bb9bSHans Petter Selasky * correctly demultiplex incoming traffic into the expected 39366bd4bb9bSHans Petter Selasky * network queues. 3937d52ffcb7SHans Petter Selasky */ 3938d52ffcb7SHans Petter Selasky priv->params.cqe_zipping_en = false; 393990cc1c77SHans Petter Selasky 3940dc7e38acSHans Petter Selasky priv->mdev = mdev; 3941dc7e38acSHans Petter Selasky priv->params.num_channels = num_comp_vectors; 394216ae32f9SHans Petter Selasky priv->params.channels_rsss = 1; 3943dc7e38acSHans Petter Selasky priv->order_base_2_num_channels = order_base_2(num_comp_vectors); 3944dc7e38acSHans Petter Selasky priv->queue_mapping_channel_mask = 3945dc7e38acSHans Petter Selasky roundup_pow_of_two(num_comp_vectors) - 1; 3946dc7e38acSHans Petter Selasky priv->num_tc = priv->params.num_tc; 3947dc7e38acSHans Petter Selasky priv->default_vlan_prio = priv->params.default_vlan_prio; 3948dc7e38acSHans Petter Selasky 3949dc7e38acSHans Petter Selasky INIT_WORK(&priv->update_stats_work, mlx5e_update_stats_work); 3950dc7e38acSHans Petter Selasky INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work); 3951dc7e38acSHans Petter Selasky INIT_WORK(&priv->set_rx_mode_work, mlx5e_set_rx_mode_work); 39523e581cabSSlava Shwartsman 39533e581cabSSlava Shwartsman return (0); 3954dc7e38acSHans Petter Selasky } 3955dc7e38acSHans Petter Selasky 3956de2437f1SHans Petter Selasky static void 3957de2437f1SHans Petter Selasky mlx5e_mkey_set_relaxed_ordering(struct mlx5_core_dev *mdev, void *mkc) 3958de2437f1SHans Petter Selasky { 3959de2437f1SHans Petter Selasky bool ro_pci_enable = 3960de2437f1SHans Petter Selasky pci_get_relaxed_ordering_enabled(mdev->pdev->dev.bsddev); 3961de2437f1SHans Petter Selasky bool ro_write = MLX5_CAP_GEN(mdev, relaxed_ordering_write); 3962de2437f1SHans Petter Selasky bool ro_read = MLX5_CAP_GEN(mdev, relaxed_ordering_read); 3963de2437f1SHans Petter Selasky 3964de2437f1SHans Petter Selasky MLX5_SET(mkc, mkc, relaxed_ordering_read, ro_pci_enable && ro_read); 3965de2437f1SHans Petter Selasky MLX5_SET(mkc, mkc, relaxed_ordering_write, ro_pci_enable && ro_write); 3966de2437f1SHans Petter Selasky } 3967de2437f1SHans Petter Selasky 3968dc7e38acSHans Petter Selasky static int 3969dc7e38acSHans Petter Selasky mlx5e_create_mkey(struct mlx5e_priv *priv, u32 pdn, 3970b633e08cSHans Petter Selasky struct mlx5_core_mkey *mkey) 3971dc7e38acSHans Petter Selasky { 39725dc00f00SJustin Hibbits if_t ifp = priv->ifp; 3973dc7e38acSHans Petter Selasky struct mlx5_core_dev *mdev = priv->mdev; 3974788333d9SHans Petter Selasky int inlen = MLX5_ST_SZ_BYTES(create_mkey_in); 3975788333d9SHans Petter Selasky void *mkc; 3976788333d9SHans Petter Selasky u32 *in; 3977dc7e38acSHans Petter Selasky int err; 3978dc7e38acSHans Petter Selasky 3979788333d9SHans Petter Selasky in = mlx5_vzalloc(inlen); 3980dc7e38acSHans Petter Selasky if (in == NULL) { 39816b4040d8SHans Petter Selasky mlx5_en_err(ifp, "failed to allocate inbox\n"); 3982dc7e38acSHans Petter Selasky return (-ENOMEM); 3983dc7e38acSHans Petter Selasky } 3984dc7e38acSHans Petter Selasky 3985788333d9SHans Petter Selasky mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); 3986788333d9SHans Petter Selasky MLX5_SET(mkc, mkc, access_mode, MLX5_ACCESS_MODE_PA); 39877272f9cdSHans Petter Selasky MLX5_SET(mkc, mkc, umr_en, 1); /* used by HW TLS */ 3988788333d9SHans Petter Selasky MLX5_SET(mkc, mkc, lw, 1); 3989788333d9SHans Petter Selasky MLX5_SET(mkc, mkc, lr, 1); 3990de2437f1SHans Petter Selasky mlx5e_mkey_set_relaxed_ordering(mdev, mkc); 3991788333d9SHans Petter Selasky MLX5_SET(mkc, mkc, pd, pdn); 3992788333d9SHans Petter Selasky MLX5_SET(mkc, mkc, length64, 1); 3993788333d9SHans Petter Selasky MLX5_SET(mkc, mkc, qpn, 0xffffff); 3994788333d9SHans Petter Selasky 3995788333d9SHans Petter Selasky err = mlx5_core_create_mkey(mdev, mkey, in, inlen); 3996dc7e38acSHans Petter Selasky if (err) 39976b4040d8SHans Petter Selasky mlx5_en_err(ifp, "mlx5_core_create_mkey failed, %d\n", 39986b4040d8SHans Petter Selasky err); 3999dc7e38acSHans Petter Selasky 4000dc7e38acSHans Petter Selasky kvfree(in); 4001dc7e38acSHans Petter Selasky return (err); 4002dc7e38acSHans Petter Selasky } 4003dc7e38acSHans Petter Selasky 4004dc7e38acSHans Petter Selasky static const char *mlx5e_vport_stats_desc[] = { 4005dc7e38acSHans Petter Selasky MLX5E_VPORT_STATS(MLX5E_STATS_DESC) 4006dc7e38acSHans Petter Selasky }; 4007dc7e38acSHans Petter Selasky 4008dc7e38acSHans Petter Selasky static const char *mlx5e_pport_stats_desc[] = { 4009dc7e38acSHans Petter Selasky MLX5E_PPORT_STATS(MLX5E_STATS_DESC) 4010dc7e38acSHans Petter Selasky }; 4011dc7e38acSHans Petter Selasky 40129dfa2148SHans Petter Selasky static int 40139dfa2148SHans Petter Selasky mlx5e_priv_static_init(struct mlx5e_priv *priv, struct mlx5_core_dev *mdev, 40149dfa2148SHans Petter Selasky const uint32_t channels) 4015dc7e38acSHans Petter Selasky { 4016eeb1ff98SHans Petter Selasky uint32_t x; 40179dfa2148SHans Petter Selasky int err; 4018eeb1ff98SHans Petter Selasky 4019dc7e38acSHans Petter Selasky mtx_init(&priv->async_events_mtx, "mlx5async", MTX_NETWORK_LOCK, MTX_DEF); 4020dc7e38acSHans Petter Selasky sx_init(&priv->state_lock, "mlx5state"); 4021dc7e38acSHans Petter Selasky callout_init_mtx(&priv->watchdog, &priv->async_events_mtx, 0); 402281b3cdc1SHans Petter Selasky MLX5_INIT_DOORBELL_LOCK(&priv->doorbell_lock); 4023eeb1ff98SHans Petter Selasky for (x = 0; x != channels; x++) 4024eeb1ff98SHans Petter Selasky mlx5e_chan_static_init(priv, &priv->channel[x], x); 40259dfa2148SHans Petter Selasky 40269dfa2148SHans Petter Selasky for (x = 0; x != channels; x++) { 40279dfa2148SHans Petter Selasky err = mlx5_alloc_bfreg(mdev, &priv->channel[x].bfreg, false, false); 40289dfa2148SHans Petter Selasky if (err) 40299dfa2148SHans Petter Selasky goto err_alloc_bfreg; 40309dfa2148SHans Petter Selasky } 40319dfa2148SHans Petter Selasky return (0); 40329dfa2148SHans Petter Selasky 40339dfa2148SHans Petter Selasky err_alloc_bfreg: 40349dfa2148SHans Petter Selasky while (x--) 40359dfa2148SHans Petter Selasky mlx5_free_bfreg(mdev, &priv->channel[x].bfreg); 40369dfa2148SHans Petter Selasky 40379dfa2148SHans Petter Selasky for (x = 0; x != channels; x++) 40389dfa2148SHans Petter Selasky mlx5e_chan_static_destroy(&priv->channel[x]); 40399dfa2148SHans Petter Selasky callout_drain(&priv->watchdog); 40409dfa2148SHans Petter Selasky mtx_destroy(&priv->async_events_mtx); 40419dfa2148SHans Petter Selasky sx_destroy(&priv->state_lock); 40429dfa2148SHans Petter Selasky return (err); 4043dc7e38acSHans Petter Selasky } 4044dc7e38acSHans Petter Selasky 4045dc7e38acSHans Petter Selasky static void 40469dfa2148SHans Petter Selasky mlx5e_priv_static_destroy(struct mlx5e_priv *priv, struct mlx5_core_dev *mdev, 40479dfa2148SHans Petter Selasky const uint32_t channels) 4048dc7e38acSHans Petter Selasky { 4049eeb1ff98SHans Petter Selasky uint32_t x; 4050eeb1ff98SHans Petter Selasky 4051eeb1ff98SHans Petter Selasky for (x = 0; x != channels; x++) 40529dfa2148SHans Petter Selasky mlx5_free_bfreg(mdev, &priv->channel[x].bfreg); 40539dfa2148SHans Petter Selasky for (x = 0; x != channels; x++) 4054eeb1ff98SHans Petter Selasky mlx5e_chan_static_destroy(&priv->channel[x]); 4055eeb1ff98SHans Petter Selasky callout_drain(&priv->watchdog); 4056dc7e38acSHans Petter Selasky mtx_destroy(&priv->async_events_mtx); 4057dc7e38acSHans Petter Selasky sx_destroy(&priv->state_lock); 4058dc7e38acSHans Petter Selasky } 4059dc7e38acSHans Petter Selasky 4060dc7e38acSHans Petter Selasky static int 4061dc7e38acSHans Petter Selasky sysctl_firmware(SYSCTL_HANDLER_ARGS) 4062dc7e38acSHans Petter Selasky { 4063bb3853c6SHans Petter Selasky /* 4064bb3853c6SHans Petter Selasky * %d.%d%.d the string format. 4065dc7e38acSHans Petter Selasky * fw_rev_{maj,min,sub} return u16, 2^16 = 65536. 4066dc7e38acSHans Petter Selasky * We need at most 5 chars to store that. 4067bb3853c6SHans Petter Selasky * It also has: two "." and NULL at the end, which means we need 18 4068bb3853c6SHans Petter Selasky * (5*3 + 3) chars at most. 4069dc7e38acSHans Petter Selasky */ 4070dc7e38acSHans Petter Selasky char fw[18]; 4071dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = arg1; 4072dc7e38acSHans Petter Selasky int error; 4073dc7e38acSHans Petter Selasky 4074dc7e38acSHans Petter Selasky snprintf(fw, sizeof(fw), "%d.%d.%d", fw_rev_maj(priv->mdev), fw_rev_min(priv->mdev), 4075dc7e38acSHans Petter Selasky fw_rev_sub(priv->mdev)); 4076dc7e38acSHans Petter Selasky error = sysctl_handle_string(oidp, fw, sizeof(fw), req); 4077dc7e38acSHans Petter Selasky return (error); 4078dc7e38acSHans Petter Selasky } 4079dc7e38acSHans Petter Selasky 4080dc7e38acSHans Petter Selasky static void 4081bb3616abSHans Petter Selasky mlx5e_disable_tx_dma(struct mlx5e_channel *ch) 4082bb3616abSHans Petter Selasky { 4083bb3616abSHans Petter Selasky int i; 4084bb3616abSHans Petter Selasky 4085eeb1ff98SHans Petter Selasky for (i = 0; i < ch->priv->num_tc; i++) 4086bb3616abSHans Petter Selasky mlx5e_drain_sq(&ch->sq[i]); 4087bb3616abSHans Petter Selasky } 4088bb3616abSHans Petter Selasky 4089bb3616abSHans Petter Selasky static void 4090bb3616abSHans Petter Selasky mlx5e_reset_sq_doorbell_record(struct mlx5e_sq *sq) 4091bb3616abSHans Petter Selasky { 4092bb3616abSHans Petter Selasky 4093bb3616abSHans Petter Selasky sq->doorbell.d32[0] = cpu_to_be32(MLX5_OPCODE_NOP); 4094bb3616abSHans Petter Selasky sq->doorbell.d32[1] = cpu_to_be32(sq->sqn << 8); 40952d5e5a0dSHans Petter Selasky mlx5e_tx_notify_hw(sq, true); 4096bb3616abSHans Petter Selasky } 4097bb3616abSHans Petter Selasky 4098bb3616abSHans Petter Selasky void 4099bb3616abSHans Petter Selasky mlx5e_resume_sq(struct mlx5e_sq *sq) 4100bb3616abSHans Petter Selasky { 4101bb3616abSHans Petter Selasky int err; 4102bb3616abSHans Petter Selasky 4103bb3616abSHans Petter Selasky /* check if already enabled */ 41043230c29dSSlava Shwartsman if (READ_ONCE(sq->running) != 0) 4105bb3616abSHans Petter Selasky return; 4106bb3616abSHans Petter Selasky 4107bb3616abSHans Petter Selasky err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_ERR, 4108bb3616abSHans Petter Selasky MLX5_SQC_STATE_RST); 4109bb3616abSHans Petter Selasky if (err != 0) { 41106b4040d8SHans Petter Selasky mlx5_en_err(sq->ifp, 4111bb3616abSHans Petter Selasky "mlx5e_modify_sq() from ERR to RST failed: %d\n", err); 4112bb3616abSHans Petter Selasky } 4113bb3616abSHans Petter Selasky 4114bb3616abSHans Petter Selasky sq->cc = 0; 4115bb3616abSHans Petter Selasky sq->pc = 0; 4116bb3616abSHans Petter Selasky 4117bb3616abSHans Petter Selasky /* reset doorbell prior to moving from RST to RDY */ 4118bb3616abSHans Petter Selasky mlx5e_reset_sq_doorbell_record(sq); 4119bb3616abSHans Petter Selasky 4120bb3616abSHans Petter Selasky err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RST, 4121bb3616abSHans Petter Selasky MLX5_SQC_STATE_RDY); 4122bb3616abSHans Petter Selasky if (err != 0) { 41236b4040d8SHans Petter Selasky mlx5_en_err(sq->ifp, 4124bb3616abSHans Petter Selasky "mlx5e_modify_sq() from RST to RDY failed: %d\n", err); 4125bb3616abSHans Petter Selasky } 4126bb3616abSHans Petter Selasky 4127bb3616abSHans Petter Selasky sq->cev_next_state = MLX5E_CEV_STATE_INITIAL; 41283230c29dSSlava Shwartsman WRITE_ONCE(sq->running, 1); 4129bb3616abSHans Petter Selasky } 4130bb3616abSHans Petter Selasky 4131bb3616abSHans Petter Selasky static void 4132bb3616abSHans Petter Selasky mlx5e_enable_tx_dma(struct mlx5e_channel *ch) 4133bb3616abSHans Petter Selasky { 4134bb3616abSHans Petter Selasky int i; 4135bb3616abSHans Petter Selasky 4136eeb1ff98SHans Petter Selasky for (i = 0; i < ch->priv->num_tc; i++) 4137bb3616abSHans Petter Selasky mlx5e_resume_sq(&ch->sq[i]); 4138bb3616abSHans Petter Selasky } 4139bb3616abSHans Petter Selasky 4140bb3616abSHans Petter Selasky static void 4141bb3616abSHans Petter Selasky mlx5e_disable_rx_dma(struct mlx5e_channel *ch) 4142bb3616abSHans Petter Selasky { 4143bb3616abSHans Petter Selasky struct mlx5e_rq *rq = &ch->rq; 4144e4881300SHans Petter Selasky struct epoch_tracker et; 4145bb3616abSHans Petter Selasky int err; 4146bb3616abSHans Petter Selasky 4147bb3616abSHans Petter Selasky mtx_lock(&rq->mtx); 4148bb3616abSHans Petter Selasky rq->enabled = 0; 4149bb3616abSHans Petter Selasky callout_stop(&rq->watchdog); 4150bb3616abSHans Petter Selasky mtx_unlock(&rq->mtx); 4151bb3616abSHans Petter Selasky 4152bb3616abSHans Petter Selasky err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_ERR); 4153bb3616abSHans Petter Selasky if (err != 0) { 41546b4040d8SHans Petter Selasky mlx5_en_err(rq->ifp, 4155bb3616abSHans Petter Selasky "mlx5e_modify_rq() from RDY to RST failed: %d\n", err); 4156bb3616abSHans Petter Selasky } 4157bb3616abSHans Petter Selasky 4158bb3616abSHans Petter Selasky while (!mlx5_wq_ll_is_empty(&rq->wq)) { 4159bb3616abSHans Petter Selasky msleep(1); 4160e4881300SHans Petter Selasky NET_EPOCH_ENTER(et); 4161f34f0a65SHans Petter Selasky rq->cq.mcq.comp(&rq->cq.mcq, NULL); 4162e4881300SHans Petter Selasky NET_EPOCH_EXIT(et); 4163bb3616abSHans Petter Selasky } 4164bb3616abSHans Petter Selasky 4165bb3616abSHans Petter Selasky /* 4166bb3616abSHans Petter Selasky * Transitioning into RST state will allow the FW to track less ERR state queues, 4167bb3616abSHans Petter Selasky * thus reducing the recv queue flushing time 4168bb3616abSHans Petter Selasky */ 4169bb3616abSHans Petter Selasky err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_ERR, MLX5_RQC_STATE_RST); 4170bb3616abSHans Petter Selasky if (err != 0) { 41716b4040d8SHans Petter Selasky mlx5_en_err(rq->ifp, 4172bb3616abSHans Petter Selasky "mlx5e_modify_rq() from ERR to RST failed: %d\n", err); 4173bb3616abSHans Petter Selasky } 4174bb3616abSHans Petter Selasky } 4175bb3616abSHans Petter Selasky 4176bb3616abSHans Petter Selasky static void 4177bb3616abSHans Petter Selasky mlx5e_enable_rx_dma(struct mlx5e_channel *ch) 4178bb3616abSHans Petter Selasky { 4179bb3616abSHans Petter Selasky struct mlx5e_rq *rq = &ch->rq; 4180e4881300SHans Petter Selasky struct epoch_tracker et; 4181bb3616abSHans Petter Selasky int err; 4182bb3616abSHans Petter Selasky 4183bb3616abSHans Petter Selasky rq->wq.wqe_ctr = 0; 4184bb3616abSHans Petter Selasky mlx5_wq_ll_update_db_record(&rq->wq); 4185bb3616abSHans Petter Selasky err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY); 4186bb3616abSHans Petter Selasky if (err != 0) { 41876b4040d8SHans Petter Selasky mlx5_en_err(rq->ifp, 4188bb3616abSHans Petter Selasky "mlx5e_modify_rq() from RST to RDY failed: %d\n", err); 4189bb3616abSHans Petter Selasky } 4190bb3616abSHans Petter Selasky 4191bb3616abSHans Petter Selasky rq->enabled = 1; 4192bb3616abSHans Petter Selasky 4193e4881300SHans Petter Selasky NET_EPOCH_ENTER(et); 4194f34f0a65SHans Petter Selasky rq->cq.mcq.comp(&rq->cq.mcq, NULL); 4195e4881300SHans Petter Selasky NET_EPOCH_EXIT(et); 4196bb3616abSHans Petter Selasky } 4197bb3616abSHans Petter Selasky 4198bb3616abSHans Petter Selasky void 4199bb3616abSHans Petter Selasky mlx5e_modify_tx_dma(struct mlx5e_priv *priv, uint8_t value) 4200bb3616abSHans Petter Selasky { 4201bb3616abSHans Petter Selasky int i; 4202bb3616abSHans Petter Selasky 42033230c29dSSlava Shwartsman if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0) 4204bb3616abSHans Petter Selasky return; 4205bb3616abSHans Petter Selasky 4206bb3616abSHans Petter Selasky for (i = 0; i < priv->params.num_channels; i++) { 4207bb3616abSHans Petter Selasky if (value) 42083230c29dSSlava Shwartsman mlx5e_disable_tx_dma(&priv->channel[i]); 4209bb3616abSHans Petter Selasky else 42103230c29dSSlava Shwartsman mlx5e_enable_tx_dma(&priv->channel[i]); 4211bb3616abSHans Petter Selasky } 4212bb3616abSHans Petter Selasky } 4213bb3616abSHans Petter Selasky 4214bb3616abSHans Petter Selasky void 4215bb3616abSHans Petter Selasky mlx5e_modify_rx_dma(struct mlx5e_priv *priv, uint8_t value) 4216bb3616abSHans Petter Selasky { 4217bb3616abSHans Petter Selasky int i; 4218bb3616abSHans Petter Selasky 42193230c29dSSlava Shwartsman if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0) 4220bb3616abSHans Petter Selasky return; 4221bb3616abSHans Petter Selasky 4222bb3616abSHans Petter Selasky for (i = 0; i < priv->params.num_channels; i++) { 4223bb3616abSHans Petter Selasky if (value) 42243230c29dSSlava Shwartsman mlx5e_disable_rx_dma(&priv->channel[i]); 4225bb3616abSHans Petter Selasky else 42263230c29dSSlava Shwartsman mlx5e_enable_rx_dma(&priv->channel[i]); 4227bb3616abSHans Petter Selasky } 4228bb3616abSHans Petter Selasky } 4229bb3616abSHans Petter Selasky 4230bb3616abSHans Petter Selasky static void 4231dc7e38acSHans Petter Selasky mlx5e_add_hw_stats(struct mlx5e_priv *priv) 4232dc7e38acSHans Petter Selasky { 4233dc7e38acSHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_hw), 42347029da5cSPawel Biernacki OID_AUTO, "fw_version", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 42357029da5cSPawel Biernacki priv, 0, sysctl_firmware, "A", "HCA firmware version"); 4236dc7e38acSHans Petter Selasky 4237dc7e38acSHans Petter Selasky SYSCTL_ADD_STRING(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_hw), 4238dc7e38acSHans Petter Selasky OID_AUTO, "board_id", CTLFLAG_RD, priv->mdev->board_id, 0, 4239dc7e38acSHans Petter Selasky "Board ID"); 4240dc7e38acSHans Petter Selasky } 4241dc7e38acSHans Petter Selasky 424210b08045SHans Petter Selasky static int 424310b08045SHans Petter Selasky mlx5e_sysctl_tx_priority_flow_control(SYSCTL_HANDLER_ARGS) 424410b08045SHans Petter Selasky { 424510b08045SHans Petter Selasky struct mlx5e_priv *priv = arg1; 424624385321SHans Petter Selasky uint8_t temp[MLX5E_MAX_PRIORITY]; 424710b08045SHans Petter Selasky uint32_t tx_pfc; 424824385321SHans Petter Selasky int err; 424924385321SHans Petter Selasky int i; 425010b08045SHans Petter Selasky 425110b08045SHans Petter Selasky PRIV_LOCK(priv); 425210b08045SHans Petter Selasky 425310b08045SHans Petter Selasky tx_pfc = priv->params.tx_priority_flow_control; 425410b08045SHans Petter Selasky 425524385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) 425624385321SHans Petter Selasky temp[i] = (tx_pfc >> i) & 1; 425710b08045SHans Petter Selasky 425824385321SHans Petter Selasky err = SYSCTL_OUT(req, temp, MLX5E_MAX_PRIORITY); 425924385321SHans Petter Selasky if (err || !req->newptr) 426024385321SHans Petter Selasky goto done; 426124385321SHans Petter Selasky err = SYSCTL_IN(req, temp, MLX5E_MAX_PRIORITY); 426224385321SHans Petter Selasky if (err) 426324385321SHans Petter Selasky goto done; 426410b08045SHans Petter Selasky 426524385321SHans Petter Selasky priv->params.tx_priority_flow_control = 0; 426624385321SHans Petter Selasky 426724385321SHans Petter Selasky /* range check input value */ 426824385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) { 426924385321SHans Petter Selasky if (temp[i] > 1) { 427024385321SHans Petter Selasky err = ERANGE; 427124385321SHans Petter Selasky goto done; 427224385321SHans Petter Selasky } 427324385321SHans Petter Selasky priv->params.tx_priority_flow_control |= (temp[i] << i); 427424385321SHans Petter Selasky } 427510b08045SHans Petter Selasky 427610b08045SHans Petter Selasky /* check if update is required */ 427724385321SHans Petter Selasky if (tx_pfc != priv->params.tx_priority_flow_control) 427824385321SHans Petter Selasky err = -mlx5e_set_port_pfc(priv); 427924385321SHans Petter Selasky done: 428024385321SHans Petter Selasky if (err != 0) 428110b08045SHans Petter Selasky priv->params.tx_priority_flow_control= tx_pfc; 428210b08045SHans Petter Selasky PRIV_UNLOCK(priv); 428310b08045SHans Petter Selasky 428424385321SHans Petter Selasky return (err); 428510b08045SHans Petter Selasky } 428610b08045SHans Petter Selasky 428710b08045SHans Petter Selasky static int 428810b08045SHans Petter Selasky mlx5e_sysctl_rx_priority_flow_control(SYSCTL_HANDLER_ARGS) 428910b08045SHans Petter Selasky { 429010b08045SHans Petter Selasky struct mlx5e_priv *priv = arg1; 429124385321SHans Petter Selasky uint8_t temp[MLX5E_MAX_PRIORITY]; 429210b08045SHans Petter Selasky uint32_t rx_pfc; 429324385321SHans Petter Selasky int err; 429424385321SHans Petter Selasky int i; 429510b08045SHans Petter Selasky 429610b08045SHans Petter Selasky PRIV_LOCK(priv); 429710b08045SHans Petter Selasky 429810b08045SHans Petter Selasky rx_pfc = priv->params.rx_priority_flow_control; 429910b08045SHans Petter Selasky 430024385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) 430124385321SHans Petter Selasky temp[i] = (rx_pfc >> i) & 1; 430210b08045SHans Petter Selasky 430324385321SHans Petter Selasky err = SYSCTL_OUT(req, temp, MLX5E_MAX_PRIORITY); 430424385321SHans Petter Selasky if (err || !req->newptr) 430524385321SHans Petter Selasky goto done; 430624385321SHans Petter Selasky err = SYSCTL_IN(req, temp, MLX5E_MAX_PRIORITY); 430724385321SHans Petter Selasky if (err) 430824385321SHans Petter Selasky goto done; 430910b08045SHans Petter Selasky 431024385321SHans Petter Selasky priv->params.rx_priority_flow_control = 0; 431124385321SHans Petter Selasky 431224385321SHans Petter Selasky /* range check input value */ 431324385321SHans Petter Selasky for (i = 0; i != MLX5E_MAX_PRIORITY; i++) { 431424385321SHans Petter Selasky if (temp[i] > 1) { 431524385321SHans Petter Selasky err = ERANGE; 431624385321SHans Petter Selasky goto done; 431724385321SHans Petter Selasky } 431824385321SHans Petter Selasky priv->params.rx_priority_flow_control |= (temp[i] << i); 431924385321SHans Petter Selasky } 432010b08045SHans Petter Selasky 432110b08045SHans Petter Selasky /* check if update is required */ 43226deb0b1eSHans Petter Selasky if (rx_pfc != priv->params.rx_priority_flow_control) { 432324385321SHans Petter Selasky err = -mlx5e_set_port_pfc(priv); 4324e525a7f0SHans Petter Selasky if (err == 0 && priv->sw_is_port_buf_owner) 43256deb0b1eSHans Petter Selasky err = mlx5e_update_buf_lossy(priv); 43266deb0b1eSHans Petter Selasky } 432724385321SHans Petter Selasky done: 432824385321SHans Petter Selasky if (err != 0) 432910b08045SHans Petter Selasky priv->params.rx_priority_flow_control= rx_pfc; 433010b08045SHans Petter Selasky PRIV_UNLOCK(priv); 433110b08045SHans Petter Selasky 433224385321SHans Petter Selasky return (err); 433310b08045SHans Petter Selasky } 433410b08045SHans Petter Selasky 43354d3b91a7SHans Petter Selasky static void 43364d3b91a7SHans Petter Selasky mlx5e_setup_pauseframes(struct mlx5e_priv *priv) 43374d3b91a7SHans Petter Selasky { 433810b08045SHans Petter Selasky int error; 43394d3b91a7SHans Petter Selasky 4340f8c33497SHans Petter Selasky /* enable pauseframes by default */ 4341f8c33497SHans Petter Selasky priv->params.tx_pauseframe_control = 1; 43424d3b91a7SHans Petter Selasky priv->params.rx_pauseframe_control = 1; 43434d3b91a7SHans Petter Selasky 434410b08045SHans Petter Selasky /* disable ports flow control, PFC, by default */ 434510b08045SHans Petter Selasky priv->params.tx_priority_flow_control = 0; 434610b08045SHans Petter Selasky priv->params.rx_priority_flow_control = 0; 434710b08045SHans Petter Selasky 434810b08045SHans Petter Selasky /* register pauseframe SYSCTLs */ 43494d3b91a7SHans Petter Selasky SYSCTL_ADD_INT(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 43504d3b91a7SHans Petter Selasky OID_AUTO, "tx_pauseframe_control", CTLFLAG_RDTUN, 43514d3b91a7SHans Petter Selasky &priv->params.tx_pauseframe_control, 0, 43524d3b91a7SHans Petter Selasky "Set to enable TX pause frames. Clear to disable."); 43534d3b91a7SHans Petter Selasky 43544d3b91a7SHans Petter Selasky SYSCTL_ADD_INT(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 43554d3b91a7SHans Petter Selasky OID_AUTO, "rx_pauseframe_control", CTLFLAG_RDTUN, 43564d3b91a7SHans Petter Selasky &priv->params.rx_pauseframe_control, 0, 43574d3b91a7SHans Petter Selasky "Set to enable RX pause frames. Clear to disable."); 43584d3b91a7SHans Petter Selasky 435924385321SHans Petter Selasky /* register priority flow control, PFC, SYSCTLs */ 436024385321SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 436124385321SHans Petter Selasky OID_AUTO, "tx_priority_flow_control", CTLTYPE_U8 | CTLFLAG_RWTUN | 436224385321SHans Petter Selasky CTLFLAG_MPSAFE, priv, 0, &mlx5e_sysctl_tx_priority_flow_control, "CU", 436324385321SHans Petter Selasky "Set to enable TX ports flow control frames for priorities 0..7. Clear to disable."); 436410b08045SHans Petter Selasky 436510b08045SHans Petter Selasky SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 436624385321SHans Petter Selasky OID_AUTO, "rx_priority_flow_control", CTLTYPE_U8 | CTLFLAG_RWTUN | 436724385321SHans Petter Selasky CTLFLAG_MPSAFE, priv, 0, &mlx5e_sysctl_rx_priority_flow_control, "CU", 436824385321SHans Petter Selasky "Set to enable RX ports flow control frames for priorities 0..7. Clear to disable."); 436910b08045SHans Petter Selasky 437010b08045SHans Petter Selasky PRIV_LOCK(priv); 437110b08045SHans Petter Selasky 43724d3b91a7SHans Petter Selasky /* range check */ 43734d3b91a7SHans Petter Selasky priv->params.tx_pauseframe_control = 43744d3b91a7SHans Petter Selasky priv->params.tx_pauseframe_control ? 1 : 0; 43754d3b91a7SHans Petter Selasky priv->params.rx_pauseframe_control = 43764d3b91a7SHans Petter Selasky priv->params.rx_pauseframe_control ? 1 : 0; 43774d3b91a7SHans Petter Selasky 43784d3b91a7SHans Petter Selasky /* update firmware */ 437910b08045SHans Petter Selasky error = mlx5e_set_port_pause_and_pfc(priv); 438010b08045SHans Petter Selasky if (error == -EINVAL) { 43816b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 438210b08045SHans Petter Selasky "Global pauseframes must be disabled before enabling PFC.\n"); 438310b08045SHans Petter Selasky priv->params.rx_priority_flow_control = 0; 438410b08045SHans Petter Selasky priv->params.tx_priority_flow_control = 0; 438510b08045SHans Petter Selasky 438610b08045SHans Petter Selasky /* update firmware */ 438710b08045SHans Petter Selasky (void) mlx5e_set_port_pause_and_pfc(priv); 438810b08045SHans Petter Selasky } 438910b08045SHans Petter Selasky PRIV_UNLOCK(priv); 43904d3b91a7SHans Petter Selasky } 43914d3b91a7SHans Petter Selasky 4392c782ea8bSJohn Baldwin static int 43935dc00f00SJustin Hibbits mlx5e_ul_snd_tag_alloc(if_t ifp, 4394cc971b22SSlava Shwartsman union if_snd_tag_alloc_params *params, 4395cc971b22SSlava Shwartsman struct m_snd_tag **ppmt) 4396cc971b22SSlava Shwartsman { 4397cc971b22SSlava Shwartsman struct mlx5e_priv *priv; 4398cc971b22SSlava Shwartsman struct mlx5e_channel *pch; 4399cc971b22SSlava Shwartsman 44005dc00f00SJustin Hibbits priv = if_getsoftc(ifp); 4401cc971b22SSlava Shwartsman 4402cc971b22SSlava Shwartsman if (unlikely(priv->gone || params->hdr.flowtype == M_HASHTYPE_NONE)) { 4403cc971b22SSlava Shwartsman return (EOPNOTSUPP); 4404cc971b22SSlava Shwartsman } else { 4405cc971b22SSlava Shwartsman /* keep this code synced with mlx5e_select_queue() */ 4406cc971b22SSlava Shwartsman u32 ch = priv->params.num_channels; 4407cc971b22SSlava Shwartsman #ifdef RSS 4408cc971b22SSlava Shwartsman u32 temp; 4409cc971b22SSlava Shwartsman 4410cc971b22SSlava Shwartsman if (rss_hash2bucket(params->hdr.flowid, 4411cc971b22SSlava Shwartsman params->hdr.flowtype, &temp) == 0) 4412cc971b22SSlava Shwartsman ch = temp % ch; 4413cc971b22SSlava Shwartsman else 4414cc971b22SSlava Shwartsman #endif 4415cc971b22SSlava Shwartsman ch = (params->hdr.flowid % 128) % ch; 4416cc971b22SSlava Shwartsman 4417cc971b22SSlava Shwartsman /* 4418cc971b22SSlava Shwartsman * NOTE: The channels array is only freed at detach 4419cc971b22SSlava Shwartsman * and it safe to return a pointer to the send tag 4420cc971b22SSlava Shwartsman * inside the channels structure as long as we 4421cc971b22SSlava Shwartsman * reference the priv. 4422cc971b22SSlava Shwartsman */ 4423cc971b22SSlava Shwartsman pch = priv->channel + ch; 4424cc971b22SSlava Shwartsman 4425cc971b22SSlava Shwartsman /* check if send queue is not running */ 4426cc971b22SSlava Shwartsman if (unlikely(pch->sq[0].running == 0)) 4427cc971b22SSlava Shwartsman return (ENXIO); 442856fb710fSJohn Baldwin m_snd_tag_ref(&pch->tag); 442956fb710fSJohn Baldwin *ppmt = &pch->tag; 4430cc971b22SSlava Shwartsman return (0); 4431cc971b22SSlava Shwartsman } 4432cc971b22SSlava Shwartsman } 4433cc971b22SSlava Shwartsman 4434c782ea8bSJohn Baldwin static int 4435cc971b22SSlava Shwartsman mlx5e_ul_snd_tag_query(struct m_snd_tag *pmt, union if_snd_tag_query_params *params) 4436cc971b22SSlava Shwartsman { 4437cc971b22SSlava Shwartsman struct mlx5e_channel *pch = 443856fb710fSJohn Baldwin container_of(pmt, struct mlx5e_channel, tag); 4439cc971b22SSlava Shwartsman 4440cc971b22SSlava Shwartsman params->unlimited.max_rate = -1ULL; 4441cc971b22SSlava Shwartsman params->unlimited.queue_level = mlx5e_sq_queue_level(&pch->sq[0]); 4442cc971b22SSlava Shwartsman return (0); 4443cc971b22SSlava Shwartsman } 4444cc971b22SSlava Shwartsman 4445c782ea8bSJohn Baldwin static void 4446cc971b22SSlava Shwartsman mlx5e_ul_snd_tag_free(struct m_snd_tag *pmt) 4447cc971b22SSlava Shwartsman { 4448cc971b22SSlava Shwartsman struct mlx5e_channel *pch = 444956fb710fSJohn Baldwin container_of(pmt, struct mlx5e_channel, tag); 4450cc971b22SSlava Shwartsman 4451c84e0068SHans Petter Selasky complete(&pch->completion); 4452cc971b22SSlava Shwartsman } 4453cc971b22SSlava Shwartsman 4454cc971b22SSlava Shwartsman static int 44555dc00f00SJustin Hibbits mlx5e_snd_tag_alloc(if_t ifp, 4456cc971b22SSlava Shwartsman union if_snd_tag_alloc_params *params, 4457cc971b22SSlava Shwartsman struct m_snd_tag **ppmt) 4458cc971b22SSlava Shwartsman { 4459cc971b22SSlava Shwartsman 4460cc971b22SSlava Shwartsman switch (params->hdr.type) { 4461cc971b22SSlava Shwartsman #ifdef RATELIMIT 4462cc971b22SSlava Shwartsman case IF_SND_TAG_TYPE_RATE_LIMIT: 4463cc971b22SSlava Shwartsman return (mlx5e_rl_snd_tag_alloc(ifp, params, ppmt)); 4464b7d92a66SJohn Baldwin #ifdef KERN_TLS 44657272f9cdSHans Petter Selasky case IF_SND_TAG_TYPE_TLS_RATE_LIMIT: 44667272f9cdSHans Petter Selasky return (mlx5e_tls_snd_tag_alloc(ifp, params, ppmt)); 44677272f9cdSHans Petter Selasky #endif 4468cc971b22SSlava Shwartsman #endif 4469cc971b22SSlava Shwartsman case IF_SND_TAG_TYPE_UNLIMITED: 4470cc971b22SSlava Shwartsman return (mlx5e_ul_snd_tag_alloc(ifp, params, ppmt)); 44717272f9cdSHans Petter Selasky #ifdef KERN_TLS 44727272f9cdSHans Petter Selasky case IF_SND_TAG_TYPE_TLS: 44737272f9cdSHans Petter Selasky return (mlx5e_tls_snd_tag_alloc(ifp, params, ppmt)); 447484d7b8e7SHans Petter Selasky case IF_SND_TAG_TYPE_TLS_RX: 447584d7b8e7SHans Petter Selasky return (mlx5e_tls_rx_snd_tag_alloc(ifp, params, ppmt)); 44767272f9cdSHans Petter Selasky #endif 4477cc971b22SSlava Shwartsman default: 4478cc971b22SSlava Shwartsman return (EOPNOTSUPP); 4479cc971b22SSlava Shwartsman } 4480cc971b22SSlava Shwartsman } 4481cc971b22SSlava Shwartsman 4482ef34be8bSMark Johnston #ifdef RATELIMIT 448320abea66SRandall Stewart #define NUM_HDWR_RATES_MLX 13 448420abea66SRandall Stewart static const uint64_t adapter_rates_mlx[NUM_HDWR_RATES_MLX] = { 448520abea66SRandall Stewart 135375, /* 1,083,000 */ 448620abea66SRandall Stewart 180500, /* 1,444,000 */ 448720abea66SRandall Stewart 270750, /* 2,166,000 */ 448820abea66SRandall Stewart 361000, /* 2,888,000 */ 448920abea66SRandall Stewart 541500, /* 4,332,000 */ 449020abea66SRandall Stewart 721875, /* 5,775,000 */ 449120abea66SRandall Stewart 1082875, /* 8,663,000 */ 449220abea66SRandall Stewart 1443875, /* 11,551,000 */ 449320abea66SRandall Stewart 2165750, /* 17,326,000 */ 449420abea66SRandall Stewart 2887750, /* 23,102,000 */ 449520abea66SRandall Stewart 4331625, /* 34,653,000 */ 449620abea66SRandall Stewart 5775500, /* 46,204,000 */ 449720abea66SRandall Stewart 8663125 /* 69,305,000 */ 449820abea66SRandall Stewart }; 449920abea66SRandall Stewart 450020abea66SRandall Stewart static void 45015dc00f00SJustin Hibbits mlx5e_ratelimit_query(if_t ifp __unused, struct if_ratelimit_query_results *q) 450220abea66SRandall Stewart { 450320abea66SRandall Stewart /* 450420abea66SRandall Stewart * This function needs updating by the driver maintainer! 450520abea66SRandall Stewart * For the MLX card there are currently (ConectX-4?) 13 450620abea66SRandall Stewart * pre-set rates and others i.e. ConnectX-5, 6, 7?? 450720abea66SRandall Stewart * 450820abea66SRandall Stewart * This will change based on later adapters 450920abea66SRandall Stewart * and this code should be updated to look at ifp 451020abea66SRandall Stewart * and figure out the specific adapter type 451120abea66SRandall Stewart * settings i.e. how many rates as well 451220abea66SRandall Stewart * as if they are fixed (as is shown here) or 451320abea66SRandall Stewart * if they are dynamic (example chelsio t4). Also if there 451420abea66SRandall Stewart * is a maximum number of flows that the adapter 451520abea66SRandall Stewart * can handle that too needs to be updated in 451620abea66SRandall Stewart * the max_flows field. 451720abea66SRandall Stewart */ 451820abea66SRandall Stewart q->rate_table = adapter_rates_mlx; 451920abea66SRandall Stewart q->flags = RT_IS_FIXED_TABLE; 452020abea66SRandall Stewart q->max_flows = 0; /* mlx has no limit */ 452120abea66SRandall Stewart q->number_of_rates = NUM_HDWR_RATES_MLX; 452220abea66SRandall Stewart q->min_segment_burst = 1; 452320abea66SRandall Stewart } 4524ef34be8bSMark Johnston #endif 452520abea66SRandall Stewart 4526cc971b22SSlava Shwartsman static void 45274ead8024SKonstantin Belousov mlx5e_ifm_add(struct mlx5e_priv *priv, int type) 45284ead8024SKonstantin Belousov { 45294ead8024SKonstantin Belousov ifmedia_add(&priv->media, type | IFM_ETHER, 0, NULL); 4530559dbeacSKonstantin Belousov ifmedia_add(&priv->media, type | IFM_ETHER | 4531559dbeacSKonstantin Belousov IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL); 4532559dbeacSKonstantin Belousov ifmedia_add(&priv->media, type | IFM_ETHER | IFM_ETH_RXPAUSE, 0, NULL); 4533559dbeacSKonstantin Belousov ifmedia_add(&priv->media, type | IFM_ETHER | IFM_ETH_TXPAUSE, 0, NULL); 4534559dbeacSKonstantin Belousov ifmedia_add(&priv->media, type | IFM_ETHER | IFM_FDX, 0, NULL); 4535559dbeacSKonstantin Belousov ifmedia_add(&priv->media, type | IFM_ETHER | IFM_FDX | 4536559dbeacSKonstantin Belousov IFM_ETH_RXPAUSE, 0, NULL); 4537559dbeacSKonstantin Belousov ifmedia_add(&priv->media, type | IFM_ETHER | IFM_FDX | 4538559dbeacSKonstantin Belousov IFM_ETH_TXPAUSE, 0, NULL); 45394ead8024SKonstantin Belousov ifmedia_add(&priv->media, type | IFM_ETHER | IFM_FDX | 45404ead8024SKonstantin Belousov IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL); 45414ead8024SKonstantin Belousov } 45424ead8024SKonstantin Belousov 4543dc7e38acSHans Petter Selasky static void * 4544dc7e38acSHans Petter Selasky mlx5e_create_ifp(struct mlx5_core_dev *mdev) 4545dc7e38acSHans Petter Selasky { 45465dc00f00SJustin Hibbits if_t ifp; 4547dc7e38acSHans Petter Selasky struct mlx5e_priv *priv; 4548dc7e38acSHans Petter Selasky u8 dev_addr[ETHER_ADDR_LEN] __aligned(4); 4549dc7e38acSHans Petter Selasky struct sysctl_oid_list *child; 4550dc7e38acSHans Petter Selasky int ncv = mdev->priv.eq_table.num_comp_vectors; 4551dc7e38acSHans Petter Selasky char unit[16]; 4552538ff57bSAndrew Gallatin struct pfil_head_args pa; 4553dc7e38acSHans Petter Selasky int err; 4554dc7e38acSHans Petter Selasky u32 eth_proto_cap; 4555ac87880aSHans Petter Selasky u32 out[MLX5_ST_SZ_DW(ptys_reg)]; 4556a888087fSHans Petter Selasky bool ext; 4557ac87880aSHans Petter Selasky struct media media_entry = {}; 4558dc7e38acSHans Petter Selasky 4559dc7e38acSHans Petter Selasky if (mlx5e_check_required_hca_cap(mdev)) { 4560dc7e38acSHans Petter Selasky mlx5_core_dbg(mdev, "mlx5e_check_required_hca_cap() failed\n"); 4561dc7e38acSHans Petter Selasky return (NULL); 4562dc7e38acSHans Petter Selasky } 45637c3eff94SHans Petter Selasky 45643230c29dSSlava Shwartsman /* 45653230c29dSSlava Shwartsman * Try to allocate the priv and make room for worst-case 45663230c29dSSlava Shwartsman * number of channel structures: 45673230c29dSSlava Shwartsman */ 45687c3eff94SHans Petter Selasky priv = malloc_domainset(sizeof(*priv) + 45693230c29dSSlava Shwartsman (sizeof(priv->channel[0]) * mdev->priv.eq_table.num_comp_vectors), 45707c3eff94SHans Petter Selasky M_MLX5EN, mlx5_dev_domainset(mdev), M_WAITOK | M_ZERO); 4571dc7e38acSHans Petter Selasky 45727687707dSAndrew Gallatin ifp = priv->ifp = if_alloc_dev(IFT_ETHER, mdev->pdev->dev.bsddev); 4573eeb1ff98SHans Petter Selasky /* setup all static fields */ 45749dfa2148SHans Petter Selasky if (mlx5e_priv_static_init(priv, mdev, mdev->priv.eq_table.num_comp_vectors)) { 45759dfa2148SHans Petter Selasky mlx5_core_err(mdev, "mlx5e_priv_static_init() failed\n"); 45769dfa2148SHans Petter Selasky goto err_free_ifp; 45779dfa2148SHans Petter Selasky } 4578eeb1ff98SHans Petter Selasky 45795dc00f00SJustin Hibbits if_setsoftc(ifp, priv); 45807c22ae80SHans Petter Selasky if_initname(ifp, "mce", device_get_unit(mdev->pdev->dev.bsddev)); 45815dc00f00SJustin Hibbits if_setmtu(ifp, ETHERMTU); 45825dc00f00SJustin Hibbits if_setinitfn(ifp, mlx5e_open); 4583a6b55ee6SGleb Smirnoff if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); 45845dc00f00SJustin Hibbits if_setioctlfn(ifp, mlx5e_ioctl); 45855dc00f00SJustin Hibbits if_settransmitfn(ifp, mlx5e_xmit); 45865dc00f00SJustin Hibbits if_setqflushfn(ifp, if_qflush); 45875dc00f00SJustin Hibbits if_setgetcounterfn(ifp, mlx5e_get_counter); 45885dc00f00SJustin Hibbits if_setsendqlen(ifp, ifqmaxlen); 4589dc7e38acSHans Petter Selasky /* 4590dc7e38acSHans Petter Selasky * Set driver features 4591dc7e38acSHans Petter Selasky */ 45925dc00f00SJustin Hibbits if_setcapabilities(ifp, IFCAP_NV); 45935dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6, 0); 45945dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING, 0); 45955dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWFILTER, 0); 45965dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_LINKSTATE | IFCAP_JUMBO_MTU, 0); 45975dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_LRO, 0); 45985dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_TSO | IFCAP_VLAN_HWTSO, 0); 45995dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_HWSTATS | IFCAP_HWRXTSTMP, 0); 46005dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_MEXTPG, 0); 4601cca0dc49SKonstantin Belousov if (mlx5e_is_tlstx_capable(mdev)) 46025dc00f00SJustin Hibbits if_setcapabilitiesbit(ifp, IFCAP_TXTLS4 | IFCAP_TXTLS6, 0); 4603cca0dc49SKonstantin Belousov if (mlx5e_is_tlsrx_capable(mdev)) 46045dc00f00SJustin Hibbits if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_RXTLS4) | 46055dc00f00SJustin Hibbits IFCAP2_BIT(IFCAP2_RXTLS6), 0); 4606cca0dc49SKonstantin Belousov if (mlx5e_is_ratelimit_capable(mdev)) { 4607cca0dc49SKonstantin Belousov if_setcapabilitiesbit(ifp, IFCAP_TXRTLMT, 0); 4608cca0dc49SKonstantin Belousov if (mlx5e_is_tlstx_capable(mdev)) 4609cca0dc49SKonstantin Belousov if_setcapabilitiesbit(ifp, IFCAP_TXTLS_RTLMT, 0); 4610cca0dc49SKonstantin Belousov } 4611de7a9275SKonstantin Belousov if_setcapabilitiesbit(ifp, IFCAP_VXLAN_HWCSUM | IFCAP_VXLAN_HWTSO, 0); 4612cca0dc49SKonstantin Belousov if (mlx5e_is_ipsec_capable(mdev)) 4613e23731dbSKonstantin Belousov if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD), 4614e23731dbSKonstantin Belousov 0); 4615e23731dbSKonstantin Belousov 46165dc00f00SJustin Hibbits if_setsndtagallocfn(ifp, mlx5e_snd_tag_alloc); 461720abea66SRandall Stewart #ifdef RATELIMIT 46185dc00f00SJustin Hibbits if_setratelimitqueryfn(ifp, mlx5e_ratelimit_query); 461920abea66SRandall Stewart #endif 4620dc7e38acSHans Petter Selasky /* set TSO limits so that we don't have to drop TX packets */ 46215dc00f00SJustin Hibbits if_sethwtsomax(ifp, MLX5E_MAX_TX_PAYLOAD_SIZE - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN)); 46225dc00f00SJustin Hibbits if_sethwtsomaxsegcount(ifp, MLX5E_MAX_TX_MBUF_FRAGS - 1 /* hdr */); 46235dc00f00SJustin Hibbits if_sethwtsomaxsegsize(ifp, MLX5E_MAX_TX_MBUF_SIZE); 4624dc7e38acSHans Petter Selasky 46255dc00f00SJustin Hibbits if_setcapenable(ifp, if_getcapabilities(ifp)); 46265dc00f00SJustin Hibbits if_setcapenable2(ifp, if_getcapabilities2(ifp)); 46275dc00f00SJustin Hibbits if_sethwassist(ifp, 0); 46285dc00f00SJustin Hibbits if (if_getcapenable(ifp) & IFCAP_TSO) 46295dc00f00SJustin Hibbits if_sethwassistbits(ifp, CSUM_TSO, 0); 46305dc00f00SJustin Hibbits if (if_getcapenable(ifp) & IFCAP_TXCSUM) 46315dc00f00SJustin Hibbits if_sethwassistbits(ifp, (CSUM_TCP | CSUM_UDP | CSUM_IP), 0); 46325dc00f00SJustin Hibbits if (if_getcapenable(ifp) & IFCAP_TXCSUM_IPV6) 46335dc00f00SJustin Hibbits if_sethwassistbits(ifp, (CSUM_UDP_IPV6 | CSUM_TCP_IPV6), 0); 46345dc00f00SJustin Hibbits if (if_getcapabilities(ifp) & IFCAP_VXLAN_HWCSUM) 46355dc00f00SJustin Hibbits if_sethwassistbits(ifp, CSUM_INNER_IP6_UDP | CSUM_INNER_IP6_TCP | 4636bf202a8dSKonstantin Belousov CSUM_INNER_IP | CSUM_INNER_IP_UDP | CSUM_INNER_IP_TCP | 46375dc00f00SJustin Hibbits CSUM_ENCAP_VXLAN, 0); 46385dc00f00SJustin Hibbits if (if_getcapabilities(ifp) & IFCAP_VXLAN_HWTSO) 46395dc00f00SJustin Hibbits if_sethwassistbits(ifp, CSUM_INNER_IP6_TSO | CSUM_INNER_IP_TSO, 0); 4640dc7e38acSHans Petter Selasky 4641dc7e38acSHans Petter Selasky /* ifnet sysctl tree */ 4642dc7e38acSHans Petter Selasky sysctl_ctx_init(&priv->sysctl_ctx); 4643dc7e38acSHans Petter Selasky priv->sysctl_ifnet = SYSCTL_ADD_NODE(&priv->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_dev), 46445dc00f00SJustin Hibbits OID_AUTO, if_getdname(ifp), CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 46457029da5cSPawel Biernacki "MLX5 ethernet - interface name"); 4646dc7e38acSHans Petter Selasky if (priv->sysctl_ifnet == NULL) { 4647dc7e38acSHans Petter Selasky mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n"); 4648dc7e38acSHans Petter Selasky goto err_free_sysctl; 4649dc7e38acSHans Petter Selasky } 46505dc00f00SJustin Hibbits snprintf(unit, sizeof(unit), "%d", if_getdunit(ifp)); 4651dc7e38acSHans Petter Selasky priv->sysctl_ifnet = SYSCTL_ADD_NODE(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 46527029da5cSPawel Biernacki OID_AUTO, unit, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 46537029da5cSPawel Biernacki "MLX5 ethernet - interface unit"); 4654dc7e38acSHans Petter Selasky if (priv->sysctl_ifnet == NULL) { 4655dc7e38acSHans Petter Selasky mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n"); 4656dc7e38acSHans Petter Selasky goto err_free_sysctl; 4657dc7e38acSHans Petter Selasky } 4658bb3853c6SHans Petter Selasky 4659dc7e38acSHans Petter Selasky /* HW sysctl tree */ 4660dc7e38acSHans Petter Selasky child = SYSCTL_CHILDREN(device_get_sysctl_tree(mdev->pdev->dev.bsddev)); 4661dc7e38acSHans Petter Selasky priv->sysctl_hw = SYSCTL_ADD_NODE(&priv->sysctl_ctx, child, 46627029da5cSPawel Biernacki OID_AUTO, "hw", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 46637029da5cSPawel Biernacki "MLX5 ethernet dev hw"); 4664dc7e38acSHans Petter Selasky if (priv->sysctl_hw == NULL) { 4665dc7e38acSHans Petter Selasky mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n"); 4666dc7e38acSHans Petter Selasky goto err_free_sysctl; 4667dc7e38acSHans Petter Selasky } 46683e581cabSSlava Shwartsman 46693e581cabSSlava Shwartsman err = mlx5e_build_ifp_priv(mdev, priv, ncv); 46703e581cabSSlava Shwartsman if (err) { 46713e581cabSSlava Shwartsman mlx5_core_err(mdev, "mlx5e_build_ifp_priv() failed (%d)\n", err); 46723e581cabSSlava Shwartsman goto err_free_sysctl; 46733e581cabSSlava Shwartsman } 467417778156SHans Petter Selasky 467540218d73SHans Petter Selasky /* reuse mlx5core's watchdog workqueue */ 467640218d73SHans Petter Selasky priv->wq = mdev->priv.health.wq_watchdog; 467717778156SHans Petter Selasky 4678b633e08cSHans Petter Selasky err = mlx5_core_alloc_pd(mdev, &priv->pdn, 0); 4679dc7e38acSHans Petter Selasky if (err) { 46806b4040d8SHans Petter Selasky mlx5_en_err(ifp, "mlx5_core_alloc_pd failed, %d\n", err); 4681f8f5b459SHans Petter Selasky goto err_free_wq; 4682dc7e38acSHans Petter Selasky } 4683b633e08cSHans Petter Selasky err = mlx5_alloc_transport_domain(mdev, &priv->tdn, 0); 4684dc7e38acSHans Petter Selasky if (err) { 46856b4040d8SHans Petter Selasky mlx5_en_err(ifp, 46866b4040d8SHans Petter Selasky "mlx5_alloc_transport_domain failed, %d\n", err); 4687dc7e38acSHans Petter Selasky goto err_dealloc_pd; 4688dc7e38acSHans Petter Selasky } 4689dc7e38acSHans Petter Selasky err = mlx5e_create_mkey(priv, priv->pdn, &priv->mr); 4690dc7e38acSHans Petter Selasky if (err) { 46916b4040d8SHans Petter Selasky mlx5_en_err(ifp, "mlx5e_create_mkey failed, %d\n", err); 4692dc7e38acSHans Petter Selasky goto err_dealloc_transport_domain; 4693dc7e38acSHans Petter Selasky } 4694dc7e38acSHans Petter Selasky mlx5_query_nic_vport_mac_address(priv->mdev, 0, dev_addr); 4695dc7e38acSHans Petter Selasky 469676a5241fSHans Petter Selasky /* check if we should generate a random MAC address */ 469776a5241fSHans Petter Selasky if (MLX5_CAP_GEN(priv->mdev, vport_group_manager) == 0 && 469876a5241fSHans Petter Selasky is_zero_ether_addr(dev_addr)) { 469976a5241fSHans Petter Selasky random_ether_addr(dev_addr); 47006b4040d8SHans Petter Selasky mlx5_en_err(ifp, "Assigned random MAC address\n"); 470176a5241fSHans Petter Selasky } 47027272f9cdSHans Petter Selasky 470338535d6cSHans Petter Selasky err = mlx5e_rl_init(priv); 470438535d6cSHans Petter Selasky if (err) { 47056b4040d8SHans Petter Selasky mlx5_en_err(ifp, "mlx5e_rl_init failed, %d\n", err); 47069dfa2148SHans Petter Selasky goto err_create_mkey; 470738535d6cSHans Petter Selasky } 47087272f9cdSHans Petter Selasky 47097272f9cdSHans Petter Selasky err = mlx5e_tls_init(priv); 47107272f9cdSHans Petter Selasky if (err) { 47117272f9cdSHans Petter Selasky if_printf(ifp, "%s: mlx5e_tls_init failed\n", __func__); 47127272f9cdSHans Petter Selasky goto err_rl_init; 47137272f9cdSHans Petter Selasky } 471476a5241fSHans Petter Selasky 4715e23731dbSKonstantin Belousov if ((if_getcapenable2(ifp) & IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD)) != 0) { 4716e23731dbSKonstantin Belousov err = mlx5e_ipsec_init(priv); 4717e23731dbSKonstantin Belousov if (err) { 4718e23731dbSKonstantin Belousov if_printf(ifp, "%s: mlx5e_tls_init failed\n", __func__); 4719e23731dbSKonstantin Belousov goto err_tls_init; 4720e23731dbSKonstantin Belousov } 4721e23731dbSKonstantin Belousov } 4722e23731dbSKonstantin Belousov 472327b778aeSHans Petter Selasky err = mlx5e_open_drop_rq(priv, &priv->drop_rq); 472427b778aeSHans Petter Selasky if (err) { 47254e40e984SHans Petter Selasky if_printf(ifp, "%s: mlx5e_open_drop_rq failed (%d)\n", __func__, err); 4726e23731dbSKonstantin Belousov goto err_ipsec_init; 472727b778aeSHans Petter Selasky } 472827b778aeSHans Petter Selasky 47298e332232SHans Petter Selasky err = mlx5e_open_rqts(priv); 473033a6a7a7SHans Petter Selasky if (err) { 47318e332232SHans Petter Selasky if_printf(ifp, "%s: mlx5e_open_rqts failed (%d)\n", __func__, err); 473233a6a7a7SHans Petter Selasky goto err_open_drop_rq; 473333a6a7a7SHans Petter Selasky } 473433a6a7a7SHans Petter Selasky 4735e059c120SHans Petter Selasky err = mlx5e_open_tirs(priv); 4736e059c120SHans Petter Selasky if (err) { 4737e059c120SHans Petter Selasky mlx5_en_err(ifp, "mlx5e_open_tirs() failed, %d\n", err); 47388e332232SHans Petter Selasky goto err_open_rqts; 47395381f936SHans Petter Selasky } 47405381f936SHans Petter Selasky 47415381f936SHans Petter Selasky err = mlx5e_open_flow_tables(priv); 47425381f936SHans Petter Selasky if (err) { 47435381f936SHans Petter Selasky if_printf(ifp, "%s: mlx5e_open_flow_tables failed (%d)\n", __func__, err); 47445381f936SHans Petter Selasky goto err_open_tirs; 4745e059c120SHans Petter Selasky } 4746e059c120SHans Petter Selasky 474784d7b8e7SHans Petter Selasky err = mlx5e_tls_rx_init(priv); 474884d7b8e7SHans Petter Selasky if (err) { 474984d7b8e7SHans Petter Selasky if_printf(ifp, "%s: mlx5e_tls_rx_init() failed, %d\n", __func__, err); 475084d7b8e7SHans Petter Selasky goto err_open_flow_tables; 475184d7b8e7SHans Petter Selasky } 475284d7b8e7SHans Petter Selasky 4753dc7e38acSHans Petter Selasky /* set default MTU */ 47545dc00f00SJustin Hibbits mlx5e_set_dev_port_mtu(ifp, if_getmtu(ifp)); 4755dc7e38acSHans Petter Selasky 4756dc7e38acSHans Petter Selasky /* Set default media status */ 4757dc7e38acSHans Petter Selasky priv->media_status_last = IFM_AVALID; 4758bab0c4b1SKonstantin Belousov priv->media_active_last = IFM_ETHER | IFM_AUTO | IFM_FDX; 4759dc7e38acSHans Petter Selasky 47604d3b91a7SHans Petter Selasky /* setup default pauseframes configuration */ 47614d3b91a7SHans Petter Selasky mlx5e_setup_pauseframes(priv); 4762dc7e38acSHans Petter Selasky 4763ac87880aSHans Petter Selasky /* Setup supported medias */ 4764ac87880aSHans Petter Selasky if (!mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1)) { 4765ac87880aSHans Petter Selasky ext = MLX5_CAP_PCAM_FEATURE(mdev, 4766ac87880aSHans Petter Selasky ptys_extended_ethernet); 4767ac87880aSHans Petter Selasky eth_proto_cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, 4768ac87880aSHans Petter Selasky eth_proto_capability); 4769ac87880aSHans Petter Selasky } else { 4770a888087fSHans Petter Selasky ext = false; 4771dc7e38acSHans Petter Selasky eth_proto_cap = 0; 47726b4040d8SHans Petter Selasky mlx5_en_err(ifp, "Query port media capability failed, %d\n", err); 4773dc7e38acSHans Petter Selasky } 4774dc7e38acSHans Petter Selasky 4775bab0c4b1SKonstantin Belousov ifmedia_init(&priv->media, IFM_IMASK, 4776dc7e38acSHans Petter Selasky mlx5e_media_change, mlx5e_media_status); 4777dc7e38acSHans Petter Selasky 4778a888087fSHans Petter Selasky if (ext) { 4779a888087fSHans Petter Selasky for (unsigned i = 0; i != MLX5E_EXT_LINK_SPEEDS_NUMBER; i++) { 4780a888087fSHans Petter Selasky /* check if hardware has the right capability */ 4781a888087fSHans Petter Selasky if (MLX5E_PROT_MASK(i) & ~eth_proto_cap) 4782dc7e38acSHans Petter Selasky continue; 4783a888087fSHans Petter Selasky for (unsigned j = 0; j != MLX5E_CABLE_TYPE_NUMBER; j++) { 4784a888087fSHans Petter Selasky media_entry = mlx5e_ext_mode_table[i][j]; 4785a888087fSHans Petter Selasky if (media_entry.subtype == 0) 4786a888087fSHans Petter Selasky continue; 4787a888087fSHans Petter Selasky /* check if this subtype was already added */ 4788a888087fSHans Petter Selasky for (unsigned k = 0; k != i; k++) { 4789a888087fSHans Petter Selasky /* check if hardware has the right capability */ 4790a888087fSHans Petter Selasky if (MLX5E_PROT_MASK(k) & ~eth_proto_cap) 4791a888087fSHans Petter Selasky continue; 4792a888087fSHans Petter Selasky for (unsigned m = 0; m != MLX5E_CABLE_TYPE_NUMBER; m++) { 4793a888087fSHans Petter Selasky if (media_entry.subtype == mlx5e_ext_mode_table[k][m].subtype) 4794a888087fSHans Petter Selasky goto skip_ext_media; 4795a888087fSHans Petter Selasky } 4796a888087fSHans Petter Selasky } 47974ead8024SKonstantin Belousov mlx5e_ifm_add(priv, media_entry.subtype); 4798a888087fSHans Petter Selasky skip_ext_media:; 4799a888087fSHans Petter Selasky } 4800a888087fSHans Petter Selasky } 4801a888087fSHans Petter Selasky } else { 4802a888087fSHans Petter Selasky for (unsigned i = 0; i != MLX5E_LINK_SPEEDS_NUMBER; i++) { 4803a888087fSHans Petter Selasky media_entry = mlx5e_mode_table[i]; 4804a888087fSHans Petter Selasky if (media_entry.subtype == 0) 4805a888087fSHans Petter Selasky continue; 4806a888087fSHans Petter Selasky if (MLX5E_PROT_MASK(i) & ~eth_proto_cap) 4807a888087fSHans Petter Selasky continue; 4808a888087fSHans Petter Selasky /* check if this subtype was already added */ 4809a888087fSHans Petter Selasky for (unsigned k = 0; k != i; k++) { 4810a888087fSHans Petter Selasky if (media_entry.subtype == mlx5e_mode_table[k].subtype) 4811a888087fSHans Petter Selasky goto skip_media; 4812a888087fSHans Petter Selasky } 4813a888087fSHans Petter Selasky mlx5e_ifm_add(priv, media_entry.subtype); 4814a888087fSHans Petter Selasky 4815a888087fSHans Petter Selasky /* NOTE: 10G ER and LR shares the same entry */ 4816a888087fSHans Petter Selasky if (media_entry.subtype == IFM_10G_ER) 4817a888087fSHans Petter Selasky mlx5e_ifm_add(priv, IFM_10G_LR); 4818a888087fSHans Petter Selasky skip_media:; 4819dc7e38acSHans Petter Selasky } 4820ac87880aSHans Petter Selasky } 4821dc7e38acSHans Petter Selasky 48224ead8024SKonstantin Belousov mlx5e_ifm_add(priv, IFM_AUTO); 48234d3b91a7SHans Petter Selasky 48244d3b91a7SHans Petter Selasky /* Set autoselect by default */ 48254d3b91a7SHans Petter Selasky ifmedia_set(&priv->media, IFM_ETHER | IFM_AUTO | IFM_FDX | 48264d3b91a7SHans Petter Selasky IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE); 482701651e96SHans Petter Selasky 482801651e96SHans Petter Selasky DEBUGNET_SET(ifp, mlx5_en); 482901651e96SHans Petter Selasky 4830dc7e38acSHans Petter Selasky ether_ifattach(ifp, dev_addr); 4831dc7e38acSHans Petter Selasky 4832dc7e38acSHans Petter Selasky /* Register for VLAN events */ 4833dc7e38acSHans Petter Selasky priv->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, 4834dc7e38acSHans Petter Selasky mlx5e_vlan_rx_add_vid, priv, EVENTHANDLER_PRI_FIRST); 4835dc7e38acSHans Petter Selasky priv->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, 4836dc7e38acSHans Petter Selasky mlx5e_vlan_rx_kill_vid, priv, EVENTHANDLER_PRI_FIRST); 4837dc7e38acSHans Petter Selasky 4838861a612dSKonstantin Belousov /* Register for VxLAN events */ 4839861a612dSKonstantin Belousov priv->vxlan_start = EVENTHANDLER_REGISTER(vxlan_start, 4840861a612dSKonstantin Belousov mlx5e_vxlan_start, priv, EVENTHANDLER_PRI_ANY); 4841861a612dSKonstantin Belousov priv->vxlan_stop = EVENTHANDLER_REGISTER(vxlan_stop, 4842861a612dSKonstantin Belousov mlx5e_vxlan_stop, priv, EVENTHANDLER_PRI_ANY); 4843861a612dSKonstantin Belousov 4844dc7e38acSHans Petter Selasky /* Link is down by default */ 4845dc7e38acSHans Petter Selasky if_link_state_change(ifp, LINK_STATE_DOWN); 4846dc7e38acSHans Petter Selasky 4847dc7e38acSHans Petter Selasky mlx5e_enable_async_events(priv); 4848dc7e38acSHans Petter Selasky 4849dc7e38acSHans Petter Selasky mlx5e_add_hw_stats(priv); 4850dc7e38acSHans Petter Selasky 4851dc7e38acSHans Petter Selasky mlx5e_create_stats(&priv->stats.vport.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 4852dc7e38acSHans Petter Selasky "vstats", mlx5e_vport_stats_desc, MLX5E_VPORT_STATS_NUM, 4853dc7e38acSHans Petter Selasky priv->stats.vport.arg); 4854dc7e38acSHans Petter Selasky 4855dc7e38acSHans Petter Selasky mlx5e_create_stats(&priv->stats.pport.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 4856dc7e38acSHans Petter Selasky "pstats", mlx5e_pport_stats_desc, MLX5E_PPORT_STATS_NUM, 4857dc7e38acSHans Petter Selasky priv->stats.pport.arg); 4858dc7e38acSHans Petter Selasky 4859dc7e38acSHans Petter Selasky mlx5e_create_ethtool(priv); 4860dc7e38acSHans Petter Selasky 4861dc7e38acSHans Petter Selasky mtx_lock(&priv->async_events_mtx); 4862dc7e38acSHans Petter Selasky mlx5e_update_stats(priv); 4863dc7e38acSHans Petter Selasky mtx_unlock(&priv->async_events_mtx); 4864dc7e38acSHans Petter Selasky 4865ef23f141SKonstantin Belousov SYSCTL_ADD_INT(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet), 4866ef23f141SKonstantin Belousov OID_AUTO, "rx_clbr_done", CTLFLAG_RD, 4867ef23f141SKonstantin Belousov &priv->clbr_done, 0, 4868ef23f141SKonstantin Belousov "RX timestamps calibration state"); 48690eb2dcd3SKonstantin Belousov callout_init(&priv->tstmp_clbr, 1); 48707cc3ea9cSRandall Stewart /* Pull out the frequency of the clock in hz */ 48717cc3ea9cSRandall Stewart priv->cclk = (uint64_t)MLX5_CAP_GEN(mdev, device_frequency_khz) * 1000ULL; 4872ef23f141SKonstantin Belousov mlx5e_reset_calibration_callout(priv); 4873ef23f141SKonstantin Belousov 4874538ff57bSAndrew Gallatin pa.pa_version = PFIL_VERSION; 4875538ff57bSAndrew Gallatin pa.pa_flags = PFIL_IN; 4876538ff57bSAndrew Gallatin pa.pa_type = PFIL_TYPE_ETHERNET; 48775dc00f00SJustin Hibbits pa.pa_headname = if_name(ifp); 4878538ff57bSAndrew Gallatin priv->pfil = pfil_head_register(&pa); 4879538ff57bSAndrew Gallatin 4880e059c120SHans Petter Selasky PRIV_LOCK(priv); 4881e059c120SHans Petter Selasky err = mlx5e_open_flow_rules(priv); 4882e059c120SHans Petter Selasky if (err) { 4883e059c120SHans Petter Selasky mlx5_en_err(ifp, 4884e059c120SHans Petter Selasky "mlx5e_open_flow_rules() failed, %d (ignored)\n", err); 4885e059c120SHans Petter Selasky } 4886e059c120SHans Petter Selasky PRIV_UNLOCK(priv); 4887e059c120SHans Petter Selasky 4888dc7e38acSHans Petter Selasky return (priv); 4889dc7e38acSHans Petter Selasky 489084d7b8e7SHans Petter Selasky err_open_flow_tables: 489184d7b8e7SHans Petter Selasky mlx5e_close_flow_tables(priv); 489284d7b8e7SHans Petter Selasky 48935381f936SHans Petter Selasky err_open_tirs: 48945381f936SHans Petter Selasky mlx5e_close_tirs(priv); 4895e059c120SHans Petter Selasky 48968e332232SHans Petter Selasky err_open_rqts: 48978e332232SHans Petter Selasky mlx5e_close_rqts(priv); 4898e059c120SHans Petter Selasky 489933a6a7a7SHans Petter Selasky err_open_drop_rq: 490033a6a7a7SHans Petter Selasky mlx5e_close_drop_rq(&priv->drop_rq); 490133a6a7a7SHans Petter Selasky 4902e23731dbSKonstantin Belousov err_ipsec_init: 4903e23731dbSKonstantin Belousov mlx5e_ipsec_cleanup(priv); 4904e23731dbSKonstantin Belousov 490527b778aeSHans Petter Selasky err_tls_init: 490627b778aeSHans Petter Selasky mlx5e_tls_cleanup(priv); 490727b778aeSHans Petter Selasky 49087272f9cdSHans Petter Selasky err_rl_init: 49097272f9cdSHans Petter Selasky mlx5e_rl_cleanup(priv); 49107272f9cdSHans Petter Selasky 491138535d6cSHans Petter Selasky err_create_mkey: 491238535d6cSHans Petter Selasky mlx5_core_destroy_mkey(priv->mdev, &priv->mr); 49137272f9cdSHans Petter Selasky 4914dc7e38acSHans Petter Selasky err_dealloc_transport_domain: 4915b633e08cSHans Petter Selasky mlx5_dealloc_transport_domain(mdev, priv->tdn, 0); 4916dc7e38acSHans Petter Selasky 4917dc7e38acSHans Petter Selasky err_dealloc_pd: 4918b633e08cSHans Petter Selasky mlx5_core_dealloc_pd(mdev, priv->pdn, 0); 4919dc7e38acSHans Petter Selasky 492017778156SHans Petter Selasky err_free_wq: 492140218d73SHans Petter Selasky flush_workqueue(priv->wq); 492217778156SHans Petter Selasky 4923dc7e38acSHans Petter Selasky err_free_sysctl: 4924dc7e38acSHans Petter Selasky sysctl_ctx_free(&priv->sysctl_ctx); 4925b3cf1493SSlava Shwartsman if (priv->sysctl_debug) 4926b3cf1493SSlava Shwartsman sysctl_ctx_free(&priv->stats.port_stats_debug.ctx); 49279dfa2148SHans Petter Selasky mlx5e_priv_static_destroy(priv, mdev, mdev->priv.eq_table.num_comp_vectors); 49289dfa2148SHans Petter Selasky 49299dfa2148SHans Petter Selasky err_free_ifp: 4930dc7e38acSHans Petter Selasky if_free(ifp); 4931dc7e38acSHans Petter Selasky free(priv, M_MLX5EN); 4932dc7e38acSHans Petter Selasky return (NULL); 4933dc7e38acSHans Petter Selasky } 4934dc7e38acSHans Petter Selasky 4935dc7e38acSHans Petter Selasky static void 4936dc7e38acSHans Petter Selasky mlx5e_destroy_ifp(struct mlx5_core_dev *mdev, void *vpriv) 4937dc7e38acSHans Petter Selasky { 4938dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = vpriv; 49395dc00f00SJustin Hibbits if_t ifp = priv->ifp; 4940dc7e38acSHans Petter Selasky 4941dc7e38acSHans Petter Selasky /* don't allow more IOCTLs */ 4942dc7e38acSHans Petter Selasky priv->gone = 1; 4943dc7e38acSHans Petter Selasky 4944dc7e38acSHans Petter Selasky /* XXX wait a bit to allow IOCTL handlers to complete */ 4945dc7e38acSHans Petter Selasky pause("W", hz); 4946dc7e38acSHans Petter Selasky 494738535d6cSHans Petter Selasky #ifdef RATELIMIT 494838535d6cSHans Petter Selasky /* 49491f628be8SAndrew Gallatin * Tell the TCP ratelimit code to release the rate-sets attached 49501f628be8SAndrew Gallatin * to our ifnet. 49511f628be8SAndrew Gallatin */ 49521f628be8SAndrew Gallatin tcp_rl_release_ifnet(ifp); 49531f628be8SAndrew Gallatin /* 49541f628be8SAndrew Gallatin * The kernel can still have reference(s) via the m_snd_tag's into 495538535d6cSHans Petter Selasky * the ratelimit channels, and these must go away before 495638535d6cSHans Petter Selasky * detaching: 495738535d6cSHans Petter Selasky */ 495838535d6cSHans Petter Selasky while (READ_ONCE(priv->rl.stats.tx_active_connections) != 0) { 49596b4040d8SHans Petter Selasky mlx5_en_err(priv->ifp, 49606b4040d8SHans Petter Selasky "Waiting for all ratelimit connections to terminate\n"); 496138535d6cSHans Petter Selasky pause("W", hz); 496238535d6cSHans Petter Selasky } 496338535d6cSHans Petter Selasky #endif 49643a934ba7SHans Petter Selasky 49653a934ba7SHans Petter Selasky #ifdef KERN_TLS 49663a934ba7SHans Petter Selasky /* wait for all TLS tags to get freed */ 49673a934ba7SHans Petter Selasky while (priv->tls.init != 0 && 49683a934ba7SHans Petter Selasky uma_zone_get_cur(priv->tls.zone) != 0) { 49693a934ba7SHans Petter Selasky mlx5_en_err(priv->ifp, 49703a934ba7SHans Petter Selasky "Waiting for all TLS connections to terminate\n"); 49713a934ba7SHans Petter Selasky pause("W", hz); 49723a934ba7SHans Petter Selasky } 497384d7b8e7SHans Petter Selasky 497484d7b8e7SHans Petter Selasky /* wait for all TLS RX tags to get freed */ 497584d7b8e7SHans Petter Selasky while (priv->tls_rx.init != 0 && 497684d7b8e7SHans Petter Selasky uma_zone_get_cur(priv->tls_rx.zone) != 0) { 497784d7b8e7SHans Petter Selasky mlx5_en_err(priv->ifp, 497884d7b8e7SHans Petter Selasky "Waiting for all TLS RX connections to terminate\n"); 497984d7b8e7SHans Petter Selasky pause("W", hz); 498084d7b8e7SHans Petter Selasky } 49813a934ba7SHans Petter Selasky #endif 4982c84e0068SHans Petter Selasky /* wait for all unlimited send tags to complete */ 4983c84e0068SHans Petter Selasky mlx5e_priv_wait_for_completion(priv, mdev->priv.eq_table.num_comp_vectors); 4984c84e0068SHans Petter Selasky 4985dc7e38acSHans Petter Selasky /* stop watchdog timer */ 4986dc7e38acSHans Petter Selasky callout_drain(&priv->watchdog); 4987dc7e38acSHans Petter Selasky 4988ef23f141SKonstantin Belousov callout_drain(&priv->tstmp_clbr); 4989ef23f141SKonstantin Belousov 4990dc7e38acSHans Petter Selasky if (priv->vlan_attach != NULL) 4991dc7e38acSHans Petter Selasky EVENTHANDLER_DEREGISTER(vlan_config, priv->vlan_attach); 4992dc7e38acSHans Petter Selasky if (priv->vlan_detach != NULL) 4993dc7e38acSHans Petter Selasky EVENTHANDLER_DEREGISTER(vlan_unconfig, priv->vlan_detach); 4994861a612dSKonstantin Belousov if (priv->vxlan_start != NULL) 4995861a612dSKonstantin Belousov EVENTHANDLER_DEREGISTER(vxlan_start, priv->vxlan_start); 4996861a612dSKonstantin Belousov if (priv->vxlan_stop != NULL) 4997861a612dSKonstantin Belousov EVENTHANDLER_DEREGISTER(vxlan_stop, priv->vxlan_stop); 4998dc7e38acSHans Petter Selasky 4999dc7e38acSHans Petter Selasky /* make sure device gets closed */ 5000dc7e38acSHans Petter Selasky PRIV_LOCK(priv); 5001dc7e38acSHans Petter Selasky mlx5e_close_locked(ifp); 5002e059c120SHans Petter Selasky mlx5e_close_flow_rules(priv); 5003dc7e38acSHans Petter Selasky PRIV_UNLOCK(priv); 5004dc7e38acSHans Petter Selasky 5005538ff57bSAndrew Gallatin /* deregister pfil */ 5006538ff57bSAndrew Gallatin if (priv->pfil != NULL) { 5007538ff57bSAndrew Gallatin pfil_head_unregister(priv->pfil); 5008538ff57bSAndrew Gallatin priv->pfil = NULL; 5009538ff57bSAndrew Gallatin } 5010538ff57bSAndrew Gallatin 5011dc7e38acSHans Petter Selasky /* unregister device */ 5012dc7e38acSHans Petter Selasky ifmedia_removeall(&priv->media); 5013dc7e38acSHans Petter Selasky ether_ifdetach(ifp); 5014dc7e38acSHans Petter Selasky 501584d7b8e7SHans Petter Selasky mlx5e_tls_rx_cleanup(priv); 5016e23731dbSKonstantin Belousov #ifdef IPSEC_OFFLOAD 5017e23731dbSKonstantin Belousov ipsec_accel_on_ifdown(priv->ifp); 5018e23731dbSKonstantin Belousov #endif 5019e059c120SHans Petter Selasky mlx5e_close_flow_tables(priv); 50205381f936SHans Petter Selasky mlx5e_close_tirs(priv); 50218e332232SHans Petter Selasky mlx5e_close_rqts(priv); 502227b778aeSHans Petter Selasky mlx5e_close_drop_rq(&priv->drop_rq); 5023e23731dbSKonstantin Belousov mlx5e_ipsec_cleanup(priv); 50247272f9cdSHans Petter Selasky mlx5e_tls_cleanup(priv); 502538535d6cSHans Petter Selasky mlx5e_rl_cleanup(priv); 50267272f9cdSHans Petter Selasky 5027dc7e38acSHans Petter Selasky /* destroy all remaining sysctl nodes */ 5028dc7e38acSHans Petter Selasky sysctl_ctx_free(&priv->stats.vport.ctx); 5029dc7e38acSHans Petter Selasky sysctl_ctx_free(&priv->stats.pport.ctx); 5030b3cf1493SSlava Shwartsman if (priv->sysctl_debug) 5031b3cf1493SSlava Shwartsman sysctl_ctx_free(&priv->stats.port_stats_debug.ctx); 5032069963d7SHans Petter Selasky sysctl_ctx_free(&priv->sysctl_ctx); 5033dc7e38acSHans Petter Selasky 5034dc7e38acSHans Petter Selasky mlx5_core_destroy_mkey(priv->mdev, &priv->mr); 5035b633e08cSHans Petter Selasky mlx5_dealloc_transport_domain(priv->mdev, priv->tdn, 0); 5036b633e08cSHans Petter Selasky mlx5_core_dealloc_pd(priv->mdev, priv->pdn, 0); 5037dc7e38acSHans Petter Selasky mlx5e_disable_async_events(priv); 503840218d73SHans Petter Selasky flush_workqueue(priv->wq); 50399dfa2148SHans Petter Selasky mlx5e_priv_static_destroy(priv, mdev, mdev->priv.eq_table.num_comp_vectors); 5040eeb1ff98SHans Petter Selasky if_free(ifp); 5041dc7e38acSHans Petter Selasky free(priv, M_MLX5EN); 5042dc7e38acSHans Petter Selasky } 5043dc7e38acSHans Petter Selasky 504401651e96SHans Petter Selasky #ifdef DEBUGNET 504501651e96SHans Petter Selasky static void 50465dc00f00SJustin Hibbits mlx5_en_debugnet_init(if_t dev, int *nrxr, int *ncl, int *clsize) 504701651e96SHans Petter Selasky { 504801651e96SHans Petter Selasky struct mlx5e_priv *priv = if_getsoftc(dev); 504901651e96SHans Petter Selasky 505001651e96SHans Petter Selasky PRIV_LOCK(priv); 505101651e96SHans Petter Selasky *nrxr = priv->params.num_channels; 505201651e96SHans Petter Selasky *ncl = DEBUGNET_MAX_IN_FLIGHT; 505301651e96SHans Petter Selasky *clsize = MLX5E_MAX_RX_BYTES; 505401651e96SHans Petter Selasky PRIV_UNLOCK(priv); 505501651e96SHans Petter Selasky } 505601651e96SHans Petter Selasky 505701651e96SHans Petter Selasky static void 50585dc00f00SJustin Hibbits mlx5_en_debugnet_event(if_t dev, enum debugnet_ev event) 505901651e96SHans Petter Selasky { 506001651e96SHans Petter Selasky } 506101651e96SHans Petter Selasky 506201651e96SHans Petter Selasky static int 50635dc00f00SJustin Hibbits mlx5_en_debugnet_transmit(if_t dev, struct mbuf *m) 506401651e96SHans Petter Selasky { 506501651e96SHans Petter Selasky struct mlx5e_priv *priv = if_getsoftc(dev); 506601651e96SHans Petter Selasky struct mlx5e_sq *sq; 506701651e96SHans Petter Selasky int err; 506801651e96SHans Petter Selasky 506901651e96SHans Petter Selasky if ((if_getdrvflags(dev) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 507001651e96SHans Petter Selasky IFF_DRV_RUNNING || (priv->media_status_last & IFM_ACTIVE) == 0) 507101651e96SHans Petter Selasky return (ENOENT); 507201651e96SHans Petter Selasky 507301651e96SHans Petter Selasky sq = &priv->channel[0].sq[0]; 507401651e96SHans Petter Selasky 507501651e96SHans Petter Selasky if (sq->running == 0) { 507601651e96SHans Petter Selasky m_freem(m); 507701651e96SHans Petter Selasky return (ENOENT); 507801651e96SHans Petter Selasky } 507901651e96SHans Petter Selasky 508001651e96SHans Petter Selasky if (mlx5e_sq_xmit(sq, &m) != 0) { 508101651e96SHans Petter Selasky m_freem(m); 508201651e96SHans Petter Selasky err = ENOBUFS; 508301651e96SHans Petter Selasky } else { 508401651e96SHans Petter Selasky err = 0; 508501651e96SHans Petter Selasky } 508601651e96SHans Petter Selasky 50872d5e5a0dSHans Petter Selasky mlx5e_tx_notify_hw(sq, true); 50882d5e5a0dSHans Petter Selasky 508901651e96SHans Petter Selasky return (err); 509001651e96SHans Petter Selasky } 509101651e96SHans Petter Selasky 509201651e96SHans Petter Selasky static int 50935dc00f00SJustin Hibbits mlx5_en_debugnet_poll(if_t dev, int count) 509401651e96SHans Petter Selasky { 509501651e96SHans Petter Selasky struct mlx5e_priv *priv = if_getsoftc(dev); 509601651e96SHans Petter Selasky 509701651e96SHans Petter Selasky if ((if_getdrvflags(dev) & IFF_DRV_RUNNING) == 0 || 509801651e96SHans Petter Selasky (priv->media_status_last & IFM_ACTIVE) == 0) 509901651e96SHans Petter Selasky return (ENOENT); 510001651e96SHans Petter Selasky 510101651e96SHans Petter Selasky mlx5_poll_interrupts(priv->mdev); 510201651e96SHans Petter Selasky 510301651e96SHans Petter Selasky return (0); 510401651e96SHans Petter Selasky } 510501651e96SHans Petter Selasky #endif /* DEBUGNET */ 510601651e96SHans Petter Selasky 5107dc7e38acSHans Petter Selasky static void * 5108dc7e38acSHans Petter Selasky mlx5e_get_ifp(void *vpriv) 5109dc7e38acSHans Petter Selasky { 5110dc7e38acSHans Petter Selasky struct mlx5e_priv *priv = vpriv; 5111dc7e38acSHans Petter Selasky 5112dc7e38acSHans Petter Selasky return (priv->ifp); 5113dc7e38acSHans Petter Selasky } 5114dc7e38acSHans Petter Selasky 5115dc7e38acSHans Petter Selasky static struct mlx5_interface mlx5e_interface = { 5116dc7e38acSHans Petter Selasky .add = mlx5e_create_ifp, 5117dc7e38acSHans Petter Selasky .remove = mlx5e_destroy_ifp, 5118dc7e38acSHans Petter Selasky .event = mlx5e_async_event, 5119dc7e38acSHans Petter Selasky .protocol = MLX5_INTERFACE_PROTOCOL_ETH, 5120dc7e38acSHans Petter Selasky .get_dev = mlx5e_get_ifp, 5121dc7e38acSHans Petter Selasky }; 5122dc7e38acSHans Petter Selasky 5123dc7e38acSHans Petter Selasky void 5124dc7e38acSHans Petter Selasky mlx5e_init(void) 5125dc7e38acSHans Petter Selasky { 5126dc7e38acSHans Petter Selasky mlx5_register_interface(&mlx5e_interface); 5127dc7e38acSHans Petter Selasky } 5128dc7e38acSHans Petter Selasky 5129dc7e38acSHans Petter Selasky void 5130dc7e38acSHans Petter Selasky mlx5e_cleanup(void) 5131dc7e38acSHans Petter Selasky { 5132dc7e38acSHans Petter Selasky mlx5_unregister_interface(&mlx5e_interface); 5133dc7e38acSHans Petter Selasky } 5134dc7e38acSHans Petter Selasky 51351866c98eSHans Petter Selasky module_init_order(mlx5e_init, SI_ORDER_SIXTH); 51361866c98eSHans Petter Selasky module_exit_order(mlx5e_cleanup, SI_ORDER_SIXTH); 5137dc7e38acSHans Petter Selasky 5138e23731dbSKonstantin Belousov MODULE_DEPEND(mlx5en, ipsec, 1, 1, 1); 5139dc7e38acSHans Petter Selasky MODULE_DEPEND(mlx5en, linuxkpi, 1, 1, 1); 5140dc7e38acSHans Petter Selasky MODULE_DEPEND(mlx5en, mlx5, 1, 1, 1); 5141dc7e38acSHans Petter Selasky MODULE_VERSION(mlx5en, 1); 5142