From 12be4b2190f0e22dc8f7c8ca173bc233d0d46246 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Thu, 11 Jun 2015 14:47:31 +0300 Subject: net/mlx5e: Support NETIF_F_SG When NETIF_F_SG is set, each send WQE may have a different size since each skb can have different number of fragments as of LSO header etc. This implies that a given WQE may wrap around the send queue, i.e begin at its end and continue at its start. While it is legal by the device spec, we preferred a solution that avoids it - when building of current WQE is done, if the next WQE may wrap around the send queue, fill the send queue with NOPs WQEs till its end, so that the next WQE will begin at send queue start. NOP WQE for itself cannot wrap around the send queue since it is of minimal size - 64 bytes, and all send WQEs are a multiple of that size. Signed-off-by: Achiad Shochat Signed-off-by: Saeed Mahameed Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 26 ++++------------------- 1 file changed, 4 insertions(+), 22 deletions(-) (limited to 'drivers/net/ethernet/mellanox/mlx5/core/en_main.c') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 5d480da801ce..7f0b694f59c7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -257,26 +257,6 @@ static void mlx5e_disable_async_events(struct mlx5e_priv *priv) spin_unlock_irq(&priv->async_events_spinlock); } -static void mlx5e_send_nop(struct mlx5e_sq *sq) -{ - struct mlx5_wq_cyc *wq = &sq->wq; - - u16 pi = sq->pc & wq->sz_m1; - 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((sq->pc << 8) | MLX5_OPCODE_NOP); - cseg->qpn_ds = cpu_to_be32((sq->sqn << 8) | 0x01); - cseg->fm_ce_se = MLX5_WQE_CTRL_CQ_UPDATE; - - sq->skb[pi] = NULL; - sq->pc++; - mlx5e_tx_notify_hw(sq, wqe); -} - #define MLX5E_HW2SW_MTU(hwmtu) (hwmtu - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)) #define MLX5E_SW2HW_MTU(swmtu) (swmtu + (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)) @@ -453,7 +433,7 @@ static int mlx5e_open_rq(struct mlx5e_channel *c, goto err_disable_rq; set_bit(MLX5E_RQ_STATE_POST_WQES_ENABLE, &rq->state); - mlx5e_send_nop(&c->sq[0]); /* trigger mlx5e_post_rx_wqes() */ + mlx5e_send_nop(&c->sq[0], true); /* trigger mlx5e_post_rx_wqes() */ return 0; @@ -542,6 +522,7 @@ static int mlx5e_create_sq(struct mlx5e_channel *c, sq->mkey_be = c->mkey_be; sq->channel = c; sq->tc = tc; + sq->edge = (sq->wq.sz_m1 + 1) - MLX5_SEND_WQE_MAX_WQEBBS; return 0; @@ -695,7 +676,7 @@ static void mlx5e_close_sq(struct mlx5e_sq *sq) /* ensure hw is notified of all pending wqes */ if (mlx5e_sq_has_room_for(sq, 1)) - mlx5e_send_nop(sq); + mlx5e_send_nop(sq, true); mlx5e_modify_sq(sq, MLX5_SQC_STATE_RDY, MLX5_SQC_STATE_ERR); while (sq->cc != sq->pc) /* wait till sq is empty */ @@ -1747,6 +1728,7 @@ static void mlx5e_build_netdev(struct net_device *netdev) netdev->ethtool_ops = &mlx5e_ethtool_ops; + netdev->vlan_features |= NETIF_F_SG; netdev->vlan_features |= NETIF_F_IP_CSUM; netdev->vlan_features |= NETIF_F_IPV6_CSUM; netdev->vlan_features |= NETIF_F_GRO; -- cgit v1.2.3-55-g7522