net/mlx5e: Added ICO SQs
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / en.h
index 5b17532..a757fcf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2015-2016, Mellanox Technologies. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,6 +29,8 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+#ifndef __MLX5_EN_H__
+#define __MLX5_EN_H__
 
 #include <linux/if_vlan.h>
 #include <linux/etherdevice.h>
 #include <linux/mlx5/driver.h>
 #include <linux/mlx5/qp.h>
 #include <linux/mlx5/cq.h>
+#include <linux/mlx5/port.h>
 #include <linux/mlx5/vport.h>
 #include <linux/mlx5/transobj.h>
+#include <linux/rhashtable.h>
 #include "wq.h"
 #include "mlx5_core.h"
 
 #define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE                0xa
 #define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE                0xd
 
+#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW            0x1
+#define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW            0x4
+#define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW            0x6
+
+#define MLX5_MPWRQ_LOG_NUM_STRIDES             11 /* >= 9, HW restriction */
+#define MLX5_MPWRQ_LOG_STRIDE_SIZE             6  /* >= 6, HW restriction */
+#define MLX5_MPWRQ_NUM_STRIDES                 BIT(MLX5_MPWRQ_LOG_NUM_STRIDES)
+#define MLX5_MPWRQ_STRIDE_SIZE                 BIT(MLX5_MPWRQ_LOG_STRIDE_SIZE)
+#define MLX5_MPWRQ_LOG_WQE_SZ                  (MLX5_MPWRQ_LOG_NUM_STRIDES +\
+                                                MLX5_MPWRQ_LOG_STRIDE_SIZE)
+#define MLX5_MPWRQ_WQE_PAGE_ORDER  (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \
+                                   MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT : 0)
+#define MLX5_MPWRQ_PAGES_PER_WQE               BIT(MLX5_MPWRQ_WQE_PAGE_ORDER)
+#define MLX5_MPWRQ_STRIDES_PER_PAGE            (MLX5_MPWRQ_NUM_STRIDES >> \
+                                                MLX5_MPWRQ_WQE_PAGE_ORDER)
+#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD      (128)
+
 #define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ                 (64 * 1024)
 #define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC      0x10
 #define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS      0x20
 #define MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC      0x10
 #define MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS      0x20
 #define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES                0x80
+#define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES_MPW            0x2
 
 #define MLX5E_LOG_INDIR_RQT_SIZE       0x7
 #define MLX5E_INDIR_RQT_SIZE           BIT(MLX5E_LOG_INDIR_RQT_SIZE)
 #define MLX5E_SQ_BF_BUDGET             16
 
 #define MLX5E_NUM_MAIN_GROUPS 9
+#define MLX5E_NET_IP_ALIGN 2
+
+static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
+{
+       switch (wq_type) {
+       case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+               return min_t(u16, MLX5E_PARAMS_DEFAULT_MIN_RX_WQES_MPW,
+                            wq_size / 2);
+       default:
+               return min_t(u16, MLX5E_PARAMS_DEFAULT_MIN_RX_WQES,
+                            wq_size / 2);
+       }
+}
+
+static inline int mlx5_min_log_rq_size(int wq_type)
+{
+       switch (wq_type) {
+       case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+               return MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW;
+       default:
+               return MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
+       }
+}
+
+static inline int mlx5_max_log_rq_size(int wq_type)
+{
+       switch (wq_type) {
+       case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+               return MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW;
+       default:
+               return MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
+       }
+}
+
+struct mlx5e_tx_wqe {
+       struct mlx5_wqe_ctrl_seg ctrl;
+       struct mlx5_wqe_eth_seg  eth;
+};
+
+struct mlx5e_rx_wqe {
+       struct mlx5_wqe_srq_next_seg  next;
+       struct mlx5_wqe_data_seg      data;
+};
+
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+#define MLX5E_MAX_BW_ALLOC 100 /* Max percentage of BW allocation */
+#define MLX5E_MIN_BW_ALLOC 1   /* Min percentage of BW allocation */
+#endif
 
 static const char vport_strings[][ETH_GSTRING_LEN] = {
        /* vport statistics */
@@ -95,16 +165,20 @@ static const char vport_strings[][ETH_GSTRING_LEN] = {
        /* SW counters */
        "tso_packets",
        "tso_bytes",
+       "tso_inner_packets",
+       "tso_inner_bytes",
        "lro_packets",
        "lro_bytes",
        "rx_csum_good",
        "rx_csum_none",
        "rx_csum_sw",
        "tx_csum_offload",
+       "tx_csum_inner",
        "tx_queue_stopped",
        "tx_queue_wake",
        "tx_queue_dropped",
        "rx_wqe_err",
+       "rx_mpwqe_filler",
 };
 
 struct mlx5e_vport_stats {
@@ -133,18 +207,22 @@ struct mlx5e_vport_stats {
        /* SW counters */
        u64 tso_packets;
        u64 tso_bytes;
+       u64 tso_inner_packets;
+       u64 tso_inner_bytes;
        u64 lro_packets;
        u64 lro_bytes;
        u64 rx_csum_good;
        u64 rx_csum_none;
        u64 rx_csum_sw;
        u64 tx_csum_offload;
+       u64 tx_csum_inner;
        u64 tx_queue_stopped;
        u64 tx_queue_wake;
        u64 tx_queue_dropped;
        u64 rx_wqe_err;
+       u64 rx_mpwqe_filler;
 
-#define NUM_VPORT_COUNTERS     32
+#define NUM_VPORT_COUNTERS     36
 };
 
 static const char pport_strings[][ETH_GSTRING_LEN] = {
@@ -221,6 +299,15 @@ struct mlx5e_pport_stats {
        __be64 RFC_2819_counters[NUM_RFC_2819_COUNTERS];
 };
 
+static const char qcounter_stats_strings[][ETH_GSTRING_LEN] = {
+       "rx_out_of_buffer",
+};
+
+struct mlx5e_qcounter_stats {
+       u32 rx_out_of_buffer;
+#define NUM_Q_COUNTERS 1
+};
+
 static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
        "packets",
        "bytes",
@@ -228,7 +315,8 @@ static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
        "csum_sw",
        "lro_packets",
        "lro_bytes",
-       "wqe_err"
+       "wqe_err",
+       "mpwqe_filler",
 };
 
 struct mlx5e_rq_stats {
@@ -239,7 +327,8 @@ struct mlx5e_rq_stats {
        u64 lro_packets;
        u64 lro_bytes;
        u64 wqe_err;
-#define NUM_RQ_STATS 7
+       u64 mpwqe_filler;
+#define NUM_RQ_STATS 8
 };
 
 static const char sq_stats_strings[][ETH_GSTRING_LEN] = {
@@ -247,36 +336,45 @@ static const char sq_stats_strings[][ETH_GSTRING_LEN] = {
        "bytes",
        "tso_packets",
        "tso_bytes",
+       "tso_inner_packets",
+       "tso_inner_bytes",
+       "csum_offload_inner",
+       "nop",
        "csum_offload_none",
        "stopped",
        "wake",
        "dropped",
-       "nop"
 };
 
 struct mlx5e_sq_stats {
+       /* commonly accessed in data path */
        u64 packets;
        u64 bytes;
        u64 tso_packets;
        u64 tso_bytes;
+       u64 tso_inner_packets;
+       u64 tso_inner_bytes;
+       u64 csum_offload_inner;
+       u64 nop;
+       /* less likely accessed in data path */
        u64 csum_offload_none;
        u64 stopped;
        u64 wake;
        u64 dropped;
-       u64 nop;
-#define NUM_SQ_STATS 9
+#define NUM_SQ_STATS 12
 };
 
 struct mlx5e_stats {
        struct mlx5e_vport_stats   vport;
        struct mlx5e_pport_stats   pport;
+       struct mlx5e_qcounter_stats qcnt;
 };
 
 struct mlx5e_params {
        u8  log_sq_size;
+       u8  rq_wq_type;
        u8  log_rq_size;
        u16 num_channels;
-       u8  default_vlan_prio;
        u8  num_tc;
        u16 rx_cq_moderation_usec;
        u16 rx_cq_moderation_pkts;
@@ -289,6 +387,9 @@ struct mlx5e_params {
        u8  rss_hfunc;
        u8  toeplitz_hash_key[40];
        u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE];
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+       struct ieee_ets ets;
+#endif
 };
 
 struct mlx5e_tstamp {
@@ -322,23 +423,44 @@ struct mlx5e_cq {
        struct mlx5_wq_ctrl        wq_ctrl;
 } ____cacheline_aligned_in_smp;
 
+struct mlx5e_rq;
+typedef void (*mlx5e_fp_handle_rx_cqe)(struct mlx5e_rq *rq,
+                                      struct mlx5_cqe64 *cqe);
+typedef int (*mlx5e_fp_alloc_wqe)(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe,
+                                 u16 ix);
+
+struct mlx5e_dma_info {
+       struct page     *page;
+       dma_addr_t      addr;
+};
+
+struct mlx5e_mpw_info {
+       struct mlx5e_dma_info dma_info;
+       u16 consumed_strides;
+       u16 skbs_frags[MLX5_MPWRQ_PAGES_PER_WQE];
+};
+
 struct mlx5e_rq {
        /* data path */
        struct mlx5_wq_ll      wq;
        u32                    wqe_sz;
        struct sk_buff       **skb;
+       struct mlx5e_mpw_info *wqe_info;
 
        struct device         *pdev;
        struct net_device     *netdev;
        struct mlx5e_tstamp   *tstamp;
        struct mlx5e_rq_stats  stats;
        struct mlx5e_cq        cq;
+       mlx5e_fp_handle_rx_cqe handle_rx_cqe;
+       mlx5e_fp_alloc_wqe     alloc_wqe;
 
        unsigned long          state;
        int                    ix;
 
        /* control */
        struct mlx5_wq_ctrl    wq_ctrl;
+       u8                     wq_type;
        u32                    rqn;
        struct mlx5e_channel  *channel;
        struct mlx5e_priv     *priv;
@@ -363,6 +485,12 @@ struct mlx5e_sq_dma {
 
 enum {
        MLX5E_SQ_STATE_WAKE_TXQ_ENABLE,
+       MLX5E_SQ_STATE_BF_ENABLE,
+};
+
+struct mlx5e_ico_wqe_info {
+       u8  opcode;
+       u8  num_wqebbs;
 };
 
 struct mlx5e_sq {
@@ -391,7 +519,6 @@ struct mlx5e_sq {
        struct mlx5_wq_cyc         wq;
        u32                        dma_fifo_mask;
        void __iomem              *uar_map;
-       void __iomem              *uar_bf_map;
        struct netdev_queue       *txq;
        u32                        sqn;
        u16                        bf_buf_size;
@@ -407,6 +534,7 @@ struct mlx5e_sq {
        struct mlx5_uar            uar;
        struct mlx5e_channel      *channel;
        int                        tc;
+       struct mlx5e_ico_wqe_info *ico_wqe_info;
 } ____cacheline_aligned_in_smp;
 
 static inline bool mlx5e_sq_has_room_for(struct mlx5e_sq *sq, u16 n)
@@ -423,6 +551,7 @@ struct mlx5e_channel {
        /* data path */
        struct mlx5e_rq            rq;
        struct mlx5e_sq            sq[MLX5E_MAX_NUM_TC];
+       struct mlx5e_sq            icosq;   /* internal control operations */
        struct napi_struct         napi;
        struct device             *pdev;
        struct net_device         *netdev;
@@ -492,21 +621,33 @@ struct mlx5e_vlan_db {
        bool          filter_disabled;
 };
 
+struct mlx5e_vxlan_db {
+       spinlock_t                      lock; /* protect vxlan table */
+       struct radix_tree_root          tree;
+};
+
 struct mlx5e_flow_table {
        int num_groups;
        struct mlx5_flow_table          *t;
        struct mlx5_flow_group          **g;
 };
 
+struct mlx5e_tc_flow_table {
+       struct mlx5_flow_table          *t;
+
+       struct rhashtable_params        ht_params;
+       struct rhashtable               ht;
+};
+
 struct mlx5e_flow_tables {
        struct mlx5_flow_namespace      *ns;
+       struct mlx5e_tc_flow_table      tc;
        struct mlx5e_flow_table         vlan;
        struct mlx5e_flow_table         main;
 };
 
 struct mlx5e_priv {
        /* priv data path fields - start */
-       int                        default_vlan_prio;
        struct mlx5e_sq            **txq_to_sq_map;
        int channeltc_to_txq_map[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
        /* priv data path fields - end */
@@ -516,7 +657,7 @@ struct mlx5e_priv {
        struct mlx5_uar            cq_uar;
        u32                        pdn;
        u32                        tdn;
-       struct mlx5_core_mr        mr;
+       struct mlx5_core_mkey      mkey;
        struct mlx5e_rq            drop_rq;
 
        struct mlx5e_channel     **channel;
@@ -527,9 +668,9 @@ struct mlx5e_priv {
        struct mlx5e_flow_tables   fts;
        struct mlx5e_eth_addr_db   eth_addr;
        struct mlx5e_vlan_db       vlan;
+       struct mlx5e_vxlan_db      vxlan;
 
        struct mlx5e_params        params;
-       spinlock_t                 async_events_spinlock; /* sync hw events */
        struct work_struct         update_carrier_work;
        struct work_struct         set_rx_mode_work;
        struct delayed_work        update_stats_work;
@@ -538,18 +679,7 @@ struct mlx5e_priv {
        struct net_device         *netdev;
        struct mlx5e_stats         stats;
        struct mlx5e_tstamp        tstamp;
-};
-
-#define MLX5E_NET_IP_ALIGN 2
-
-struct mlx5e_tx_wqe {
-       struct mlx5_wqe_ctrl_seg ctrl;
-       struct mlx5_wqe_eth_seg  eth;
-};
-
-struct mlx5e_rx_wqe {
-       struct mlx5_wqe_srq_next_seg  next;
-       struct mlx5_wqe_data_seg      data;
+       u16 q_counter;
 };
 
 enum mlx5e_link_mode {
@@ -592,9 +722,14 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev);
 void mlx5e_completion_event(struct mlx5_core_cq *mcq);
 void mlx5e_cq_error_event(struct mlx5_core_cq *mcq, enum mlx5_event event);
 int mlx5e_napi_poll(struct napi_struct *napi, int budget);
-bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq);
+bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
 int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget);
+
+void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
+void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
 bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq);
+int mlx5e_alloc_rx_wqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix);
+int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix);
 struct mlx5_cqe64 *mlx5e_get_cqe(struct mlx5e_cq *cq);
 
 void mlx5e_update_stats(struct mlx5e_priv *priv);
@@ -623,7 +758,8 @@ void mlx5e_build_tir_ctx_hash(void *tirc, struct mlx5e_priv *priv);
 
 int mlx5e_open_locked(struct net_device *netdev);
 int mlx5e_close_locked(struct net_device *netdev);
-void mlx5e_build_default_indir_rqt(u32 *indirection_rqt, int len,
+void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
+                                  u32 *indirection_rqt, int len,
                                   int num_channels);
 
 static inline void mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
@@ -640,16 +776,12 @@ static inline void mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
         * doorbell
         */
        wmb();
-
-       if (bf_sz) {
-               __iowrite64_copy(sq->uar_bf_map + ofst, &wqe->ctrl, bf_sz);
-
-               /* flush the write-combining mapped buffer */
-               wmb();
-
-       } else {
+       if (bf_sz)
+               __iowrite64_copy(sq->uar_map + ofst, &wqe->ctrl, bf_sz);
+       else
                mlx5_write64((__be32 *)&wqe->ctrl, sq->uar_map + ofst, NULL);
-       }
+       /* flush the write-combining mapped buffer */
+       wmb();
 
        sq->bf_offset ^= sq->bf_buf_size;
 }
@@ -669,4 +801,11 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
 }
 
 extern const struct ethtool_ops mlx5e_ethtool_ops;
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+extern const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops;
+int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets);
+#endif
+
 u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev);
+
+#endif /* __MLX5_EN_H__ */