|
@@ -257,25 +257,8 @@ 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))
|
|
|
|
|
|
static int mlx5e_create_rq(struct mlx5e_channel *c,
|
|
|
struct mlx5e_rq_param *param,
|
|
@@ -305,13 +288,16 @@ static int mlx5e_create_rq(struct mlx5e_channel *c,
|
|
|
}
|
|
|
|
|
|
rq->wqe_sz = (priv->params.lro_en) ? priv->params.lro_wqe_sz :
|
|
|
- priv->netdev->mtu + ETH_HLEN + VLAN_HLEN;
|
|
|
+ MLX5E_SW2HW_MTU(priv->netdev->mtu);
|
|
|
+ rq->wqe_sz = SKB_DATA_ALIGN(rq->wqe_sz + MLX5E_NET_IP_ALIGN);
|
|
|
|
|
|
for (i = 0; i < wq_sz; i++) {
|
|
|
struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(&rq->wq, i);
|
|
|
+ u32 byte_count = rq->wqe_sz - MLX5E_NET_IP_ALIGN;
|
|
|
|
|
|
wqe->data.lkey = c->mkey_be;
|
|
|
- wqe->data.byte_count = cpu_to_be32(rq->wqe_sz);
|
|
|
+ wqe->data.byte_count =
|
|
|
+ cpu_to_be32(byte_count | MLX5_HW_START_PADDING);
|
|
|
}
|
|
|
|
|
|
rq->pdev = c->pdev;
|
|
@@ -447,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;
|
|
|
|
|
@@ -536,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;
|
|
|
|
|
@@ -689,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 */
|
|
@@ -1115,6 +1102,7 @@ static int mlx5e_open_tis(struct mlx5e_priv *priv, int tc)
|
|
|
memset(in, 0, sizeof(in));
|
|
|
|
|
|
MLX5_SET(tisc, tisc, prio, tc);
|
|
|
+ MLX5_SET(tisc, tisc, transport_domain, priv->tdn);
|
|
|
|
|
|
return mlx5_core_create_tis(mdev, in, sizeof(in), &priv->tisn[tc]);
|
|
|
}
|
|
@@ -1213,6 +1201,8 @@ static void mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 *tirc, int tt)
|
|
|
{
|
|
|
void *hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
|
|
|
|
|
|
+ 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 |\
|
|
@@ -1367,11 +1357,30 @@ static void mlx5e_close_tirs(struct mlx5e_priv *priv)
|
|
|
mlx5e_close_tir(priv, i);
|
|
|
}
|
|
|
|
|
|
-int mlx5e_open_locked(struct net_device *netdev)
|
|
|
+static int mlx5e_set_dev_port_mtu(struct net_device *netdev)
|
|
|
{
|
|
|
struct mlx5e_priv *priv = netdev_priv(netdev);
|
|
|
struct mlx5_core_dev *mdev = priv->mdev;
|
|
|
- int actual_mtu;
|
|
|
+ int hw_mtu;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ err = mlx5_set_port_mtu(mdev, MLX5E_SW2HW_MTU(netdev->mtu), 1);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1);
|
|
|
+
|
|
|
+ if (MLX5E_HW2SW_MTU(hw_mtu) != netdev->mtu)
|
|
|
+ netdev_warn(netdev, "%s: Port MTU %d is different than netdev mtu %d\n",
|
|
|
+ __func__, MLX5E_HW2SW_MTU(hw_mtu), netdev->mtu);
|
|
|
+
|
|
|
+ netdev->mtu = MLX5E_HW2SW_MTU(hw_mtu);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int mlx5e_open_locked(struct net_device *netdev)
|
|
|
+{
|
|
|
+ struct mlx5e_priv *priv = netdev_priv(netdev);
|
|
|
int num_txqs;
|
|
|
int err;
|
|
|
|
|
@@ -1380,25 +1389,9 @@ int mlx5e_open_locked(struct net_device *netdev)
|
|
|
netif_set_real_num_tx_queues(netdev, num_txqs);
|
|
|
netif_set_real_num_rx_queues(netdev, priv->params.num_channels);
|
|
|
|
|
|
- err = mlx5_set_port_mtu(mdev, netdev->mtu);
|
|
|
- if (err) {
|
|
|
- netdev_err(netdev, "%s: mlx5_set_port_mtu failed %d\n",
|
|
|
- __func__, err);
|
|
|
- return err;
|
|
|
- }
|
|
|
-
|
|
|
- err = mlx5_query_port_oper_mtu(mdev, &actual_mtu, 1);
|
|
|
- if (err) {
|
|
|
- netdev_err(netdev, "%s: mlx5_query_port_oper_mtu failed %d\n",
|
|
|
- __func__, err);
|
|
|
+ err = mlx5e_set_dev_port_mtu(netdev);
|
|
|
+ if (err)
|
|
|
return err;
|
|
|
- }
|
|
|
-
|
|
|
- if (actual_mtu != netdev->mtu)
|
|
|
- netdev_warn(netdev, "%s: Failed to set MTU to %d\n",
|
|
|
- __func__, netdev->mtu);
|
|
|
-
|
|
|
- netdev->mtu = actual_mtu;
|
|
|
|
|
|
err = mlx5e_open_tises(priv);
|
|
|
if (err) {
|
|
@@ -1613,15 +1606,14 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
|
|
|
struct mlx5e_priv *priv = netdev_priv(netdev);
|
|
|
struct mlx5_core_dev *mdev = priv->mdev;
|
|
|
int max_mtu;
|
|
|
- int err = 0;
|
|
|
+ int err;
|
|
|
|
|
|
- err = mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
+ mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
|
|
|
|
|
|
- if (new_mtu > max_mtu || new_mtu < MLX5E_PARAMS_MIN_MTU) {
|
|
|
- netdev_err(netdev, "%s: Bad MTU size, mtu must be [%d-%d]\n",
|
|
|
- __func__, MLX5E_PARAMS_MIN_MTU, max_mtu);
|
|
|
+ if (new_mtu > max_mtu) {
|
|
|
+ netdev_err(netdev,
|
|
|
+ "%s: Bad MTU (%d) > (%d) Max\n",
|
|
|
+ __func__, new_mtu, max_mtu);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
@@ -1655,7 +1647,10 @@ static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
|
|
|
!MLX5_CAP_ETH(mdev, csum_cap) ||
|
|
|
!MLX5_CAP_ETH(mdev, max_lso_cap) ||
|
|
|
!MLX5_CAP_ETH(mdev, vlan_cap) ||
|
|
|
- !MLX5_CAP_ETH(mdev, rss_ind_tbl_cap)) {
|
|
|
+ !MLX5_CAP_ETH(mdev, rss_ind_tbl_cap) ||
|
|
|
+ MLX5_CAP_FLOWTABLE(mdev,
|
|
|
+ flow_table_properties_nic_receive.max_ft_level)
|
|
|
+ < 3) {
|
|
|
mlx5_core_warn(mdev,
|
|
|
"Not creating net device, some required device capabilities are missing\n");
|
|
|
return -ENOTSUPP;
|
|
@@ -1736,6 +1731,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;
|
|
@@ -1748,7 +1744,6 @@ static void mlx5e_build_netdev(struct net_device *netdev)
|
|
|
netdev->vlan_features |= NETIF_F_LRO;
|
|
|
|
|
|
netdev->hw_features = netdev->vlan_features;
|
|
|
- netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
|
|
|
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
|
|
|
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
|
|
|
|
@@ -1827,11 +1822,18 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
|
|
|
goto err_unmap_free_uar;
|
|
|
}
|
|
|
|
|
|
+ err = mlx5_alloc_transport_domain(mdev, &priv->tdn);
|
|
|
+ if (err) {
|
|
|
+ netdev_err(netdev, "%s: mlx5_alloc_transport_domain failed, %d\n",
|
|
|
+ __func__, err);
|
|
|
+ goto err_dealloc_pd;
|
|
|
+ }
|
|
|
+
|
|
|
err = mlx5e_create_mkey(priv, priv->pdn, &priv->mr);
|
|
|
if (err) {
|
|
|
netdev_err(netdev, "%s: mlx5e_create_mkey failed, %d\n",
|
|
|
__func__, err);
|
|
|
- goto err_dealloc_pd;
|
|
|
+ goto err_dealloc_transport_domain;
|
|
|
}
|
|
|
|
|
|
err = register_netdev(netdev);
|
|
@@ -1848,6 +1850,9 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
|
|
|
err_destroy_mkey:
|
|
|
mlx5_core_destroy_mkey(mdev, &priv->mr);
|
|
|
|
|
|
+err_dealloc_transport_domain:
|
|
|
+ mlx5_dealloc_transport_domain(mdev, priv->tdn);
|
|
|
+
|
|
|
err_dealloc_pd:
|
|
|
mlx5_core_dealloc_pd(mdev, priv->pdn);
|
|
|
|
|
@@ -1867,6 +1872,7 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
|
|
|
|
|
|
unregister_netdev(netdev);
|
|
|
mlx5_core_destroy_mkey(priv->mdev, &priv->mr);
|
|
|
+ mlx5_dealloc_transport_domain(priv->mdev, priv->tdn);
|
|
|
mlx5_core_dealloc_pd(priv->mdev, priv->pdn);
|
|
|
mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar);
|
|
|
mlx5e_disable_async_events(priv);
|