diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4/main.c')
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index efecdf0216d8..f567160a4a56 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -335,7 +335,7 @@ int mlx4_ib_gid_index_to_real_index(struct mlx4_ib_dev *ibdev, | |||
335 | if (!rdma_cap_roce_gid_table(&ibdev->ib_dev, port_num)) | 335 | if (!rdma_cap_roce_gid_table(&ibdev->ib_dev, port_num)) |
336 | return index; | 336 | return index; |
337 | 337 | ||
338 | ret = ib_get_cached_gid(&ibdev->ib_dev, port_num, index, &gid); | 338 | ret = ib_get_cached_gid(&ibdev->ib_dev, port_num, index, &gid, NULL); |
339 | if (ret) | 339 | if (ret) |
340 | return ret; | 340 | return ret; |
341 | 341 | ||
@@ -442,6 +442,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
442 | props->device_cap_flags |= IB_DEVICE_MANAGED_FLOW_STEERING; | 442 | props->device_cap_flags |= IB_DEVICE_MANAGED_FLOW_STEERING; |
443 | } | 443 | } |
444 | 444 | ||
445 | props->device_cap_flags |= IB_DEVICE_RAW_IP_CSUM; | ||
446 | |||
445 | props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & | 447 | props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & |
446 | 0xffffff; | 448 | 0xffffff; |
447 | props->vendor_part_id = dev->dev->persist->pdev->device; | 449 | props->vendor_part_id = dev->dev->persist->pdev->device; |
@@ -754,7 +756,7 @@ static int mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index, | |||
754 | if (!rdma_cap_roce_gid_table(ibdev, port)) | 756 | if (!rdma_cap_roce_gid_table(ibdev, port)) |
755 | return -ENODEV; | 757 | return -ENODEV; |
756 | 758 | ||
757 | ret = ib_get_cached_gid(ibdev, port, index, gid); | 759 | ret = ib_get_cached_gid(ibdev, port, index, gid, NULL); |
758 | if (ret == -EAGAIN) { | 760 | if (ret == -EAGAIN) { |
759 | memcpy(gid, &zgid, sizeof(*gid)); | 761 | memcpy(gid, &zgid, sizeof(*gid)); |
760 | return 0; | 762 | return 0; |
@@ -1247,6 +1249,22 @@ static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid) | |||
1247 | return 0; | 1249 | return 0; |
1248 | } | 1250 | } |
1249 | 1251 | ||
1252 | static void mlx4_ib_delete_counters_table(struct mlx4_ib_dev *ibdev, | ||
1253 | struct mlx4_ib_counters *ctr_table) | ||
1254 | { | ||
1255 | struct counter_index *counter, *tmp_count; | ||
1256 | |||
1257 | mutex_lock(&ctr_table->mutex); | ||
1258 | list_for_each_entry_safe(counter, tmp_count, &ctr_table->counters_list, | ||
1259 | list) { | ||
1260 | if (counter->allocated) | ||
1261 | mlx4_counter_free(ibdev->dev, counter->index); | ||
1262 | list_del(&counter->list); | ||
1263 | kfree(counter); | ||
1264 | } | ||
1265 | mutex_unlock(&ctr_table->mutex); | ||
1266 | } | ||
1267 | |||
1250 | int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp, | 1268 | int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp, |
1251 | union ib_gid *gid) | 1269 | union ib_gid *gid) |
1252 | { | 1270 | { |
@@ -2131,6 +2149,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2131 | int num_req_counters; | 2149 | int num_req_counters; |
2132 | int allocated; | 2150 | int allocated; |
2133 | u32 counter_index; | 2151 | u32 counter_index; |
2152 | struct counter_index *new_counter_index = NULL; | ||
2134 | 2153 | ||
2135 | pr_info_once("%s", mlx4_ib_version); | 2154 | pr_info_once("%s", mlx4_ib_version); |
2136 | 2155 | ||
@@ -2247,8 +2266,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2247 | ibdev->ib_dev.rereg_user_mr = mlx4_ib_rereg_user_mr; | 2266 | ibdev->ib_dev.rereg_user_mr = mlx4_ib_rereg_user_mr; |
2248 | ibdev->ib_dev.dereg_mr = mlx4_ib_dereg_mr; | 2267 | ibdev->ib_dev.dereg_mr = mlx4_ib_dereg_mr; |
2249 | ibdev->ib_dev.alloc_mr = mlx4_ib_alloc_mr; | 2268 | ibdev->ib_dev.alloc_mr = mlx4_ib_alloc_mr; |
2250 | ibdev->ib_dev.alloc_fast_reg_page_list = mlx4_ib_alloc_fast_reg_page_list; | 2269 | ibdev->ib_dev.map_mr_sg = mlx4_ib_map_mr_sg; |
2251 | ibdev->ib_dev.free_fast_reg_page_list = mlx4_ib_free_fast_reg_page_list; | ||
2252 | ibdev->ib_dev.attach_mcast = mlx4_ib_mcg_attach; | 2270 | ibdev->ib_dev.attach_mcast = mlx4_ib_mcg_attach; |
2253 | ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach; | 2271 | ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach; |
2254 | ibdev->ib_dev.process_mad = mlx4_ib_process_mad; | 2272 | ibdev->ib_dev.process_mad = mlx4_ib_process_mad; |
@@ -2293,7 +2311,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2293 | 2311 | ||
2294 | ibdev->ib_dev.uverbs_ex_cmd_mask |= | 2312 | ibdev->ib_dev.uverbs_ex_cmd_mask |= |
2295 | (1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE) | | 2313 | (1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE) | |
2296 | (1ull << IB_USER_VERBS_EX_CMD_CREATE_CQ); | 2314 | (1ull << IB_USER_VERBS_EX_CMD_CREATE_CQ) | |
2315 | (1ull << IB_USER_VERBS_EX_CMD_CREATE_QP); | ||
2297 | 2316 | ||
2298 | mlx4_ib_alloc_eqs(dev, ibdev); | 2317 | mlx4_ib_alloc_eqs(dev, ibdev); |
2299 | 2318 | ||
@@ -2302,6 +2321,11 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2302 | if (init_node_data(ibdev)) | 2321 | if (init_node_data(ibdev)) |
2303 | goto err_map; | 2322 | goto err_map; |
2304 | 2323 | ||
2324 | for (i = 0; i < ibdev->num_ports; ++i) { | ||
2325 | mutex_init(&ibdev->counters_table[i].mutex); | ||
2326 | INIT_LIST_HEAD(&ibdev->counters_table[i].counters_list); | ||
2327 | } | ||
2328 | |||
2305 | num_req_counters = mlx4_is_bonded(dev) ? 1 : ibdev->num_ports; | 2329 | num_req_counters = mlx4_is_bonded(dev) ? 1 : ibdev->num_ports; |
2306 | for (i = 0; i < num_req_counters; ++i) { | 2330 | for (i = 0; i < num_req_counters; ++i) { |
2307 | mutex_init(&ibdev->qp1_proxy_lock[i]); | 2331 | mutex_init(&ibdev->qp1_proxy_lock[i]); |
@@ -2320,15 +2344,34 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2320 | counter_index = mlx4_get_default_counter_index(dev, | 2344 | counter_index = mlx4_get_default_counter_index(dev, |
2321 | i + 1); | 2345 | i + 1); |
2322 | } | 2346 | } |
2323 | ibdev->counters[i].index = counter_index; | 2347 | new_counter_index = kmalloc(sizeof(*new_counter_index), |
2324 | ibdev->counters[i].allocated = allocated; | 2348 | GFP_KERNEL); |
2349 | if (!new_counter_index) { | ||
2350 | if (allocated) | ||
2351 | mlx4_counter_free(ibdev->dev, counter_index); | ||
2352 | goto err_counter; | ||
2353 | } | ||
2354 | new_counter_index->index = counter_index; | ||
2355 | new_counter_index->allocated = allocated; | ||
2356 | list_add_tail(&new_counter_index->list, | ||
2357 | &ibdev->counters_table[i].counters_list); | ||
2358 | ibdev->counters_table[i].default_counter = counter_index; | ||
2325 | pr_info("counter index %d for port %d allocated %d\n", | 2359 | pr_info("counter index %d for port %d allocated %d\n", |
2326 | counter_index, i + 1, allocated); | 2360 | counter_index, i + 1, allocated); |
2327 | } | 2361 | } |
2328 | if (mlx4_is_bonded(dev)) | 2362 | if (mlx4_is_bonded(dev)) |
2329 | for (i = 1; i < ibdev->num_ports ; ++i) { | 2363 | for (i = 1; i < ibdev->num_ports ; ++i) { |
2330 | ibdev->counters[i].index = ibdev->counters[0].index; | 2364 | new_counter_index = |
2331 | ibdev->counters[i].allocated = 0; | 2365 | kmalloc(sizeof(struct counter_index), |
2366 | GFP_KERNEL); | ||
2367 | if (!new_counter_index) | ||
2368 | goto err_counter; | ||
2369 | new_counter_index->index = counter_index; | ||
2370 | new_counter_index->allocated = 0; | ||
2371 | list_add_tail(&new_counter_index->list, | ||
2372 | &ibdev->counters_table[i].counters_list); | ||
2373 | ibdev->counters_table[i].default_counter = | ||
2374 | counter_index; | ||
2332 | } | 2375 | } |
2333 | 2376 | ||
2334 | mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB) | 2377 | mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB) |
@@ -2437,12 +2480,9 @@ err_steer_qp_release: | |||
2437 | mlx4_qp_release_range(dev, ibdev->steer_qpn_base, | 2480 | mlx4_qp_release_range(dev, ibdev->steer_qpn_base, |
2438 | ibdev->steer_qpn_count); | 2481 | ibdev->steer_qpn_count); |
2439 | err_counter: | 2482 | err_counter: |
2440 | for (i = 0; i < ibdev->num_ports; ++i) { | 2483 | for (i = 0; i < ibdev->num_ports; ++i) |
2441 | if (ibdev->counters[i].index != -1 && | 2484 | mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]); |
2442 | ibdev->counters[i].allocated) | 2485 | |
2443 | mlx4_counter_free(ibdev->dev, | ||
2444 | ibdev->counters[i].index); | ||
2445 | } | ||
2446 | err_map: | 2486 | err_map: |
2447 | iounmap(ibdev->uar_map); | 2487 | iounmap(ibdev->uar_map); |
2448 | 2488 | ||
@@ -2546,9 +2586,8 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr) | |||
2546 | 2586 | ||
2547 | iounmap(ibdev->uar_map); | 2587 | iounmap(ibdev->uar_map); |
2548 | for (p = 0; p < ibdev->num_ports; ++p) | 2588 | for (p = 0; p < ibdev->num_ports; ++p) |
2549 | if (ibdev->counters[p].index != -1 && | 2589 | mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[p]); |
2550 | ibdev->counters[p].allocated) | 2590 | |
2551 | mlx4_counter_free(ibdev->dev, ibdev->counters[p].index); | ||
2552 | mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB) | 2591 | mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB) |
2553 | mlx4_CLOSE_PORT(dev, p); | 2592 | mlx4_CLOSE_PORT(dev, p); |
2554 | 2593 | ||