main.c (37aa5c36aa70c9fc5f633b89cce990f04aaa3cd4) main.c (cff5a0f3a3cda0d852425093f92acca169eb5aea)
1/*
2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:

--- 24 unchanged lines hidden (view full) ---

33#include <linux/highmem.h>
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/errno.h>
37#include <linux/pci.h>
38#include <linux/dma-mapping.h>
39#include <linux/slab.h>
40#include <linux/io-mapping.h>
1/*
2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:

--- 24 unchanged lines hidden (view full) ---

33#include <linux/highmem.h>
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/errno.h>
37#include <linux/pci.h>
38#include <linux/dma-mapping.h>
39#include <linux/slab.h>
40#include <linux/io-mapping.h>
41#if defined(CONFIG_X86)
42#include <asm/pat.h>
43#endif
44#include <linux/sched.h>
45#include <rdma/ib_user_verbs.h>
46#include <rdma/ib_addr.h>
47#include <rdma/ib_cache.h>
48#include <linux/mlx5/port.h>
49#include <linux/mlx5/vport.h>
50#include <rdma/ib_smi.h>
51#include <rdma/ib_umem.h>

--- 463 unchanged lines hidden (view full) ---

515 (MLX5_CAP_ETH(dev->mdev, csum_cap)))
516 props->device_cap_flags |= IB_DEVICE_RAW_IP_CSUM;
517
518 if (MLX5_CAP_GEN(mdev, ipoib_basic_offloads)) {
519 props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM;
520 props->device_cap_flags |= IB_DEVICE_UD_TSO;
521 }
522
41#include <linux/sched.h>
42#include <rdma/ib_user_verbs.h>
43#include <rdma/ib_addr.h>
44#include <rdma/ib_cache.h>
45#include <linux/mlx5/port.h>
46#include <linux/mlx5/vport.h>
47#include <rdma/ib_smi.h>
48#include <rdma/ib_umem.h>

--- 463 unchanged lines hidden (view full) ---

512 (MLX5_CAP_ETH(dev->mdev, csum_cap)))
513 props->device_cap_flags |= IB_DEVICE_RAW_IP_CSUM;
514
515 if (MLX5_CAP_GEN(mdev, ipoib_basic_offloads)) {
516 props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM;
517 props->device_cap_flags |= IB_DEVICE_UD_TSO;
518 }
519
520 if (MLX5_CAP_GEN(dev->mdev, eth_net_offloads) &&
521 MLX5_CAP_ETH(dev->mdev, scatter_fcs))
522 props->device_cap_flags |= IB_DEVICE_RAW_SCATTER_FCS;
523
523 props->vendor_part_id = mdev->pdev->device;
524 props->hw_ver = mdev->pdev->revision;
525
526 props->max_mr_size = ~0ull;
527 props->page_size_cap = ~(min_page_size - 1);
528 props->max_qp = 1 << MLX5_CAP_GEN(mdev, log_max_qp);
529 props->max_qp_wr = 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz);
530 max_rq_sg = MLX5_CAP_GEN(mdev, max_wqe_sz_rq) /

--- 535 unchanged lines hidden (view full) ---

1066 return offset & ((1 << MLX5_IB_MMAP_CMD_SHIFT) - 1);
1067}
1068
1069static int get_index(unsigned long offset)
1070{
1071 return get_arg(offset);
1072}
1073
524 props->vendor_part_id = mdev->pdev->device;
525 props->hw_ver = mdev->pdev->revision;
526
527 props->max_mr_size = ~0ull;
528 props->page_size_cap = ~(min_page_size - 1);
529 props->max_qp = 1 << MLX5_CAP_GEN(mdev, log_max_qp);
530 props->max_qp_wr = 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz);
531 max_rq_sg = MLX5_CAP_GEN(mdev, max_wqe_sz_rq) /

--- 535 unchanged lines hidden (view full) ---

1067 return offset & ((1 << MLX5_IB_MMAP_CMD_SHIFT) - 1);
1068}
1069
1070static int get_index(unsigned long offset)
1071{
1072 return get_arg(offset);
1073}
1074
1074static inline char *mmap_cmd2str(enum mlx5_ib_mmap_cmd cmd)
1075{
1076 switch (cmd) {
1077 case MLX5_IB_MMAP_WC_PAGE:
1078 return "WC";
1079 case MLX5_IB_MMAP_REGULAR_PAGE:
1080 return "best effort WC";
1081 case MLX5_IB_MMAP_NC_PAGE:
1082 return "NC";
1083 default:
1084 return NULL;
1085 }
1086}
1087
1088static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd,
1089 struct vm_area_struct *vma, struct mlx5_uuar_info *uuari)
1090{
1091 int err;
1092 unsigned long idx;
1093 phys_addr_t pfn, pa;
1094 pgprot_t prot;
1095
1096 switch (cmd) {
1097 case MLX5_IB_MMAP_WC_PAGE:
1098/* Some architectures don't support WC memory */
1099#if defined(CONFIG_X86)
1100 if (!pat_enabled())
1101 return -EPERM;
1102#elif !(defined(CONFIG_PPC) || (defined(CONFIG_ARM) && defined(CONFIG_MMU)))
1103 return -EPERM;
1104#endif
1105 /* fall through */
1106 case MLX5_IB_MMAP_REGULAR_PAGE:
1107 /* For MLX5_IB_MMAP_REGULAR_PAGE do the best effort to get WC */
1108 prot = pgprot_writecombine(vma->vm_page_prot);
1109 break;
1110 case MLX5_IB_MMAP_NC_PAGE:
1111 prot = pgprot_noncached(vma->vm_page_prot);
1112 break;
1113 default:
1114 return -EINVAL;
1115 }
1116
1117 if (vma->vm_end - vma->vm_start != PAGE_SIZE)
1118 return -EINVAL;
1119
1120 idx = get_index(vma->vm_pgoff);
1121 if (idx >= uuari->num_uars)
1122 return -EINVAL;
1123
1124 pfn = uar_index2pfn(dev, uuari->uars[idx].index);
1125 mlx5_ib_dbg(dev, "uar idx 0x%lx, pfn %pa\n", idx, &pfn);
1126
1127 vma->vm_page_prot = prot;
1128 err = io_remap_pfn_range(vma, vma->vm_start, pfn,
1129 PAGE_SIZE, vma->vm_page_prot);
1130 if (err) {
1131 mlx5_ib_err(dev, "io_remap_pfn_range failed with error=%d, vm_start=0x%lx, pfn=%pa, mmap_cmd=%s\n",
1132 err, vma->vm_start, &pfn, mmap_cmd2str(cmd));
1133 return -EAGAIN;
1134 }
1135
1136 pa = pfn << PAGE_SHIFT;
1137 mlx5_ib_dbg(dev, "mapped %s at 0x%lx, PA %pa\n", mmap_cmd2str(cmd),
1138 vma->vm_start, &pa);
1139
1140 return 0;
1141}
1142
1143static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
1144{
1145 struct mlx5_ib_ucontext *context = to_mucontext(ibcontext);
1146 struct mlx5_ib_dev *dev = to_mdev(ibcontext->device);
1147 struct mlx5_uuar_info *uuari = &context->uuari;
1148 unsigned long command;
1075static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
1076{
1077 struct mlx5_ib_ucontext *context = to_mucontext(ibcontext);
1078 struct mlx5_ib_dev *dev = to_mdev(ibcontext->device);
1079 struct mlx5_uuar_info *uuari = &context->uuari;
1080 unsigned long command;
1081 unsigned long idx;
1149 phys_addr_t pfn;
1150
1151 command = get_command(vma->vm_pgoff);
1152 switch (command) {
1082 phys_addr_t pfn;
1083
1084 command = get_command(vma->vm_pgoff);
1085 switch (command) {
1153 case MLX5_IB_MMAP_WC_PAGE:
1154 case MLX5_IB_MMAP_NC_PAGE:
1155 case MLX5_IB_MMAP_REGULAR_PAGE:
1086 case MLX5_IB_MMAP_REGULAR_PAGE:
1156 return uar_mmap(dev, command, vma, uuari);
1087 if (vma->vm_end - vma->vm_start != PAGE_SIZE)
1088 return -EINVAL;
1157
1089
1090 idx = get_index(vma->vm_pgoff);
1091 if (idx >= uuari->num_uars)
1092 return -EINVAL;
1093
1094 pfn = uar_index2pfn(dev, uuari->uars[idx].index);
1095 mlx5_ib_dbg(dev, "uar idx 0x%lx, pfn 0x%llx\n", idx,
1096 (unsigned long long)pfn);
1097
1098 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
1099 if (io_remap_pfn_range(vma, vma->vm_start, pfn,
1100 PAGE_SIZE, vma->vm_page_prot))
1101 return -EAGAIN;
1102
1103 mlx5_ib_dbg(dev, "mapped WC at 0x%lx, PA 0x%llx\n",
1104 vma->vm_start,
1105 (unsigned long long)pfn << PAGE_SHIFT);
1106 break;
1107
1158 case MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES:
1159 return -ENOSYS;
1160
1161 case MLX5_IB_MMAP_CORE_CLOCK:
1162 if (vma->vm_end - vma->vm_start != PAGE_SIZE)
1163 return -EINVAL;
1164
1108 case MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES:
1109 return -ENOSYS;
1110
1111 case MLX5_IB_MMAP_CORE_CLOCK:
1112 if (vma->vm_end - vma->vm_start != PAGE_SIZE)
1113 return -EINVAL;
1114
1165 if (vma->vm_flags & VM_WRITE)
1115 if (vma->vm_flags & (VM_WRITE | VM_EXEC))
1166 return -EPERM;
1167
1168 /* Don't expose to user-space information it shouldn't have */
1169 if (PAGE_SIZE > 4096)
1170 return -EOPNOTSUPP;
1171
1172 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1173 pfn = (dev->mdev->iseg_base +

--- 1383 unchanged lines hidden ---
1116 return -EPERM;
1117
1118 /* Don't expose to user-space information it shouldn't have */
1119 if (PAGE_SIZE > 4096)
1120 return -EOPNOTSUPP;
1121
1122 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1123 pfn = (dev->mdev->iseg_base +

--- 1383 unchanged lines hidden ---