aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/mlx5/mlx5_en/mlx5_en_main.c')
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_main.c376
1 files changed, 254 insertions, 122 deletions
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index e1dbd02fcf3a..f83506bda1aa 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -24,17 +24,22 @@
* SUCH DAMAGE.
*/
+#include "opt_ipsec.h"
#include "opt_kern_tls.h"
#include "opt_rss.h"
#include "opt_ratelimit.h"
#include <dev/mlx5/mlx5_en/en.h>
+#include <dev/mlx5/mlx5_accel/ipsec.h>
#include <sys/eventhandler.h>
#include <sys/sockio.h>
#include <machine/atomic.h>
#include <net/debugnet.h>
+#include <netinet/tcp_ratelimit.h>
+#include <netipsec/keydb.h>
+#include <netipsec/ipsec_offload.h>
static int mlx5e_get_wqe_sz(struct mlx5e_priv *priv, u32 *wqe_sz, u32 *nsegs);
static if_snd_tag_query_t mlx5e_ul_snd_tag_query;
@@ -164,186 +169,186 @@ static const struct media mlx5e_mode_table[MLX5E_LINK_SPEEDS_NUMBER] =
},
};
-static const struct media mlx5e_ext_mode_table[MLX5E_EXT_LINK_SPEEDS_NUMBER][MLX5E_CABLE_TYPE_NUMBER] =
+static const struct media mlx5e_ext_mode_table[MLX5E_EXT_LINK_SPEEDS_NUMBER][MLX5E_CONNECTOR_TYPE_NUMBER] =
{
/**/
- [MLX5E_SGMII_100M][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_SGMII_100M][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_100_SGMII,
.baudrate = IF_Mbps(100),
},
/**/
- [MLX5E_1000BASE_X_SGMII][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_1000BASE_X_SGMII][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_1000_CX,
.baudrate = IF_Mbps(1000),
},
- [MLX5E_1000BASE_X_SGMII][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_1000BASE_X_SGMII][MLX5E_PORT_FIBRE] = {
.subtype = IFM_1000_SX,
.baudrate = IF_Mbps(1000),
},
/**/
- [MLX5E_5GBASE_R][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_5GBASE_R][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_5000_KR,
.baudrate = IF_Mbps(5000),
},
- [MLX5E_5GBASE_R][MLX5E_CABLE_TYPE_TWISTED_PAIR] = {
+ [MLX5E_5GBASE_R][MLX5E_PORT_TP] = {
.subtype = IFM_5000_T,
.baudrate = IF_Mbps(5000),
},
/**/
- [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_10G_KR,
.baudrate = IF_Gbps(10ULL),
},
- [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_PORT_DA] = {
.subtype = IFM_10G_CR1,
.baudrate = IF_Gbps(10ULL),
},
- [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_10GBASE_XFI_XAUI_1][MLX5E_PORT_FIBRE] = {
.subtype = IFM_10G_SR,
.baudrate = IF_Gbps(10ULL),
},
/**/
- [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_40G_KR4,
.baudrate = IF_Gbps(40ULL),
},
- [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_PORT_DA] = {
.subtype = IFM_40G_CR4,
.baudrate = IF_Gbps(40ULL),
},
- [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_40GBASE_XLAUI_4_XLPPI_4][MLX5E_PORT_FIBRE] = {
.subtype = IFM_40G_SR4,
.baudrate = IF_Gbps(40ULL),
},
/**/
- [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_25G_KR,
.baudrate = IF_Gbps(25ULL),
},
- [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_PORT_DA] = {
.subtype = IFM_25G_CR,
.baudrate = IF_Gbps(25ULL),
},
- [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_PORT_FIBRE] = {
.subtype = IFM_25G_SR,
.baudrate = IF_Gbps(25ULL),
},
- [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_CABLE_TYPE_TWISTED_PAIR] = {
+ [MLX5E_25GAUI_1_25GBASE_CR_KR][MLX5E_PORT_TP] = {
.subtype = IFM_25G_T,
.baudrate = IF_Gbps(25ULL),
},
/**/
- [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_50G_KR2,
.baudrate = IF_Gbps(50ULL),
},
- [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_PORT_DA] = {
.subtype = IFM_50G_CR2,
.baudrate = IF_Gbps(50ULL),
},
- [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2][MLX5E_PORT_FIBRE] = {
.subtype = IFM_50G_SR2,
.baudrate = IF_Gbps(50ULL),
},
/**/
- [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_50G_KR_PAM4,
.baudrate = IF_Gbps(50ULL),
},
- [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_PORT_DA] = {
.subtype = IFM_50G_CP,
.baudrate = IF_Gbps(50ULL),
},
- [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR][MLX5E_PORT_FIBRE] = {
.subtype = IFM_50G_SR,
.baudrate = IF_Gbps(50ULL),
},
/**/
- [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_100G_KR4,
.baudrate = IF_Gbps(100ULL),
},
- [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_PORT_DA] = {
.subtype = IFM_100G_CR4,
.baudrate = IF_Gbps(100ULL),
},
- [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_CAUI_4_100GBASE_CR4_KR4][MLX5E_PORT_FIBRE] = {
.subtype = IFM_100G_SR4,
.baudrate = IF_Gbps(100ULL),
},
/**/
- [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_100G_KR_PAM4,
.baudrate = IF_Gbps(100ULL),
},
- [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_PORT_DA] = {
.subtype = IFM_100G_CR_PAM4,
.baudrate = IF_Gbps(100ULL),
},
- [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_100GAUI_1_100GBASE_CR_KR][MLX5E_PORT_FIBRE] = {
.subtype = IFM_100G_SR2, /* XXX */
.baudrate = IF_Gbps(100ULL),
},
/**/
- [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_100G_KR4,
.baudrate = IF_Gbps(100ULL),
},
- [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_PORT_DA] = {
.subtype = IFM_100G_CP2,
.baudrate = IF_Gbps(100ULL),
},
- [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_100GAUI_2_100GBASE_CR2_KR2][MLX5E_PORT_FIBRE] = {
.subtype = IFM_100G_SR2,
.baudrate = IF_Gbps(100ULL),
},
/**/
- [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_200G_KR4_PAM4, /* XXX */
.baudrate = IF_Gbps(200ULL),
},
- [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_PORT_DA] = {
.subtype = IFM_200G_CR4_PAM4, /* XXX */
.baudrate = IF_Gbps(200ULL),
},
- [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_200GAUI_2_200GBASE_CR2_KR2][MLX5E_PORT_FIBRE] = {
.subtype = IFM_200G_SR4, /* XXX */
.baudrate = IF_Gbps(200ULL),
},
/**/
- [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_200G_KR4_PAM4,
.baudrate = IF_Gbps(200ULL),
},
- [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_CABLE_TYPE_PASSIVE_COPPER] = {
+ [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_PORT_DA] = {
.subtype = IFM_200G_CR4_PAM4,
.baudrate = IF_Gbps(200ULL),
},
- [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_CABLE_TYPE_OPTICAL_MODULE] = {
+ [MLX5E_200GAUI_4_200GBASE_CR4_KR4][MLX5E_PORT_FIBRE] = {
.subtype = IFM_200G_SR4,
.baudrate = IF_Gbps(200ULL),
},
/**/
- [MLX5E_400GAUI_8][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_400GAUI_8][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_400G_LR8, /* XXX */
.baudrate = IF_Gbps(400ULL),
},
/**/
- [MLX5E_400GAUI_4_400GBASE_CR4_KR4][MLX5E_CABLE_TYPE_UNKNOWN] = {
+ [MLX5E_400GAUI_4_400GBASE_CR4_KR4][MLX5E_PORT_UNKNOWN] = {
.subtype = IFM_400G_LR8, /* XXX */
.baudrate = IF_Gbps(400ULL),
},
@@ -367,7 +372,7 @@ mlx5e_update_carrier(struct mlx5e_priv *priv)
u32 eth_proto_oper;
int error;
u8 i;
- u8 cable_type;
+ u8 connector_type;
u8 port_state;
u8 is_er_type;
bool ext;
@@ -398,24 +403,14 @@ mlx5e_update_carrier(struct mlx5e_priv *priv)
ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
eth_proto_oper);
-
+ connector_type = MLX5_GET(ptys_reg, out, connector_type);
i = ilog2(eth_proto_oper);
if (ext) {
- error = mlx5_query_pddr_cable_type(mdev, 1, &cable_type);
- if (error != 0) {
- /* use fallback entry */
- media_entry = mlx5e_ext_mode_table[i][MLX5E_CABLE_TYPE_UNKNOWN];
-
- mlx5_en_err(priv->ifp,
- "query port pddr failed: %d\n", error);
- } else {
- media_entry = mlx5e_ext_mode_table[i][cable_type];
-
+ media_entry = mlx5e_ext_mode_table[i][connector_type];
/* check if we should use fallback entry */
- if (media_entry.subtype == 0)
- media_entry = mlx5e_ext_mode_table[i][MLX5E_CABLE_TYPE_UNKNOWN];
- }
+ if (media_entry.subtype == 0)
+ media_entry = mlx5e_ext_mode_table[i][MLX5E_PORT_UNKNOWN];
} else {
media_entry = mlx5e_mode_table[i];
}
@@ -1221,9 +1216,9 @@ mlx5e_create_rq(struct mlx5e_channel *c,
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- nsegs * MLX5E_MAX_RX_BYTES, /* maxsize */
+ nsegs * wqe_sz, /* maxsize */
nsegs, /* nsegments */
- nsegs * MLX5E_MAX_RX_BYTES, /* maxsegsize */
+ nsegs * wqe_sz, /* maxsegsize */
0, /* flags */
NULL, NULL, /* lockfunc, lockfuncarg */
&rq->dma_tag)))
@@ -1320,6 +1315,8 @@ mlx5e_destroy_rq(struct mlx5e_rq *rq)
wq_sz = mlx5_wq_ll_get_size(&rq->wq);
for (i = 0; i != wq_sz; i++) {
if (rq->mbuf[i].mbuf != NULL) {
+ if (rq->mbuf[i].ipsec_mtag != NULL)
+ m_tag_free(&rq->mbuf[i].ipsec_mtag->tag);
bus_dmamap_unload(rq->dma_tag, rq->mbuf[i].dma_map);
m_freem(rq->mbuf[i].mbuf);
}
@@ -1463,6 +1460,17 @@ static void
mlx5e_close_rq_wait(struct mlx5e_rq *rq)
{
+ mtx_lock(&rq->mtx);
+ MPASS(rq->enabled == 0);
+ while (rq->processing > 0) {
+ /*
+ * No wakeup, relying on timeout.
+ * Use msleep_sbt() since msleep() conflicts with linuxkpi.
+ */
+ msleep_sbt(&rq->processing, &rq->mtx, 0, "mlx5ecrq",
+ tick_sbt * hz, 0, C_HARDCLOCK);
+ }
+ mtx_unlock(&rq->mtx);
mlx5e_disable_rq(rq);
mlx5e_close_cq(&rq->cq);
cancel_work_sync(&rq->dim.work);
@@ -2310,30 +2318,18 @@ mlx5e_close_channel_wait(struct mlx5e_channel *c)
static int
mlx5e_get_wqe_sz(struct mlx5e_priv *priv, u32 *wqe_sz, u32 *nsegs)
{
- u32 r, n;
+ u32 r, n, maxs;
- r = priv->params.hw_lro_en ? priv->params.lro_wqe_sz :
+ maxs = priv->params.hw_lro_en ? priv->params.lro_wqe_sz :
MLX5E_SW2MB_MTU(if_getmtu(priv->ifp));
- if (r > MJUM16BYTES)
- return (-ENOMEM);
-
- if (r > MJUM9BYTES)
- r = MJUM16BYTES;
- else if (r > MJUMPAGESIZE)
- r = MJUM9BYTES;
- else if (r > MCLBYTES)
- r = MJUMPAGESIZE;
- else
- r = MCLBYTES;
+ r = maxs > MCLBYTES ? MJUMPAGESIZE : MCLBYTES;
/*
* n + 1 must be a power of two, because stride size must be.
* Stride size is 16 * (n + 1), as the first segment is
* control.
*/
- for (n = howmany(r, MLX5E_MAX_RX_BYTES); !powerof2(n + 1); n++)
- ;
-
+ n = roundup_pow_of_two(1 + howmany(maxs, r)) - 1;
if (n > MLX5E_MAX_BUSDMA_RX_SEGS)
return (-ENOMEM);
@@ -2940,6 +2936,71 @@ mlx5e_get_rss_key(void *key_ptr)
}
static void
+mlx5e_hw_lro_set_tir_ctx_lro_max_msg_sz(struct mlx5e_priv *priv, u32 *tirc)
+{
+ MLX5_SET(tirc, tirc, lro_max_msg_sz, (priv->params.lro_wqe_sz >> 8) -
+ (MLX5_CAP_ETH(priv->mdev, lro_max_msg_sz_mode) == 0 ? 1 : 0));
+}
+
+static void
+mlx5e_hw_lro_set_tir_ctx(struct mlx5e_priv *priv, u32 *tirc)
+{
+ MLX5_SET(tirc, tirc, lro_enable_mask,
+ MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
+ MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO);
+ /* TODO: add the option to choose timer value dynamically */
+ MLX5_SET(tirc, tirc, lro_timeout_period_usecs,
+ MLX5_CAP_ETH(priv->mdev, lro_timer_supported_periods[2]));
+ mlx5e_hw_lro_set_tir_ctx_lro_max_msg_sz(priv, tirc);
+}
+
+static int
+mlx5e_hw_lro_update_tir(struct mlx5e_priv *priv, int tt, bool inner_vxlan)
+{
+ struct mlx5_core_dev *mdev = priv->mdev;
+ u32 *in;
+ void *tirc;
+ int inlen;
+ int err;
+
+ inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
+ in = mlx5_vzalloc(inlen);
+ if (in == NULL)
+ return (-ENOMEM);
+ tirc = MLX5_ADDR_OF(modify_tir_in, in, tir_context);
+
+ /* fill the command part */
+ MLX5_SET(modify_tir_in, in, tirn, inner_vxlan ?
+ priv->tirn_inner_vxlan[tt] : priv->tirn[tt]);
+ MLX5_SET64(modify_tir_in, in, modify_bitmask,
+ (1 << MLX5_MODIFY_TIR_BITMASK_LRO));
+
+ /* fill the context */
+ if (priv->params.hw_lro_en)
+ mlx5e_hw_lro_set_tir_ctx(priv, tirc);
+
+ err = mlx5_core_modify_tir(mdev, in, inlen);
+
+ kvfree(in);
+ return (err);
+}
+
+int
+mlx5e_hw_lro_update_tirs(struct mlx5e_priv *priv)
+{
+ int err, err1, i;
+
+ err = 0;
+ for (i = 0; i != 2 * MLX5E_NUM_TT; i++) {
+ err1 = mlx5e_hw_lro_update_tir(priv, i / 2, (i % 2) ? true :
+ false);
+ if (err1 != 0 && err == 0)
+ err = err1;
+ }
+ return (-err);
+}
+
+static void
mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, int tt, bool inner_vxlan)
{
void *hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
@@ -2949,8 +3010,6 @@ mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, int tt, bool inner_vxla
MLX5_SET(tirc, tirc, transport_domain, priv->tdn);
-#define ROUGH_MAX_L2_L3_HDR_SZ 256
-
#define MLX5_HASH_IP (MLX5_HASH_FIELD_SEL_SRC_IP |\
MLX5_HASH_FIELD_SEL_DST_IP)
@@ -2963,18 +3022,8 @@ mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, int tt, bool inner_vxla
MLX5_HASH_FIELD_SEL_DST_IP |\
MLX5_HASH_FIELD_SEL_IPSEC_SPI)
- if (priv->params.hw_lro_en) {
- MLX5_SET(tirc, tirc, lro_enable_mask,
- MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
- MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO);
- MLX5_SET(tirc, tirc, lro_max_msg_sz,
- (priv->params.lro_wqe_sz -
- ROUGH_MAX_L2_L3_HDR_SZ) >> 8);
- /* TODO: add the option to choose timer value dynamically */
- MLX5_SET(tirc, tirc, lro_timeout_period_usecs,
- MLX5_CAP_ETH(priv->mdev,
- lro_timer_supported_periods[2]));
- }
+ if (priv->params.hw_lro_en)
+ mlx5e_hw_lro_set_tir_ctx(priv, tirc);
if (inner_vxlan)
MLX5_SET(tirc, tirc, tunneled_offload_en, 1);
@@ -3399,6 +3448,51 @@ mlx5e_set_rx_mode(if_t ifp)
queue_work(priv->wq, &priv->set_rx_mode_work);
}
+static bool
+mlx5e_is_ipsec_capable(struct mlx5_core_dev *mdev)
+{
+#ifdef IPSEC_OFFLOAD
+ if ((mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_PACKET_OFFLOAD) != 0)
+ return (true);
+#endif
+ return (false);
+}
+
+static bool
+mlx5e_is_ratelimit_capable(struct mlx5_core_dev *mdev)
+{
+#ifdef RATELIMIT
+ if (MLX5_CAP_GEN(mdev, qos) &&
+ MLX5_CAP_QOS(mdev, packet_pacing))
+ return (true);
+#endif
+ return (false);
+}
+
+static bool
+mlx5e_is_tlstx_capable(struct mlx5_core_dev *mdev)
+{
+#ifdef KERN_TLS
+ if (MLX5_CAP_GEN(mdev, tls_tx) != 0 &&
+ MLX5_CAP_GEN(mdev, log_max_dek) != 0)
+ return (true);
+#endif
+ return (false);
+}
+
+static bool
+mlx5e_is_tlsrx_capable(struct mlx5_core_dev *mdev)
+{
+#ifdef KERN_TLS
+ if (MLX5_CAP_GEN(mdev, tls_rx) != 0 &&
+ MLX5_CAP_GEN(mdev, log_max_dek) != 0 &&
+ MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
+ ft_field_support.outer_ip_version) != 0)
+ return (true);
+#endif
+ return (false);
+}
+
static int
mlx5e_ioctl(if_t ifp, u_long command, caddr_t data)
{
@@ -3502,6 +3596,24 @@ mlx5e_ioctl(if_t ifp, u_long command, caddr_t data)
drv_ioctl_data = (struct siocsifcapnv_driver_data *)data;
PRIV_LOCK(priv);
siocsifcap_driver:
+ if (!mlx5e_is_tlstx_capable(priv->mdev)) {
+ drv_ioctl_data->reqcap &= ~(IFCAP_TXTLS4 |
+ IFCAP_TXTLS6);
+ }
+ if (!mlx5e_is_tlsrx_capable(priv->mdev)) {
+ drv_ioctl_data->reqcap2 &= ~(
+ IFCAP2_BIT(IFCAP2_RXTLS4) |
+ IFCAP2_BIT(IFCAP2_RXTLS6));
+ }
+ if (!mlx5e_is_ipsec_capable(priv->mdev)) {
+ drv_ioctl_data->reqcap2 &=
+ ~IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD);
+ }
+ if (!mlx5e_is_ratelimit_capable(priv->mdev)) {
+ drv_ioctl_data->reqcap &= ~(IFCAP_TXTLS_RTLMT |
+ IFCAP_TXRTLMT);
+ }
+
mask = drv_ioctl_data->reqcap ^ if_getcapenable(ifp);
if (mask & IFCAP_TXCSUM) {
@@ -3602,31 +3714,11 @@ siocsifcap_driver:
}
VLAN_CAPABILITIES(ifp);
- /* turn off LRO means also turn of HW LRO - if it's on */
- if (mask & IFCAP_LRO) {
- int was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
- bool need_restart = false;
+ /* hw_lro and IFCAP_LRO are divorsed, only toggle sw LRO. */
+ if (mask & IFCAP_LRO)
if_togglecapenable(ifp, IFCAP_LRO);
- /* figure out if updating HW LRO is needed */
- if (!(if_getcapenable(ifp) & IFCAP_LRO)) {
- if (priv->params.hw_lro_en) {
- priv->params.hw_lro_en = false;
- need_restart = true;
- }
- } else {
- if (priv->params.hw_lro_en == false &&
- priv->params_ethtool.hw_lro != 0) {
- priv->params.hw_lro_en = true;
- need_restart = true;
- }
- }
- if (was_opened && need_restart) {
- mlx5e_close_locked(ifp);
- mlx5e_open_locked(ifp);
- }
- }
if (mask & IFCAP_HWRXTSTMP) {
if_togglecapenable(ifp, IFCAP_HWRXTSTMP);
if (if_getcapenable(ifp) & IFCAP_HWRXTSTMP) {
@@ -3642,6 +3734,18 @@ siocsifcap_driver:
if_togglecapenable2(ifp, IFCAP2_BIT(IFCAP2_RXTLS4));
if ((mask & IFCAP2_BIT(IFCAP2_RXTLS6)) != 0)
if_togglecapenable2(ifp, IFCAP2_BIT(IFCAP2_RXTLS6));
+#ifdef IPSEC_OFFLOAD
+ if ((mask & IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD)) != 0) {
+ bool was_enabled = (if_getcapenable2(ifp) &
+ IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD)) != 0;
+ mlx5e_close_locked(ifp);
+ if (was_enabled)
+ ipsec_accel_on_ifdown(priv->ifp);
+ if_togglecapenable2(ifp,
+ IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD));
+ mlx5e_open_locked(ifp);
+ }
+#endif
out:
PRIV_UNLOCK(priv);
break;
@@ -3674,6 +3778,11 @@ out:
/* Check if module is present before doing an access */
module_status = mlx5_query_module_status(priv->mdev, module_num);
if (module_status != MLX5_MODULE_STATUS_PLUGGED_ENABLED) {
+ if (bootverbose)
+ mlx5_en_err(ifp,
+ "Query module %d status: not plugged (%d), "
+ "eeprom reading is not supported\n",
+ module_num, module_status);
error = EINVAL;
goto err_i2c;
}
@@ -4485,10 +4594,6 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev)
M_MLX5EN, mlx5_dev_domainset(mdev), M_WAITOK | M_ZERO);
ifp = priv->ifp = if_alloc_dev(IFT_ETHER, mdev->pdev->dev.bsddev);
- if (ifp == NULL) {
- mlx5_core_err(mdev, "if_alloc() failed\n");
- goto err_free_priv;
- }
/* setup all static fields */
if (mlx5e_priv_static_init(priv, mdev, mdev->priv.eq_table.num_comp_vectors)) {
mlx5_core_err(mdev, "mlx5e_priv_static_init() failed\n");
@@ -4517,13 +4622,21 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev)
if_setcapabilitiesbit(ifp, IFCAP_TSO | IFCAP_VLAN_HWTSO, 0);
if_setcapabilitiesbit(ifp, IFCAP_HWSTATS | IFCAP_HWRXTSTMP, 0);
if_setcapabilitiesbit(ifp, IFCAP_MEXTPG, 0);
- if_setcapabilitiesbit(ifp, IFCAP_TXTLS4 | IFCAP_TXTLS6, 0);
-#ifdef RATELIMIT
- if_setcapabilitiesbit(ifp, IFCAP_TXRTLMT | IFCAP_TXTLS_RTLMT, 0);
-#endif
+ if (mlx5e_is_tlstx_capable(mdev))
+ if_setcapabilitiesbit(ifp, IFCAP_TXTLS4 | IFCAP_TXTLS6, 0);
+ if (mlx5e_is_tlsrx_capable(mdev))
+ if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_RXTLS4) |
+ IFCAP2_BIT(IFCAP2_RXTLS6), 0);
+ if (mlx5e_is_ratelimit_capable(mdev)) {
+ if_setcapabilitiesbit(ifp, IFCAP_TXRTLMT, 0);
+ if (mlx5e_is_tlstx_capable(mdev))
+ if_setcapabilitiesbit(ifp, IFCAP_TXTLS_RTLMT, 0);
+ }
if_setcapabilitiesbit(ifp, IFCAP_VXLAN_HWCSUM | IFCAP_VXLAN_HWTSO, 0);
- if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_RXTLS4) |
- IFCAP2_BIT(IFCAP2_RXTLS6), 0);
+ if (mlx5e_is_ipsec_capable(mdev))
+ if_setcapabilities2bit(ifp, IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD),
+ 0);
+
if_setsndtagallocfn(ifp, mlx5e_snd_tag_alloc);
#ifdef RATELIMIT
if_setratelimitqueryfn(ifp, mlx5e_ratelimit_query);
@@ -4623,10 +4736,18 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev)
goto err_rl_init;
}
+ if ((if_getcapenable2(ifp) & IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD)) != 0) {
+ err = mlx5e_ipsec_init(priv);
+ if (err) {
+ if_printf(ifp, "%s: mlx5e_tls_init failed\n", __func__);
+ goto err_tls_init;
+ }
+ }
+
err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
if (err) {
if_printf(ifp, "%s: mlx5e_open_drop_rq failed (%d)\n", __func__, err);
- goto err_tls_init;
+ goto err_ipsec_init;
}
err = mlx5e_open_rqts(priv);
@@ -4802,6 +4923,9 @@ err_open_rqts:
err_open_drop_rq:
mlx5e_close_drop_rq(&priv->drop_rq);
+err_ipsec_init:
+ mlx5e_ipsec_cleanup(priv);
+
err_tls_init:
mlx5e_tls_cleanup(priv);
@@ -4828,8 +4952,6 @@ err_free_sysctl:
err_free_ifp:
if_free(ifp);
-
-err_free_priv:
free(priv, M_MLX5EN);
return (NULL);
}
@@ -4848,7 +4970,12 @@ mlx5e_destroy_ifp(struct mlx5_core_dev *mdev, void *vpriv)
#ifdef RATELIMIT
/*
- * The kernel can have reference(s) via the m_snd_tag's into
+ * Tell the TCP ratelimit code to release the rate-sets attached
+ * to our ifnet.
+ */
+ tcp_rl_release_ifnet(ifp);
+ /*
+ * The kernel can still have reference(s) via the m_snd_tag's into
* the ratelimit channels, and these must go away before
* detaching:
*/
@@ -4910,10 +5037,14 @@ mlx5e_destroy_ifp(struct mlx5_core_dev *mdev, void *vpriv)
ether_ifdetach(ifp);
mlx5e_tls_rx_cleanup(priv);
+#ifdef IPSEC_OFFLOAD
+ ipsec_accel_on_ifdown(priv->ifp);
+#endif
mlx5e_close_flow_tables(priv);
mlx5e_close_tirs(priv);
mlx5e_close_rqts(priv);
mlx5e_close_drop_rq(&priv->drop_rq);
+ mlx5e_ipsec_cleanup(priv);
mlx5e_tls_cleanup(priv);
mlx5e_rl_cleanup(priv);
@@ -5028,6 +5159,7 @@ mlx5e_cleanup(void)
module_init_order(mlx5e_init, SI_ORDER_SIXTH);
module_exit_order(mlx5e_cleanup, SI_ORDER_SIXTH);
+MODULE_DEPEND(mlx5en, ipsec, 1, 1, 1);
MODULE_DEPEND(mlx5en, linuxkpi, 1, 1, 1);
MODULE_DEPEND(mlx5en, mlx5, 1, 1, 1);
MODULE_VERSION(mlx5en, 1);