summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/device.c63
-rw-r--r--drivers/infiniband/core/sysfs.c1
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c17
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c17
-rw-r--r--drivers/infiniband/hw/cxgb4/provider.c17
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c17
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c17
-rw-r--r--drivers/infiniband/hw/mlx4/main.c17
-rw-r--r--drivers/infiniband/hw/mlx5/main.c17
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c17
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c16
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_main.c17
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.c17
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_main.c17
-rw-r--r--include/rdma/ib_verbs.h19
15 files changed, 249 insertions, 37 deletions
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 0f16dd4d9bb4..4aa4f5420bc9 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -93,7 +93,8 @@ static int ib_device_check_mandatory(struct ib_device *device)
93 IB_MANDATORY_FUNC(poll_cq), 93 IB_MANDATORY_FUNC(poll_cq),
94 IB_MANDATORY_FUNC(req_notify_cq), 94 IB_MANDATORY_FUNC(req_notify_cq),
95 IB_MANDATORY_FUNC(get_dma_mr), 95 IB_MANDATORY_FUNC(get_dma_mr),
96 IB_MANDATORY_FUNC(dereg_mr) 96 IB_MANDATORY_FUNC(dereg_mr),
97 IB_MANDATORY_FUNC(get_port_immutable)
97 }; 98 };
98 int i; 99 int i;
99 100
@@ -211,42 +212,38 @@ static int add_client_context(struct ib_device *device, struct ib_client *client
211 return 0; 212 return 0;
212} 213}
213 214
214static int read_port_table_lengths(struct ib_device *device) 215static int read_port_immutable(struct ib_device *device)
215{ 216{
216 struct ib_port_attr *tprops = NULL; 217 int ret = -ENOMEM;
217 int num_ports, ret = -ENOMEM; 218 u8 start_port = rdma_start_port(device);
218 u8 port_index; 219 u8 end_port = rdma_end_port(device);
219 220 u8 port;
220 tprops = kmalloc(sizeof *tprops, GFP_KERNEL); 221
221 if (!tprops) 222 /**
222 goto out; 223 * device->port_immutable is indexed directly by the port number to make
223 224 * access to this data as efficient as possible.
224 num_ports = rdma_end_port(device) - rdma_start_port(device) + 1; 225 *
225 226 * Therefore port_immutable is declared as a 1 based array with
226 device->pkey_tbl_len = kmalloc(sizeof *device->pkey_tbl_len * num_ports, 227 * potential empty slots at the beginning.
227 GFP_KERNEL); 228 */
228 device->gid_tbl_len = kmalloc(sizeof *device->gid_tbl_len * num_ports, 229 device->port_immutable = kzalloc(sizeof(*device->port_immutable)
229 GFP_KERNEL); 230 * (end_port + 1),
230 if (!device->pkey_tbl_len || !device->gid_tbl_len) 231 GFP_KERNEL);
232 if (!device->port_immutable)
231 goto err; 233 goto err;
232 234
233 for (port_index = 0; port_index < num_ports; ++port_index) { 235 for (port = start_port; port <= end_port; ++port) {
234 ret = ib_query_port(device, port_index + rdma_start_port(device), 236 ret = device->get_port_immutable(device, port,
235 tprops); 237 &device->port_immutable[port]);
236 if (ret) 238 if (ret)
237 goto err; 239 goto err;
238 device->pkey_tbl_len[port_index] = tprops->pkey_tbl_len;
239 device->gid_tbl_len[port_index] = tprops->gid_tbl_len;
240 } 240 }
241 241
242 ret = 0; 242 ret = 0;
243 goto out; 243 goto out;
244
245err: 244err:
246 kfree(device->gid_tbl_len); 245 kfree(device->port_immutable);
247 kfree(device->pkey_tbl_len);
248out: 246out:
249 kfree(tprops);
250 return ret; 247 return ret;
251} 248}
252 249
@@ -283,9 +280,9 @@ int ib_register_device(struct ib_device *device,
283 spin_lock_init(&device->event_handler_lock); 280 spin_lock_init(&device->event_handler_lock);
284 spin_lock_init(&device->client_data_lock); 281 spin_lock_init(&device->client_data_lock);
285 282
286 ret = read_port_table_lengths(device); 283 ret = read_port_immutable(device);
287 if (ret) { 284 if (ret) {
288 printk(KERN_WARNING "Couldn't create table lengths cache for device %s\n", 285 printk(KERN_WARNING "Couldn't create per port immutable data %s\n",
289 device->name); 286 device->name);
290 goto out; 287 goto out;
291 } 288 }
@@ -294,8 +291,7 @@ int ib_register_device(struct ib_device *device,
294 if (ret) { 291 if (ret) {
295 printk(KERN_WARNING "Couldn't register device %s with driver model\n", 292 printk(KERN_WARNING "Couldn't register device %s with driver model\n",
296 device->name); 293 device->name);
297 kfree(device->gid_tbl_len); 294 kfree(device->port_immutable);
298 kfree(device->pkey_tbl_len);
299 goto out; 295 goto out;
300 } 296 }
301 297
@@ -337,9 +333,6 @@ void ib_unregister_device(struct ib_device *device)
337 333
338 list_del(&device->core_list); 334 list_del(&device->core_list);
339 335
340 kfree(device->gid_tbl_len);
341 kfree(device->pkey_tbl_len);
342
343 mutex_unlock(&device_mutex); 336 mutex_unlock(&device_mutex);
344 337
345 ib_device_unregister_sysfs(device); 338 ib_device_unregister_sysfs(device);
@@ -666,7 +659,7 @@ int ib_find_gid(struct ib_device *device, union ib_gid *gid,
666 int ret, port, i; 659 int ret, port, i;
667 660
668 for (port = rdma_start_port(device); port <= rdma_end_port(device); ++port) { 661 for (port = rdma_start_port(device); port <= rdma_end_port(device); ++port) {
669 for (i = 0; i < device->gid_tbl_len[port - rdma_start_port(device)]; ++i) { 662 for (i = 0; i < device->port_immutable[port].gid_tbl_len; ++i) {
670 ret = ib_query_gid(device, port, i, &tmp_gid); 663 ret = ib_query_gid(device, port, i, &tmp_gid);
671 if (ret) 664 if (ret)
672 return ret; 665 return ret;
@@ -698,7 +691,7 @@ int ib_find_pkey(struct ib_device *device,
698 u16 tmp_pkey; 691 u16 tmp_pkey;
699 int partial_ix = -1; 692 int partial_ix = -1;
700 693
701 for (i = 0; i < device->pkey_tbl_len[port_num - rdma_start_port(device)]; ++i) { 694 for (i = 0; i < device->port_immutable[port_num].pkey_tbl_len; ++i) {
702 ret = ib_query_pkey(device, port_num, i, &tmp_pkey); 695 ret = ib_query_pkey(device, port_num, i, &tmp_pkey);
703 if (ret) 696 if (ret)
704 return ret; 697 return ret;
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index cbd0383f622e..d0334c101ecb 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -456,6 +456,7 @@ static void ib_device_release(struct device *device)
456{ 456{
457 struct ib_device *dev = container_of(device, struct ib_device, dev); 457 struct ib_device *dev = container_of(device, struct ib_device, dev);
458 458
459 kfree(dev->port_immutable);
459 kfree(dev); 460 kfree(dev);
460} 461}
461 462
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index 6fe329a5d595..fa638963908f 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -763,6 +763,22 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
763 return netdev; 763 return netdev;
764} 764}
765 765
766static int c2_port_immutable(struct ib_device *ibdev, u8 port_num,
767 struct ib_port_immutable *immutable)
768{
769 struct ib_port_attr attr;
770 int err;
771
772 err = c2_query_port(ibdev, port_num, &attr);
773 if (err)
774 return err;
775
776 immutable->pkey_tbl_len = attr.pkey_tbl_len;
777 immutable->gid_tbl_len = attr.gid_tbl_len;
778
779 return 0;
780}
781
766int c2_register_device(struct c2_dev *dev) 782int c2_register_device(struct c2_dev *dev)
767{ 783{
768 int ret = -ENOMEM; 784 int ret = -ENOMEM;
@@ -827,6 +843,7 @@ int c2_register_device(struct c2_dev *dev)
827 dev->ibdev.reg_phys_mr = c2_reg_phys_mr; 843 dev->ibdev.reg_phys_mr = c2_reg_phys_mr;
828 dev->ibdev.reg_user_mr = c2_reg_user_mr; 844 dev->ibdev.reg_user_mr = c2_reg_user_mr;
829 dev->ibdev.dereg_mr = c2_dereg_mr; 845 dev->ibdev.dereg_mr = c2_dereg_mr;
846 dev->ibdev.get_port_immutable = c2_port_immutable;
830 847
831 dev->ibdev.alloc_fmr = NULL; 848 dev->ibdev.alloc_fmr = NULL;
832 dev->ibdev.unmap_fmr = NULL; 849 dev->ibdev.unmap_fmr = NULL;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 298d1caab3a5..590ba0f422a1 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -1349,6 +1349,22 @@ static struct device_attribute *iwch_class_attributes[] = {
1349 &dev_attr_board_id, 1349 &dev_attr_board_id,
1350}; 1350};
1351 1351
1352static int iwch_port_immutable(struct ib_device *ibdev, u8 port_num,
1353 struct ib_port_immutable *immutable)
1354{
1355 struct ib_port_attr attr;
1356 int err;
1357
1358 err = iwch_query_port(ibdev, port_num, &attr);
1359 if (err)
1360 return err;
1361
1362 immutable->pkey_tbl_len = attr.pkey_tbl_len;
1363 immutable->gid_tbl_len = attr.gid_tbl_len;
1364
1365 return 0;
1366}
1367
1352int iwch_register_device(struct iwch_dev *dev) 1368int iwch_register_device(struct iwch_dev *dev)
1353{ 1369{
1354 int ret; 1370 int ret;
@@ -1427,6 +1443,7 @@ int iwch_register_device(struct iwch_dev *dev)
1427 dev->ibdev.post_recv = iwch_post_receive; 1443 dev->ibdev.post_recv = iwch_post_receive;
1428 dev->ibdev.get_protocol_stats = iwch_get_mib; 1444 dev->ibdev.get_protocol_stats = iwch_get_mib;
1429 dev->ibdev.uverbs_abi_ver = IWCH_UVERBS_ABI_VERSION; 1445 dev->ibdev.uverbs_abi_ver = IWCH_UVERBS_ABI_VERSION;
1446 dev->ibdev.get_port_immutable = iwch_port_immutable;
1430 1447
1431 dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL); 1448 dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL);
1432 if (!dev->ibdev.iwcm) 1449 if (!dev->ibdev.iwcm)
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
index f52ee6343d41..5eded1b3bbad 100644
--- a/drivers/infiniband/hw/cxgb4/provider.c
+++ b/drivers/infiniband/hw/cxgb4/provider.c
@@ -471,6 +471,22 @@ static struct device_attribute *c4iw_class_attributes[] = {
471 &dev_attr_board_id, 471 &dev_attr_board_id,
472}; 472};
473 473
474static int c4iw_port_immutable(struct ib_device *ibdev, u8 port_num,
475 struct ib_port_immutable *immutable)
476{
477 struct ib_port_attr attr;
478 int err;
479
480 err = c4iw_query_port(ibdev, port_num, &attr);
481 if (err)
482 return err;
483
484 immutable->pkey_tbl_len = attr.pkey_tbl_len;
485 immutable->gid_tbl_len = attr.gid_tbl_len;
486
487 return 0;
488}
489
474int c4iw_register_device(struct c4iw_dev *dev) 490int c4iw_register_device(struct c4iw_dev *dev)
475{ 491{
476 int ret; 492 int ret;
@@ -549,6 +565,7 @@ int c4iw_register_device(struct c4iw_dev *dev)
549 dev->ibdev.post_recv = c4iw_post_receive; 565 dev->ibdev.post_recv = c4iw_post_receive;
550 dev->ibdev.get_protocol_stats = c4iw_get_mib; 566 dev->ibdev.get_protocol_stats = c4iw_get_mib;
551 dev->ibdev.uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION; 567 dev->ibdev.uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION;
568 dev->ibdev.get_port_immutable = c4iw_port_immutable;
552 569
553 dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL); 570 dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL);
554 if (!dev->ibdev.iwcm) 571 if (!dev->ibdev.iwcm)
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 321545b708ad..8454186e16ab 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -431,6 +431,22 @@ init_node_guid1:
431 return ret; 431 return ret;
432} 432}
433 433
434static int ehca_port_immutable(struct ib_device *ibdev, u8 port_num,
435 struct ib_port_immutable *immutable)
436{
437 struct ib_port_attr attr;
438 int err;
439
440 err = ehca_query_port(ibdev, port_num, &attr);
441 if (err)
442 return err;
443
444 immutable->pkey_tbl_len = attr.pkey_tbl_len;
445 immutable->gid_tbl_len = attr.gid_tbl_len;
446
447 return 0;
448}
449
434static int ehca_init_device(struct ehca_shca *shca) 450static int ehca_init_device(struct ehca_shca *shca)
435{ 451{
436 int ret; 452 int ret;
@@ -511,6 +527,7 @@ static int ehca_init_device(struct ehca_shca *shca)
511 shca->ib_device.process_mad = ehca_process_mad; 527 shca->ib_device.process_mad = ehca_process_mad;
512 shca->ib_device.mmap = ehca_mmap; 528 shca->ib_device.mmap = ehca_mmap;
513 shca->ib_device.dma_ops = &ehca_dma_mapping_ops; 529 shca->ib_device.dma_ops = &ehca_dma_mapping_ops;
530 shca->ib_device.get_port_immutable = ehca_port_immutable;
514 531
515 if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) { 532 if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
516 shca->ib_device.uverbs_cmd_mask |= 533 shca->ib_device.uverbs_cmd_mask |=
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 34b94c3ae674..49b774b6f7e8 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1986,6 +1986,22 @@ static int disable_timer(struct ipath_devdata *dd)
1986 return 0; 1986 return 0;
1987} 1987}
1988 1988
1989static int ipath_port_immutable(struct ib_device *ibdev, u8 port_num,
1990 struct ib_port_immutable *immutable)
1991{
1992 struct ib_port_attr attr;
1993 int err;
1994
1995 err = ipath_query_port(ibdev, port_num, &attr);
1996 if (err)
1997 return err;
1998
1999 immutable->pkey_tbl_len = attr.pkey_tbl_len;
2000 immutable->gid_tbl_len = attr.gid_tbl_len;
2001
2002 return 0;
2003}
2004
1989/** 2005/**
1990 * ipath_register_ib_device - register our device with the infiniband core 2006 * ipath_register_ib_device - register our device with the infiniband core
1991 * @dd: the device data structure 2007 * @dd: the device data structure
@@ -2186,6 +2202,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
2186 dev->process_mad = ipath_process_mad; 2202 dev->process_mad = ipath_process_mad;
2187 dev->mmap = ipath_mmap; 2203 dev->mmap = ipath_mmap;
2188 dev->dma_ops = &ipath_dma_mapping_ops; 2204 dev->dma_ops = &ipath_dma_mapping_ops;
2205 dev->get_port_immutable = ipath_port_immutable;
2189 2206
2190 snprintf(dev->node_desc, sizeof(dev->node_desc), 2207 snprintf(dev->node_desc, sizeof(dev->node_desc),
2191 IPATH_IDSTR " %s", init_utsname()->nodename); 2208 IPATH_IDSTR " %s", init_utsname()->nodename);
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 64f591437925..f46b1be08fc5 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -2123,6 +2123,22 @@ static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev)
2123 kfree(ibdev->eq_table); 2123 kfree(ibdev->eq_table);
2124} 2124}
2125 2125
2126static int mlx4_port_immutable(struct ib_device *ibdev, u8 port_num,
2127 struct ib_port_immutable *immutable)
2128{
2129 struct ib_port_attr attr;
2130 int err;
2131
2132 err = mlx4_ib_query_port(ibdev, port_num, &attr);
2133 if (err)
2134 return err;
2135
2136 immutable->pkey_tbl_len = attr.pkey_tbl_len;
2137 immutable->gid_tbl_len = attr.gid_tbl_len;
2138
2139 return 0;
2140}
2141
2126static void *mlx4_ib_add(struct mlx4_dev *dev) 2142static void *mlx4_ib_add(struct mlx4_dev *dev)
2127{ 2143{
2128 struct mlx4_ib_dev *ibdev; 2144 struct mlx4_ib_dev *ibdev;
@@ -2251,6 +2267,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
2251 ibdev->ib_dev.attach_mcast = mlx4_ib_mcg_attach; 2267 ibdev->ib_dev.attach_mcast = mlx4_ib_mcg_attach;
2252 ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach; 2268 ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach;
2253 ibdev->ib_dev.process_mad = mlx4_ib_process_mad; 2269 ibdev->ib_dev.process_mad = mlx4_ib_process_mad;
2270 ibdev->ib_dev.get_port_immutable = mlx4_port_immutable;
2254 2271
2255 if (!mlx4_is_slave(ibdev->dev)) { 2272 if (!mlx4_is_slave(ibdev->dev)) {
2256 ibdev->ib_dev.alloc_fmr = mlx4_ib_fmr_alloc; 2273 ibdev->ib_dev.alloc_fmr = mlx4_ib_fmr_alloc;
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 8dec38055c49..8db0edca6dd8 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1188,6 +1188,22 @@ static void destroy_dev_resources(struct mlx5_ib_resources *devr)
1188 mlx5_ib_dealloc_pd(devr->p0); 1188 mlx5_ib_dealloc_pd(devr->p0);
1189} 1189}
1190 1190
1191static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num,
1192 struct ib_port_immutable *immutable)
1193{
1194 struct ib_port_attr attr;
1195 int err;
1196
1197 err = mlx5_ib_query_port(ibdev, port_num, &attr);
1198 if (err)
1199 return err;
1200
1201 immutable->pkey_tbl_len = attr.pkey_tbl_len;
1202 immutable->gid_tbl_len = attr.gid_tbl_len;
1203
1204 return 0;
1205}
1206
1191static void *mlx5_ib_add(struct mlx5_core_dev *mdev) 1207static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
1192{ 1208{
1193 struct mlx5_ib_dev *dev; 1209 struct mlx5_ib_dev *dev;
@@ -1292,6 +1308,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
1292 dev->ib_dev.alloc_fast_reg_page_list = mlx5_ib_alloc_fast_reg_page_list; 1308 dev->ib_dev.alloc_fast_reg_page_list = mlx5_ib_alloc_fast_reg_page_list;
1293 dev->ib_dev.free_fast_reg_page_list = mlx5_ib_free_fast_reg_page_list; 1309 dev->ib_dev.free_fast_reg_page_list = mlx5_ib_free_fast_reg_page_list;
1294 dev->ib_dev.check_mr_status = mlx5_ib_check_mr_status; 1310 dev->ib_dev.check_mr_status = mlx5_ib_check_mr_status;
1311 dev->ib_dev.get_port_immutable = mlx5_port_immutable;
1295 1312
1296 mlx5_ib_internal_query_odp_caps(dev); 1313 mlx5_ib_internal_query_odp_caps(dev);
1297 1314
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index ad1cca3a3a5c..4662fd20b8e6 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -1250,6 +1250,22 @@ out:
1250 return err; 1250 return err;
1251} 1251}
1252 1252
1253static int mthca_port_immutable(struct ib_device *ibdev, u8 port_num,
1254 struct ib_port_immutable *immutable)
1255{
1256 struct ib_port_attr attr;
1257 int err;
1258
1259 err = mthca_query_port(ibdev, port_num, &attr);
1260 if (err)
1261 return err;
1262
1263 immutable->pkey_tbl_len = attr.pkey_tbl_len;
1264 immutable->gid_tbl_len = attr.gid_tbl_len;
1265
1266 return 0;
1267}
1268
1253int mthca_register_device(struct mthca_dev *dev) 1269int mthca_register_device(struct mthca_dev *dev)
1254{ 1270{
1255 int ret; 1271 int ret;
@@ -1330,6 +1346,7 @@ int mthca_register_device(struct mthca_dev *dev)
1330 dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr; 1346 dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr;
1331 dev->ib_dev.reg_user_mr = mthca_reg_user_mr; 1347 dev->ib_dev.reg_user_mr = mthca_reg_user_mr;
1332 dev->ib_dev.dereg_mr = mthca_dereg_mr; 1348 dev->ib_dev.dereg_mr = mthca_dereg_mr;
1349 dev->ib_dev.get_port_immutable = mthca_port_immutable;
1333 1350
1334 if (dev->mthca_flags & MTHCA_FLAG_FMR) { 1351 if (dev->mthca_flags & MTHCA_FLAG_FMR) {
1335 dev->ib_dev.alloc_fmr = mthca_alloc_fmr; 1352 dev->ib_dev.alloc_fmr = mthca_alloc_fmr;
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 027f6d1cd059..4ed2d967d324 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -3833,6 +3833,21 @@ static int nes_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_
3833 return 0; 3833 return 0;
3834} 3834}
3835 3835
3836static int nes_port_immutable(struct ib_device *ibdev, u8 port_num,
3837 struct ib_port_immutable *immutable)
3838{
3839 struct ib_port_attr attr;
3840 int err;
3841
3842 err = nes_query_port(ibdev, port_num, &attr);
3843 if (err)
3844 return err;
3845
3846 immutable->pkey_tbl_len = attr.pkey_tbl_len;
3847 immutable->gid_tbl_len = attr.gid_tbl_len;
3848
3849 return 0;
3850}
3836 3851
3837/** 3852/**
3838 * nes_init_ofa_device 3853 * nes_init_ofa_device
@@ -3934,6 +3949,7 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev)
3934 nesibdev->ibdev.iwcm->reject = nes_reject; 3949 nesibdev->ibdev.iwcm->reject = nes_reject;
3935 nesibdev->ibdev.iwcm->create_listen = nes_create_listen; 3950 nesibdev->ibdev.iwcm->create_listen = nes_create_listen;
3936 nesibdev->ibdev.iwcm->destroy_listen = nes_destroy_listen; 3951 nesibdev->ibdev.iwcm->destroy_listen = nes_destroy_listen;
3952 nesibdev->ibdev.get_port_immutable = nes_port_immutable;
3937 3953
3938 return nesibdev; 3954 return nesibdev;
3939} 3955}
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
index 85d99e9306a0..21744be6cac5 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
@@ -202,6 +202,22 @@ static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device,
202 return IB_LINK_LAYER_ETHERNET; 202 return IB_LINK_LAYER_ETHERNET;
203} 203}
204 204
205static int ocrdma_port_immutable(struct ib_device *ibdev, u8 port_num,
206 struct ib_port_immutable *immutable)
207{
208 struct ib_port_attr attr;
209 int err;
210
211 err = ocrdma_query_port(ibdev, port_num, &attr);
212 if (err)
213 return err;
214
215 immutable->pkey_tbl_len = attr.pkey_tbl_len;
216 immutable->gid_tbl_len = attr.gid_tbl_len;
217
218 return 0;
219}
220
205static int ocrdma_register_device(struct ocrdma_dev *dev) 221static int ocrdma_register_device(struct ocrdma_dev *dev)
206{ 222{
207 strlcpy(dev->ibdev.name, "ocrdma%d", IB_DEVICE_NAME_MAX); 223 strlcpy(dev->ibdev.name, "ocrdma%d", IB_DEVICE_NAME_MAX);
@@ -287,6 +303,7 @@ static int ocrdma_register_device(struct ocrdma_dev *dev)
287 dev->ibdev.dma_device = &dev->nic_info.pdev->dev; 303 dev->ibdev.dma_device = &dev->nic_info.pdev->dev;
288 304
289 dev->ibdev.process_mad = ocrdma_process_mad; 305 dev->ibdev.process_mad = ocrdma_process_mad;
306 dev->ibdev.get_port_immutable = ocrdma_port_immutable;
290 307
291 if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) { 308 if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
292 dev->ibdev.uverbs_cmd_mask |= 309 dev->ibdev.uverbs_cmd_mask |=
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
index 9fd4b285e5e5..48f4784c53a6 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.c
+++ b/drivers/infiniband/hw/qib/qib_verbs.c
@@ -2046,6 +2046,22 @@ static void init_ibport(struct qib_pportdata *ppd)
2046 RCU_INIT_POINTER(ibp->qp1, NULL); 2046 RCU_INIT_POINTER(ibp->qp1, NULL);
2047} 2047}
2048 2048
2049static int qib_port_immutable(struct ib_device *ibdev, u8 port_num,
2050 struct ib_port_immutable *immutable)
2051{
2052 struct ib_port_attr attr;
2053 int err;
2054
2055 err = qib_query_port(ibdev, port_num, &attr);
2056 if (err)
2057 return err;
2058
2059 immutable->pkey_tbl_len = attr.pkey_tbl_len;
2060 immutable->gid_tbl_len = attr.gid_tbl_len;
2061
2062 return 0;
2063}
2064
2049/** 2065/**
2050 * qib_register_ib_device - register our device with the infiniband core 2066 * qib_register_ib_device - register our device with the infiniband core
2051 * @dd: the device data structure 2067 * @dd: the device data structure
@@ -2234,6 +2250,7 @@ int qib_register_ib_device(struct qib_devdata *dd)
2234 ibdev->process_mad = qib_process_mad; 2250 ibdev->process_mad = qib_process_mad;
2235 ibdev->mmap = qib_mmap; 2251 ibdev->mmap = qib_mmap;
2236 ibdev->dma_ops = &qib_dma_mapping_ops; 2252 ibdev->dma_ops = &qib_dma_mapping_ops;
2253 ibdev->get_port_immutable = qib_port_immutable;
2237 2254
2238 snprintf(ibdev->node_desc, sizeof(ibdev->node_desc), 2255 snprintf(ibdev->node_desc, sizeof(ibdev->node_desc),
2239 "Intel Infiniband HCA %s", init_utsname()->nodename); 2256 "Intel Infiniband HCA %s", init_utsname()->nodename);
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_main.c b/drivers/infiniband/hw/usnic/usnic_ib_main.c
index bd9f364e909c..ce3e19bcfe00 100644
--- a/drivers/infiniband/hw/usnic/usnic_ib_main.c
+++ b/drivers/infiniband/hw/usnic/usnic_ib_main.c
@@ -300,6 +300,22 @@ static struct notifier_block usnic_ib_inetaddr_notifier = {
300}; 300};
301/* End of inet section*/ 301/* End of inet section*/
302 302
303static int usnic_port_immutable(struct ib_device *ibdev, u8 port_num,
304 struct ib_port_immutable *immutable)
305{
306 struct ib_port_attr attr;
307 int err;
308
309 err = usnic_ib_query_port(ibdev, port_num, &attr);
310 if (err)
311 return err;
312
313 immutable->pkey_tbl_len = attr.pkey_tbl_len;
314 immutable->gid_tbl_len = attr.gid_tbl_len;
315
316 return 0;
317}
318
303/* Start of PF discovery section */ 319/* Start of PF discovery section */
304static void *usnic_ib_device_add(struct pci_dev *dev) 320static void *usnic_ib_device_add(struct pci_dev *dev)
305{ 321{
@@ -384,6 +400,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
384 us_ibdev->ib_dev.poll_cq = usnic_ib_poll_cq; 400 us_ibdev->ib_dev.poll_cq = usnic_ib_poll_cq;
385 us_ibdev->ib_dev.req_notify_cq = usnic_ib_req_notify_cq; 401 us_ibdev->ib_dev.req_notify_cq = usnic_ib_req_notify_cq;
386 us_ibdev->ib_dev.get_dma_mr = usnic_ib_get_dma_mr; 402 us_ibdev->ib_dev.get_dma_mr = usnic_ib_get_dma_mr;
403 us_ibdev->ib_dev.get_port_immutable = usnic_port_immutable;
387 404
388 405
389 if (ib_register_device(&us_ibdev->ib_dev, NULL)) 406 if (ib_register_device(&us_ibdev->ib_dev, NULL))
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index be4465b5df7b..2d3515edc3fa 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1481,6 +1481,11 @@ struct ib_dma_mapping_ops {
1481 1481
1482struct iw_cm_verbs; 1482struct iw_cm_verbs;
1483 1483
1484struct ib_port_immutable {
1485 int pkey_tbl_len;
1486 int gid_tbl_len;
1487};
1488
1484struct ib_device { 1489struct ib_device {
1485 struct device *dma_device; 1490 struct device *dma_device;
1486 1491
@@ -1494,8 +1499,10 @@ struct ib_device {
1494 struct list_head client_data_list; 1499 struct list_head client_data_list;
1495 1500
1496 struct ib_cache cache; 1501 struct ib_cache cache;
1497 int *pkey_tbl_len; 1502 /**
1498 int *gid_tbl_len; 1503 * port_immutable is indexed by port number
1504 */
1505 struct ib_port_immutable *port_immutable;
1499 1506
1500 int num_comp_vectors; 1507 int num_comp_vectors;
1501 1508
@@ -1684,6 +1691,14 @@ struct ib_device {
1684 u32 local_dma_lkey; 1691 u32 local_dma_lkey;
1685 u8 node_type; 1692 u8 node_type;
1686 u8 phys_port_cnt; 1693 u8 phys_port_cnt;
1694
1695 /**
1696 * The following mandatory functions are used only at device
1697 * registration. Keep functions such as these at the end of this
1698 * structure to avoid cache line misses when accessing struct ib_device
1699 * in fast paths.
1700 */
1701 int (*get_port_immutable)(struct ib_device *, u8, struct ib_port_immutable *);
1687}; 1702};
1688 1703
1689struct ib_client { 1704struct ib_client {