net/mlx5e: Move mlx5e_select_queue to en/selq.c
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_tx.c
index 7fd33b3..2dc4840 100644 (file)
@@ -53,117 +53,6 @@ static void mlx5e_dma_unmap_wqe_err(struct mlx5e_txqsq *sq, u8 num_dma)
        }
 }
 
-#ifdef CONFIG_MLX5_CORE_EN_DCB
-static inline int mlx5e_get_dscp_up(struct mlx5e_priv *priv, struct sk_buff *skb)
-{
-       int dscp_cp = 0;
-
-       if (skb->protocol == htons(ETH_P_IP))
-               dscp_cp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
-       else if (skb->protocol == htons(ETH_P_IPV6))
-               dscp_cp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
-
-       return priv->dcbx_dp.dscp2prio[dscp_cp];
-}
-#endif
-
-static u16 mlx5e_select_ptpsq(struct net_device *dev, struct sk_buff *skb)
-{
-       struct mlx5e_priv *priv = netdev_priv(dev);
-       int up = 0;
-
-       if (!netdev_get_num_tc(dev))
-               goto return_txq;
-
-#ifdef CONFIG_MLX5_CORE_EN_DCB
-       if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP)
-               up = mlx5e_get_dscp_up(priv, skb);
-       else
-#endif
-               if (skb_vlan_tag_present(skb))
-                       up = skb_vlan_tag_get_prio(skb);
-
-return_txq:
-       return priv->port_ptp_tc2realtxq[up];
-}
-
-static int mlx5e_select_htb_queue(struct mlx5e_priv *priv, struct sk_buff *skb,
-                                 u16 htb_maj_id)
-{
-       u16 classid;
-
-       if ((TC_H_MAJ(skb->priority) >> 16) == htb_maj_id)
-               classid = TC_H_MIN(skb->priority);
-       else
-               classid = READ_ONCE(priv->htb.defcls);
-
-       if (!classid)
-               return 0;
-
-       return mlx5e_get_txq_by_classid(priv, classid);
-}
-
-u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
-                      struct net_device *sb_dev)
-{
-       struct mlx5e_priv *priv = netdev_priv(dev);
-       int num_tc_x_num_ch;
-       int txq_ix;
-       int up = 0;
-       int ch_ix;
-
-       /* Sync with mlx5e_update_num_tc_x_num_ch - avoid refetching. */
-       num_tc_x_num_ch = READ_ONCE(priv->num_tc_x_num_ch);
-       if (unlikely(dev->real_num_tx_queues > num_tc_x_num_ch)) {
-               struct mlx5e_ptp *ptp_channel;
-
-               /* Order maj_id before defcls - pairs with mlx5e_htb_root_add. */
-               u16 htb_maj_id = smp_load_acquire(&priv->htb.maj_id);
-
-               if (unlikely(htb_maj_id)) {
-                       txq_ix = mlx5e_select_htb_queue(priv, skb, htb_maj_id);
-                       if (txq_ix > 0)
-                               return txq_ix;
-               }
-
-               ptp_channel = READ_ONCE(priv->channels.ptp);
-               if (unlikely(ptp_channel &&
-                            test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state) &&
-                            mlx5e_use_ptpsq(skb)))
-                       return mlx5e_select_ptpsq(dev, skb);
-
-               txq_ix = netdev_pick_tx(dev, skb, NULL);
-               /* Fix netdev_pick_tx() not to choose ptp_channel and HTB txqs.
-                * If they are selected, switch to regular queues.
-                * Driver to select these queues only at mlx5e_select_ptpsq()
-                * and mlx5e_select_htb_queue().
-                */
-               if (unlikely(txq_ix >= num_tc_x_num_ch))
-                       txq_ix %= num_tc_x_num_ch;
-       } else {
-               txq_ix = netdev_pick_tx(dev, skb, NULL);
-       }
-
-       if (!netdev_get_num_tc(dev))
-               return txq_ix;
-
-#ifdef CONFIG_MLX5_CORE_EN_DCB
-       if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP)
-               up = mlx5e_get_dscp_up(priv, skb);
-       else
-#endif
-               if (skb_vlan_tag_present(skb))
-                       up = skb_vlan_tag_get_prio(skb);
-
-       /* Normalize any picked txq_ix to [0, num_channels),
-        * So we can return a txq_ix that matches the channel and
-        * packet UP.
-        */
-       ch_ix = priv->txq2sq[txq_ix]->ch_ix;
-
-       return priv->channel_tc2realtxq[ch_ix][up];
-}
-
 static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
 {
 #define MLX5E_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
@@ -208,7 +97,7 @@ static inline void mlx5e_insert_vlan(void *start, struct sk_buff *skb, u16 ihs)
        int cpy1_sz = 2 * ETH_ALEN;
        int cpy2_sz = ihs - cpy1_sz;
 
-       memcpy(vhdr, skb->data, cpy1_sz);
+       memcpy(&vhdr->addrs, skb->data, cpy1_sz);
        vhdr->h_vlan_proto = skb->vlan_proto;
        vhdr->h_vlan_TCI = cpu_to_be16(skb_vlan_tag_get(skb));
        memcpy(&vhdr->h_vlan_encapsulated_proto, skb->data + cpy1_sz, cpy2_sz);
@@ -544,7 +433,7 @@ static void mlx5e_tx_mpwqe_session_start(struct mlx5e_txqsq *sq,
        struct mlx5e_tx_wqe *wqe;
        u16 pi;
 
-       pi = mlx5e_txqsq_get_next_pi(sq, MLX5E_TX_MPW_MAX_WQEBBS);
+       pi = mlx5e_txqsq_get_next_pi(sq, sq->max_sq_mpw_wqebbs);
        wqe = MLX5E_TX_FETCH_WQE(sq, pi);
        net_prefetchw(wqe->data);
 
@@ -645,7 +534,7 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
 
        mlx5e_tx_skb_update_hwts_flags(skb);
 
-       if (unlikely(mlx5e_tx_mpwqe_is_full(&sq->mpwqe))) {
+       if (unlikely(mlx5e_tx_mpwqe_is_full(&sq->mpwqe, sq->max_sq_mpw_wqebbs))) {
                /* Might stop the queue and affect the retval of __netdev_tx_sent_queue. */
                cseg = mlx5e_tx_mpwqe_session_complete(sq);
 
@@ -691,8 +580,21 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev)
        struct mlx5e_txqsq *sq;
        u16 pi;
 
+       /* All changes to txq2sq are performed in sync with mlx5e_xmit, when the
+        * queue being changed is disabled, and smp_wmb guarantees that the
+        * changes are visible before mlx5e_xmit tries to read from txq2sq. It
+        * guarantees that the value of txq2sq[qid] doesn't change while
+        * mlx5e_xmit is running on queue number qid. smb_wmb is paired with
+        * HARD_TX_LOCK around ndo_start_xmit, which serves as an ACQUIRE.
+        */
        sq = priv->txq2sq[skb_get_queue_mapping(skb)];
        if (unlikely(!sq)) {
+               /* Two cases when sq can be NULL:
+                * 1. The HTB node is registered, and mlx5e_select_queue
+                * selected its queue ID, but the SQ itself is not yet created.
+                * 2. HTB SQ creation failed. Similar to the previous case, but
+                * the SQ won't be created.
+                */
                dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
        }