IB/core: Add IPv6 support to flow steering
[cascardo/linux.git] / include / rdma / ib_verbs.h
index fc0320c..9bbca68 100644 (file)
@@ -217,10 +217,10 @@ enum ib_device_cap_flags {
        IB_DEVICE_CROSS_CHANNEL         = (1 << 27),
        IB_DEVICE_MANAGED_FLOW_STEERING         = (1 << 29),
        IB_DEVICE_SIGNATURE_HANDOVER            = (1 << 30),
-       IB_DEVICE_ON_DEMAND_PAGING              = (1 << 31),
+       IB_DEVICE_ON_DEMAND_PAGING              = (1ULL << 31),
        IB_DEVICE_SG_GAPS_REG                   = (1ULL << 32),
-       IB_DEVICE_VIRTUAL_FUNCTION              = ((u64)1 << 33),
-       IB_DEVICE_RAW_SCATTER_FCS               = ((u64)1 << 34),
+       IB_DEVICE_VIRTUAL_FUNCTION              = (1ULL << 33),
+       IB_DEVICE_RAW_SCATTER_FCS               = (1ULL << 34),
 };
 
 enum ib_signature_prot_cap {
@@ -403,56 +403,55 @@ enum ib_port_speed {
        IB_SPEED_EDR    = 32
 };
 
-struct ib_protocol_stats {
-       /* TBD... */
-};
-
-struct iw_protocol_stats {
-       u64     ipInReceives;
-       u64     ipInHdrErrors;
-       u64     ipInTooBigErrors;
-       u64     ipInNoRoutes;
-       u64     ipInAddrErrors;
-       u64     ipInUnknownProtos;
-       u64     ipInTruncatedPkts;
-       u64     ipInDiscards;
-       u64     ipInDelivers;
-       u64     ipOutForwDatagrams;
-       u64     ipOutRequests;
-       u64     ipOutDiscards;
-       u64     ipOutNoRoutes;
-       u64     ipReasmTimeout;
-       u64     ipReasmReqds;
-       u64     ipReasmOKs;
-       u64     ipReasmFails;
-       u64     ipFragOKs;
-       u64     ipFragFails;
-       u64     ipFragCreates;
-       u64     ipInMcastPkts;
-       u64     ipOutMcastPkts;
-       u64     ipInBcastPkts;
-       u64     ipOutBcastPkts;
-
-       u64     tcpRtoAlgorithm;
-       u64     tcpRtoMin;
-       u64     tcpRtoMax;
-       u64     tcpMaxConn;
-       u64     tcpActiveOpens;
-       u64     tcpPassiveOpens;
-       u64     tcpAttemptFails;
-       u64     tcpEstabResets;
-       u64     tcpCurrEstab;
-       u64     tcpInSegs;
-       u64     tcpOutSegs;
-       u64     tcpRetransSegs;
-       u64     tcpInErrs;
-       u64     tcpOutRsts;
-};
-
-union rdma_protocol_stats {
-       struct ib_protocol_stats        ib;
-       struct iw_protocol_stats        iw;
-};
+/**
+ * struct rdma_hw_stats
+ * @timestamp - Used by the core code to track when the last update was
+ * @lifespan - Used by the core code to determine how old the counters
+ *   should be before being updated again.  Stored in jiffies, defaults
+ *   to 10 milliseconds, drivers can override the default be specifying
+ *   their own value during their allocation routine.
+ * @name - Array of pointers to static names used for the counters in
+ *   directory.
+ * @num_counters - How many hardware counters there are.  If name is
+ *   shorter than this number, a kernel oops will result.  Driver authors
+ *   are encouraged to leave BUILD_BUG_ON(ARRAY_SIZE(@name) < num_counters)
+ *   in their code to prevent this.
+ * @value - Array of u64 counters that are accessed by the sysfs code and
+ *   filled in by the drivers get_stats routine
+ */
+struct rdma_hw_stats {
+       unsigned long   timestamp;
+       unsigned long   lifespan;
+       const char * const *names;
+       int             num_counters;
+       u64             value[];
+};
+
+#define RDMA_HW_STATS_DEFAULT_LIFESPAN 10
+/**
+ * rdma_alloc_hw_stats_struct - Helper function to allocate dynamic struct
+ *   for drivers.
+ * @names - Array of static const char *
+ * @num_counters - How many elements in array
+ * @lifespan - How many milliseconds between updates
+ */
+static inline struct rdma_hw_stats *rdma_alloc_hw_stats_struct(
+               const char * const *names, int num_counters,
+               unsigned long lifespan)
+{
+       struct rdma_hw_stats *stats;
+
+       stats = kzalloc(sizeof(*stats) + num_counters * sizeof(u64),
+                       GFP_KERNEL);
+       if (!stats)
+               return NULL;
+       stats->names = names;
+       stats->num_counters = num_counters;
+       stats->lifespan = msecs_to_jiffies(lifespan);
+
+       return stats;
+}
+
 
 /* Define bits for the various functionality this port needs to be supported by
  * the core.
@@ -563,6 +562,7 @@ enum ib_event_type {
        IB_EVENT_QP_LAST_WQE_REACHED,
        IB_EVENT_CLIENT_REREGISTER,
        IB_EVENT_GID_CHANGE,
+       IB_EVENT_WQ_FATAL,
 };
 
 const char *__attribute_const__ ib_event_msg(enum ib_event_type event);
@@ -573,6 +573,7 @@ struct ib_event {
                struct ib_cq    *cq;
                struct ib_qp    *qp;
                struct ib_srq   *srq;
+               struct ib_wq    *wq;
                u8              port_num;
        } element;
        enum ib_event_type      event;
@@ -1016,6 +1017,7 @@ struct ib_qp_init_attr {
         * Only needed for special QP types, or when using the RW API.
         */
        u8                      port_num;
+       struct ib_rwq_ind_table *rwq_ind_tbl;
 };
 
 struct ib_qp_open_attr {
@@ -1324,6 +1326,8 @@ struct ib_ucontext {
        struct list_head        ah_list;
        struct list_head        xrcd_list;
        struct list_head        rule_list;
+       struct list_head        wq_list;
+       struct list_head        rwq_ind_tbl_list;
        int                     closing;
 
        struct pid             *tgid;
@@ -1429,6 +1433,63 @@ struct ib_srq {
        } ext;
 };
 
+enum ib_wq_type {
+       IB_WQT_RQ
+};
+
+enum ib_wq_state {
+       IB_WQS_RESET,
+       IB_WQS_RDY,
+       IB_WQS_ERR
+};
+
+struct ib_wq {
+       struct ib_device       *device;
+       struct ib_uobject      *uobject;
+       void                *wq_context;
+       void                (*event_handler)(struct ib_event *, void *);
+       struct ib_pd           *pd;
+       struct ib_cq           *cq;
+       u32             wq_num;
+       enum ib_wq_state       state;
+       enum ib_wq_type wq_type;
+       atomic_t                usecnt;
+};
+
+struct ib_wq_init_attr {
+       void                   *wq_context;
+       enum ib_wq_type wq_type;
+       u32             max_wr;
+       u32             max_sge;
+       struct  ib_cq          *cq;
+       void                (*event_handler)(struct ib_event *, void *);
+};
+
+enum ib_wq_attr_mask {
+       IB_WQ_STATE     = 1 << 0,
+       IB_WQ_CUR_STATE = 1 << 1,
+};
+
+struct ib_wq_attr {
+       enum    ib_wq_state     wq_state;
+       enum    ib_wq_state     curr_wq_state;
+};
+
+struct ib_rwq_ind_table {
+       struct ib_device        *device;
+       struct ib_uobject      *uobject;
+       atomic_t                usecnt;
+       u32             ind_tbl_num;
+       u32             log_ind_tbl_size;
+       struct ib_wq    **ind_tbl;
+};
+
+struct ib_rwq_ind_table_init_attr {
+       u32             log_ind_tbl_size;
+       /* Each entry is a pointer to Receive Work Queue */
+       struct ib_wq    **ind_tbl;
+};
+
 struct ib_qp {
        struct ib_device       *device;
        struct ib_pd           *pd;
@@ -1451,6 +1512,7 @@ struct ib_qp {
        void                   *qp_context;
        u32                     qp_num;
        enum ib_qp_type         qp_type;
+       struct ib_rwq_ind_table *rwq_ind_tbl;
 };
 
 struct ib_mr {
@@ -1507,6 +1569,7 @@ enum ib_flow_spec_type {
        IB_FLOW_SPEC_IB         = 0x22,
        /* L3 header*/
        IB_FLOW_SPEC_IPV4       = 0x30,
+       IB_FLOW_SPEC_IPV6       = 0x31,
        /* L4 headers*/
        IB_FLOW_SPEC_TCP        = 0x40,
        IB_FLOW_SPEC_UDP        = 0x41
@@ -1568,6 +1631,18 @@ struct ib_flow_spec_ipv4 {
        struct ib_flow_ipv4_filter mask;
 };
 
+struct ib_flow_ipv6_filter {
+       u8      src_ip[16];
+       u8      dst_ip[16];
+};
+
+struct ib_flow_spec_ipv6 {
+       enum ib_flow_spec_type     type;
+       u16                        size;
+       struct ib_flow_ipv6_filter val;
+       struct ib_flow_ipv6_filter mask;
+};
+
 struct ib_flow_tcp_udp_filter {
        __be16  dst_port;
        __be16  src_port;
@@ -1589,6 +1664,7 @@ union ib_flow_spec {
        struct ib_flow_spec_ib          ib;
        struct ib_flow_spec_ipv4        ipv4;
        struct ib_flow_spec_tcp_udp     tcp_udp;
+       struct ib_flow_spec_ipv6        ipv6;
 };
 
 struct ib_flow_attr {
@@ -1707,8 +1783,29 @@ struct ib_device {
 
        struct iw_cm_verbs           *iwcm;
 
-       int                        (*get_protocol_stats)(struct ib_device *device,
-                                                        union rdma_protocol_stats *stats);
+       /**
+        * alloc_hw_stats - Allocate a struct rdma_hw_stats and fill in the
+        *   driver initialized data.  The struct is kfree()'ed by the sysfs
+        *   core when the device is removed.  A lifespan of -1 in the return
+        *   struct tells the core to set a default lifespan.
+        */
+       struct rdma_hw_stats      *(*alloc_hw_stats)(struct ib_device *device,
+                                                    u8 port_num);
+       /**
+        * get_hw_stats - Fill in the counter value(s) in the stats struct.
+        * @index - The index in the value array we wish to have updated, or
+        *   num_counters if we want all stats updated
+        * Return codes -
+        *   < 0 - Error, no counters updated
+        *   index - Updated the single counter pointed to by index
+        *   num_counters - Updated all counters (will reset the timestamp
+        *     and prevent further calls for lifespan milliseconds)
+        * Drivers are allowed to update all counters in leiu of just the
+        *   one given in index at their option
+        */
+       int                        (*get_hw_stats)(struct ib_device *device,
+                                                  struct rdma_hw_stats *stats,
+                                                  u8 port, int index);
        int                        (*query_device)(struct ib_device *device,
                                                   struct ib_device_attr *device_attr,
                                                   struct ib_udata *udata);
@@ -1901,7 +1998,18 @@ struct ib_device {
                                                   struct ifla_vf_stats *stats);
        int                        (*set_vf_guid)(struct ib_device *device, int vf, u8 port, u64 guid,
                                                  int type);
-
+       struct ib_wq *             (*create_wq)(struct ib_pd *pd,
+                                               struct ib_wq_init_attr *init_attr,
+                                               struct ib_udata *udata);
+       int                        (*destroy_wq)(struct ib_wq *wq);
+       int                        (*modify_wq)(struct ib_wq *wq,
+                                               struct ib_wq_attr *attr,
+                                               u32 wq_attr_mask,
+                                               struct ib_udata *udata);
+       struct ib_rwq_ind_table *  (*create_rwq_ind_table)(struct ib_device *device,
+                                                          struct ib_rwq_ind_table_init_attr *init_attr,
+                                                          struct ib_udata *udata);
+       int                        (*destroy_rwq_ind_table)(struct ib_rwq_ind_table *wq_ind_table);
        struct ib_dma_mapping_ops   *dma_ops;
 
        struct module               *owner;
@@ -1926,6 +2034,8 @@ struct ib_device {
        u8                           node_type;
        u8                           phys_port_cnt;
        struct ib_device_attr        attrs;
+       struct attribute_group       *hw_stats_ag;
+       struct rdma_hw_stats         *hw_stats;
 
        /**
         * The following mandatory functions are used only at device
@@ -3145,6 +3255,15 @@ int ib_check_mr_status(struct ib_mr *mr, u32 check_mask,
 struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, u8 port,
                                            u16 pkey, const union ib_gid *gid,
                                            const struct sockaddr *addr);
+struct ib_wq *ib_create_wq(struct ib_pd *pd,
+                          struct ib_wq_init_attr *init_attr);
+int ib_destroy_wq(struct ib_wq *wq);
+int ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *attr,
+                u32 wq_attr_mask);
+struct ib_rwq_ind_table *ib_create_rwq_ind_table(struct ib_device *device,
+                                                struct ib_rwq_ind_table_init_attr*
+                                                wq_ind_table_init_attr);
+int ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *wq_ind_table);
 
 int ib_map_mr_sg(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,
                 unsigned int *sg_offset, unsigned int page_size);