net/mlx5e: Move helper functions to a new txrx datapath header
Take datapath helper functions to a new header file en/txrx.h. Signed-off-by: Tariq Toukan <tariqt@mellanox.com> Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
fc707e59c9
commit
542578c679
|
@ -549,12 +549,6 @@ struct mlx5e_icosq {
|
|||
struct mlx5e_channel *channel;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
static inline bool
|
||||
mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n)
|
||||
{
|
||||
return (mlx5_wq_cyc_ctr2ix(wq, cc - pc) >= n) || (cc == pc);
|
||||
}
|
||||
|
||||
struct mlx5e_wqe_frag_info {
|
||||
struct mlx5e_dma_info *di;
|
||||
u32 offset;
|
||||
|
@ -1023,102 +1017,6 @@ static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev)
|
|||
MLX5_CAP_ETH(mdev, swp_csum) && MLX5_CAP_ETH(mdev, swp_lso);
|
||||
}
|
||||
|
||||
struct mlx5e_swp_spec {
|
||||
__be16 l3_proto;
|
||||
u8 l4_proto;
|
||||
u8 is_tun;
|
||||
__be16 tun_l3_proto;
|
||||
u8 tun_l4_proto;
|
||||
};
|
||||
|
||||
static inline void
|
||||
mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,
|
||||
struct mlx5e_swp_spec *swp_spec)
|
||||
{
|
||||
/* SWP offsets are in 2-bytes words */
|
||||
eseg->swp_outer_l3_offset = skb_network_offset(skb) / 2;
|
||||
if (swp_spec->l3_proto == htons(ETH_P_IPV6))
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L3_IPV6;
|
||||
if (swp_spec->l4_proto) {
|
||||
eseg->swp_outer_l4_offset = skb_transport_offset(skb) / 2;
|
||||
if (swp_spec->l4_proto == IPPROTO_UDP)
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L4_UDP;
|
||||
}
|
||||
|
||||
if (swp_spec->is_tun) {
|
||||
eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
|
||||
if (swp_spec->tun_l3_proto == htons(ETH_P_IPV6))
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
|
||||
} else { /* typically for ipsec when xfrm mode != XFRM_MODE_TUNNEL */
|
||||
eseg->swp_inner_l3_offset = skb_network_offset(skb) / 2;
|
||||
if (swp_spec->l3_proto == htons(ETH_P_IPV6))
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
|
||||
}
|
||||
switch (swp_spec->tun_l4_proto) {
|
||||
case IPPROTO_UDP:
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L4_UDP;
|
||||
/* fall through */
|
||||
case IPPROTO_TCP:
|
||||
eseg->swp_inner_l4_offset = skb_inner_transport_offset(skb) / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void mlx5e_sq_fetch_wqe(struct mlx5e_txqsq *sq,
|
||||
struct mlx5e_tx_wqe **wqe,
|
||||
u16 *pi)
|
||||
{
|
||||
struct mlx5_wq_cyc *wq = &sq->wq;
|
||||
|
||||
*pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
|
||||
*wqe = mlx5_wq_cyc_get_wqe(wq, *pi);
|
||||
memset(*wqe, 0, sizeof(**wqe));
|
||||
}
|
||||
|
||||
static inline
|
||||
struct mlx5e_tx_wqe *mlx5e_post_nop(struct mlx5_wq_cyc *wq, u32 sqn, u16 *pc)
|
||||
{
|
||||
u16 pi = mlx5_wq_cyc_ctr2ix(wq, *pc);
|
||||
struct mlx5e_tx_wqe *wqe = mlx5_wq_cyc_get_wqe(wq, pi);
|
||||
struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
|
||||
|
||||
memset(cseg, 0, sizeof(*cseg));
|
||||
|
||||
cseg->opmod_idx_opcode = cpu_to_be32((*pc << 8) | MLX5_OPCODE_NOP);
|
||||
cseg->qpn_ds = cpu_to_be32((sqn << 8) | 0x01);
|
||||
|
||||
(*pc)++;
|
||||
|
||||
return wqe;
|
||||
}
|
||||
|
||||
static inline
|
||||
void mlx5e_notify_hw(struct mlx5_wq_cyc *wq, u16 pc,
|
||||
void __iomem *uar_map,
|
||||
struct mlx5_wqe_ctrl_seg *ctrl)
|
||||
{
|
||||
ctrl->fm_ce_se = MLX5_WQE_CTRL_CQ_UPDATE;
|
||||
/* ensure wqe is visible to device before updating doorbell record */
|
||||
dma_wmb();
|
||||
|
||||
*wq->db = cpu_to_be32(pc);
|
||||
|
||||
/* ensure doorbell record is visible to device before ringing the
|
||||
* doorbell
|
||||
*/
|
||||
wmb();
|
||||
|
||||
mlx5_write64((__be32 *)ctrl, uar_map);
|
||||
}
|
||||
|
||||
static inline void mlx5e_cq_arm(struct mlx5e_cq *cq)
|
||||
{
|
||||
struct mlx5_core_cq *mcq;
|
||||
|
||||
mcq = &cq->mcq;
|
||||
mlx5_cq_arm(mcq, MLX5_CQ_DB_REQ_NOT, mcq->uar->map, cq->wq.cc);
|
||||
}
|
||||
|
||||
extern const struct ethtool_ops mlx5e_ethtool_ops;
|
||||
#ifdef CONFIG_MLX5_CORE_EN_DCB
|
||||
extern const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops;
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
|
||||
/* Copyright (c) 2019 Mellanox Technologies. */
|
||||
|
||||
#ifndef __MLX5_EN_TXRX_H___
|
||||
#define __MLX5_EN_TXRX_H___
|
||||
|
||||
#include "en.h"
|
||||
|
||||
#define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start))
|
||||
|
||||
static inline bool
|
||||
mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n)
|
||||
{
|
||||
return (mlx5_wq_cyc_ctr2ix(wq, cc - pc) >= n) || (cc == pc);
|
||||
}
|
||||
|
||||
static inline void mlx5e_sq_fetch_wqe(struct mlx5e_txqsq *sq,
|
||||
struct mlx5e_tx_wqe **wqe,
|
||||
u16 *pi)
|
||||
{
|
||||
struct mlx5_wq_cyc *wq = &sq->wq;
|
||||
|
||||
*pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
|
||||
*wqe = mlx5_wq_cyc_get_wqe(wq, *pi);
|
||||
memset(*wqe, 0, sizeof(**wqe));
|
||||
}
|
||||
|
||||
static inline struct mlx5e_tx_wqe *
|
||||
mlx5e_post_nop(struct mlx5_wq_cyc *wq, u32 sqn, u16 *pc)
|
||||
{
|
||||
u16 pi = mlx5_wq_cyc_ctr2ix(wq, *pc);
|
||||
struct mlx5e_tx_wqe *wqe = mlx5_wq_cyc_get_wqe(wq, pi);
|
||||
struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
|
||||
|
||||
memset(cseg, 0, sizeof(*cseg));
|
||||
|
||||
cseg->opmod_idx_opcode = cpu_to_be32((*pc << 8) | MLX5_OPCODE_NOP);
|
||||
cseg->qpn_ds = cpu_to_be32((sqn << 8) | 0x01);
|
||||
|
||||
(*pc)++;
|
||||
|
||||
return wqe;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5e_fill_sq_frag_edge(struct mlx5e_txqsq *sq, struct mlx5_wq_cyc *wq,
|
||||
u16 pi, u16 nnops)
|
||||
{
|
||||
struct mlx5e_tx_wqe_info *edge_wi, *wi = &sq->db.wqe_info[pi];
|
||||
|
||||
edge_wi = wi + nnops;
|
||||
|
||||
/* fill sq frag edge with nops to avoid wqe wrapping two pages */
|
||||
for (; wi < edge_wi; wi++) {
|
||||
wi->skb = NULL;
|
||||
wi->num_wqebbs = 1;
|
||||
mlx5e_post_nop(wq, sq->sqn, &sq->pc);
|
||||
}
|
||||
sq->stats->nop += nnops;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5e_notify_hw(struct mlx5_wq_cyc *wq, u16 pc, void __iomem *uar_map,
|
||||
struct mlx5_wqe_ctrl_seg *ctrl)
|
||||
{
|
||||
ctrl->fm_ce_se = MLX5_WQE_CTRL_CQ_UPDATE;
|
||||
/* ensure wqe is visible to device before updating doorbell record */
|
||||
dma_wmb();
|
||||
|
||||
*wq->db = cpu_to_be32(pc);
|
||||
|
||||
/* ensure doorbell record is visible to device before ringing the
|
||||
* doorbell
|
||||
*/
|
||||
wmb();
|
||||
|
||||
mlx5_write64((__be32 *)ctrl, uar_map);
|
||||
}
|
||||
|
||||
static inline void mlx5e_cq_arm(struct mlx5e_cq *cq)
|
||||
{
|
||||
struct mlx5_core_cq *mcq;
|
||||
|
||||
mcq = &cq->mcq;
|
||||
mlx5_cq_arm(mcq, MLX5_CQ_DB_REQ_NOT, mcq->uar->map, cq->wq.cc);
|
||||
}
|
||||
|
||||
static inline struct mlx5e_sq_dma *
|
||||
mlx5e_dma_get(struct mlx5e_txqsq *sq, u32 i)
|
||||
{
|
||||
return &sq->db.dma_fifo[i & sq->dma_fifo_mask];
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5e_dma_push(struct mlx5e_txqsq *sq, dma_addr_t addr, u32 size,
|
||||
enum mlx5e_dma_map_type map_type)
|
||||
{
|
||||
struct mlx5e_sq_dma *dma = mlx5e_dma_get(sq, sq->dma_fifo_pc++);
|
||||
|
||||
dma->addr = addr;
|
||||
dma->size = size;
|
||||
dma->type = map_type;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5e_tx_dma_unmap(struct device *pdev, struct mlx5e_sq_dma *dma)
|
||||
{
|
||||
switch (dma->type) {
|
||||
case MLX5E_DMA_MAP_SINGLE:
|
||||
dma_unmap_single(pdev, dma->addr, dma->size, DMA_TO_DEVICE);
|
||||
break;
|
||||
case MLX5E_DMA_MAP_PAGE:
|
||||
dma_unmap_page(pdev, dma->addr, dma->size, DMA_TO_DEVICE);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "mlx5e_tx_dma_unmap unknown DMA type!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* SW parser related functions */
|
||||
|
||||
struct mlx5e_swp_spec {
|
||||
__be16 l3_proto;
|
||||
u8 l4_proto;
|
||||
u8 is_tun;
|
||||
__be16 tun_l3_proto;
|
||||
u8 tun_l4_proto;
|
||||
};
|
||||
|
||||
static inline void
|
||||
mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,
|
||||
struct mlx5e_swp_spec *swp_spec)
|
||||
{
|
||||
/* SWP offsets are in 2-bytes words */
|
||||
eseg->swp_outer_l3_offset = skb_network_offset(skb) / 2;
|
||||
if (swp_spec->l3_proto == htons(ETH_P_IPV6))
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L3_IPV6;
|
||||
if (swp_spec->l4_proto) {
|
||||
eseg->swp_outer_l4_offset = skb_transport_offset(skb) / 2;
|
||||
if (swp_spec->l4_proto == IPPROTO_UDP)
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L4_UDP;
|
||||
}
|
||||
|
||||
if (swp_spec->is_tun) {
|
||||
eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
|
||||
if (swp_spec->tun_l3_proto == htons(ETH_P_IPV6))
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
|
||||
} else { /* typically for ipsec when xfrm mode != XFRM_MODE_TUNNEL */
|
||||
eseg->swp_inner_l3_offset = skb_network_offset(skb) / 2;
|
||||
if (swp_spec->l3_proto == htons(ETH_P_IPV6))
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
|
||||
}
|
||||
switch (swp_spec->tun_l4_proto) {
|
||||
case IPPROTO_UDP:
|
||||
eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L4_UDP;
|
||||
/* fall through */
|
||||
case IPPROTO_TCP:
|
||||
eseg->swp_inner_l4_offset = skb_inner_transport_offset(skb) / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -33,6 +33,7 @@
|
|||
#define __MLX5_EN_XDP_H__
|
||||
|
||||
#include "en.h"
|
||||
#include "en/txrx.h"
|
||||
|
||||
#define MLX5E_XDP_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
|
||||
#define MLX5E_XDP_TX_EMPTY_DS_COUNT \
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "en_accel/ipsec_rxtx.h"
|
||||
#include "en_accel/tls_rxtx.h"
|
||||
#include "en.h"
|
||||
#include "en/txrx.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_GENEVE)
|
||||
static inline bool mlx5_geneve_tx_allowed(struct mlx5_core_dev *mdev)
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <linux/skbuff.h>
|
||||
#include <net/xfrm.h>
|
||||
#include "en.h"
|
||||
#include "en/txrx.h"
|
||||
|
||||
struct sk_buff *mlx5e_ipsec_handle_rx_skb(struct net_device *netdev,
|
||||
struct sk_buff *skb, u32 *cqe_bcnt);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include <linux/skbuff.h>
|
||||
#include "en.h"
|
||||
#include "en/txrx.h"
|
||||
|
||||
struct sk_buff *mlx5e_tls_handle_tx_skb(struct net_device *netdev,
|
||||
struct mlx5e_txqsq *sq,
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <net/xdp_sock.h>
|
||||
#include "eswitch.h"
|
||||
#include "en.h"
|
||||
#include "en/txrx.h"
|
||||
#include "en_tc.h"
|
||||
#include "en_rep.h"
|
||||
#include "en_accel/ipsec.h"
|
||||
|
@ -62,6 +63,7 @@
|
|||
#include "en/xsk/rx.h"
|
||||
#include "en/xsk/tx.h"
|
||||
|
||||
|
||||
bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
bool striding_rq_umr = MLX5_CAP_GEN(mdev, striding_rq) &&
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <net/geneve.h>
|
||||
#include <net/dsfield.h>
|
||||
#include "en.h"
|
||||
#include "en/txrx.h"
|
||||
#include "ipoib/ipoib.h"
|
||||
#include "en_accel/en_accel.h"
|
||||
#include "lib/clock.h"
|
||||
|
@ -52,38 +53,6 @@
|
|||
MLX5E_SQ_NOPS_ROOM)
|
||||
#endif
|
||||
|
||||
static inline void mlx5e_tx_dma_unmap(struct device *pdev,
|
||||
struct mlx5e_sq_dma *dma)
|
||||
{
|
||||
switch (dma->type) {
|
||||
case MLX5E_DMA_MAP_SINGLE:
|
||||
dma_unmap_single(pdev, dma->addr, dma->size, DMA_TO_DEVICE);
|
||||
break;
|
||||
case MLX5E_DMA_MAP_PAGE:
|
||||
dma_unmap_page(pdev, dma->addr, dma->size, DMA_TO_DEVICE);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(true, "mlx5e_tx_dma_unmap unknown DMA type!\n");
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct mlx5e_sq_dma *mlx5e_dma_get(struct mlx5e_txqsq *sq, u32 i)
|
||||
{
|
||||
return &sq->db.dma_fifo[i & sq->dma_fifo_mask];
|
||||
}
|
||||
|
||||
static inline void mlx5e_dma_push(struct mlx5e_txqsq *sq,
|
||||
dma_addr_t addr,
|
||||
u32 size,
|
||||
enum mlx5e_dma_map_type map_type)
|
||||
{
|
||||
struct mlx5e_sq_dma *dma = mlx5e_dma_get(sq, sq->dma_fifo_pc++);
|
||||
|
||||
dma->addr = addr;
|
||||
dma->size = size;
|
||||
dma->type = map_type;
|
||||
}
|
||||
|
||||
static void mlx5e_dma_unmap_wqe_err(struct mlx5e_txqsq *sq, u8 num_dma)
|
||||
{
|
||||
int i;
|
||||
|
@ -277,23 +246,6 @@ dma_unmap_wqe_err:
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static inline void mlx5e_fill_sq_frag_edge(struct mlx5e_txqsq *sq,
|
||||
struct mlx5_wq_cyc *wq,
|
||||
u16 pi, u16 nnops)
|
||||
{
|
||||
struct mlx5e_tx_wqe_info *edge_wi, *wi = &sq->db.wqe_info[pi];
|
||||
|
||||
edge_wi = wi + nnops;
|
||||
|
||||
/* fill sq frag edge with nops to avoid wqe wrapping two pages */
|
||||
for (; wi < edge_wi; wi++) {
|
||||
wi->skb = NULL;
|
||||
wi->num_wqebbs = 1;
|
||||
mlx5e_post_nop(wq, sq->sqn, &sq->pc);
|
||||
}
|
||||
sq->stats->nop += nnops;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
||||
u8 opcode, u16 ds_cnt, u8 num_wqebbs, u32 num_bytes, u8 num_dma,
|
||||
|
@ -326,8 +278,6 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
|||
mlx5e_notify_hw(wq, sq->pc, sq->uar_map, cseg);
|
||||
}
|
||||
|
||||
#define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start))
|
||||
|
||||
netdev_tx_t mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
||||
struct mlx5e_tx_wqe *wqe, u16 pi, bool xmit_more)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue