Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
0002 /* Copyright (c) 2018-2021, Mellanox Technologies inc.  All rights reserved. */
0003 
0004 #ifndef __LIB_MLX5_EQ_H__
0005 #define __LIB_MLX5_EQ_H__
0006 #include <linux/mlx5/driver.h>
0007 #include <linux/mlx5/eq.h>
0008 #include <linux/mlx5/cq.h>
0009 
0010 #define MLX5_EQE_SIZE       (sizeof(struct mlx5_eqe))
0011 
0012 struct mlx5_eq_tasklet {
0013     struct list_head      list;
0014     struct list_head      process_list;
0015     struct tasklet_struct task;
0016     spinlock_t            lock; /* lock completion tasklet list */
0017 };
0018 
0019 struct mlx5_cq_table {
0020     spinlock_t              lock;   /* protect radix tree */
0021     struct radix_tree_root  tree;
0022 };
0023 
0024 struct mlx5_eq {
0025     struct mlx5_frag_buf_ctrl fbc;
0026     struct mlx5_frag_buf    frag_buf;
0027     struct mlx5_core_dev    *dev;
0028     struct mlx5_cq_table    cq_table;
0029     __be32 __iomem          *doorbell;
0030     u32                     cons_index;
0031     unsigned int            vecidx;
0032     unsigned int            irqn;
0033     u8                      eqn;
0034     struct mlx5_rsc_debug   *dbg;
0035     struct mlx5_irq         *irq;
0036 };
0037 
0038 struct mlx5_eq_async {
0039     struct mlx5_eq          core;
0040     struct notifier_block   irq_nb;
0041     spinlock_t              lock; /* To avoid irq EQ handle races with resiliency flows */
0042 };
0043 
0044 struct mlx5_eq_comp {
0045     struct mlx5_eq          core;
0046     struct notifier_block   irq_nb;
0047     struct mlx5_eq_tasklet  tasklet_ctx;
0048     struct list_head        list;
0049 };
0050 
0051 static inline u32 eq_get_size(struct mlx5_eq *eq)
0052 {
0053     return eq->fbc.sz_m1 + 1;
0054 }
0055 
0056 static inline struct mlx5_eqe *get_eqe(struct mlx5_eq *eq, u32 entry)
0057 {
0058     return mlx5_frag_buf_get_wqe(&eq->fbc, entry);
0059 }
0060 
0061 static inline struct mlx5_eqe *next_eqe_sw(struct mlx5_eq *eq)
0062 {
0063     struct mlx5_eqe *eqe = get_eqe(eq, eq->cons_index & eq->fbc.sz_m1);
0064 
0065     return (eqe->owner ^ (eq->cons_index >> eq->fbc.log_sz)) & 1 ? NULL : eqe;
0066 }
0067 
0068 static inline void eq_update_ci(struct mlx5_eq *eq, int arm)
0069 {
0070     __be32 __iomem *addr = eq->doorbell + (arm ? 0 : 2);
0071     u32 val = (eq->cons_index & 0xffffff) | (eq->eqn << 24);
0072 
0073     __raw_writel((__force u32)cpu_to_be32(val), addr);
0074     /* We still want ordering, just not swabbing, so add a barrier */
0075     mb();
0076 }
0077 
0078 int mlx5_eq_table_init(struct mlx5_core_dev *dev);
0079 void mlx5_eq_table_cleanup(struct mlx5_core_dev *dev);
0080 int mlx5_eq_table_create(struct mlx5_core_dev *dev);
0081 void mlx5_eq_table_destroy(struct mlx5_core_dev *dev);
0082 
0083 int mlx5_eq_add_cq(struct mlx5_eq *eq, struct mlx5_core_cq *cq);
0084 void mlx5_eq_del_cq(struct mlx5_eq *eq, struct mlx5_core_cq *cq);
0085 struct mlx5_eq_comp *mlx5_eqn2comp_eq(struct mlx5_core_dev *dev, int eqn);
0086 struct mlx5_eq *mlx5_get_async_eq(struct mlx5_core_dev *dev);
0087 void mlx5_cq_tasklet_cb(struct tasklet_struct *t);
0088 struct cpumask *mlx5_eq_comp_cpumask(struct mlx5_core_dev *dev, int ix);
0089 
0090 u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq_comp *eq);
0091 void mlx5_cmd_eq_recover(struct mlx5_core_dev *dev);
0092 void mlx5_eq_synchronize_async_irq(struct mlx5_core_dev *dev);
0093 void mlx5_eq_synchronize_cmd_irq(struct mlx5_core_dev *dev);
0094 
0095 int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
0096 void mlx5_debug_eq_remove(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
0097 void mlx5_eq_debugfs_init(struct mlx5_core_dev *dev);
0098 void mlx5_eq_debugfs_cleanup(struct mlx5_core_dev *dev);
0099 
0100 /* This function should only be called after mlx5_cmd_force_teardown_hca */
0101 void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev);
0102 
0103 #ifdef CONFIG_RFS_ACCEL
0104 struct cpu_rmap *mlx5_eq_table_get_rmap(struct mlx5_core_dev *dev);
0105 #endif
0106 
0107 int mlx5_vector2irqn(struct mlx5_core_dev *dev, int vector, unsigned int *irqn);
0108 
0109 #endif