Merge commit '900cfa46191a7d87cf1891924cb90499287fd235'; branches 'timers/nohz',...
[cascardo/linux.git] / drivers / infiniband / hw / ehca / ehca_main.c
index a86ebcc..482103e 100644 (file)
 #include "ehca_tools.h"
 #include "hcp_if.h"
 
-#define HCAD_VERSION "0025"
+#define HCAD_VERSION "0026"
 
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
 MODULE_VERSION(HCAD_VERSION);
 
-int ehca_open_aqp1     = 0;
+static int ehca_open_aqp1     = 0;
+static int ehca_hw_level      = 0;
+static int ehca_poll_all_eqs  = 1;
+
 int ehca_debug_level   = 0;
-int ehca_hw_level      = 0;
 int ehca_nr_ports      = 2;
 int ehca_use_hp_mr     = 0;
 int ehca_port_act_time = 30;
-int ehca_poll_all_eqs  = 1;
 int ehca_static_rate   = -1;
 int ehca_scaling_code  = 0;
-int ehca_mr_largepage  = 1;
 int ehca_lock_hcalls   = -1;
-
-module_param_named(open_aqp1,     ehca_open_aqp1,     int, S_IRUGO);
-module_param_named(debug_level,   ehca_debug_level,   int, S_IRUGO);
-module_param_named(hw_level,      ehca_hw_level,      int, S_IRUGO);
-module_param_named(nr_ports,      ehca_nr_ports,      int, S_IRUGO);
-module_param_named(use_hp_mr,     ehca_use_hp_mr,     int, S_IRUGO);
-module_param_named(port_act_time, ehca_port_act_time, int, S_IRUGO);
-module_param_named(poll_all_eqs,  ehca_poll_all_eqs,  int, S_IRUGO);
-module_param_named(static_rate,   ehca_static_rate,   int, S_IRUGO);
-module_param_named(scaling_code,  ehca_scaling_code,  int, S_IRUGO);
-module_param_named(mr_largepage,  ehca_mr_largepage,  int, S_IRUGO);
+int ehca_max_cq        = -1;
+int ehca_max_qp        = -1;
+
+module_param_named(open_aqp1,     ehca_open_aqp1,     bool, S_IRUGO);
+module_param_named(debug_level,   ehca_debug_level,   int,  S_IRUGO);
+module_param_named(hw_level,      ehca_hw_level,      int,  S_IRUGO);
+module_param_named(nr_ports,      ehca_nr_ports,      int,  S_IRUGO);
+module_param_named(use_hp_mr,     ehca_use_hp_mr,     bool, S_IRUGO);
+module_param_named(port_act_time, ehca_port_act_time, int,  S_IRUGO);
+module_param_named(poll_all_eqs,  ehca_poll_all_eqs,  bool, S_IRUGO);
+module_param_named(static_rate,   ehca_static_rate,   int,  S_IRUGO);
+module_param_named(scaling_code,  ehca_scaling_code,  bool, S_IRUGO);
 module_param_named(lock_hcalls,   ehca_lock_hcalls,   bool, S_IRUGO);
+module_param_named(number_of_cqs, ehca_max_cq,        int,  S_IRUGO);
+module_param_named(number_of_qps, ehca_max_qp,        int,  S_IRUGO);
 
 MODULE_PARM_DESC(open_aqp1,
-                "AQP1 on startup (0: no (default), 1: yes)");
+                "Open AQP1 on startup (default: no)");
 MODULE_PARM_DESC(debug_level,
-                "debug level"
-                " (0: no debug traces (default), 1: with debug traces)");
+                "Amount of debug output (0: none (default), 1: traces, "
+                "2: some dumps, 3: lots)");
 MODULE_PARM_DESC(hw_level,
-                "hardware level"
-                " (0: autosensing (default), 1: v. 0.20, 2: v. 0.21)");
+                "Hardware level (0: autosensing (default), "
+                "0x10..0x14: eHCA, 0x20..0x23: eHCA2)");
 MODULE_PARM_DESC(nr_ports,
                 "number of connected ports (-1: autodetect, 1: port one only, "
                 "2: two ports (default)");
 MODULE_PARM_DESC(use_hp_mr,
-                "high performance MRs (0: no (default), 1: yes)");
+                "Use high performance MRs (default: no)");
 MODULE_PARM_DESC(port_act_time,
-                "time to wait for port activation (default: 30 sec)");
+                "Time to wait for port activation (default: 30 sec)");
 MODULE_PARM_DESC(poll_all_eqs,
-                "polls all event queues periodically"
-                " (0: no, 1: yes (default))");
+                "Poll all event queues periodically (default: yes)");
 MODULE_PARM_DESC(static_rate,
-                "set permanent static rate (default: disabled)");
+                "Set permanent static rate (default: no static rate)");
 MODULE_PARM_DESC(scaling_code,
-                "set scaling code (0: disabled/default, 1: enabled)");
-MODULE_PARM_DESC(mr_largepage,
-                "use large page for MR (0: use PAGE_SIZE (default), "
-                "1: use large page depending on MR size");
+                "Enable scaling code (default: no)");
 MODULE_PARM_DESC(lock_hcalls,
-                "serialize all hCalls made by the driver "
+                "Serialize all hCalls made by the driver "
                 "(default: autodetect)");
+MODULE_PARM_DESC(number_of_cqs,
+               "Max number of CQs which can be allocated "
+               "(default: autodetect)");
+MODULE_PARM_DESC(number_of_qps,
+               "Max number of QPs which can be allocated "
+               "(default: autodetect)");
 
 DEFINE_RWLOCK(ehca_qp_idr_lock);
 DEFINE_RWLOCK(ehca_cq_idr_lock);
@@ -274,6 +279,7 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
        u64 h_ret;
        struct hipz_query_hca *rblock;
        struct hipz_query_port *port;
+       const char *loc_code;
 
        static const u32 pgsize_map[] = {
                HCA_CAP_MR_PGSIZE_4K,  0x1000,
@@ -282,6 +288,12 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
                HCA_CAP_MR_PGSIZE_16M, 0x1000000,
        };
 
+       ehca_gen_dbg("Probing adapter %s...",
+                    shca->ofdev->node->full_name);
+       loc_code = of_get_property(shca->ofdev->node, "ibm,loc-code", NULL);
+       if (loc_code)
+               ehca_gen_dbg(" ... location lode=%s", loc_code);
+
        rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
        if (!rblock) {
                ehca_gen_err("Cannot allocate rblock memory.");
@@ -349,10 +361,27 @@ static int ehca_sense_attributes(struct ehca_shca *shca)
 
        /* translate supported MR page sizes; always support 4K */
        shca->hca_cap_mr_pgsize = EHCA_PAGESIZE;
-       if (ehca_mr_largepage) { /* support extra sizes only if enabled */
-               for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2)
-                       if (rblock->memory_page_size_supported & pgsize_map[i])
-                               shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
+       for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2)
+               if (rblock->memory_page_size_supported & pgsize_map[i])
+                       shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
+
+       /* Set maximum number of CQs and QPs to calculate EQ size */
+       if (ehca_max_qp == -1)
+               ehca_max_qp = min_t(int, rblock->max_qp, EHCA_MAX_NUM_QUEUES);
+       else if (ehca_max_qp < 1 || ehca_max_qp > rblock->max_qp) {
+               ehca_gen_err("Requested number of QPs is out of range (1 - %i) "
+                       "specified by HW", rblock->max_qp);
+               ret = -EINVAL;
+               goto sense_attributes1;
+       }
+
+       if (ehca_max_cq == -1)
+               ehca_max_cq = min_t(int, rblock->max_cq, EHCA_MAX_NUM_QUEUES);
+       else if (ehca_max_cq < 1 || ehca_max_cq > rblock->max_cq) {
+               ehca_gen_err("Requested number of CQs is out of range (1 - %i) "
+                       "specified by HW", rblock->max_cq);
+               ret = -EINVAL;
+               goto sense_attributes1;
        }
 
        /* query max MTU from first port -- it's the same for all ports */
@@ -396,7 +425,7 @@ init_node_guid1:
        return ret;
 }
 
-int ehca_init_device(struct ehca_shca *shca)
+static int ehca_init_device(struct ehca_shca *shca)
 {
        int ret;
 
@@ -566,8 +595,7 @@ static int ehca_destroy_aqp1(struct ehca_sport *sport)
 
 static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n",
-                       ehca_debug_level);
+       return snprintf(buf, PAGE_SIZE, "%d\n", ehca_debug_level);
 }
 
 static ssize_t ehca_store_debug_level(struct device_driver *ddp,
@@ -579,8 +607,8 @@ static ssize_t ehca_store_debug_level(struct device_driver *ddp,
        return 1;
 }
 
-DRIVER_ATTR(debug_level, S_IRUSR | S_IWUSR,
-           ehca_show_debug_level, ehca_store_debug_level);
+static DRIVER_ATTR(debug_level, S_IRUSR | S_IWUSR,
+                  ehca_show_debug_level, ehca_store_debug_level);
 
 static struct attribute *ehca_drv_attrs[] = {
        &driver_attr_debug_level.attr,
@@ -656,14 +684,6 @@ static ssize_t ehca_show_adapter_handle(struct device *dev,
 }
 static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);
 
-static ssize_t ehca_show_mr_largepage(struct device *dev,
-                                     struct device_attribute *attr,
-                                     char *buf)
-{
-       return sprintf(buf, "%d\n", ehca_mr_largepage);
-}
-static DEVICE_ATTR(mr_largepage, S_IRUGO, ehca_show_mr_largepage, NULL);
-
 static struct attribute *ehca_dev_attrs[] = {
        &dev_attr_adapter_handle.attr,
        &dev_attr_num_ports.attr,
@@ -680,7 +700,6 @@ static struct attribute *ehca_dev_attrs[] = {
        &dev_attr_cur_mw.attr,
        &dev_attr_max_pd.attr,
        &dev_attr_max_ah.attr,
-       &dev_attr_mr_largepage.attr,
        NULL
 };
 
@@ -694,7 +713,7 @@ static int __devinit ehca_probe(struct of_device *dev,
        struct ehca_shca *shca;
        const u64 *handle;
        struct ib_pd *ibpd;
-       int ret, i;
+       int ret, i, eq_size;
 
        handle = of_get_property(dev->node, "ibm,hca-handle", NULL);
        if (!handle) {
@@ -715,6 +734,8 @@ static int __devinit ehca_probe(struct of_device *dev,
                return -ENOMEM;
        }
        mutex_init(&shca->modify_mutex);
+       atomic_set(&shca->num_cqs, 0);
+       atomic_set(&shca->num_qps, 0);
        for (i = 0; i < ARRAY_SIZE(shca->sport); i++)
                spin_lock_init(&shca->sport[i].mod_sqp_lock);
 
@@ -734,8 +755,9 @@ static int __devinit ehca_probe(struct of_device *dev,
                goto probe1;
        }
 
+       eq_size = 2 * ehca_max_cq + 4 * ehca_max_qp;
        /* create event queues */
-       ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
+       ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, eq_size);
        if (ret) {
                ehca_err(&shca->ib_device, "Cannot create EQ.");
                goto probe1;
@@ -941,7 +963,7 @@ void ehca_poll_eqs(unsigned long data)
        spin_unlock(&shca_list_lock);
 }
 
-int __init ehca_module_init(void)
+static int __init ehca_module_init(void)
 {
        int ret;
 
@@ -988,7 +1010,7 @@ module_init1:
        return ret;
 };
 
-void __exit ehca_module_exit(void)
+static void __exit ehca_module_exit(void)
 {
        if (ehca_poll_all_eqs == 1)
                del_timer_sync(&poll_eqs_timer);