MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0022");
+MODULE_VERSION("SVNEHCA_0023");
int ehca_open_aqp1 = 0;
int ehca_debug_level = 0;
int ehca_port_act_time = 30;
int ehca_poll_all_eqs = 1;
int ehca_static_rate = -1;
-int ehca_scaling_code = 1;
+int ehca_scaling_code = 0;
module_param_named(open_aqp1, ehca_open_aqp1, int, 0);
module_param_named(debug_level, ehca_debug_level, int, 0);
MODULE_PARM_DESC(static_rate,
"set permanent static rate (default: disabled)");
MODULE_PARM_DESC(scaling_code,
- "set scaling code (0: disabled, 1: enabled/default)");
+ "set scaling code (0: disabled/default, 1: enabled)");
spinlock_t ehca_qp_idr_lock;
spinlock_t ehca_cq_idr_lock;
+spinlock_t hcall_lock;
DEFINE_IDR(ehca_qp_idr);
DEFINE_IDR(ehca_cq_idr);
#define EHCA_HCAAVER EHCA_BMASK_IBM(32,39)
#define EHCA_REVID EHCA_BMASK_IBM(40,63)
+static struct cap_descr {
+ u64 mask;
+ char *descr;
+} hca_cap_descr[] = {
+ { HCA_CAP_AH_PORT_NR_CHECK, "HCA_CAP_AH_PORT_NR_CHECK" },
+ { HCA_CAP_ATOMIC, "HCA_CAP_ATOMIC" },
+ { HCA_CAP_AUTO_PATH_MIG, "HCA_CAP_AUTO_PATH_MIG" },
+ { HCA_CAP_BAD_P_KEY_CTR, "HCA_CAP_BAD_P_KEY_CTR" },
+ { HCA_CAP_SQD_RTS_PORT_CHANGE, "HCA_CAP_SQD_RTS_PORT_CHANGE" },
+ { HCA_CAP_CUR_QP_STATE_MOD, "HCA_CAP_CUR_QP_STATE_MOD" },
+ { HCA_CAP_INIT_TYPE, "HCA_CAP_INIT_TYPE" },
+ { HCA_CAP_PORT_ACTIVE_EVENT, "HCA_CAP_PORT_ACTIVE_EVENT" },
+ { HCA_CAP_Q_KEY_VIOL_CTR, "HCA_CAP_Q_KEY_VIOL_CTR" },
+ { HCA_CAP_WQE_RESIZE, "HCA_CAP_WQE_RESIZE" },
+ { HCA_CAP_RAW_PACKET_MCAST, "HCA_CAP_RAW_PACKET_MCAST" },
+ { HCA_CAP_SHUTDOWN_PORT, "HCA_CAP_SHUTDOWN_PORT" },
+ { HCA_CAP_RC_LL_QP, "HCA_CAP_RC_LL_QP" },
+ { HCA_CAP_SRQ, "HCA_CAP_SRQ" },
+ { HCA_CAP_UD_LL_QP, "HCA_CAP_UD_LL_QP" },
+ { HCA_CAP_RESIZE_MR, "HCA_CAP_RESIZE_MR" },
+ { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
+};
+
int ehca_sense_attributes(struct ehca_shca *shca)
{
- int ret = 0;
+ int i, ret = 0;
u64 h_ret;
struct hipz_query_hca *rblock;
+ struct hipz_query_port *port;
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
if (!rblock) {
ehca_gen_err("Cannot query device properties. h_ret=%lx",
h_ret);
ret = -EPERM;
- goto num_ports1;
+ goto sense_attributes1;
}
if (ehca_nr_ports == 1)
ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid);
if ((hcaaver == 1) && (revid == 0))
- shca->hw_level = 0;
+ shca->hw_level = 0x11;
else if ((hcaaver == 1) && (revid == 1))
- shca->hw_level = 1;
+ shca->hw_level = 0x12;
else if ((hcaaver == 1) && (revid == 2))
- shca->hw_level = 2;
+ shca->hw_level = 0x13;
+ else if ((hcaaver == 2) && (revid == 0))
+ shca->hw_level = 0x21;
+ else if ((hcaaver == 2) && (revid == 0x10))
+ shca->hw_level = 0x22;
+ else {
+ ehca_gen_warn("unknown hardware version"
+ " - assuming default level");
+ shca->hw_level = 0x22;
+ }
}
ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
shca->sport[0].rate = IB_RATE_30_GBPS;
shca->sport[1].rate = IB_RATE_30_GBPS;
-num_ports1:
+ shca->hca_cap = rblock->hca_cap_indicators;
+ ehca_gen_dbg(" ... HCA capabilities:");
+ for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++)
+ if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
+ ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
+
+ port = (struct hipz_query_port *) rblock;
+ h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
+ if (h_ret != H_SUCCESS) {
+ ehca_gen_err("Cannot query port properties. h_ret=%lx",
+ h_ret);
+ ret = -EPERM;
+ goto sense_attributes1;
+ }
+
+ shca->max_mtu = port->max_mtu;
+
+sense_attributes1:
ehca_free_fw_ctrlblock(rblock);
return ret;
}
shca->ib_device.node_type = RDMA_NODE_IB_CA;
shca->ib_device.phys_port_cnt = shca->num_ports;
+ shca->ib_device.num_comp_vectors = 1;
shca->ib_device.dma_device = &shca->ibmebus_dev->ofdev.dev;
shca->ib_device.query_device = ehca_query_device;
shca->ib_device.query_port = ehca_query_port;
return -EPERM;
}
- ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10);
+ ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10, 0);
if (IS_ERR(ibcq)) {
ehca_err(&shca->ib_device, "Cannot create AQP1 CQ.");
return PTR_ERR(ibcq);
DRIVER_ATTR(debug_level, S_IRUSR | S_IWUSR,
ehca_show_debug_level, ehca_store_debug_level);
-void ehca_create_driver_sysfs(struct ibmebus_driver *drv)
-{
- driver_create_file(&drv->driver, &driver_attr_debug_level);
-}
+static struct attribute *ehca_drv_attrs[] = {
+ &driver_attr_debug_level.attr,
+ NULL
+};
-void ehca_remove_driver_sysfs(struct ibmebus_driver *drv)
-{
- driver_remove_file(&drv->driver, &driver_attr_debug_level);
-}
+static struct attribute_group ehca_drv_attr_grp = {
+ .attrs = ehca_drv_attrs
+};
#define EHCA_RESOURCE_ATTR(name) \
static ssize_t ehca_show_##name(struct device *dev, \
}
static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);
+static struct attribute *ehca_dev_attrs[] = {
+ &dev_attr_adapter_handle.attr,
+ &dev_attr_num_ports.attr,
+ &dev_attr_hw_ver.attr,
+ &dev_attr_max_eq.attr,
+ &dev_attr_cur_eq.attr,
+ &dev_attr_max_cq.attr,
+ &dev_attr_cur_cq.attr,
+ &dev_attr_max_qp.attr,
+ &dev_attr_cur_qp.attr,
+ &dev_attr_max_mr.attr,
+ &dev_attr_cur_mr.attr,
+ &dev_attr_max_mw.attr,
+ &dev_attr_cur_mw.attr,
+ &dev_attr_max_pd.attr,
+ &dev_attr_max_ah.attr,
+ NULL
+};
-void ehca_create_device_sysfs(struct ibmebus_dev *dev)
-{
- device_create_file(&dev->ofdev.dev, &dev_attr_adapter_handle);
- device_create_file(&dev->ofdev.dev, &dev_attr_num_ports);
- device_create_file(&dev->ofdev.dev, &dev_attr_hw_ver);
- device_create_file(&dev->ofdev.dev, &dev_attr_max_eq);
- device_create_file(&dev->ofdev.dev, &dev_attr_cur_eq);
- device_create_file(&dev->ofdev.dev, &dev_attr_max_cq);
- device_create_file(&dev->ofdev.dev, &dev_attr_cur_cq);
- device_create_file(&dev->ofdev.dev, &dev_attr_max_qp);
- device_create_file(&dev->ofdev.dev, &dev_attr_cur_qp);
- device_create_file(&dev->ofdev.dev, &dev_attr_max_mr);
- device_create_file(&dev->ofdev.dev, &dev_attr_cur_mr);
- device_create_file(&dev->ofdev.dev, &dev_attr_max_mw);
- device_create_file(&dev->ofdev.dev, &dev_attr_cur_mw);
- device_create_file(&dev->ofdev.dev, &dev_attr_max_pd);
- device_create_file(&dev->ofdev.dev, &dev_attr_max_ah);
-}
-
-void ehca_remove_device_sysfs(struct ibmebus_dev *dev)
-{
- device_remove_file(&dev->ofdev.dev, &dev_attr_adapter_handle);
- device_remove_file(&dev->ofdev.dev, &dev_attr_num_ports);
- device_remove_file(&dev->ofdev.dev, &dev_attr_hw_ver);
- device_remove_file(&dev->ofdev.dev, &dev_attr_max_eq);
- device_remove_file(&dev->ofdev.dev, &dev_attr_cur_eq);
- device_remove_file(&dev->ofdev.dev, &dev_attr_max_cq);
- device_remove_file(&dev->ofdev.dev, &dev_attr_cur_cq);
- device_remove_file(&dev->ofdev.dev, &dev_attr_max_qp);
- device_remove_file(&dev->ofdev.dev, &dev_attr_cur_qp);
- device_remove_file(&dev->ofdev.dev, &dev_attr_max_mr);
- device_remove_file(&dev->ofdev.dev, &dev_attr_cur_mr);
- device_remove_file(&dev->ofdev.dev, &dev_attr_max_mw);
- device_remove_file(&dev->ofdev.dev, &dev_attr_cur_mw);
- device_remove_file(&dev->ofdev.dev, &dev_attr_max_pd);
- device_remove_file(&dev->ofdev.dev, &dev_attr_max_ah);
-}
+static struct attribute_group ehca_dev_attr_grp = {
+ .attrs = ehca_dev_attrs
+};
static int __devinit ehca_probe(struct ibmebus_dev *dev,
const struct of_device_id *id)
{
struct ehca_shca *shca;
- u64 *handle;
+ const u64 *handle;
struct ib_pd *ibpd;
int ret;
- handle = (u64 *)get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
+ handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
if (!handle) {
ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
dev->ofdev.node->full_name);
ehca_gen_err("Cannot allocate shca memory.");
return -ENOMEM;
}
+ mutex_init(&shca->modify_mutex);
shca->ibmebus_dev = dev;
shca->ipz_hca_handle.handle = *handle;
}
}
- ehca_create_device_sysfs(dev);
+ ret = sysfs_create_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
+ if (ret) /* only complain; we can live without attributes */
+ ehca_err(&shca->ib_device,
+ "Cannot create device attributes ret=%d", ret);
spin_lock(&shca_list_lock);
list_add(&shca->shca_list, &shca_list);
struct ehca_shca *shca = dev->ofdev.dev.driver_data;
int ret;
- ehca_remove_device_sysfs(dev);
+ sysfs_remove_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
if (ehca_open_aqp1 == 1) {
int i;
int ret;
printk(KERN_INFO "eHCA Infiniband Device Driver "
- "(Rel.: SVNEHCA_0022)\n");
+ "(Rel.: SVNEHCA_0023)\n");
idr_init(&ehca_qp_idr);
idr_init(&ehca_cq_idr);
spin_lock_init(&ehca_qp_idr_lock);
spin_lock_init(&ehca_cq_idr_lock);
+ spin_lock_init(&hcall_lock);
INIT_LIST_HEAD(&shca_list);
spin_lock_init(&shca_list_lock);
goto module_init2;
}
- ehca_create_driver_sysfs(&ehca_driver);
+ ret = sysfs_create_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp);
+ if (ret) /* only complain; we can live without attributes */
+ ehca_gen_err("Cannot create driver attributes ret=%d", ret);
if (ehca_poll_all_eqs != 1) {
ehca_gen_err("WARNING!!!");
if (ehca_poll_all_eqs == 1)
del_timer_sync(&poll_eqs_timer);
- ehca_remove_driver_sysfs(&ehca_driver);
+ sysfs_remove_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp);
ibmebus_unregister_driver(&ehca_driver);
ehca_destroy_slab_caches();