net/mlx5e: Implement RX mapped page cache for page recycle
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / en.h
index bf722aa..7dd4763 100644 (file)
 #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_DEFAULT_LOG_RQ_SIZE_MPW            0x3
 #define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW            0x6
 
 #define MLX5_MPWRQ_LOG_STRIDE_SIZE             6  /* >= 6, HW restriction */
 #define MLX5_MPWRQ_LOG_STRIDE_SIZE_CQE_COMPRESS        8  /* >= 6, HW restriction */
-#define MLX5_MPWRQ_LOG_WQE_SZ                  17
+#define MLX5_MPWRQ_LOG_WQE_SZ                  18
 #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)
@@ -287,20 +287,34 @@ struct mlx5e_rx_am { /* Adaptive Moderation */
        u8                                      tired;
 };
 
+/* a single cache unit is capable to serve one napi call (for non-striding rq)
+ * or a MPWQE (for striding rq).
+ */
+#define MLX5E_CACHE_UNIT       (MLX5_MPWRQ_PAGES_PER_WQE > NAPI_POLL_WEIGHT ? \
+                                MLX5_MPWRQ_PAGES_PER_WQE : NAPI_POLL_WEIGHT)
+#define MLX5E_CACHE_SIZE       (2 * roundup_pow_of_two(MLX5E_CACHE_UNIT))
+struct mlx5e_page_cache {
+       u32 head;
+       u32 tail;
+       struct mlx5e_dma_info page_cache[MLX5E_CACHE_SIZE];
+};
+
 struct mlx5e_rq {
        /* data path */
        struct mlx5_wq_ll      wq;
        u32                    wqe_sz;
        struct sk_buff       **skb;
        struct mlx5e_mpw_info *wqe_info;
+       void                  *mtt_no_align;
        __be32                 mkey_be;
-       __be32                 umr_mkey_be;
 
        struct device         *pdev;
        struct net_device     *netdev;
        struct mlx5e_tstamp   *tstamp;
        struct mlx5e_rq_stats  stats;
        struct mlx5e_cq        cq;
+       struct mlx5e_page_cache page_cache;
+
        mlx5e_fp_handle_rx_cqe handle_rx_cqe;
        mlx5e_fp_alloc_wqe     alloc_wqe;
        mlx5e_fp_dealloc_wqe   dealloc_wqe;
@@ -323,32 +337,15 @@ struct mlx5e_rq {
 
 struct mlx5e_umr_dma_info {
        __be64                *mtt;
-       __be64                *mtt_no_align;
        dma_addr_t             mtt_addr;
-       struct mlx5e_dma_info *dma_info;
+       struct mlx5e_dma_info  dma_info[MLX5_MPWRQ_PAGES_PER_WQE];
+       struct mlx5e_umr_wqe   wqe;
 };
 
 struct mlx5e_mpw_info {
-       union {
-               struct mlx5e_dma_info     dma_info;
-               struct mlx5e_umr_dma_info umr;
-       };
+       struct mlx5e_umr_dma_info umr;
        u16 consumed_strides;
        u16 skbs_frags[MLX5_MPWRQ_PAGES_PER_WQE];
-
-       void (*dma_pre_sync)(struct device *pdev,
-                            struct mlx5e_mpw_info *wi,
-                            u32 wqe_offset, u32 len);
-       void (*add_skb_frag)(struct mlx5e_rq *rq,
-                            struct sk_buff *skb,
-                            struct mlx5e_mpw_info *wi,
-                            u32 page_idx, u32 frag_offset, u32 len);
-       void (*copy_skb_header)(struct device *pdev,
-                               struct sk_buff *skb,
-                               struct mlx5e_mpw_info *wi,
-                               u32 page_idx, u32 offset,
-                               u32 headlen);
-       void (*free_wqe)(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi);
 };
 
 struct mlx5e_tx_wqe_info {
@@ -654,40 +651,6 @@ struct mlx5e_priv {
        void                      *ppriv;
 };
 
-enum mlx5e_link_mode {
-       MLX5E_1000BASE_CX_SGMII  = 0,
-       MLX5E_1000BASE_KX        = 1,
-       MLX5E_10GBASE_CX4        = 2,
-       MLX5E_10GBASE_KX4        = 3,
-       MLX5E_10GBASE_KR         = 4,
-       MLX5E_20GBASE_KR2        = 5,
-       MLX5E_40GBASE_CR4        = 6,
-       MLX5E_40GBASE_KR4        = 7,
-       MLX5E_56GBASE_R4         = 8,
-       MLX5E_10GBASE_CR         = 12,
-       MLX5E_10GBASE_SR         = 13,
-       MLX5E_10GBASE_ER         = 14,
-       MLX5E_40GBASE_SR4        = 15,
-       MLX5E_40GBASE_LR4        = 16,
-       MLX5E_50GBASE_SR2        = 18,
-       MLX5E_100GBASE_CR4       = 20,
-       MLX5E_100GBASE_SR4       = 21,
-       MLX5E_100GBASE_KR4       = 22,
-       MLX5E_100GBASE_LR4       = 23,
-       MLX5E_100BASE_TX         = 24,
-       MLX5E_1000BASE_T         = 25,
-       MLX5E_10GBASE_T          = 26,
-       MLX5E_25GBASE_CR         = 27,
-       MLX5E_25GBASE_KR         = 28,
-       MLX5E_25GBASE_SR         = 29,
-       MLX5E_50GBASE_CR2        = 30,
-       MLX5E_50GBASE_KR2        = 31,
-       MLX5E_LINK_MODES_NUMBER,
-};
-
-#define MLX5E_PROT_MASK(link_mode) (1 << link_mode)
-
-
 void mlx5e_build_ptys2ethtool_map(void);
 
 void mlx5e_send_nop(struct mlx5e_sq *sq, bool notify_hw);
@@ -702,28 +665,17 @@ 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_free_tx_descs(struct mlx5e_sq *sq);
 
+void mlx5e_page_release(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info,
+                       bool recycle);
 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);
+int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe,        u16 ix);
 void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix);
 void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix);
-void mlx5e_post_rx_fragmented_mpwqe(struct mlx5e_rq *rq);
-void mlx5e_complete_rx_linear_mpwqe(struct mlx5e_rq *rq,
-                                   struct mlx5_cqe64 *cqe,
-                                   u16 byte_cnt,
-                                   struct mlx5e_mpw_info *wi,
-                                   struct sk_buff *skb);
-void mlx5e_complete_rx_fragmented_mpwqe(struct mlx5e_rq *rq,
-                                       struct mlx5_cqe64 *cqe,
-                                       u16 byte_cnt,
-                                       struct mlx5e_mpw_info *wi,
-                                       struct sk_buff *skb);
-void mlx5e_free_rx_linear_mpwqe(struct mlx5e_rq *rq,
-                               struct mlx5e_mpw_info *wi);
-void mlx5e_free_rx_fragmented_mpwqe(struct mlx5e_rq *rq,
-                                   struct mlx5e_mpw_info *wi);
+void mlx5e_post_rx_mpwqe(struct mlx5e_rq *rq);
+void mlx5e_free_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi);
 struct mlx5_cqe64 *mlx5e_get_cqe(struct mlx5e_cq *cq);
 
 void mlx5e_rx_am(struct mlx5e_rq *rq);
@@ -810,6 +762,12 @@ static inline void mlx5e_cq_arm(struct mlx5e_cq *cq)
        mlx5_cq_arm(mcq, MLX5_CQ_DB_REQ_NOT, mcq->uar->map, NULL, cq->wq.cc);
 }
 
+static inline u32 mlx5e_get_wqe_mtt_offset(struct mlx5e_rq *rq, u16 wqe_ix)
+{
+       return rq->mpwqe_mtt_offset +
+               wqe_ix * ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8);
+}
+
 static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
 {
        return min_t(int, mdev->priv.eq_table.num_comp_vectors,
@@ -878,9 +836,12 @@ void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv);
 int mlx5e_close(struct net_device *netdev);
 int mlx5e_open(struct net_device *netdev);
 void mlx5e_update_stats_work(struct work_struct *work);
-void *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
-                         const struct mlx5e_profile *profile, void *ppriv);
+struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
+                                      const struct mlx5e_profile *profile,
+                                      void *ppriv);
 void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv);
+int mlx5e_attach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev);
+void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev);
 struct rtnl_link_stats64 *
 mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats);