diff options
author | Doug Ledford <dledford@redhat.com> | 2016-05-26 12:50:05 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-05-26 12:50:05 -0400 |
commit | 8779e7658df2496f27660586e3a20a86c75fb526 (patch) | |
tree | 831a1ebc8e399ee231fe23cf1eecc3fc4a70948a | |
parent | e6f61130ed7a124138c4f7b1bd35e24e8113cb83 (diff) | |
parent | f158486527ebfb4c1fe4dcb69b12479090d66b72 (diff) |
Merge branch 'hfi1-2' into k.o/for-4.7
-rw-r--r-- | MAINTAINERS | 13 | ||||
-rw-r--r-- | drivers/infiniband/Kconfig | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/Makefile | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/Kconfig (renamed from drivers/staging/rdma/hfi1/Kconfig) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/Makefile (renamed from drivers/staging/rdma/hfi1/Makefile) | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/affinity.c (renamed from drivers/staging/rdma/hfi1/affinity.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/affinity.h (renamed from drivers/staging/rdma/hfi1/affinity.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/aspm.h (renamed from drivers/staging/rdma/hfi1/aspm.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/chip.c (renamed from drivers/staging/rdma/hfi1/chip.c) | 41 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/chip.h (renamed from drivers/staging/rdma/hfi1/chip.h) | 6 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/chip_registers.h (renamed from drivers/staging/rdma/hfi1/chip_registers.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/common.h (renamed from drivers/staging/rdma/hfi1/common.h) | 5 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/debugfs.c (renamed from drivers/staging/rdma/hfi1/debugfs.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/debugfs.h (renamed from drivers/staging/rdma/hfi1/debugfs.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/device.c (renamed from drivers/staging/rdma/hfi1/device.c) | 18 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/device.h (renamed from drivers/staging/rdma/hfi1/device.h) | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/dma.c (renamed from drivers/staging/rdma/hfi1/dma.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/driver.c (renamed from drivers/staging/rdma/hfi1/driver.c) | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/efivar.c (renamed from drivers/staging/rdma/hfi1/efivar.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/efivar.h (renamed from drivers/staging/rdma/hfi1/efivar.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/eprom.c | 102 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/eprom.h (renamed from drivers/staging/rdma/hfi1/eprom.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/file_ops.c (renamed from drivers/staging/rdma/hfi1/file_ops.c) | 549 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/firmware.c (renamed from drivers/staging/rdma/hfi1/firmware.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/hfi.h (renamed from drivers/staging/rdma/hfi1/hfi.h) | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/init.c (renamed from drivers/staging/rdma/hfi1/init.c) | 22 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/intr.c (renamed from drivers/staging/rdma/hfi1/intr.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/iowait.h (renamed from drivers/staging/rdma/hfi1/iowait.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/mad.c (renamed from drivers/staging/rdma/hfi1/mad.c) | 99 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/mad.h (renamed from drivers/staging/rdma/hfi1/mad.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/mmu_rb.c (renamed from drivers/staging/rdma/hfi1/mmu_rb.c) | 22 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/mmu_rb.h (renamed from drivers/staging/rdma/hfi1/mmu_rb.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/opa_compat.h (renamed from drivers/staging/rdma/hfi1/opa_compat.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/pcie.c (renamed from drivers/staging/rdma/hfi1/pcie.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/pio.c (renamed from drivers/staging/rdma/hfi1/pio.c) | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/pio.h (renamed from drivers/staging/rdma/hfi1/pio.h) | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/pio_copy.c (renamed from drivers/staging/rdma/hfi1/pio_copy.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/platform.c (renamed from drivers/staging/rdma/hfi1/platform.c) | 27 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/platform.h (renamed from drivers/staging/rdma/hfi1/platform.h) | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/qp.c (renamed from drivers/staging/rdma/hfi1/qp.c) | 9 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/qp.h (renamed from drivers/staging/rdma/hfi1/qp.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/qsfp.c (renamed from drivers/staging/rdma/hfi1/qsfp.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/qsfp.h (renamed from drivers/staging/rdma/hfi1/qsfp.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/rc.c (renamed from drivers/staging/rdma/hfi1/rc.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/ruc.c (renamed from drivers/staging/rdma/hfi1/ruc.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/sdma.c (renamed from drivers/staging/rdma/hfi1/sdma.c) | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/sdma.h (renamed from drivers/staging/rdma/hfi1/sdma.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/sdma_txreq.h (renamed from drivers/staging/rdma/hfi1/sdma_txreq.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/sysfs.c (renamed from drivers/staging/rdma/hfi1/sysfs.c) | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/trace.c (renamed from drivers/staging/rdma/hfi1/trace.c) | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/trace.h (renamed from drivers/staging/rdma/hfi1/trace.h) | 5 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/twsi.c (renamed from drivers/staging/rdma/hfi1/twsi.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/twsi.h (renamed from drivers/staging/rdma/hfi1/twsi.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/uc.c (renamed from drivers/staging/rdma/hfi1/uc.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/ud.c (renamed from drivers/staging/rdma/hfi1/ud.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/user_exp_rcv.c (renamed from drivers/staging/rdma/hfi1/user_exp_rcv.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/user_exp_rcv.h (renamed from drivers/staging/rdma/hfi1/user_exp_rcv.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/user_pages.c (renamed from drivers/staging/rdma/hfi1/user_pages.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/user_sdma.c (renamed from drivers/staging/rdma/hfi1/user_sdma.c) | 18 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/user_sdma.h (renamed from drivers/staging/rdma/hfi1/user_sdma.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/verbs.c (renamed from drivers/staging/rdma/hfi1/verbs.c) | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/verbs.h (renamed from drivers/staging/rdma/hfi1/verbs.h) | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/verbs_txreq.c (renamed from drivers/staging/rdma/hfi1/verbs_txreq.c) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/hfi1/verbs_txreq.h (renamed from drivers/staging/rdma/hfi1/verbs_txreq.h) | 0 | ||||
-rw-r--r-- | drivers/infiniband/hw/qib/qib_iba7322.c | 15 | ||||
-rw-r--r-- | drivers/infiniband/hw/qib/qib_verbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/sw/rdmavt/cq.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/sw/rdmavt/mr.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/sw/rdmavt/qp.c | 30 | ||||
-rw-r--r-- | drivers/staging/rdma/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/rdma/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/rdma/hfi1/TODO | 6 | ||||
-rw-r--r-- | drivers/staging/rdma/hfi1/diag.c | 1925 | ||||
-rw-r--r-- | drivers/staging/rdma/hfi1/eprom.c | 471 | ||||
-rw-r--r-- | include/rdma/ib_pack.h | 5 | ||||
-rw-r--r-- | include/rdma/rdma_vt.h | 13 | ||||
-rw-r--r-- | include/rdma/rdmavt_qp.h | 5 | ||||
-rw-r--r-- | include/uapi/rdma/hfi/hfi1_user.h | 80 |
78 files changed, 551 insertions, 2994 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c8025946eaae..98234560cfdc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5086,6 +5086,13 @@ F: drivers/block/cciss* | |||
5086 | F: include/linux/cciss_ioctl.h | 5086 | F: include/linux/cciss_ioctl.h |
5087 | F: include/uapi/linux/cciss_ioctl.h | 5087 | F: include/uapi/linux/cciss_ioctl.h |
5088 | 5088 | ||
5089 | HFI1 DRIVER | ||
5090 | M: Mike Marciniszyn <mike.marciniszyn@intel.com> | ||
5091 | M: Dennis Dalessandro <dennis.dalessandro@intel.com> | ||
5092 | L: linux-rdma@vger.kernel.org | ||
5093 | S: Supported | ||
5094 | F: drivers/infiniband/hw/hfi1 | ||
5095 | |||
5089 | HFS FILESYSTEM | 5096 | HFS FILESYSTEM |
5090 | L: linux-fsdevel@vger.kernel.org | 5097 | L: linux-fsdevel@vger.kernel.org |
5091 | S: Orphan | 5098 | S: Orphan |
@@ -10661,12 +10668,6 @@ M: Arnaud Patard <arnaud.patard@rtp-net.org> | |||
10661 | S: Odd Fixes | 10668 | S: Odd Fixes |
10662 | F: drivers/staging/xgifb/ | 10669 | F: drivers/staging/xgifb/ |
10663 | 10670 | ||
10664 | HFI1 DRIVER | ||
10665 | M: Mike Marciniszyn <infinipath@intel.com> | ||
10666 | L: linux-rdma@vger.kernel.org | ||
10667 | S: Supported | ||
10668 | F: drivers/staging/rdma/hfi1 | ||
10669 | |||
10670 | STARFIRE/DURALAN NETWORK DRIVER | 10671 | STARFIRE/DURALAN NETWORK DRIVER |
10671 | M: Ion Badulescu <ionut@badula.org> | 10672 | M: Ion Badulescu <ionut@badula.org> |
10672 | S: Odd Fixes | 10673 | S: Odd Fixes |
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index 6425c0e5d18a..2137adfbd8c3 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig | |||
@@ -85,4 +85,6 @@ source "drivers/infiniband/ulp/isert/Kconfig" | |||
85 | 85 | ||
86 | source "drivers/infiniband/sw/rdmavt/Kconfig" | 86 | source "drivers/infiniband/sw/rdmavt/Kconfig" |
87 | 87 | ||
88 | source "drivers/infiniband/hw/hfi1/Kconfig" | ||
89 | |||
88 | endif # INFINIBAND | 90 | endif # INFINIBAND |
diff --git a/drivers/infiniband/hw/Makefile b/drivers/infiniband/hw/Makefile index c7ad0a4c8b15..c0c7cf8af3f4 100644 --- a/drivers/infiniband/hw/Makefile +++ b/drivers/infiniband/hw/Makefile | |||
@@ -8,3 +8,4 @@ obj-$(CONFIG_MLX5_INFINIBAND) += mlx5/ | |||
8 | obj-$(CONFIG_INFINIBAND_NES) += nes/ | 8 | obj-$(CONFIG_INFINIBAND_NES) += nes/ |
9 | obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma/ | 9 | obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma/ |
10 | obj-$(CONFIG_INFINIBAND_USNIC) += usnic/ | 10 | obj-$(CONFIG_INFINIBAND_USNIC) += usnic/ |
11 | obj-$(CONFIG_INFINIBAND_HFI1) += hfi1/ | ||
diff --git a/drivers/staging/rdma/hfi1/Kconfig b/drivers/infiniband/hw/hfi1/Kconfig index a925fb0db706..a925fb0db706 100644 --- a/drivers/staging/rdma/hfi1/Kconfig +++ b/drivers/infiniband/hw/hfi1/Kconfig | |||
diff --git a/drivers/staging/rdma/hfi1/Makefile b/drivers/infiniband/hw/hfi1/Makefile index 8dc59382ee96..9b5382c94b0c 100644 --- a/drivers/staging/rdma/hfi1/Makefile +++ b/drivers/infiniband/hw/hfi1/Makefile | |||
@@ -7,7 +7,7 @@ | |||
7 | # | 7 | # |
8 | obj-$(CONFIG_INFINIBAND_HFI1) += hfi1.o | 8 | obj-$(CONFIG_INFINIBAND_HFI1) += hfi1.o |
9 | 9 | ||
10 | hfi1-y := affinity.o chip.o device.o diag.o driver.o efivar.o \ | 10 | hfi1-y := affinity.o chip.o device.o driver.o efivar.o \ |
11 | eprom.o file_ops.o firmware.o \ | 11 | eprom.o file_ops.o firmware.o \ |
12 | init.o intr.o mad.o mmu_rb.o pcie.o pio.o pio_copy.o platform.o \ | 12 | init.o intr.o mad.o mmu_rb.o pcie.o pio.o pio_copy.o platform.o \ |
13 | qp.o qsfp.o rc.o ruc.o sdma.o sysfs.o trace.o twsi.o \ | 13 | qp.o qsfp.o rc.o ruc.o sdma.o sysfs.o trace.o twsi.o \ |
diff --git a/drivers/staging/rdma/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c index 6e7050ab9e16..6e7050ab9e16 100644 --- a/drivers/staging/rdma/hfi1/affinity.c +++ b/drivers/infiniband/hw/hfi1/affinity.c | |||
diff --git a/drivers/staging/rdma/hfi1/affinity.h b/drivers/infiniband/hw/hfi1/affinity.h index 20f52fe74091..20f52fe74091 100644 --- a/drivers/staging/rdma/hfi1/affinity.h +++ b/drivers/infiniband/hw/hfi1/affinity.h | |||
diff --git a/drivers/staging/rdma/hfi1/aspm.h b/drivers/infiniband/hw/hfi1/aspm.h index 0d58fe3b49b5..0d58fe3b49b5 100644 --- a/drivers/staging/rdma/hfi1/aspm.h +++ b/drivers/infiniband/hw/hfi1/aspm.h | |||
diff --git a/drivers/staging/rdma/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index dcae8e723f98..3b876da745a1 100644 --- a/drivers/staging/rdma/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c | |||
@@ -1037,6 +1037,7 @@ static void dc_shutdown(struct hfi1_devdata *); | |||
1037 | static void dc_start(struct hfi1_devdata *); | 1037 | static void dc_start(struct hfi1_devdata *); |
1038 | static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp, | 1038 | static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp, |
1039 | unsigned int *np); | 1039 | unsigned int *np); |
1040 | static void remove_full_mgmt_pkey(struct hfi1_pportdata *ppd); | ||
1040 | 1041 | ||
1041 | /* | 1042 | /* |
1042 | * Error interrupt table entry. This is used as input to the interrupt | 1043 | * Error interrupt table entry. This is used as input to the interrupt |
@@ -6105,7 +6106,7 @@ int acquire_lcb_access(struct hfi1_devdata *dd, int sleep_ok) | |||
6105 | } | 6106 | } |
6106 | 6107 | ||
6107 | /* this access is valid only when the link is up */ | 6108 | /* this access is valid only when the link is up */ |
6108 | if ((ppd->host_link_state & HLS_UP) == 0) { | 6109 | if (ppd->host_link_state & HLS_DOWN) { |
6109 | dd_dev_info(dd, "%s: link state %s not up\n", | 6110 | dd_dev_info(dd, "%s: link state %s not up\n", |
6110 | __func__, link_state_name(ppd->host_link_state)); | 6111 | __func__, link_state_name(ppd->host_link_state)); |
6111 | ret = -EBUSY; | 6112 | ret = -EBUSY; |
@@ -6961,6 +6962,8 @@ void handle_link_down(struct work_struct *work) | |||
6961 | } | 6962 | } |
6962 | 6963 | ||
6963 | reset_neighbor_info(ppd); | 6964 | reset_neighbor_info(ppd); |
6965 | if (ppd->mgmt_allowed) | ||
6966 | remove_full_mgmt_pkey(ppd); | ||
6964 | 6967 | ||
6965 | /* disable the port */ | 6968 | /* disable the port */ |
6966 | clear_rcvctrl(ppd->dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK); | 6969 | clear_rcvctrl(ppd->dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK); |
@@ -7069,6 +7072,12 @@ static void add_full_mgmt_pkey(struct hfi1_pportdata *ppd) | |||
7069 | (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0); | 7072 | (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0); |
7070 | } | 7073 | } |
7071 | 7074 | ||
7075 | static void remove_full_mgmt_pkey(struct hfi1_pportdata *ppd) | ||
7076 | { | ||
7077 | ppd->pkeys[2] = 0; | ||
7078 | (void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0); | ||
7079 | } | ||
7080 | |||
7072 | /* | 7081 | /* |
7073 | * Convert the given link width to the OPA link width bitmask. | 7082 | * Convert the given link width to the OPA link width bitmask. |
7074 | */ | 7083 | */ |
@@ -7429,7 +7438,7 @@ void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths) | |||
7429 | retry: | 7438 | retry: |
7430 | mutex_lock(&ppd->hls_lock); | 7439 | mutex_lock(&ppd->hls_lock); |
7431 | /* only apply if the link is up */ | 7440 | /* only apply if the link is up */ |
7432 | if (!(ppd->host_link_state & HLS_UP)) { | 7441 | if (ppd->host_link_state & HLS_DOWN) { |
7433 | /* still going up..wait and retry */ | 7442 | /* still going up..wait and retry */ |
7434 | if (ppd->host_link_state & HLS_GOING_UP) { | 7443 | if (ppd->host_link_state & HLS_GOING_UP) { |
7435 | if (++tries < 1000) { | 7444 | if (++tries < 1000) { |
@@ -9212,9 +9221,6 @@ void reset_qsfp(struct hfi1_pportdata *ppd) | |||
9212 | 9221 | ||
9213 | /* Reset the QSFP */ | 9222 | /* Reset the QSFP */ |
9214 | mask = (u64)QSFP_HFI0_RESET_N; | 9223 | mask = (u64)QSFP_HFI0_RESET_N; |
9215 | qsfp_mask = read_csr(dd, dd->hfi1_id ? ASIC_QSFP2_OE : ASIC_QSFP1_OE); | ||
9216 | qsfp_mask |= mask; | ||
9217 | write_csr(dd, dd->hfi1_id ? ASIC_QSFP2_OE : ASIC_QSFP1_OE, qsfp_mask); | ||
9218 | 9224 | ||
9219 | qsfp_mask = read_csr(dd, | 9225 | qsfp_mask = read_csr(dd, |
9220 | dd->hfi1_id ? ASIC_QSFP2_OUT : ASIC_QSFP1_OUT); | 9226 | dd->hfi1_id ? ASIC_QSFP2_OUT : ASIC_QSFP1_OUT); |
@@ -9252,6 +9258,12 @@ static int handle_qsfp_error_conditions(struct hfi1_pportdata *ppd, | |||
9252 | dd_dev_info(dd, "%s: QSFP cable temperature too low\n", | 9258 | dd_dev_info(dd, "%s: QSFP cable temperature too low\n", |
9253 | __func__); | 9259 | __func__); |
9254 | 9260 | ||
9261 | /* | ||
9262 | * The remaining alarms/warnings don't matter if the link is down. | ||
9263 | */ | ||
9264 | if (ppd->host_link_state & HLS_DOWN) | ||
9265 | return 0; | ||
9266 | |||
9255 | if ((qsfp_interrupt_status[1] & QSFP_HIGH_VCC_ALARM) || | 9267 | if ((qsfp_interrupt_status[1] & QSFP_HIGH_VCC_ALARM) || |
9256 | (qsfp_interrupt_status[1] & QSFP_HIGH_VCC_WARNING)) | 9268 | (qsfp_interrupt_status[1] & QSFP_HIGH_VCC_WARNING)) |
9257 | dd_dev_info(dd, "%s: QSFP supply voltage too high\n", | 9269 | dd_dev_info(dd, "%s: QSFP supply voltage too high\n", |
@@ -9346,9 +9358,8 @@ void qsfp_event(struct work_struct *work) | |||
9346 | return; | 9358 | return; |
9347 | 9359 | ||
9348 | /* | 9360 | /* |
9349 | * Turn DC back on after cables has been | 9361 | * Turn DC back on after cable has been re-inserted. Up until |
9350 | * re-inserted. Up until now, the DC has been in | 9362 | * now, the DC has been in reset to save power. |
9351 | * reset to save power. | ||
9352 | */ | 9363 | */ |
9353 | dc_start(dd); | 9364 | dc_start(dd); |
9354 | 9365 | ||
@@ -9480,7 +9491,15 @@ int bringup_serdes(struct hfi1_pportdata *ppd) | |||
9480 | return ret; | 9491 | return ret; |
9481 | } | 9492 | } |
9482 | 9493 | ||
9483 | /* tune the SERDES to a ballpark setting for | 9494 | get_port_type(ppd); |
9495 | if (ppd->port_type == PORT_TYPE_QSFP) { | ||
9496 | set_qsfp_int_n(ppd, 0); | ||
9497 | wait_for_qsfp_init(ppd); | ||
9498 | set_qsfp_int_n(ppd, 1); | ||
9499 | } | ||
9500 | |||
9501 | /* | ||
9502 | * Tune the SerDes to a ballpark setting for | ||
9484 | * optimal signal and bit error rate | 9503 | * optimal signal and bit error rate |
9485 | * Needs to be done before starting the link | 9504 | * Needs to be done before starting the link |
9486 | */ | 9505 | */ |
@@ -10074,7 +10093,7 @@ u32 driver_physical_state(struct hfi1_pportdata *ppd) | |||
10074 | */ | 10093 | */ |
10075 | u32 driver_logical_state(struct hfi1_pportdata *ppd) | 10094 | u32 driver_logical_state(struct hfi1_pportdata *ppd) |
10076 | { | 10095 | { |
10077 | if (ppd->host_link_state && !(ppd->host_link_state & HLS_UP)) | 10096 | if (ppd->host_link_state && (ppd->host_link_state & HLS_DOWN)) |
10078 | return IB_PORT_DOWN; | 10097 | return IB_PORT_DOWN; |
10079 | 10098 | ||
10080 | switch (ppd->host_link_state & HLS_UP) { | 10099 | switch (ppd->host_link_state & HLS_UP) { |
@@ -14578,7 +14597,7 @@ u64 create_pbc(struct hfi1_pportdata *ppd, u64 flags, int srate_mbs, u32 vl, | |||
14578 | (reason), (ret)) | 14597 | (reason), (ret)) |
14579 | 14598 | ||
14580 | /* | 14599 | /* |
14581 | * Initialize the Avago Thermal sensor. | 14600 | * Initialize the thermal sensor. |
14582 | * | 14601 | * |
14583 | * After initialization, enable polling of thermal sensor through | 14602 | * After initialization, enable polling of thermal sensor through |
14584 | * SBus interface. In order for this to work, the SBus Master | 14603 | * SBus interface. In order for this to work, the SBus Master |
diff --git a/drivers/staging/rdma/hfi1/chip.h b/drivers/infiniband/hw/hfi1/chip.h index 1948706fff1a..66a327978739 100644 --- a/drivers/staging/rdma/hfi1/chip.h +++ b/drivers/infiniband/hw/hfi1/chip.h | |||
@@ -398,6 +398,12 @@ | |||
398 | /* Lane ID for general configuration registers */ | 398 | /* Lane ID for general configuration registers */ |
399 | #define GENERAL_CONFIG 4 | 399 | #define GENERAL_CONFIG 4 |
400 | 400 | ||
401 | /* LINK_TUNING_PARAMETERS fields */ | ||
402 | #define TUNING_METHOD_SHIFT 24 | ||
403 | |||
404 | /* LINK_OPTIMIZATION_SETTINGS fields */ | ||
405 | #define ENABLE_EXT_DEV_CONFIG_SHIFT 24 | ||
406 | |||
401 | /* LOAD_DATA 8051 command shifts and fields */ | 407 | /* LOAD_DATA 8051 command shifts and fields */ |
402 | #define LOAD_DATA_FIELD_ID_SHIFT 40 | 408 | #define LOAD_DATA_FIELD_ID_SHIFT 40 |
403 | #define LOAD_DATA_FIELD_ID_MASK 0xfull | 409 | #define LOAD_DATA_FIELD_ID_MASK 0xfull |
diff --git a/drivers/staging/rdma/hfi1/chip_registers.h b/drivers/infiniband/hw/hfi1/chip_registers.h index 8744de6667c2..8744de6667c2 100644 --- a/drivers/staging/rdma/hfi1/chip_registers.h +++ b/drivers/infiniband/hw/hfi1/chip_registers.h | |||
diff --git a/drivers/staging/rdma/hfi1/common.h b/drivers/infiniband/hw/hfi1/common.h index e9b6bb322025..fcc9c217a97a 100644 --- a/drivers/staging/rdma/hfi1/common.h +++ b/drivers/infiniband/hw/hfi1/common.h | |||
@@ -178,7 +178,8 @@ | |||
178 | HFI1_CAP_PKEY_CHECK | \ | 178 | HFI1_CAP_PKEY_CHECK | \ |
179 | HFI1_CAP_NO_INTEGRITY) | 179 | HFI1_CAP_NO_INTEGRITY) |
180 | 180 | ||
181 | #define HFI1_USER_SWVERSION ((HFI1_USER_SWMAJOR << 16) | HFI1_USER_SWMINOR) | 181 | #define HFI1_USER_SWVERSION ((HFI1_USER_SWMAJOR << HFI1_SWMAJOR_SHIFT) | \ |
182 | HFI1_USER_SWMINOR) | ||
182 | 183 | ||
183 | #ifndef HFI1_KERN_TYPE | 184 | #ifndef HFI1_KERN_TYPE |
184 | #define HFI1_KERN_TYPE 0 | 185 | #define HFI1_KERN_TYPE 0 |
@@ -349,6 +350,8 @@ struct hfi1_message_header { | |||
349 | #define HFI1_BECN_MASK 1 | 350 | #define HFI1_BECN_MASK 1 |
350 | #define HFI1_BECN_SMASK BIT(HFI1_BECN_SHIFT) | 351 | #define HFI1_BECN_SMASK BIT(HFI1_BECN_SHIFT) |
351 | 352 | ||
353 | #define HFI1_PSM_IOC_BASE_SEQ 0x0 | ||
354 | |||
352 | static inline __u64 rhf_to_cpu(const __le32 *rbuf) | 355 | static inline __u64 rhf_to_cpu(const __le32 *rbuf) |
353 | { | 356 | { |
354 | return __le64_to_cpu(*((__le64 *)rbuf)); | 357 | return __le64_to_cpu(*((__le64 *)rbuf)); |
diff --git a/drivers/staging/rdma/hfi1/debugfs.c b/drivers/infiniband/hw/hfi1/debugfs.c index dbab9d9cc288..dbab9d9cc288 100644 --- a/drivers/staging/rdma/hfi1/debugfs.c +++ b/drivers/infiniband/hw/hfi1/debugfs.c | |||
diff --git a/drivers/staging/rdma/hfi1/debugfs.h b/drivers/infiniband/hw/hfi1/debugfs.h index b6fb6814f1b8..b6fb6814f1b8 100644 --- a/drivers/staging/rdma/hfi1/debugfs.h +++ b/drivers/infiniband/hw/hfi1/debugfs.h | |||
diff --git a/drivers/staging/rdma/hfi1/device.c b/drivers/infiniband/hw/hfi1/device.c index c05c39da83b1..bf64b5a7bfd7 100644 --- a/drivers/staging/rdma/hfi1/device.c +++ b/drivers/infiniband/hw/hfi1/device.c | |||
@@ -60,7 +60,8 @@ static dev_t hfi1_dev; | |||
60 | int hfi1_cdev_init(int minor, const char *name, | 60 | int hfi1_cdev_init(int minor, const char *name, |
61 | const struct file_operations *fops, | 61 | const struct file_operations *fops, |
62 | struct cdev *cdev, struct device **devp, | 62 | struct cdev *cdev, struct device **devp, |
63 | bool user_accessible) | 63 | bool user_accessible, |
64 | struct kobject *parent) | ||
64 | { | 65 | { |
65 | const dev_t dev = MKDEV(MAJOR(hfi1_dev), minor); | 66 | const dev_t dev = MKDEV(MAJOR(hfi1_dev), minor); |
66 | struct device *device = NULL; | 67 | struct device *device = NULL; |
@@ -68,6 +69,7 @@ int hfi1_cdev_init(int minor, const char *name, | |||
68 | 69 | ||
69 | cdev_init(cdev, fops); | 70 | cdev_init(cdev, fops); |
70 | cdev->owner = THIS_MODULE; | 71 | cdev->owner = THIS_MODULE; |
72 | cdev->kobj.parent = parent; | ||
71 | kobject_set_name(&cdev->kobj, name); | 73 | kobject_set_name(&cdev->kobj, name); |
72 | 74 | ||
73 | ret = cdev_add(cdev, dev, 1); | 75 | ret = cdev_add(cdev, dev, 1); |
@@ -82,13 +84,13 @@ int hfi1_cdev_init(int minor, const char *name, | |||
82 | else | 84 | else |
83 | device = device_create(class, NULL, dev, NULL, "%s", name); | 85 | device = device_create(class, NULL, dev, NULL, "%s", name); |
84 | 86 | ||
85 | if (!IS_ERR(device)) | 87 | if (IS_ERR(device)) { |
86 | goto done; | 88 | ret = PTR_ERR(device); |
87 | ret = PTR_ERR(device); | 89 | device = NULL; |
88 | device = NULL; | 90 | pr_err("Could not create device for minor %d, %s (err %d)\n", |
89 | pr_err("Could not create device for minor %d, %s (err %d)\n", | 91 | minor, name, -ret); |
90 | minor, name, -ret); | 92 | cdev_del(cdev); |
91 | cdev_del(cdev); | 93 | } |
92 | done: | 94 | done: |
93 | *devp = device; | 95 | *devp = device; |
94 | return ret; | 96 | return ret; |
diff --git a/drivers/staging/rdma/hfi1/device.h b/drivers/infiniband/hw/hfi1/device.h index 5bb3e83cf2da..c3ec19cb0ac9 100644 --- a/drivers/staging/rdma/hfi1/device.h +++ b/drivers/infiniband/hw/hfi1/device.h | |||
@@ -50,7 +50,8 @@ | |||
50 | int hfi1_cdev_init(int minor, const char *name, | 50 | int hfi1_cdev_init(int minor, const char *name, |
51 | const struct file_operations *fops, | 51 | const struct file_operations *fops, |
52 | struct cdev *cdev, struct device **devp, | 52 | struct cdev *cdev, struct device **devp, |
53 | bool user_accessible); | 53 | bool user_accessible, |
54 | struct kobject *parent); | ||
54 | void hfi1_cdev_cleanup(struct cdev *cdev, struct device **devp); | 55 | void hfi1_cdev_cleanup(struct cdev *cdev, struct device **devp); |
55 | const char *class_name(void); | 56 | const char *class_name(void); |
56 | int __init dev_init(void); | 57 | int __init dev_init(void); |
diff --git a/drivers/staging/rdma/hfi1/dma.c b/drivers/infiniband/hw/hfi1/dma.c index 7e8dab892848..7e8dab892848 100644 --- a/drivers/staging/rdma/hfi1/dma.c +++ b/drivers/infiniband/hw/hfi1/dma.c | |||
diff --git a/drivers/staging/rdma/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c index 700c6fa3a633..c75b0ae688f8 100644 --- a/drivers/staging/rdma/hfi1/driver.c +++ b/drivers/infiniband/hw/hfi1/driver.c | |||
@@ -1161,7 +1161,7 @@ int hfi1_set_lid(struct hfi1_pportdata *ppd, u32 lid, u8 lmc) | |||
1161 | ppd->lmc = lmc; | 1161 | ppd->lmc = lmc; |
1162 | hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_LIDLMC, 0); | 1162 | hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_LIDLMC, 0); |
1163 | 1163 | ||
1164 | dd_dev_info(dd, "IB%u:%u got a lid: 0x%x\n", dd->unit, ppd->port, lid); | 1164 | dd_dev_info(dd, "port %u: got a lid: 0x%x\n", ppd->port, lid); |
1165 | 1165 | ||
1166 | return 0; | 1166 | return 0; |
1167 | } | 1167 | } |
diff --git a/drivers/staging/rdma/hfi1/efivar.c b/drivers/infiniband/hw/hfi1/efivar.c index 106349fc1fb9..106349fc1fb9 100644 --- a/drivers/staging/rdma/hfi1/efivar.c +++ b/drivers/infiniband/hw/hfi1/efivar.c | |||
diff --git a/drivers/staging/rdma/hfi1/efivar.h b/drivers/infiniband/hw/hfi1/efivar.h index 94e9e70de568..94e9e70de568 100644 --- a/drivers/staging/rdma/hfi1/efivar.h +++ b/drivers/infiniband/hw/hfi1/efivar.h | |||
diff --git a/drivers/infiniband/hw/hfi1/eprom.c b/drivers/infiniband/hw/hfi1/eprom.c new file mode 100644 index 000000000000..36b77943cbfd --- /dev/null +++ b/drivers/infiniband/hw/hfi1/eprom.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * Copyright(c) 2015, 2016 Intel Corporation. | ||
3 | * | ||
4 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
5 | * redistributing this file, you may do so under either license. | ||
6 | * | ||
7 | * GPL LICENSE SUMMARY | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of version 2 of the GNU General Public License as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * BSD LICENSE | ||
19 | * | ||
20 | * Redistribution and use in source and binary forms, with or without | ||
21 | * modification, are permitted provided that the following conditions | ||
22 | * are met: | ||
23 | * | ||
24 | * - Redistributions of source code must retain the above copyright | ||
25 | * notice, this list of conditions and the following disclaimer. | ||
26 | * - Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * - Neither the name of Intel Corporation nor the names of its | ||
31 | * contributors may be used to endorse or promote products derived | ||
32 | * from this software without specific prior written permission. | ||
33 | * | ||
34 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
35 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
36 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
37 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
38 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
39 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
40 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
41 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
42 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
43 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
44 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
45 | * | ||
46 | */ | ||
47 | #include <linux/delay.h> | ||
48 | #include "hfi.h" | ||
49 | #include "common.h" | ||
50 | #include "eprom.h" | ||
51 | |||
52 | #define CMD_SHIFT 24 | ||
53 | #define CMD_RELEASE_POWERDOWN_NOID ((0xab << CMD_SHIFT)) | ||
54 | |||
55 | /* controller interface speeds */ | ||
56 | #define EP_SPEED_FULL 0x2 /* full speed */ | ||
57 | |||
58 | /* | ||
59 | * How long to wait for the EPROM to become available, in ms. | ||
60 | * The spec 32 Mb EPROM takes around 40s to erase then write. | ||
61 | * Double it for safety. | ||
62 | */ | ||
63 | #define EPROM_TIMEOUT 80000 /* ms */ | ||
64 | /* | ||
65 | * Initialize the EPROM handler. | ||
66 | */ | ||
67 | int eprom_init(struct hfi1_devdata *dd) | ||
68 | { | ||
69 | int ret = 0; | ||
70 | |||
71 | /* only the discrete chip has an EPROM */ | ||
72 | if (dd->pcidev->device != PCI_DEVICE_ID_INTEL0) | ||
73 | return 0; | ||
74 | |||
75 | /* | ||
76 | * It is OK if both HFIs reset the EPROM as long as they don't | ||
77 | * do it at the same time. | ||
78 | */ | ||
79 | ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); | ||
80 | if (ret) { | ||
81 | dd_dev_err(dd, | ||
82 | "%s: unable to acquire EPROM resource, no EPROM support\n", | ||
83 | __func__); | ||
84 | goto done_asic; | ||
85 | } | ||
86 | |||
87 | /* reset EPROM to be sure it is in a good state */ | ||
88 | |||
89 | /* set reset */ | ||
90 | write_csr(dd, ASIC_EEP_CTL_STAT, ASIC_EEP_CTL_STAT_EP_RESET_SMASK); | ||
91 | /* clear reset, set speed */ | ||
92 | write_csr(dd, ASIC_EEP_CTL_STAT, | ||
93 | EP_SPEED_FULL << ASIC_EEP_CTL_STAT_RATE_SPI_SHIFT); | ||
94 | |||
95 | /* wake the device with command "release powerdown NoID" */ | ||
96 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_RELEASE_POWERDOWN_NOID); | ||
97 | |||
98 | dd->eprom_available = true; | ||
99 | release_chip_resource(dd, CR_EPROM); | ||
100 | done_asic: | ||
101 | return ret; | ||
102 | } | ||
diff --git a/drivers/staging/rdma/hfi1/eprom.h b/drivers/infiniband/hw/hfi1/eprom.h index d41f0b1afb15..d41f0b1afb15 100644 --- a/drivers/staging/rdma/hfi1/eprom.h +++ b/drivers/infiniband/hw/hfi1/eprom.h | |||
diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index c1c5bf82addb..7a5b0e676cc7 100644 --- a/drivers/staging/rdma/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c | |||
@@ -72,8 +72,6 @@ | |||
72 | */ | 72 | */ |
73 | static int hfi1_file_open(struct inode *, struct file *); | 73 | static int hfi1_file_open(struct inode *, struct file *); |
74 | static int hfi1_file_close(struct inode *, struct file *); | 74 | static int hfi1_file_close(struct inode *, struct file *); |
75 | static ssize_t hfi1_file_write(struct file *, const char __user *, | ||
76 | size_t, loff_t *); | ||
77 | static ssize_t hfi1_write_iter(struct kiocb *, struct iov_iter *); | 75 | static ssize_t hfi1_write_iter(struct kiocb *, struct iov_iter *); |
78 | static unsigned int hfi1_poll(struct file *, struct poll_table_struct *); | 76 | static unsigned int hfi1_poll(struct file *, struct poll_table_struct *); |
79 | static int hfi1_file_mmap(struct file *, struct vm_area_struct *); | 77 | static int hfi1_file_mmap(struct file *, struct vm_area_struct *); |
@@ -86,8 +84,7 @@ static int get_ctxt_info(struct file *, void __user *, __u32); | |||
86 | static int get_base_info(struct file *, void __user *, __u32); | 84 | static int get_base_info(struct file *, void __user *, __u32); |
87 | static int setup_ctxt(struct file *); | 85 | static int setup_ctxt(struct file *); |
88 | static int setup_subctxt(struct hfi1_ctxtdata *); | 86 | static int setup_subctxt(struct hfi1_ctxtdata *); |
89 | static int get_user_context(struct file *, struct hfi1_user_info *, | 87 | static int get_user_context(struct file *, struct hfi1_user_info *, int); |
90 | int, unsigned); | ||
91 | static int find_shared_ctxt(struct file *, const struct hfi1_user_info *); | 88 | static int find_shared_ctxt(struct file *, const struct hfi1_user_info *); |
92 | static int allocate_ctxt(struct file *, struct hfi1_devdata *, | 89 | static int allocate_ctxt(struct file *, struct hfi1_devdata *, |
93 | struct hfi1_user_info *); | 90 | struct hfi1_user_info *); |
@@ -97,13 +94,15 @@ static int user_event_ack(struct hfi1_ctxtdata *, int, unsigned long); | |||
97 | static int set_ctxt_pkey(struct hfi1_ctxtdata *, unsigned, u16); | 94 | static int set_ctxt_pkey(struct hfi1_ctxtdata *, unsigned, u16); |
98 | static int manage_rcvq(struct hfi1_ctxtdata *, unsigned, int); | 95 | static int manage_rcvq(struct hfi1_ctxtdata *, unsigned, int); |
99 | static int vma_fault(struct vm_area_struct *, struct vm_fault *); | 96 | static int vma_fault(struct vm_area_struct *, struct vm_fault *); |
97 | static long hfi1_file_ioctl(struct file *fp, unsigned int cmd, | ||
98 | unsigned long arg); | ||
100 | 99 | ||
101 | static const struct file_operations hfi1_file_ops = { | 100 | static const struct file_operations hfi1_file_ops = { |
102 | .owner = THIS_MODULE, | 101 | .owner = THIS_MODULE, |
103 | .write = hfi1_file_write, | ||
104 | .write_iter = hfi1_write_iter, | 102 | .write_iter = hfi1_write_iter, |
105 | .open = hfi1_file_open, | 103 | .open = hfi1_file_open, |
106 | .release = hfi1_file_close, | 104 | .release = hfi1_file_close, |
105 | .unlocked_ioctl = hfi1_file_ioctl, | ||
107 | .poll = hfi1_poll, | 106 | .poll = hfi1_poll, |
108 | .mmap = hfi1_file_mmap, | 107 | .mmap = hfi1_file_mmap, |
109 | .llseek = noop_llseek, | 108 | .llseek = noop_llseek, |
@@ -169,6 +168,13 @@ static inline int is_valid_mmap(u64 token) | |||
169 | 168 | ||
170 | static int hfi1_file_open(struct inode *inode, struct file *fp) | 169 | static int hfi1_file_open(struct inode *inode, struct file *fp) |
171 | { | 170 | { |
171 | struct hfi1_devdata *dd = container_of(inode->i_cdev, | ||
172 | struct hfi1_devdata, | ||
173 | user_cdev); | ||
174 | |||
175 | /* Just take a ref now. Not all opens result in a context assign */ | ||
176 | kobject_get(&dd->kobj); | ||
177 | |||
172 | /* The real work is performed later in assign_ctxt() */ | 178 | /* The real work is performed later in assign_ctxt() */ |
173 | fp->private_data = kzalloc(sizeof(struct hfi1_filedata), GFP_KERNEL); | 179 | fp->private_data = kzalloc(sizeof(struct hfi1_filedata), GFP_KERNEL); |
174 | if (fp->private_data) /* no cpu affinity by default */ | 180 | if (fp->private_data) /* no cpu affinity by default */ |
@@ -176,127 +182,59 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) | |||
176 | return fp->private_data ? 0 : -ENOMEM; | 182 | return fp->private_data ? 0 : -ENOMEM; |
177 | } | 183 | } |
178 | 184 | ||
179 | static ssize_t hfi1_file_write(struct file *fp, const char __user *data, | 185 | static long hfi1_file_ioctl(struct file *fp, unsigned int cmd, |
180 | size_t count, loff_t *offset) | 186 | unsigned long arg) |
181 | { | 187 | { |
182 | const struct hfi1_cmd __user *ucmd; | ||
183 | struct hfi1_filedata *fd = fp->private_data; | 188 | struct hfi1_filedata *fd = fp->private_data; |
184 | struct hfi1_ctxtdata *uctxt = fd->uctxt; | 189 | struct hfi1_ctxtdata *uctxt = fd->uctxt; |
185 | struct hfi1_cmd cmd; | ||
186 | struct hfi1_user_info uinfo; | 190 | struct hfi1_user_info uinfo; |
187 | struct hfi1_tid_info tinfo; | 191 | struct hfi1_tid_info tinfo; |
192 | int ret = 0; | ||
188 | unsigned long addr; | 193 | unsigned long addr; |
189 | ssize_t consumed = 0, copy = 0, ret = 0; | 194 | int uval = 0; |
190 | void *dest = NULL; | 195 | unsigned long ul_uval = 0; |
191 | __u64 user_val = 0; | 196 | u16 uval16 = 0; |
192 | int uctxt_required = 1; | 197 | |
193 | int must_be_root = 0; | 198 | hfi1_cdbg(IOCTL, "IOCTL recv: 0x%x", cmd); |
194 | 199 | if (cmd != HFI1_IOCTL_ASSIGN_CTXT && | |
195 | /* FIXME: This interface cannot continue out of staging */ | 200 | cmd != HFI1_IOCTL_GET_VERS && |
196 | if (WARN_ON_ONCE(!ib_safe_file_access(fp))) | 201 | !uctxt) |
197 | return -EACCES; | 202 | return -EINVAL; |
198 | |||
199 | if (count < sizeof(cmd)) { | ||
200 | ret = -EINVAL; | ||
201 | goto bail; | ||
202 | } | ||
203 | |||
204 | ucmd = (const struct hfi1_cmd __user *)data; | ||
205 | if (copy_from_user(&cmd, ucmd, sizeof(cmd))) { | ||
206 | ret = -EFAULT; | ||
207 | goto bail; | ||
208 | } | ||
209 | |||
210 | consumed = sizeof(cmd); | ||
211 | |||
212 | switch (cmd.type) { | ||
213 | case HFI1_CMD_ASSIGN_CTXT: | ||
214 | uctxt_required = 0; /* assigned user context not required */ | ||
215 | copy = sizeof(uinfo); | ||
216 | dest = &uinfo; | ||
217 | break; | ||
218 | case HFI1_CMD_SDMA_STATUS_UPD: | ||
219 | case HFI1_CMD_CREDIT_UPD: | ||
220 | copy = 0; | ||
221 | break; | ||
222 | case HFI1_CMD_TID_UPDATE: | ||
223 | case HFI1_CMD_TID_FREE: | ||
224 | case HFI1_CMD_TID_INVAL_READ: | ||
225 | copy = sizeof(tinfo); | ||
226 | dest = &tinfo; | ||
227 | break; | ||
228 | case HFI1_CMD_USER_INFO: | ||
229 | case HFI1_CMD_RECV_CTRL: | ||
230 | case HFI1_CMD_POLL_TYPE: | ||
231 | case HFI1_CMD_ACK_EVENT: | ||
232 | case HFI1_CMD_CTXT_INFO: | ||
233 | case HFI1_CMD_SET_PKEY: | ||
234 | case HFI1_CMD_CTXT_RESET: | ||
235 | copy = 0; | ||
236 | user_val = cmd.addr; | ||
237 | break; | ||
238 | case HFI1_CMD_EP_INFO: | ||
239 | case HFI1_CMD_EP_ERASE_CHIP: | ||
240 | case HFI1_CMD_EP_ERASE_RANGE: | ||
241 | case HFI1_CMD_EP_READ_RANGE: | ||
242 | case HFI1_CMD_EP_WRITE_RANGE: | ||
243 | uctxt_required = 0; /* assigned user context not required */ | ||
244 | must_be_root = 1; /* validate user */ | ||
245 | copy = 0; | ||
246 | break; | ||
247 | default: | ||
248 | ret = -EINVAL; | ||
249 | goto bail; | ||
250 | } | ||
251 | |||
252 | /* If the command comes with user data, copy it. */ | ||
253 | if (copy) { | ||
254 | if (copy_from_user(dest, (void __user *)cmd.addr, copy)) { | ||
255 | ret = -EFAULT; | ||
256 | goto bail; | ||
257 | } | ||
258 | consumed += copy; | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * Make sure there is a uctxt when needed. | ||
263 | */ | ||
264 | if (uctxt_required && !uctxt) { | ||
265 | ret = -EINVAL; | ||
266 | goto bail; | ||
267 | } | ||
268 | 203 | ||
269 | /* only root can do these operations */ | 204 | switch (cmd) { |
270 | if (must_be_root && !capable(CAP_SYS_ADMIN)) { | 205 | case HFI1_IOCTL_ASSIGN_CTXT: |
271 | ret = -EPERM; | 206 | if (copy_from_user(&uinfo, |
272 | goto bail; | 207 | (struct hfi1_user_info __user *)arg, |
273 | } | 208 | sizeof(uinfo))) |
209 | return -EFAULT; | ||
274 | 210 | ||
275 | switch (cmd.type) { | ||
276 | case HFI1_CMD_ASSIGN_CTXT: | ||
277 | ret = assign_ctxt(fp, &uinfo); | 211 | ret = assign_ctxt(fp, &uinfo); |
278 | if (ret < 0) | 212 | if (ret < 0) |
279 | goto bail; | 213 | return ret; |
280 | ret = setup_ctxt(fp); | 214 | setup_ctxt(fp); |
281 | if (ret) | 215 | if (ret) |
282 | goto bail; | 216 | return ret; |
283 | ret = user_init(fp); | 217 | ret = user_init(fp); |
284 | break; | 218 | break; |
285 | case HFI1_CMD_CTXT_INFO: | 219 | case HFI1_IOCTL_CTXT_INFO: |
286 | ret = get_ctxt_info(fp, (void __user *)(unsigned long) | 220 | ret = get_ctxt_info(fp, (void __user *)(unsigned long)arg, |
287 | user_val, cmd.len); | 221 | sizeof(struct hfi1_ctxt_info)); |
288 | break; | ||
289 | case HFI1_CMD_USER_INFO: | ||
290 | ret = get_base_info(fp, (void __user *)(unsigned long) | ||
291 | user_val, cmd.len); | ||
292 | break; | 222 | break; |
293 | case HFI1_CMD_SDMA_STATUS_UPD: | 223 | case HFI1_IOCTL_USER_INFO: |
224 | ret = get_base_info(fp, (void __user *)(unsigned long)arg, | ||
225 | sizeof(struct hfi1_base_info)); | ||
294 | break; | 226 | break; |
295 | case HFI1_CMD_CREDIT_UPD: | 227 | case HFI1_IOCTL_CREDIT_UPD: |
296 | if (uctxt && uctxt->sc) | 228 | if (uctxt && uctxt->sc) |
297 | sc_return_credits(uctxt->sc); | 229 | sc_return_credits(uctxt->sc); |
298 | break; | 230 | break; |
299 | case HFI1_CMD_TID_UPDATE: | 231 | |
232 | case HFI1_IOCTL_TID_UPDATE: | ||
233 | if (copy_from_user(&tinfo, | ||
234 | (struct hfi11_tid_info __user *)arg, | ||
235 | sizeof(tinfo))) | ||
236 | return -EFAULT; | ||
237 | |||
300 | ret = hfi1_user_exp_rcv_setup(fp, &tinfo); | 238 | ret = hfi1_user_exp_rcv_setup(fp, &tinfo); |
301 | if (!ret) { | 239 | if (!ret) { |
302 | /* | 240 | /* |
@@ -305,57 +243,82 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, | |||
305 | * These fields are adjacent in the structure so | 243 | * These fields are adjacent in the structure so |
306 | * we can copy them at the same time. | 244 | * we can copy them at the same time. |
307 | */ | 245 | */ |
308 | addr = (unsigned long)cmd.addr + | 246 | addr = arg + offsetof(struct hfi1_tid_info, tidcnt); |
309 | offsetof(struct hfi1_tid_info, tidcnt); | ||
310 | if (copy_to_user((void __user *)addr, &tinfo.tidcnt, | 247 | if (copy_to_user((void __user *)addr, &tinfo.tidcnt, |
311 | sizeof(tinfo.tidcnt) + | 248 | sizeof(tinfo.tidcnt) + |
312 | sizeof(tinfo.length))) | 249 | sizeof(tinfo.length))) |
313 | ret = -EFAULT; | 250 | ret = -EFAULT; |
314 | } | 251 | } |
315 | break; | 252 | break; |
316 | case HFI1_CMD_TID_INVAL_READ: | 253 | |
317 | ret = hfi1_user_exp_rcv_invalid(fp, &tinfo); | 254 | case HFI1_IOCTL_TID_FREE: |
255 | if (copy_from_user(&tinfo, | ||
256 | (struct hfi11_tid_info __user *)arg, | ||
257 | sizeof(tinfo))) | ||
258 | return -EFAULT; | ||
259 | |||
260 | ret = hfi1_user_exp_rcv_clear(fp, &tinfo); | ||
318 | if (ret) | 261 | if (ret) |
319 | break; | 262 | break; |
320 | addr = (unsigned long)cmd.addr + | 263 | addr = arg + offsetof(struct hfi1_tid_info, tidcnt); |
321 | offsetof(struct hfi1_tid_info, tidcnt); | ||
322 | if (copy_to_user((void __user *)addr, &tinfo.tidcnt, | 264 | if (copy_to_user((void __user *)addr, &tinfo.tidcnt, |
323 | sizeof(tinfo.tidcnt))) | 265 | sizeof(tinfo.tidcnt))) |
324 | ret = -EFAULT; | 266 | ret = -EFAULT; |
325 | break; | 267 | break; |
326 | case HFI1_CMD_TID_FREE: | 268 | |
327 | ret = hfi1_user_exp_rcv_clear(fp, &tinfo); | 269 | case HFI1_IOCTL_TID_INVAL_READ: |
270 | if (copy_from_user(&tinfo, | ||
271 | (struct hfi11_tid_info __user *)arg, | ||
272 | sizeof(tinfo))) | ||
273 | return -EFAULT; | ||
274 | |||
275 | ret = hfi1_user_exp_rcv_invalid(fp, &tinfo); | ||
328 | if (ret) | 276 | if (ret) |
329 | break; | 277 | break; |
330 | addr = (unsigned long)cmd.addr + | 278 | addr = arg + offsetof(struct hfi1_tid_info, tidcnt); |
331 | offsetof(struct hfi1_tid_info, tidcnt); | ||
332 | if (copy_to_user((void __user *)addr, &tinfo.tidcnt, | 279 | if (copy_to_user((void __user *)addr, &tinfo.tidcnt, |
333 | sizeof(tinfo.tidcnt))) | 280 | sizeof(tinfo.tidcnt))) |
334 | ret = -EFAULT; | 281 | ret = -EFAULT; |
335 | break; | 282 | break; |
336 | case HFI1_CMD_RECV_CTRL: | 283 | |
337 | ret = manage_rcvq(uctxt, fd->subctxt, (int)user_val); | 284 | case HFI1_IOCTL_RECV_CTRL: |
285 | ret = get_user(uval, (int __user *)arg); | ||
286 | if (ret != 0) | ||
287 | return -EFAULT; | ||
288 | ret = manage_rcvq(uctxt, fd->subctxt, uval); | ||
338 | break; | 289 | break; |
339 | case HFI1_CMD_POLL_TYPE: | 290 | |
340 | uctxt->poll_type = (typeof(uctxt->poll_type))user_val; | 291 | case HFI1_IOCTL_POLL_TYPE: |
292 | ret = get_user(uval, (int __user *)arg); | ||
293 | if (ret != 0) | ||
294 | return -EFAULT; | ||
295 | uctxt->poll_type = (typeof(uctxt->poll_type))uval; | ||
341 | break; | 296 | break; |
342 | case HFI1_CMD_ACK_EVENT: | 297 | |
343 | ret = user_event_ack(uctxt, fd->subctxt, user_val); | 298 | case HFI1_IOCTL_ACK_EVENT: |
299 | ret = get_user(ul_uval, (unsigned long __user *)arg); | ||
300 | if (ret != 0) | ||
301 | return -EFAULT; | ||
302 | ret = user_event_ack(uctxt, fd->subctxt, ul_uval); | ||
344 | break; | 303 | break; |
345 | case HFI1_CMD_SET_PKEY: | 304 | |
305 | case HFI1_IOCTL_SET_PKEY: | ||
306 | ret = get_user(uval16, (u16 __user *)arg); | ||
307 | if (ret != 0) | ||
308 | return -EFAULT; | ||
346 | if (HFI1_CAP_IS_USET(PKEY_CHECK)) | 309 | if (HFI1_CAP_IS_USET(PKEY_CHECK)) |
347 | ret = set_ctxt_pkey(uctxt, fd->subctxt, user_val); | 310 | ret = set_ctxt_pkey(uctxt, fd->subctxt, uval16); |
348 | else | 311 | else |
349 | ret = -EPERM; | 312 | return -EPERM; |
350 | break; | 313 | break; |
351 | case HFI1_CMD_CTXT_RESET: { | 314 | |
315 | case HFI1_IOCTL_CTXT_RESET: { | ||
352 | struct send_context *sc; | 316 | struct send_context *sc; |
353 | struct hfi1_devdata *dd; | 317 | struct hfi1_devdata *dd; |
354 | 318 | ||
355 | if (!uctxt || !uctxt->dd || !uctxt->sc) { | 319 | if (!uctxt || !uctxt->dd || !uctxt->sc) |
356 | ret = -EINVAL; | 320 | return -EINVAL; |
357 | break; | 321 | |
358 | } | ||
359 | /* | 322 | /* |
360 | * There is no protection here. User level has to | 323 | * There is no protection here. User level has to |
361 | * guarantee that no one will be writing to the send | 324 | * guarantee that no one will be writing to the send |
@@ -373,10 +336,9 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, | |||
373 | wait_event_interruptible_timeout( | 336 | wait_event_interruptible_timeout( |
374 | sc->halt_wait, (sc->flags & SCF_HALTED), | 337 | sc->halt_wait, (sc->flags & SCF_HALTED), |
375 | msecs_to_jiffies(SEND_CTXT_HALT_TIMEOUT)); | 338 | msecs_to_jiffies(SEND_CTXT_HALT_TIMEOUT)); |
376 | if (!(sc->flags & SCF_HALTED)) { | 339 | if (!(sc->flags & SCF_HALTED)) |
377 | ret = -ENOLCK; | 340 | return -ENOLCK; |
378 | break; | 341 | |
379 | } | ||
380 | /* | 342 | /* |
381 | * If the send context was halted due to a Freeze, | 343 | * If the send context was halted due to a Freeze, |
382 | * wait until the device has been "unfrozen" before | 344 | * wait until the device has been "unfrozen" before |
@@ -387,18 +349,16 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, | |||
387 | dd->event_queue, | 349 | dd->event_queue, |
388 | !(ACCESS_ONCE(dd->flags) & HFI1_FROZEN), | 350 | !(ACCESS_ONCE(dd->flags) & HFI1_FROZEN), |
389 | msecs_to_jiffies(SEND_CTXT_HALT_TIMEOUT)); | 351 | msecs_to_jiffies(SEND_CTXT_HALT_TIMEOUT)); |
390 | if (dd->flags & HFI1_FROZEN) { | 352 | if (dd->flags & HFI1_FROZEN) |
391 | ret = -ENOLCK; | 353 | return -ENOLCK; |
392 | break; | 354 | |
393 | } | 355 | if (dd->flags & HFI1_FORCED_FREEZE) |
394 | if (dd->flags & HFI1_FORCED_FREEZE) { | ||
395 | /* | 356 | /* |
396 | * Don't allow context reset if we are into | 357 | * Don't allow context reset if we are into |
397 | * forced freeze | 358 | * forced freeze |
398 | */ | 359 | */ |
399 | ret = -ENODEV; | 360 | return -ENODEV; |
400 | break; | 361 | |
401 | } | ||
402 | sc_disable(sc); | 362 | sc_disable(sc); |
403 | ret = sc_enable(sc); | 363 | ret = sc_enable(sc); |
404 | hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_ENB, | 364 | hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_ENB, |
@@ -410,18 +370,17 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data, | |||
410 | sc_return_credits(sc); | 370 | sc_return_credits(sc); |
411 | break; | 371 | break; |
412 | } | 372 | } |
413 | case HFI1_CMD_EP_INFO: | 373 | |
414 | case HFI1_CMD_EP_ERASE_CHIP: | 374 | case HFI1_IOCTL_GET_VERS: |
415 | case HFI1_CMD_EP_ERASE_RANGE: | 375 | uval = HFI1_USER_SWVERSION; |
416 | case HFI1_CMD_EP_READ_RANGE: | 376 | if (put_user(uval, (int __user *)arg)) |
417 | case HFI1_CMD_EP_WRITE_RANGE: | 377 | return -EFAULT; |
418 | ret = handle_eprom_command(fp, &cmd); | ||
419 | break; | 378 | break; |
379 | |||
380 | default: | ||
381 | return -EINVAL; | ||
420 | } | 382 | } |
421 | 383 | ||
422 | if (ret >= 0) | ||
423 | ret = consumed; | ||
424 | bail: | ||
425 | return ret; | 384 | return ret; |
426 | } | 385 | } |
427 | 386 | ||
@@ -738,7 +697,9 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) | |||
738 | { | 697 | { |
739 | struct hfi1_filedata *fdata = fp->private_data; | 698 | struct hfi1_filedata *fdata = fp->private_data; |
740 | struct hfi1_ctxtdata *uctxt = fdata->uctxt; | 699 | struct hfi1_ctxtdata *uctxt = fdata->uctxt; |
741 | struct hfi1_devdata *dd; | 700 | struct hfi1_devdata *dd = container_of(inode->i_cdev, |
701 | struct hfi1_devdata, | ||
702 | user_cdev); | ||
742 | unsigned long flags, *ev; | 703 | unsigned long flags, *ev; |
743 | 704 | ||
744 | fp->private_data = NULL; | 705 | fp->private_data = NULL; |
@@ -747,7 +708,6 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) | |||
747 | goto done; | 708 | goto done; |
748 | 709 | ||
749 | hfi1_cdbg(PROC, "freeing ctxt %u:%u", uctxt->ctxt, fdata->subctxt); | 710 | hfi1_cdbg(PROC, "freeing ctxt %u:%u", uctxt->ctxt, fdata->subctxt); |
750 | dd = uctxt->dd; | ||
751 | mutex_lock(&hfi1_mutex); | 711 | mutex_lock(&hfi1_mutex); |
752 | 712 | ||
753 | flush_wc(); | 713 | flush_wc(); |
@@ -813,6 +773,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) | |||
813 | mutex_unlock(&hfi1_mutex); | 773 | mutex_unlock(&hfi1_mutex); |
814 | hfi1_free_ctxtdata(dd, uctxt); | 774 | hfi1_free_ctxtdata(dd, uctxt); |
815 | done: | 775 | done: |
776 | kobject_put(&dd->kobj); | ||
816 | kfree(fdata); | 777 | kfree(fdata); |
817 | return 0; | 778 | return 0; |
818 | } | 779 | } |
@@ -836,7 +797,7 @@ static u64 kvirt_to_phys(void *addr) | |||
836 | static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo) | 797 | static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo) |
837 | { | 798 | { |
838 | int i_minor, ret = 0; | 799 | int i_minor, ret = 0; |
839 | unsigned swmajor, swminor, alg = HFI1_ALG_ACROSS; | 800 | unsigned int swmajor, swminor; |
840 | 801 | ||
841 | swmajor = uinfo->userversion >> 16; | 802 | swmajor = uinfo->userversion >> 16; |
842 | if (swmajor != HFI1_USER_SWMAJOR) { | 803 | if (swmajor != HFI1_USER_SWMAJOR) { |
@@ -846,9 +807,6 @@ static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo) | |||
846 | 807 | ||
847 | swminor = uinfo->userversion & 0xffff; | 808 | swminor = uinfo->userversion & 0xffff; |
848 | 809 | ||
849 | if (uinfo->hfi1_alg < HFI1_ALG_COUNT) | ||
850 | alg = uinfo->hfi1_alg; | ||
851 | |||
852 | mutex_lock(&hfi1_mutex); | 810 | mutex_lock(&hfi1_mutex); |
853 | /* First, lets check if we need to setup a shared context? */ | 811 | /* First, lets check if we need to setup a shared context? */ |
854 | if (uinfo->subctxt_cnt) { | 812 | if (uinfo->subctxt_cnt) { |
@@ -868,7 +826,7 @@ static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo) | |||
868 | */ | 826 | */ |
869 | if (!ret) { | 827 | if (!ret) { |
870 | i_minor = iminor(file_inode(fp)) - HFI1_USER_MINOR_BASE; | 828 | i_minor = iminor(file_inode(fp)) - HFI1_USER_MINOR_BASE; |
871 | ret = get_user_context(fp, uinfo, i_minor - 1, alg); | 829 | ret = get_user_context(fp, uinfo, i_minor); |
872 | } | 830 | } |
873 | done_unlock: | 831 | done_unlock: |
874 | mutex_unlock(&hfi1_mutex); | 832 | mutex_unlock(&hfi1_mutex); |
@@ -876,71 +834,26 @@ done: | |||
876 | return ret; | 834 | return ret; |
877 | } | 835 | } |
878 | 836 | ||
879 | /* return true if the device available for general use */ | ||
880 | static int usable_device(struct hfi1_devdata *dd) | ||
881 | { | ||
882 | struct hfi1_pportdata *ppd = dd->pport; | ||
883 | |||
884 | return driver_lstate(ppd) == IB_PORT_ACTIVE; | ||
885 | } | ||
886 | |||
887 | static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo, | 837 | static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo, |
888 | int devno, unsigned alg) | 838 | int devno) |
889 | { | 839 | { |
890 | struct hfi1_devdata *dd = NULL; | 840 | struct hfi1_devdata *dd = NULL; |
891 | int ret = 0, devmax, npresent, nup, dev; | 841 | int devmax, npresent, nup; |
892 | 842 | ||
893 | devmax = hfi1_count_units(&npresent, &nup); | 843 | devmax = hfi1_count_units(&npresent, &nup); |
894 | if (!npresent) { | 844 | if (!npresent) |
895 | ret = -ENXIO; | 845 | return -ENXIO; |
896 | goto done; | 846 | |
897 | } | 847 | if (!nup) |
898 | if (!nup) { | 848 | return -ENETDOWN; |
899 | ret = -ENETDOWN; | 849 | |
900 | goto done; | 850 | dd = hfi1_lookup(devno); |
901 | } | 851 | if (!dd) |
902 | if (devno >= 0) { | 852 | return -ENODEV; |
903 | dd = hfi1_lookup(devno); | 853 | else if (!dd->freectxts) |
904 | if (!dd) | 854 | return -EBUSY; |
905 | ret = -ENODEV; | 855 | |
906 | else if (!dd->freectxts) | 856 | return allocate_ctxt(fp, dd, uinfo); |
907 | ret = -EBUSY; | ||
908 | } else { | ||
909 | struct hfi1_devdata *pdd; | ||
910 | |||
911 | if (alg == HFI1_ALG_ACROSS) { | ||
912 | unsigned free = 0U; | ||
913 | |||
914 | for (dev = 0; dev < devmax; dev++) { | ||
915 | pdd = hfi1_lookup(dev); | ||
916 | if (!pdd) | ||
917 | continue; | ||
918 | if (!usable_device(pdd)) | ||
919 | continue; | ||
920 | if (pdd->freectxts && | ||
921 | pdd->freectxts > free) { | ||
922 | dd = pdd; | ||
923 | free = pdd->freectxts; | ||
924 | } | ||
925 | } | ||
926 | } else { | ||
927 | for (dev = 0; dev < devmax; dev++) { | ||
928 | pdd = hfi1_lookup(dev); | ||
929 | if (!pdd) | ||
930 | continue; | ||
931 | if (!usable_device(pdd)) | ||
932 | continue; | ||
933 | if (pdd->freectxts) { | ||
934 | dd = pdd; | ||
935 | break; | ||
936 | } | ||
937 | } | ||
938 | } | ||
939 | if (!dd) | ||
940 | ret = -EBUSY; | ||
941 | } | ||
942 | done: | ||
943 | return ret ? ret : allocate_ctxt(fp, dd, uinfo); | ||
944 | } | 857 | } |
945 | 858 | ||
946 | static int find_shared_ctxt(struct file *fp, | 859 | static int find_shared_ctxt(struct file *fp, |
@@ -1546,170 +1459,10 @@ done: | |||
1546 | return ret; | 1459 | return ret; |
1547 | } | 1460 | } |
1548 | 1461 | ||
1549 | static int ui_open(struct inode *inode, struct file *filp) | ||
1550 | { | ||
1551 | struct hfi1_devdata *dd; | ||
1552 | |||
1553 | dd = container_of(inode->i_cdev, struct hfi1_devdata, ui_cdev); | ||
1554 | filp->private_data = dd; /* for other methods */ | ||
1555 | return 0; | ||
1556 | } | ||
1557 | |||
1558 | static int ui_release(struct inode *inode, struct file *filp) | ||
1559 | { | ||
1560 | /* nothing to do */ | ||
1561 | return 0; | ||
1562 | } | ||
1563 | |||
1564 | static loff_t ui_lseek(struct file *filp, loff_t offset, int whence) | ||
1565 | { | ||
1566 | struct hfi1_devdata *dd = filp->private_data; | ||
1567 | |||
1568 | return fixed_size_llseek(filp, offset, whence, | ||
1569 | (dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE); | ||
1570 | } | ||
1571 | |||
1572 | /* NOTE: assumes unsigned long is 8 bytes */ | ||
1573 | static ssize_t ui_read(struct file *filp, char __user *buf, size_t count, | ||
1574 | loff_t *f_pos) | ||
1575 | { | ||
1576 | struct hfi1_devdata *dd = filp->private_data; | ||
1577 | void __iomem *base = dd->kregbase; | ||
1578 | unsigned long total, csr_off, | ||
1579 | barlen = (dd->kregend - dd->kregbase); | ||
1580 | u64 data; | ||
1581 | |||
1582 | /* only read 8 byte quantities */ | ||
1583 | if ((count % 8) != 0) | ||
1584 | return -EINVAL; | ||
1585 | /* offset must be 8-byte aligned */ | ||
1586 | if ((*f_pos % 8) != 0) | ||
1587 | return -EINVAL; | ||
1588 | /* destination buffer must be 8-byte aligned */ | ||
1589 | if ((unsigned long)buf % 8 != 0) | ||
1590 | return -EINVAL; | ||
1591 | /* must be in range */ | ||
1592 | if (*f_pos + count > (barlen + DC8051_DATA_MEM_SIZE)) | ||
1593 | return -EINVAL; | ||
1594 | /* only set the base if we are not starting past the BAR */ | ||
1595 | if (*f_pos < barlen) | ||
1596 | base += *f_pos; | ||
1597 | csr_off = *f_pos; | ||
1598 | for (total = 0; total < count; total += 8, csr_off += 8) { | ||
1599 | /* accessing LCB CSRs requires more checks */ | ||
1600 | if (is_lcb_offset(csr_off)) { | ||
1601 | if (read_lcb_csr(dd, csr_off, (u64 *)&data)) | ||
1602 | break; /* failed */ | ||
1603 | } | ||
1604 | /* | ||
1605 | * Cannot read ASIC GPIO/QSFP* clear and force CSRs without a | ||
1606 | * false parity error. Avoid the whole issue by not reading | ||
1607 | * them. These registers are defined as having a read value | ||
1608 | * of 0. | ||
1609 | */ | ||
1610 | else if (csr_off == ASIC_GPIO_CLEAR || | ||
1611 | csr_off == ASIC_GPIO_FORCE || | ||
1612 | csr_off == ASIC_QSFP1_CLEAR || | ||
1613 | csr_off == ASIC_QSFP1_FORCE || | ||
1614 | csr_off == ASIC_QSFP2_CLEAR || | ||
1615 | csr_off == ASIC_QSFP2_FORCE) | ||
1616 | data = 0; | ||
1617 | else if (csr_off >= barlen) { | ||
1618 | /* | ||
1619 | * read_8051_data can read more than just 8 bytes at | ||
1620 | * a time. However, folding this into the loop and | ||
1621 | * handling the reads in 8 byte increments allows us | ||
1622 | * to smoothly transition from chip memory to 8051 | ||
1623 | * memory. | ||
1624 | */ | ||
1625 | if (read_8051_data(dd, | ||
1626 | (u32)(csr_off - barlen), | ||
1627 | sizeof(data), &data)) | ||
1628 | break; /* failed */ | ||
1629 | } else | ||
1630 | data = readq(base + total); | ||
1631 | if (put_user(data, (unsigned long __user *)(buf + total))) | ||
1632 | break; | ||
1633 | } | ||
1634 | *f_pos += total; | ||
1635 | return total; | ||
1636 | } | ||
1637 | |||
1638 | /* NOTE: assumes unsigned long is 8 bytes */ | ||
1639 | static ssize_t ui_write(struct file *filp, const char __user *buf, | ||
1640 | size_t count, loff_t *f_pos) | ||
1641 | { | ||
1642 | struct hfi1_devdata *dd = filp->private_data; | ||
1643 | void __iomem *base; | ||
1644 | unsigned long total, data, csr_off; | ||
1645 | int in_lcb; | ||
1646 | |||
1647 | /* only write 8 byte quantities */ | ||
1648 | if ((count % 8) != 0) | ||
1649 | return -EINVAL; | ||
1650 | /* offset must be 8-byte aligned */ | ||
1651 | if ((*f_pos % 8) != 0) | ||
1652 | return -EINVAL; | ||
1653 | /* source buffer must be 8-byte aligned */ | ||
1654 | if ((unsigned long)buf % 8 != 0) | ||
1655 | return -EINVAL; | ||
1656 | /* must be in range */ | ||
1657 | if (*f_pos + count > dd->kregend - dd->kregbase) | ||
1658 | return -EINVAL; | ||
1659 | |||
1660 | base = (void __iomem *)dd->kregbase + *f_pos; | ||
1661 | csr_off = *f_pos; | ||
1662 | in_lcb = 0; | ||
1663 | for (total = 0; total < count; total += 8, csr_off += 8) { | ||
1664 | if (get_user(data, (unsigned long __user *)(buf + total))) | ||
1665 | break; | ||
1666 | /* accessing LCB CSRs requires a special procedure */ | ||
1667 | if (is_lcb_offset(csr_off)) { | ||
1668 | if (!in_lcb) { | ||
1669 | int ret = acquire_lcb_access(dd, 1); | ||
1670 | |||
1671 | if (ret) | ||
1672 | break; | ||
1673 | in_lcb = 1; | ||
1674 | } | ||
1675 | } else { | ||
1676 | if (in_lcb) { | ||
1677 | release_lcb_access(dd, 1); | ||
1678 | in_lcb = 0; | ||
1679 | } | ||
1680 | } | ||
1681 | writeq(data, base + total); | ||
1682 | } | ||
1683 | if (in_lcb) | ||
1684 | release_lcb_access(dd, 1); | ||
1685 | *f_pos += total; | ||
1686 | return total; | ||
1687 | } | ||
1688 | |||
1689 | static const struct file_operations ui_file_ops = { | ||
1690 | .owner = THIS_MODULE, | ||
1691 | .llseek = ui_lseek, | ||
1692 | .read = ui_read, | ||
1693 | .write = ui_write, | ||
1694 | .open = ui_open, | ||
1695 | .release = ui_release, | ||
1696 | }; | ||
1697 | |||
1698 | #define UI_OFFSET 192 /* device minor offset for UI devices */ | ||
1699 | static int create_ui = 1; | ||
1700 | |||
1701 | static struct cdev wildcard_cdev; | ||
1702 | static struct device *wildcard_device; | ||
1703 | |||
1704 | static atomic_t user_count = ATOMIC_INIT(0); | ||
1705 | |||
1706 | static void user_remove(struct hfi1_devdata *dd) | 1462 | static void user_remove(struct hfi1_devdata *dd) |
1707 | { | 1463 | { |
1708 | if (atomic_dec_return(&user_count) == 0) | ||
1709 | hfi1_cdev_cleanup(&wildcard_cdev, &wildcard_device); | ||
1710 | 1464 | ||
1711 | hfi1_cdev_cleanup(&dd->user_cdev, &dd->user_device); | 1465 | hfi1_cdev_cleanup(&dd->user_cdev, &dd->user_device); |
1712 | hfi1_cdev_cleanup(&dd->ui_cdev, &dd->ui_device); | ||
1713 | } | 1466 | } |
1714 | 1467 | ||
1715 | static int user_add(struct hfi1_devdata *dd) | 1468 | static int user_add(struct hfi1_devdata *dd) |
@@ -1717,34 +1470,13 @@ static int user_add(struct hfi1_devdata *dd) | |||
1717 | char name[10]; | 1470 | char name[10]; |
1718 | int ret; | 1471 | int ret; |
1719 | 1472 | ||
1720 | if (atomic_inc_return(&user_count) == 1) { | ||
1721 | ret = hfi1_cdev_init(0, class_name(), &hfi1_file_ops, | ||
1722 | &wildcard_cdev, &wildcard_device, | ||
1723 | true); | ||
1724 | if (ret) | ||
1725 | goto done; | ||
1726 | } | ||
1727 | |||
1728 | snprintf(name, sizeof(name), "%s_%d", class_name(), dd->unit); | 1473 | snprintf(name, sizeof(name), "%s_%d", class_name(), dd->unit); |
1729 | ret = hfi1_cdev_init(dd->unit + 1, name, &hfi1_file_ops, | 1474 | ret = hfi1_cdev_init(dd->unit, name, &hfi1_file_ops, |
1730 | &dd->user_cdev, &dd->user_device, | 1475 | &dd->user_cdev, &dd->user_device, |
1731 | true); | 1476 | true, &dd->kobj); |
1732 | if (ret) | 1477 | if (ret) |
1733 | goto done; | 1478 | user_remove(dd); |
1734 | 1479 | ||
1735 | if (create_ui) { | ||
1736 | snprintf(name, sizeof(name), | ||
1737 | "%s_ui%d", class_name(), dd->unit); | ||
1738 | ret = hfi1_cdev_init(dd->unit + UI_OFFSET, name, &ui_file_ops, | ||
1739 | &dd->ui_cdev, &dd->ui_device, | ||
1740 | false); | ||
1741 | if (ret) | ||
1742 | goto done; | ||
1743 | } | ||
1744 | |||
1745 | return 0; | ||
1746 | done: | ||
1747 | user_remove(dd); | ||
1748 | return ret; | 1480 | return ret; |
1749 | } | 1481 | } |
1750 | 1482 | ||
@@ -1753,13 +1485,7 @@ done: | |||
1753 | */ | 1485 | */ |
1754 | int hfi1_device_create(struct hfi1_devdata *dd) | 1486 | int hfi1_device_create(struct hfi1_devdata *dd) |
1755 | { | 1487 | { |
1756 | int r, ret; | 1488 | return user_add(dd); |
1757 | |||
1758 | r = user_add(dd); | ||
1759 | ret = hfi1_diag_add(dd); | ||
1760 | if (r && !ret) | ||
1761 | ret = r; | ||
1762 | return ret; | ||
1763 | } | 1489 | } |
1764 | 1490 | ||
1765 | /* | 1491 | /* |
@@ -1769,5 +1495,4 @@ int hfi1_device_create(struct hfi1_devdata *dd) | |||
1769 | void hfi1_device_remove(struct hfi1_devdata *dd) | 1495 | void hfi1_device_remove(struct hfi1_devdata *dd) |
1770 | { | 1496 | { |
1771 | user_remove(dd); | 1497 | user_remove(dd); |
1772 | hfi1_diag_remove(dd); | ||
1773 | } | 1498 | } |
diff --git a/drivers/staging/rdma/hfi1/firmware.c b/drivers/infiniband/hw/hfi1/firmware.c index ed680fda611d..ed680fda611d 100644 --- a/drivers/staging/rdma/hfi1/firmware.c +++ b/drivers/infiniband/hw/hfi1/firmware.c | |||
diff --git a/drivers/staging/rdma/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 7b78d56de7f5..4417a0fd3ef9 100644 --- a/drivers/staging/rdma/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h | |||
@@ -453,6 +453,7 @@ struct rvt_sge_state; | |||
453 | #define HLS_LINK_COOLDOWN BIT(__HLS_LINK_COOLDOWN_BP) | 453 | #define HLS_LINK_COOLDOWN BIT(__HLS_LINK_COOLDOWN_BP) |
454 | 454 | ||
455 | #define HLS_UP (HLS_UP_INIT | HLS_UP_ARMED | HLS_UP_ACTIVE) | 455 | #define HLS_UP (HLS_UP_INIT | HLS_UP_ARMED | HLS_UP_ACTIVE) |
456 | #define HLS_DOWN ~(HLS_UP) | ||
456 | 457 | ||
457 | /* use this MTU size if none other is given */ | 458 | /* use this MTU size if none other is given */ |
458 | #define HFI1_DEFAULT_ACTIVE_MTU 10240 | 459 | #define HFI1_DEFAULT_ACTIVE_MTU 10240 |
@@ -1168,6 +1169,7 @@ struct hfi1_devdata { | |||
1168 | atomic_t aspm_disabled_cnt; | 1169 | atomic_t aspm_disabled_cnt; |
1169 | 1170 | ||
1170 | struct hfi1_affinity *affinity; | 1171 | struct hfi1_affinity *affinity; |
1172 | struct kobject kobj; | ||
1171 | }; | 1173 | }; |
1172 | 1174 | ||
1173 | /* 8051 firmware version helper */ | 1175 | /* 8051 firmware version helper */ |
@@ -1882,9 +1884,8 @@ static inline u64 hfi1_pkt_base_sdma_integrity(struct hfi1_devdata *dd) | |||
1882 | get_unit_name((dd)->unit), ##__VA_ARGS__) | 1884 | get_unit_name((dd)->unit), ##__VA_ARGS__) |
1883 | 1885 | ||
1884 | #define hfi1_dev_porterr(dd, port, fmt, ...) \ | 1886 | #define hfi1_dev_porterr(dd, port, fmt, ...) \ |
1885 | dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \ | 1887 | dev_err(&(dd)->pcidev->dev, "%s: port %u: " fmt, \ |
1886 | get_unit_name((dd)->unit), (dd)->unit, (port), \ | 1888 | get_unit_name((dd)->unit), (port), ##__VA_ARGS__) |
1887 | ##__VA_ARGS__) | ||
1888 | 1889 | ||
1889 | /* | 1890 | /* |
1890 | * this is used for formatting hw error messages... | 1891 | * this is used for formatting hw error messages... |
diff --git a/drivers/staging/rdma/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index 502b7cf4647d..5cc492e5776d 100644 --- a/drivers/staging/rdma/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c | |||
@@ -732,12 +732,12 @@ int hfi1_init(struct hfi1_devdata *dd, int reinit) | |||
732 | lastfail = hfi1_create_rcvhdrq(dd, rcd); | 732 | lastfail = hfi1_create_rcvhdrq(dd, rcd); |
733 | if (!lastfail) | 733 | if (!lastfail) |
734 | lastfail = hfi1_setup_eagerbufs(rcd); | 734 | lastfail = hfi1_setup_eagerbufs(rcd); |
735 | if (lastfail) | 735 | if (lastfail) { |
736 | dd_dev_err(dd, | 736 | dd_dev_err(dd, |
737 | "failed to allocate kernel ctxt's rcvhdrq and/or egr bufs\n"); | 737 | "failed to allocate kernel ctxt's rcvhdrq and/or egr bufs\n"); |
738 | ret = lastfail; | ||
739 | } | ||
738 | } | 740 | } |
739 | if (lastfail) | ||
740 | ret = lastfail; | ||
741 | 741 | ||
742 | /* Allocate enough memory for user event notification. */ | 742 | /* Allocate enough memory for user event notification. */ |
743 | len = PAGE_ALIGN(dd->chip_rcv_contexts * HFI1_MAX_SHARED_CTXTS * | 743 | len = PAGE_ALIGN(dd->chip_rcv_contexts * HFI1_MAX_SHARED_CTXTS * |
@@ -989,8 +989,10 @@ static void release_asic_data(struct hfi1_devdata *dd) | |||
989 | dd->asic_data = NULL; | 989 | dd->asic_data = NULL; |
990 | } | 990 | } |
991 | 991 | ||
992 | void hfi1_free_devdata(struct hfi1_devdata *dd) | 992 | static void __hfi1_free_devdata(struct kobject *kobj) |
993 | { | 993 | { |
994 | struct hfi1_devdata *dd = | ||
995 | container_of(kobj, struct hfi1_devdata, kobj); | ||
994 | unsigned long flags; | 996 | unsigned long flags; |
995 | 997 | ||
996 | spin_lock_irqsave(&hfi1_devs_lock, flags); | 998 | spin_lock_irqsave(&hfi1_devs_lock, flags); |
@@ -1007,6 +1009,15 @@ void hfi1_free_devdata(struct hfi1_devdata *dd) | |||
1007 | rvt_dealloc_device(&dd->verbs_dev.rdi); | 1009 | rvt_dealloc_device(&dd->verbs_dev.rdi); |
1008 | } | 1010 | } |
1009 | 1011 | ||
1012 | static struct kobj_type hfi1_devdata_type = { | ||
1013 | .release = __hfi1_free_devdata, | ||
1014 | }; | ||
1015 | |||
1016 | void hfi1_free_devdata(struct hfi1_devdata *dd) | ||
1017 | { | ||
1018 | kobject_put(&dd->kobj); | ||
1019 | } | ||
1020 | |||
1010 | /* | 1021 | /* |
1011 | * Allocate our primary per-unit data structure. Must be done via verbs | 1022 | * Allocate our primary per-unit data structure. Must be done via verbs |
1012 | * allocator, because the verbs cleanup process both does cleanup and | 1023 | * allocator, because the verbs cleanup process both does cleanup and |
@@ -1102,6 +1113,7 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra) | |||
1102 | &pdev->dev, | 1113 | &pdev->dev, |
1103 | "Could not alloc cpulist info, cpu affinity might be wrong\n"); | 1114 | "Could not alloc cpulist info, cpu affinity might be wrong\n"); |
1104 | } | 1115 | } |
1116 | kobject_init(&dd->kobj, &hfi1_devdata_type); | ||
1105 | return dd; | 1117 | return dd; |
1106 | 1118 | ||
1107 | bail: | 1119 | bail: |
@@ -1300,7 +1312,7 @@ static void cleanup_device_data(struct hfi1_devdata *dd) | |||
1300 | 1312 | ||
1301 | spin_lock(&ppd->cc_state_lock); | 1313 | spin_lock(&ppd->cc_state_lock); |
1302 | cc_state = get_cc_state(ppd); | 1314 | cc_state = get_cc_state(ppd); |
1303 | rcu_assign_pointer(ppd->cc_state, NULL); | 1315 | RCU_INIT_POINTER(ppd->cc_state, NULL); |
1304 | spin_unlock(&ppd->cc_state_lock); | 1316 | spin_unlock(&ppd->cc_state_lock); |
1305 | 1317 | ||
1306 | if (cc_state) | 1318 | if (cc_state) |
diff --git a/drivers/staging/rdma/hfi1/intr.c b/drivers/infiniband/hw/hfi1/intr.c index 65348d16ab2f..65348d16ab2f 100644 --- a/drivers/staging/rdma/hfi1/intr.c +++ b/drivers/infiniband/hw/hfi1/intr.c | |||
diff --git a/drivers/staging/rdma/hfi1/iowait.h b/drivers/infiniband/hw/hfi1/iowait.h index 2ec6ef38d389..2ec6ef38d389 100644 --- a/drivers/staging/rdma/hfi1/iowait.h +++ b/drivers/infiniband/hw/hfi1/iowait.h | |||
diff --git a/drivers/staging/rdma/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c index ed58cf21e790..219029576ba0 100644 --- a/drivers/staging/rdma/hfi1/mad.c +++ b/drivers/infiniband/hw/hfi1/mad.c | |||
@@ -1403,6 +1403,12 @@ static int set_pkeys(struct hfi1_devdata *dd, u8 port, u16 *pkeys) | |||
1403 | if (key == okey) | 1403 | if (key == okey) |
1404 | continue; | 1404 | continue; |
1405 | /* | 1405 | /* |
1406 | * Don't update pkeys[2], if an HFI port without MgmtAllowed | ||
1407 | * by neighbor is a switch. | ||
1408 | */ | ||
1409 | if (i == 2 && !ppd->mgmt_allowed && ppd->neighbor_type == 1) | ||
1410 | continue; | ||
1411 | /* | ||
1406 | * The SM gives us the complete PKey table. We have | 1412 | * The SM gives us the complete PKey table. We have |
1407 | * to ensure that we put the PKeys in the matching | 1413 | * to ensure that we put the PKeys in the matching |
1408 | * slots. | 1414 | * slots. |
@@ -3363,6 +3369,50 @@ static int __subn_get_opa_cong_setting(struct opa_smp *smp, u32 am, | |||
3363 | return reply((struct ib_mad_hdr *)smp); | 3369 | return reply((struct ib_mad_hdr *)smp); |
3364 | } | 3370 | } |
3365 | 3371 | ||
3372 | /* | ||
3373 | * Apply congestion control information stored in the ppd to the | ||
3374 | * active structure. | ||
3375 | */ | ||
3376 | static void apply_cc_state(struct hfi1_pportdata *ppd) | ||
3377 | { | ||
3378 | struct cc_state *old_cc_state, *new_cc_state; | ||
3379 | |||
3380 | new_cc_state = kzalloc(sizeof(*new_cc_state), GFP_KERNEL); | ||
3381 | if (!new_cc_state) | ||
3382 | return; | ||
3383 | |||
3384 | /* | ||
3385 | * Hold the lock for updating *and* to prevent ppd information | ||
3386 | * from changing during the update. | ||
3387 | */ | ||
3388 | spin_lock(&ppd->cc_state_lock); | ||
3389 | |||
3390 | old_cc_state = get_cc_state(ppd); | ||
3391 | if (!old_cc_state) { | ||
3392 | /* never active, or shutting down */ | ||
3393 | spin_unlock(&ppd->cc_state_lock); | ||
3394 | kfree(new_cc_state); | ||
3395 | return; | ||
3396 | } | ||
3397 | |||
3398 | *new_cc_state = *old_cc_state; | ||
3399 | |||
3400 | new_cc_state->cct.ccti_limit = ppd->total_cct_entry - 1; | ||
3401 | memcpy(new_cc_state->cct.entries, ppd->ccti_entries, | ||
3402 | ppd->total_cct_entry * sizeof(struct ib_cc_table_entry)); | ||
3403 | |||
3404 | new_cc_state->cong_setting.port_control = IB_CC_CCS_PC_SL_BASED; | ||
3405 | new_cc_state->cong_setting.control_map = ppd->cc_sl_control_map; | ||
3406 | memcpy(new_cc_state->cong_setting.entries, ppd->congestion_entries, | ||
3407 | OPA_MAX_SLS * sizeof(struct opa_congestion_setting_entry)); | ||
3408 | |||
3409 | rcu_assign_pointer(ppd->cc_state, new_cc_state); | ||
3410 | |||
3411 | spin_unlock(&ppd->cc_state_lock); | ||
3412 | |||
3413 | call_rcu(&old_cc_state->rcu, cc_state_reclaim); | ||
3414 | } | ||
3415 | |||
3366 | static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data, | 3416 | static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data, |
3367 | struct ib_device *ibdev, u8 port, | 3417 | struct ib_device *ibdev, u8 port, |
3368 | u32 *resp_len) | 3418 | u32 *resp_len) |
@@ -3374,6 +3424,11 @@ static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data, | |||
3374 | struct opa_congestion_setting_entry_shadow *entries; | 3424 | struct opa_congestion_setting_entry_shadow *entries; |
3375 | int i; | 3425 | int i; |
3376 | 3426 | ||
3427 | /* | ||
3428 | * Save details from packet into the ppd. Hold the cc_state_lock so | ||
3429 | * our information is consistent with anyone trying to apply the state. | ||
3430 | */ | ||
3431 | spin_lock(&ppd->cc_state_lock); | ||
3377 | ppd->cc_sl_control_map = be32_to_cpu(p->control_map); | 3432 | ppd->cc_sl_control_map = be32_to_cpu(p->control_map); |
3378 | 3433 | ||
3379 | entries = ppd->congestion_entries; | 3434 | entries = ppd->congestion_entries; |
@@ -3384,6 +3439,10 @@ static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data, | |||
3384 | p->entries[i].trigger_threshold; | 3439 | p->entries[i].trigger_threshold; |
3385 | entries[i].ccti_min = p->entries[i].ccti_min; | 3440 | entries[i].ccti_min = p->entries[i].ccti_min; |
3386 | } | 3441 | } |
3442 | spin_unlock(&ppd->cc_state_lock); | ||
3443 | |||
3444 | /* now apply the information */ | ||
3445 | apply_cc_state(ppd); | ||
3387 | 3446 | ||
3388 | return __subn_get_opa_cong_setting(smp, am, data, ibdev, port, | 3447 | return __subn_get_opa_cong_setting(smp, am, data, ibdev, port, |
3389 | resp_len); | 3448 | resp_len); |
@@ -3526,7 +3585,6 @@ static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data, | |||
3526 | int i, j; | 3585 | int i, j; |
3527 | u32 sentry, eentry; | 3586 | u32 sentry, eentry; |
3528 | u16 ccti_limit; | 3587 | u16 ccti_limit; |
3529 | struct cc_state *old_cc_state, *new_cc_state; | ||
3530 | 3588 | ||
3531 | /* sanity check n_blocks, start_block */ | 3589 | /* sanity check n_blocks, start_block */ |
3532 | if (n_blocks == 0 || | 3590 | if (n_blocks == 0 || |
@@ -3546,45 +3604,20 @@ static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data, | |||
3546 | return reply((struct ib_mad_hdr *)smp); | 3604 | return reply((struct ib_mad_hdr *)smp); |
3547 | } | 3605 | } |
3548 | 3606 | ||
3549 | new_cc_state = kzalloc(sizeof(*new_cc_state), GFP_KERNEL); | 3607 | /* |
3550 | if (!new_cc_state) | 3608 | * Save details from packet into the ppd. Hold the cc_state_lock so |
3551 | goto getit; | 3609 | * our information is consistent with anyone trying to apply the state. |
3552 | 3610 | */ | |
3553 | spin_lock(&ppd->cc_state_lock); | 3611 | spin_lock(&ppd->cc_state_lock); |
3554 | |||
3555 | old_cc_state = get_cc_state(ppd); | ||
3556 | |||
3557 | if (!old_cc_state) { | ||
3558 | spin_unlock(&ppd->cc_state_lock); | ||
3559 | kfree(new_cc_state); | ||
3560 | return reply((struct ib_mad_hdr *)smp); | ||
3561 | } | ||
3562 | |||
3563 | *new_cc_state = *old_cc_state; | ||
3564 | |||
3565 | new_cc_state->cct.ccti_limit = ccti_limit; | ||
3566 | |||
3567 | entries = ppd->ccti_entries; | ||
3568 | ppd->total_cct_entry = ccti_limit + 1; | 3612 | ppd->total_cct_entry = ccti_limit + 1; |
3569 | 3613 | entries = ppd->ccti_entries; | |
3570 | for (j = 0, i = sentry; i < eentry; j++, i++) | 3614 | for (j = 0, i = sentry; i < eentry; j++, i++) |
3571 | entries[i].entry = be16_to_cpu(p->ccti_entries[j].entry); | 3615 | entries[i].entry = be16_to_cpu(p->ccti_entries[j].entry); |
3572 | |||
3573 | memcpy(new_cc_state->cct.entries, entries, | ||
3574 | eentry * sizeof(struct ib_cc_table_entry)); | ||
3575 | |||
3576 | new_cc_state->cong_setting.port_control = IB_CC_CCS_PC_SL_BASED; | ||
3577 | new_cc_state->cong_setting.control_map = ppd->cc_sl_control_map; | ||
3578 | memcpy(new_cc_state->cong_setting.entries, ppd->congestion_entries, | ||
3579 | OPA_MAX_SLS * sizeof(struct opa_congestion_setting_entry)); | ||
3580 | |||
3581 | rcu_assign_pointer(ppd->cc_state, new_cc_state); | ||
3582 | |||
3583 | spin_unlock(&ppd->cc_state_lock); | 3616 | spin_unlock(&ppd->cc_state_lock); |
3584 | 3617 | ||
3585 | call_rcu(&old_cc_state->rcu, cc_state_reclaim); | 3618 | /* now apply the information */ |
3619 | apply_cc_state(ppd); | ||
3586 | 3620 | ||
3587 | getit: | ||
3588 | return __subn_get_opa_cc_table(smp, am, data, ibdev, port, resp_len); | 3621 | return __subn_get_opa_cc_table(smp, am, data, ibdev, port, resp_len); |
3589 | } | 3622 | } |
3590 | 3623 | ||
diff --git a/drivers/staging/rdma/hfi1/mad.h b/drivers/infiniband/hw/hfi1/mad.h index 55ee08675333..55ee08675333 100644 --- a/drivers/staging/rdma/hfi1/mad.h +++ b/drivers/infiniband/hw/hfi1/mad.h | |||
diff --git a/drivers/staging/rdma/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index 2b0e91d3093d..b7a80aa1ae30 100644 --- a/drivers/staging/rdma/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c | |||
@@ -45,6 +45,7 @@ | |||
45 | * | 45 | * |
46 | */ | 46 | */ |
47 | #include <linux/list.h> | 47 | #include <linux/list.h> |
48 | #include <linux/rculist.h> | ||
48 | #include <linux/mmu_notifier.h> | 49 | #include <linux/mmu_notifier.h> |
49 | #include <linux/interval_tree_generic.h> | 50 | #include <linux/interval_tree_generic.h> |
50 | 51 | ||
@@ -97,7 +98,6 @@ static unsigned long mmu_node_last(struct mmu_rb_node *node) | |||
97 | int hfi1_mmu_rb_register(struct rb_root *root, struct mmu_rb_ops *ops) | 98 | int hfi1_mmu_rb_register(struct rb_root *root, struct mmu_rb_ops *ops) |
98 | { | 99 | { |
99 | struct mmu_rb_handler *handlr; | 100 | struct mmu_rb_handler *handlr; |
100 | unsigned long flags; | ||
101 | 101 | ||
102 | if (!ops->invalidate) | 102 | if (!ops->invalidate) |
103 | return -EINVAL; | 103 | return -EINVAL; |
@@ -111,9 +111,9 @@ int hfi1_mmu_rb_register(struct rb_root *root, struct mmu_rb_ops *ops) | |||
111 | INIT_HLIST_NODE(&handlr->mn.hlist); | 111 | INIT_HLIST_NODE(&handlr->mn.hlist); |
112 | spin_lock_init(&handlr->lock); | 112 | spin_lock_init(&handlr->lock); |
113 | handlr->mn.ops = &mn_opts; | 113 | handlr->mn.ops = &mn_opts; |
114 | spin_lock_irqsave(&mmu_rb_lock, flags); | 114 | spin_lock(&mmu_rb_lock); |
115 | list_add_tail(&handlr->list, &mmu_rb_handlers); | 115 | list_add_tail_rcu(&handlr->list, &mmu_rb_handlers); |
116 | spin_unlock_irqrestore(&mmu_rb_lock, flags); | 116 | spin_unlock(&mmu_rb_lock); |
117 | 117 | ||
118 | return mmu_notifier_register(&handlr->mn, current->mm); | 118 | return mmu_notifier_register(&handlr->mn, current->mm); |
119 | } | 119 | } |
@@ -130,9 +130,10 @@ void hfi1_mmu_rb_unregister(struct rb_root *root) | |||
130 | if (current->mm) | 130 | if (current->mm) |
131 | mmu_notifier_unregister(&handler->mn, current->mm); | 131 | mmu_notifier_unregister(&handler->mn, current->mm); |
132 | 132 | ||
133 | spin_lock_irqsave(&mmu_rb_lock, flags); | 133 | spin_lock(&mmu_rb_lock); |
134 | list_del(&handler->list); | 134 | list_del_rcu(&handler->list); |
135 | spin_unlock_irqrestore(&mmu_rb_lock, flags); | 135 | spin_unlock(&mmu_rb_lock); |
136 | synchronize_rcu(); | ||
136 | 137 | ||
137 | spin_lock_irqsave(&handler->lock, flags); | 138 | spin_lock_irqsave(&handler->lock, flags); |
138 | if (!RB_EMPTY_ROOT(root)) { | 139 | if (!RB_EMPTY_ROOT(root)) { |
@@ -271,16 +272,15 @@ void hfi1_mmu_rb_remove(struct rb_root *root, struct mmu_rb_node *node) | |||
271 | static struct mmu_rb_handler *find_mmu_handler(struct rb_root *root) | 272 | static struct mmu_rb_handler *find_mmu_handler(struct rb_root *root) |
272 | { | 273 | { |
273 | struct mmu_rb_handler *handler; | 274 | struct mmu_rb_handler *handler; |
274 | unsigned long flags; | ||
275 | 275 | ||
276 | spin_lock_irqsave(&mmu_rb_lock, flags); | 276 | rcu_read_lock(); |
277 | list_for_each_entry(handler, &mmu_rb_handlers, list) { | 277 | list_for_each_entry_rcu(handler, &mmu_rb_handlers, list) { |
278 | if (handler->root == root) | 278 | if (handler->root == root) |
279 | goto unlock; | 279 | goto unlock; |
280 | } | 280 | } |
281 | handler = NULL; | 281 | handler = NULL; |
282 | unlock: | 282 | unlock: |
283 | spin_unlock_irqrestore(&mmu_rb_lock, flags); | 283 | rcu_read_unlock(); |
284 | return handler; | 284 | return handler; |
285 | } | 285 | } |
286 | 286 | ||
diff --git a/drivers/staging/rdma/hfi1/mmu_rb.h b/drivers/infiniband/hw/hfi1/mmu_rb.h index 7a57b9c49d27..7a57b9c49d27 100644 --- a/drivers/staging/rdma/hfi1/mmu_rb.h +++ b/drivers/infiniband/hw/hfi1/mmu_rb.h | |||
diff --git a/drivers/staging/rdma/hfi1/opa_compat.h b/drivers/infiniband/hw/hfi1/opa_compat.h index 6ef3c1cbdcd7..6ef3c1cbdcd7 100644 --- a/drivers/staging/rdma/hfi1/opa_compat.h +++ b/drivers/infiniband/hw/hfi1/opa_compat.h | |||
diff --git a/drivers/staging/rdma/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c index 0bac21e6a658..0bac21e6a658 100644 --- a/drivers/staging/rdma/hfi1/pcie.c +++ b/drivers/infiniband/hw/hfi1/pcie.c | |||
diff --git a/drivers/staging/rdma/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c index c67b9ad3fcf4..d5edb1afbb8f 100644 --- a/drivers/staging/rdma/hfi1/pio.c +++ b/drivers/infiniband/hw/hfi1/pio.c | |||
@@ -1835,8 +1835,7 @@ int pio_map_init(struct hfi1_devdata *dd, u8 port, u8 num_vls, u8 *vl_scontexts) | |||
1835 | struct pio_vl_map *oldmap, *newmap; | 1835 | struct pio_vl_map *oldmap, *newmap; |
1836 | 1836 | ||
1837 | if (!vl_scontexts) { | 1837 | if (!vl_scontexts) { |
1838 | /* send context 0 reserved for VL15 */ | 1838 | for (i = 0; i < dd->num_send_contexts; i++) |
1839 | for (i = 1; i < dd->num_send_contexts; i++) | ||
1840 | if (dd->send_contexts[i].type == SC_KERNEL) | 1839 | if (dd->send_contexts[i].type == SC_KERNEL) |
1841 | num_kernel_send_contexts++; | 1840 | num_kernel_send_contexts++; |
1842 | /* truncate divide */ | 1841 | /* truncate divide */ |
diff --git a/drivers/staging/rdma/hfi1/pio.h b/drivers/infiniband/hw/hfi1/pio.h index 53a08edb7f64..464cbd27b975 100644 --- a/drivers/staging/rdma/hfi1/pio.h +++ b/drivers/infiniband/hw/hfi1/pio.h | |||
@@ -49,10 +49,10 @@ | |||
49 | 49 | ||
50 | /* send context types */ | 50 | /* send context types */ |
51 | #define SC_KERNEL 0 | 51 | #define SC_KERNEL 0 |
52 | #define SC_ACK 1 | 52 | #define SC_VL15 1 |
53 | #define SC_USER 2 | 53 | #define SC_ACK 2 |
54 | #define SC_VL15 3 | 54 | #define SC_USER 3 /* must be the last one: it may take all left */ |
55 | #define SC_MAX 4 | 55 | #define SC_MAX 4 /* count of send context types */ |
56 | 56 | ||
57 | /* invalid send context index */ | 57 | /* invalid send context index */ |
58 | #define INVALID_SCI 0xff | 58 | #define INVALID_SCI 0xff |
diff --git a/drivers/staging/rdma/hfi1/pio_copy.c b/drivers/infiniband/hw/hfi1/pio_copy.c index 8c25e1b58849..8c25e1b58849 100644 --- a/drivers/staging/rdma/hfi1/pio_copy.c +++ b/drivers/infiniband/hw/hfi1/pio_copy.c | |||
diff --git a/drivers/staging/rdma/hfi1/platform.c b/drivers/infiniband/hw/hfi1/platform.c index 8fe8a205b5bb..03df9322f862 100644 --- a/drivers/staging/rdma/hfi1/platform.c +++ b/drivers/infiniband/hw/hfi1/platform.c | |||
@@ -87,6 +87,17 @@ void free_platform_config(struct hfi1_devdata *dd) | |||
87 | */ | 87 | */ |
88 | } | 88 | } |
89 | 89 | ||
90 | void get_port_type(struct hfi1_pportdata *ppd) | ||
91 | { | ||
92 | int ret; | ||
93 | |||
94 | ret = get_platform_config_field(ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0, | ||
95 | PORT_TABLE_PORT_TYPE, &ppd->port_type, | ||
96 | 4); | ||
97 | if (ret) | ||
98 | ppd->port_type = PORT_TYPE_UNKNOWN; | ||
99 | } | ||
100 | |||
90 | int set_qsfp_tx(struct hfi1_pportdata *ppd, int on) | 101 | int set_qsfp_tx(struct hfi1_pportdata *ppd, int on) |
91 | { | 102 | { |
92 | u8 tx_ctrl_byte = on ? 0x0 : 0xF; | 103 | u8 tx_ctrl_byte = on ? 0x0 : 0xF; |
@@ -529,7 +540,8 @@ static void apply_tunings( | |||
529 | /* Enable external device config if channel is limiting active */ | 540 | /* Enable external device config if channel is limiting active */ |
530 | read_8051_config(ppd->dd, LINK_OPTIMIZATION_SETTINGS, | 541 | read_8051_config(ppd->dd, LINK_OPTIMIZATION_SETTINGS, |
531 | GENERAL_CONFIG, &config_data); | 542 | GENERAL_CONFIG, &config_data); |
532 | config_data |= limiting_active; | 543 | config_data &= ~(0xff << ENABLE_EXT_DEV_CONFIG_SHIFT); |
544 | config_data |= ((u32)limiting_active << ENABLE_EXT_DEV_CONFIG_SHIFT); | ||
533 | ret = load_8051_config(ppd->dd, LINK_OPTIMIZATION_SETTINGS, | 545 | ret = load_8051_config(ppd->dd, LINK_OPTIMIZATION_SETTINGS, |
534 | GENERAL_CONFIG, config_data); | 546 | GENERAL_CONFIG, config_data); |
535 | if (ret != HCMD_SUCCESS) | 547 | if (ret != HCMD_SUCCESS) |
@@ -542,7 +554,8 @@ static void apply_tunings( | |||
542 | /* Pass tuning method to 8051 */ | 554 | /* Pass tuning method to 8051 */ |
543 | read_8051_config(ppd->dd, LINK_TUNING_PARAMETERS, GENERAL_CONFIG, | 555 | read_8051_config(ppd->dd, LINK_TUNING_PARAMETERS, GENERAL_CONFIG, |
544 | &config_data); | 556 | &config_data); |
545 | config_data |= tuning_method; | 557 | config_data &= ~(0xff << TUNING_METHOD_SHIFT); |
558 | config_data |= ((u32)tuning_method << TUNING_METHOD_SHIFT); | ||
546 | ret = load_8051_config(ppd->dd, LINK_TUNING_PARAMETERS, GENERAL_CONFIG, | 559 | ret = load_8051_config(ppd->dd, LINK_TUNING_PARAMETERS, GENERAL_CONFIG, |
547 | config_data); | 560 | config_data); |
548 | if (ret != HCMD_SUCCESS) | 561 | if (ret != HCMD_SUCCESS) |
@@ -564,8 +577,8 @@ static void apply_tunings( | |||
564 | ret = read_8051_config(ppd->dd, DC_HOST_COMM_SETTINGS, | 577 | ret = read_8051_config(ppd->dd, DC_HOST_COMM_SETTINGS, |
565 | GENERAL_CONFIG, &config_data); | 578 | GENERAL_CONFIG, &config_data); |
566 | /* Clear, then set the external device config field */ | 579 | /* Clear, then set the external device config field */ |
567 | config_data &= ~(0xFF << 24); | 580 | config_data &= ~(u32)0xFF; |
568 | config_data |= (external_device_config << 24); | 581 | config_data |= external_device_config; |
569 | ret = load_8051_config(ppd->dd, DC_HOST_COMM_SETTINGS, | 582 | ret = load_8051_config(ppd->dd, DC_HOST_COMM_SETTINGS, |
570 | GENERAL_CONFIG, config_data); | 583 | GENERAL_CONFIG, config_data); |
571 | if (ret != HCMD_SUCCESS) | 584 | if (ret != HCMD_SUCCESS) |
@@ -784,12 +797,6 @@ void tune_serdes(struct hfi1_pportdata *ppd) | |||
784 | return; | 797 | return; |
785 | } | 798 | } |
786 | 799 | ||
787 | ret = get_platform_config_field(ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0, | ||
788 | PORT_TABLE_PORT_TYPE, &ppd->port_type, | ||
789 | 4); | ||
790 | if (ret) | ||
791 | ppd->port_type = PORT_TYPE_UNKNOWN; | ||
792 | |||
793 | switch (ppd->port_type) { | 800 | switch (ppd->port_type) { |
794 | case PORT_TYPE_DISCONNECTED: | 801 | case PORT_TYPE_DISCONNECTED: |
795 | ppd->offline_disabled_reason = | 802 | ppd->offline_disabled_reason = |
diff --git a/drivers/staging/rdma/hfi1/platform.h b/drivers/infiniband/hw/hfi1/platform.h index 19620cf546d5..e2c21613c326 100644 --- a/drivers/staging/rdma/hfi1/platform.h +++ b/drivers/infiniband/hw/hfi1/platform.h | |||
@@ -298,6 +298,7 @@ enum link_tuning_encoding { | |||
298 | /* platform.c */ | 298 | /* platform.c */ |
299 | void get_platform_config(struct hfi1_devdata *dd); | 299 | void get_platform_config(struct hfi1_devdata *dd); |
300 | void free_platform_config(struct hfi1_devdata *dd); | 300 | void free_platform_config(struct hfi1_devdata *dd); |
301 | void get_port_type(struct hfi1_pportdata *ppd); | ||
301 | int set_qsfp_tx(struct hfi1_pportdata *ppd, int on); | 302 | int set_qsfp_tx(struct hfi1_pportdata *ppd, int on); |
302 | void tune_serdes(struct hfi1_pportdata *ppd); | 303 | void tune_serdes(struct hfi1_pportdata *ppd); |
303 | 304 | ||
diff --git a/drivers/staging/rdma/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c index 91eb42316df9..1a942ffba4cb 100644 --- a/drivers/staging/rdma/hfi1/qp.c +++ b/drivers/infiniband/hw/hfi1/qp.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/vmalloc.h> | 49 | #include <linux/vmalloc.h> |
50 | #include <linux/hash.h> | 50 | #include <linux/hash.h> |
51 | #include <linux/module.h> | 51 | #include <linux/module.h> |
52 | #include <linux/random.h> | ||
53 | #include <linux/seq_file.h> | 52 | #include <linux/seq_file.h> |
54 | #include <rdma/rdma_vt.h> | 53 | #include <rdma/rdma_vt.h> |
55 | #include <rdma/rdmavt_qp.h> | 54 | #include <rdma/rdmavt_qp.h> |
@@ -161,9 +160,6 @@ static inline int opa_mtu_enum_to_int(int mtu) | |||
161 | * This function is what we would push to the core layer if we wanted to be a | 160 | * This function is what we would push to the core layer if we wanted to be a |
162 | * "first class citizen". Instead we hide this here and rely on Verbs ULPs | 161 | * "first class citizen". Instead we hide this here and rely on Verbs ULPs |
163 | * to blindly pass the MTU enum value from the PathRecord to us. | 162 | * to blindly pass the MTU enum value from the PathRecord to us. |
164 | * | ||
165 | * The actual flag used to determine "8k MTU" will change and is currently | ||
166 | * unknown. | ||
167 | */ | 163 | */ |
168 | static inline int verbs_mtu_enum_to_int(struct ib_device *dev, enum ib_mtu mtu) | 164 | static inline int verbs_mtu_enum_to_int(struct ib_device *dev, enum ib_mtu mtu) |
169 | { | 165 | { |
@@ -516,6 +512,7 @@ static void iowait_wakeup(struct iowait *wait, int reason) | |||
516 | static void iowait_sdma_drained(struct iowait *wait) | 512 | static void iowait_sdma_drained(struct iowait *wait) |
517 | { | 513 | { |
518 | struct rvt_qp *qp = iowait_to_qp(wait); | 514 | struct rvt_qp *qp = iowait_to_qp(wait); |
515 | unsigned long flags; | ||
519 | 516 | ||
520 | /* | 517 | /* |
521 | * This happens when the send engine notes | 518 | * This happens when the send engine notes |
@@ -523,12 +520,12 @@ static void iowait_sdma_drained(struct iowait *wait) | |||
523 | * do the flush work until that QP's | 520 | * do the flush work until that QP's |
524 | * sdma work has finished. | 521 | * sdma work has finished. |
525 | */ | 522 | */ |
526 | spin_lock(&qp->s_lock); | 523 | spin_lock_irqsave(&qp->s_lock, flags); |
527 | if (qp->s_flags & RVT_S_WAIT_DMA) { | 524 | if (qp->s_flags & RVT_S_WAIT_DMA) { |
528 | qp->s_flags &= ~RVT_S_WAIT_DMA; | 525 | qp->s_flags &= ~RVT_S_WAIT_DMA; |
529 | hfi1_schedule_send(qp); | 526 | hfi1_schedule_send(qp); |
530 | } | 527 | } |
531 | spin_unlock(&qp->s_lock); | 528 | spin_unlock_irqrestore(&qp->s_lock, flags); |
532 | } | 529 | } |
533 | 530 | ||
534 | /** | 531 | /** |
diff --git a/drivers/staging/rdma/hfi1/qp.h b/drivers/infiniband/hw/hfi1/qp.h index e7bc8d6cf681..e7bc8d6cf681 100644 --- a/drivers/staging/rdma/hfi1/qp.h +++ b/drivers/infiniband/hw/hfi1/qp.h | |||
diff --git a/drivers/staging/rdma/hfi1/qsfp.c b/drivers/infiniband/hw/hfi1/qsfp.c index 2441669f0817..2441669f0817 100644 --- a/drivers/staging/rdma/hfi1/qsfp.c +++ b/drivers/infiniband/hw/hfi1/qsfp.c | |||
diff --git a/drivers/staging/rdma/hfi1/qsfp.h b/drivers/infiniband/hw/hfi1/qsfp.h index dadc66c442b9..dadc66c442b9 100644 --- a/drivers/staging/rdma/hfi1/qsfp.h +++ b/drivers/infiniband/hw/hfi1/qsfp.h | |||
diff --git a/drivers/staging/rdma/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c index 792f15eb8efe..792f15eb8efe 100644 --- a/drivers/staging/rdma/hfi1/rc.c +++ b/drivers/infiniband/hw/hfi1/rc.c | |||
diff --git a/drivers/staging/rdma/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c index a659aec3c3c6..a659aec3c3c6 100644 --- a/drivers/staging/rdma/hfi1/ruc.c +++ b/drivers/infiniband/hw/hfi1/ruc.c | |||
diff --git a/drivers/staging/rdma/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index abb8ebc1fcac..f9befc05b349 100644 --- a/drivers/staging/rdma/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c | |||
@@ -134,6 +134,7 @@ static const char * const sdma_state_names[] = { | |||
134 | [sdma_state_s99_running] = "s99_Running", | 134 | [sdma_state_s99_running] = "s99_Running", |
135 | }; | 135 | }; |
136 | 136 | ||
137 | #ifdef CONFIG_SDMA_VERBOSITY | ||
137 | static const char * const sdma_event_names[] = { | 138 | static const char * const sdma_event_names[] = { |
138 | [sdma_event_e00_go_hw_down] = "e00_GoHwDown", | 139 | [sdma_event_e00_go_hw_down] = "e00_GoHwDown", |
139 | [sdma_event_e10_go_hw_start] = "e10_GoHwStart", | 140 | [sdma_event_e10_go_hw_start] = "e10_GoHwStart", |
@@ -150,6 +151,7 @@ static const char * const sdma_event_names[] = { | |||
150 | [sdma_event_e85_link_down] = "e85_LinkDown", | 151 | [sdma_event_e85_link_down] = "e85_LinkDown", |
151 | [sdma_event_e90_sw_halted] = "e90_SwHalted", | 152 | [sdma_event_e90_sw_halted] = "e90_SwHalted", |
152 | }; | 153 | }; |
154 | #endif | ||
153 | 155 | ||
154 | static const struct sdma_set_state_action sdma_action_table[] = { | 156 | static const struct sdma_set_state_action sdma_action_table[] = { |
155 | [sdma_state_s00_hw_down] = { | 157 | [sdma_state_s00_hw_down] = { |
@@ -376,7 +378,7 @@ static inline void complete_tx(struct sdma_engine *sde, | |||
376 | sdma_txclean(sde->dd, tx); | 378 | sdma_txclean(sde->dd, tx); |
377 | if (complete) | 379 | if (complete) |
378 | (*complete)(tx, res); | 380 | (*complete)(tx, res); |
379 | if (iowait_sdma_dec(wait) && wait) | 381 | if (wait && iowait_sdma_dec(wait)) |
380 | iowait_drain_wakeup(wait); | 382 | iowait_drain_wakeup(wait); |
381 | } | 383 | } |
382 | 384 | ||
diff --git a/drivers/staging/rdma/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h index 8f50c99fe711..8f50c99fe711 100644 --- a/drivers/staging/rdma/hfi1/sdma.h +++ b/drivers/infiniband/hw/hfi1/sdma.h | |||
diff --git a/drivers/staging/rdma/hfi1/sdma_txreq.h b/drivers/infiniband/hw/hfi1/sdma_txreq.h index bf7d777d756e..bf7d777d756e 100644 --- a/drivers/staging/rdma/hfi1/sdma_txreq.h +++ b/drivers/infiniband/hw/hfi1/sdma_txreq.h | |||
diff --git a/drivers/staging/rdma/hfi1/sysfs.c b/drivers/infiniband/hw/hfi1/sysfs.c index 8cd6df8634ad..91fc2aed6aed 100644 --- a/drivers/staging/rdma/hfi1/sysfs.c +++ b/drivers/infiniband/hw/hfi1/sysfs.c | |||
@@ -721,8 +721,8 @@ int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, | |||
721 | } | 721 | } |
722 | 722 | ||
723 | dd_dev_info(dd, | 723 | dd_dev_info(dd, |
724 | "IB%u: Congestion Control Agent enabled for port %d\n", | 724 | "Congestion Control Agent enabled for port %d\n", |
725 | dd->unit, port_num); | 725 | port_num); |
726 | 726 | ||
727 | return 0; | 727 | return 0; |
728 | 728 | ||
diff --git a/drivers/staging/rdma/hfi1/trace.c b/drivers/infiniband/hw/hfi1/trace.c index 8b62fefcf903..79b2952c0dfb 100644 --- a/drivers/staging/rdma/hfi1/trace.c +++ b/drivers/infiniband/hw/hfi1/trace.c | |||
@@ -66,6 +66,7 @@ u8 ibhdr_exhdr_len(struct hfi1_ib_header *hdr) | |||
66 | #define RETH_PRN "reth vaddr 0x%.16llx rkey 0x%.8x dlen 0x%.8x" | 66 | #define RETH_PRN "reth vaddr 0x%.16llx rkey 0x%.8x dlen 0x%.8x" |
67 | #define AETH_PRN "aeth syn 0x%.2x %s msn 0x%.8x" | 67 | #define AETH_PRN "aeth syn 0x%.2x %s msn 0x%.8x" |
68 | #define DETH_PRN "deth qkey 0x%.8x sqpn 0x%.6x" | 68 | #define DETH_PRN "deth qkey 0x%.8x sqpn 0x%.6x" |
69 | #define IETH_PRN "ieth rkey 0x%.8x" | ||
69 | #define ATOMICACKETH_PRN "origdata %lld" | 70 | #define ATOMICACKETH_PRN "origdata %lld" |
70 | #define ATOMICETH_PRN "vaddr 0x%llx rkey 0x%.8x sdata %lld cdata %lld" | 71 | #define ATOMICETH_PRN "vaddr 0x%llx rkey 0x%.8x sdata %lld cdata %lld" |
71 | 72 | ||
@@ -166,6 +167,12 @@ const char *parse_everbs_hdrs( | |||
166 | be32_to_cpu(eh->ud.deth[0]), | 167 | be32_to_cpu(eh->ud.deth[0]), |
167 | be32_to_cpu(eh->ud.deth[1]) & RVT_QPN_MASK); | 168 | be32_to_cpu(eh->ud.deth[1]) & RVT_QPN_MASK); |
168 | break; | 169 | break; |
170 | /* ieth */ | ||
171 | case OP(RC, SEND_LAST_WITH_INVALIDATE): | ||
172 | case OP(RC, SEND_ONLY_WITH_INVALIDATE): | ||
173 | trace_seq_printf(p, IETH_PRN, | ||
174 | be32_to_cpu(eh->ieth)); | ||
175 | break; | ||
169 | } | 176 | } |
170 | trace_seq_putc(p, 0); | 177 | trace_seq_putc(p, 0); |
171 | return ret; | 178 | return ret; |
@@ -233,3 +240,4 @@ __hfi1_trace_fn(FIRMWARE); | |||
233 | __hfi1_trace_fn(RCVCTRL); | 240 | __hfi1_trace_fn(RCVCTRL); |
234 | __hfi1_trace_fn(TID); | 241 | __hfi1_trace_fn(TID); |
235 | __hfi1_trace_fn(MMU); | 242 | __hfi1_trace_fn(MMU); |
243 | __hfi1_trace_fn(IOCTL); | ||
diff --git a/drivers/staging/rdma/hfi1/trace.h b/drivers/infiniband/hw/hfi1/trace.h index 963dc948c38a..28c1d0832886 100644 --- a/drivers/staging/rdma/hfi1/trace.h +++ b/drivers/infiniband/hw/hfi1/trace.h | |||
@@ -74,8 +74,8 @@ __print_symbolic(etype, \ | |||
74 | 74 | ||
75 | TRACE_EVENT(hfi1_rcvhdr, | 75 | TRACE_EVENT(hfi1_rcvhdr, |
76 | TP_PROTO(struct hfi1_devdata *dd, | 76 | TP_PROTO(struct hfi1_devdata *dd, |
77 | u64 eflags, | ||
78 | u32 ctxt, | 77 | u32 ctxt, |
78 | u64 eflags, | ||
79 | u32 etype, | 79 | u32 etype, |
80 | u32 hlen, | 80 | u32 hlen, |
81 | u32 tlen, | 81 | u32 tlen, |
@@ -392,6 +392,8 @@ __print_symbolic(opcode, \ | |||
392 | ib_opcode_name(RC_ATOMIC_ACKNOWLEDGE), \ | 392 | ib_opcode_name(RC_ATOMIC_ACKNOWLEDGE), \ |
393 | ib_opcode_name(RC_COMPARE_SWAP), \ | 393 | ib_opcode_name(RC_COMPARE_SWAP), \ |
394 | ib_opcode_name(RC_FETCH_ADD), \ | 394 | ib_opcode_name(RC_FETCH_ADD), \ |
395 | ib_opcode_name(RC_SEND_LAST_WITH_INVALIDATE), \ | ||
396 | ib_opcode_name(RC_SEND_ONLY_WITH_INVALIDATE), \ | ||
395 | ib_opcode_name(UC_SEND_FIRST), \ | 397 | ib_opcode_name(UC_SEND_FIRST), \ |
396 | ib_opcode_name(UC_SEND_MIDDLE), \ | 398 | ib_opcode_name(UC_SEND_MIDDLE), \ |
397 | ib_opcode_name(UC_SEND_LAST), \ | 399 | ib_opcode_name(UC_SEND_LAST), \ |
@@ -1341,6 +1343,7 @@ __hfi1_trace_def(FIRMWARE); | |||
1341 | __hfi1_trace_def(RCVCTRL); | 1343 | __hfi1_trace_def(RCVCTRL); |
1342 | __hfi1_trace_def(TID); | 1344 | __hfi1_trace_def(TID); |
1343 | __hfi1_trace_def(MMU); | 1345 | __hfi1_trace_def(MMU); |
1346 | __hfi1_trace_def(IOCTL); | ||
1344 | 1347 | ||
1345 | #define hfi1_cdbg(which, fmt, ...) \ | 1348 | #define hfi1_cdbg(which, fmt, ...) \ |
1346 | __hfi1_trace_##which(__func__, fmt, ##__VA_ARGS__) | 1349 | __hfi1_trace_##which(__func__, fmt, ##__VA_ARGS__) |
diff --git a/drivers/staging/rdma/hfi1/twsi.c b/drivers/infiniband/hw/hfi1/twsi.c index e82e52a63d35..e82e52a63d35 100644 --- a/drivers/staging/rdma/hfi1/twsi.c +++ b/drivers/infiniband/hw/hfi1/twsi.c | |||
diff --git a/drivers/staging/rdma/hfi1/twsi.h b/drivers/infiniband/hw/hfi1/twsi.h index 5b8a5b5e7eae..5b8a5b5e7eae 100644 --- a/drivers/staging/rdma/hfi1/twsi.h +++ b/drivers/infiniband/hw/hfi1/twsi.h | |||
diff --git a/drivers/staging/rdma/hfi1/uc.c b/drivers/infiniband/hw/hfi1/uc.c index df773d433297..df773d433297 100644 --- a/drivers/staging/rdma/hfi1/uc.c +++ b/drivers/infiniband/hw/hfi1/uc.c | |||
diff --git a/drivers/staging/rdma/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c index 1e503ad0bebb..1e503ad0bebb 100644 --- a/drivers/staging/rdma/hfi1/ud.c +++ b/drivers/infiniband/hw/hfi1/ud.c | |||
diff --git a/drivers/staging/rdma/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index 1b640a35b3fe..1b640a35b3fe 100644 --- a/drivers/staging/rdma/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c | |||
diff --git a/drivers/staging/rdma/hfi1/user_exp_rcv.h b/drivers/infiniband/hw/hfi1/user_exp_rcv.h index 9bc8d9fba87e..9bc8d9fba87e 100644 --- a/drivers/staging/rdma/hfi1/user_exp_rcv.h +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.h | |||
diff --git a/drivers/staging/rdma/hfi1/user_pages.c b/drivers/infiniband/hw/hfi1/user_pages.c index 88e10b5f55f1..88e10b5f55f1 100644 --- a/drivers/staging/rdma/hfi1/user_pages.c +++ b/drivers/infiniband/hw/hfi1/user_pages.c | |||
diff --git a/drivers/staging/rdma/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index 0014c9c0e967..29f4795f866c 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c | |||
@@ -166,6 +166,8 @@ static unsigned initial_pkt_count = 8; | |||
166 | 166 | ||
167 | #define SDMA_IOWAIT_TIMEOUT 1000 /* in milliseconds */ | 167 | #define SDMA_IOWAIT_TIMEOUT 1000 /* in milliseconds */ |
168 | 168 | ||
169 | struct sdma_mmu_node; | ||
170 | |||
169 | struct user_sdma_iovec { | 171 | struct user_sdma_iovec { |
170 | struct list_head list; | 172 | struct list_head list; |
171 | struct iovec iov; | 173 | struct iovec iov; |
@@ -178,6 +180,7 @@ struct user_sdma_iovec { | |||
178 | * which we last left off. | 180 | * which we last left off. |
179 | */ | 181 | */ |
180 | u64 offset; | 182 | u64 offset; |
183 | struct sdma_mmu_node *node; | ||
181 | }; | 184 | }; |
182 | 185 | ||
183 | #define SDMA_CACHE_NODE_EVICT BIT(0) | 186 | #define SDMA_CACHE_NODE_EVICT BIT(0) |
@@ -507,6 +510,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, | |||
507 | struct sdma_req_info info; | 510 | struct sdma_req_info info; |
508 | struct user_sdma_request *req; | 511 | struct user_sdma_request *req; |
509 | u8 opcode, sc, vl; | 512 | u8 opcode, sc, vl; |
513 | int req_queued = 0; | ||
510 | 514 | ||
511 | if (iovec[idx].iov_len < sizeof(info) + sizeof(req->hdr)) { | 515 | if (iovec[idx].iov_len < sizeof(info) + sizeof(req->hdr)) { |
512 | hfi1_cdbg( | 516 | hfi1_cdbg( |
@@ -703,6 +707,7 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, | |||
703 | 707 | ||
704 | set_comp_state(pq, cq, info.comp_idx, QUEUED, 0); | 708 | set_comp_state(pq, cq, info.comp_idx, QUEUED, 0); |
705 | atomic_inc(&pq->n_reqs); | 709 | atomic_inc(&pq->n_reqs); |
710 | req_queued = 1; | ||
706 | /* Send the first N packets in the request to buy us some time */ | 711 | /* Send the first N packets in the request to buy us some time */ |
707 | ret = user_sdma_send_pkts(req, pcount); | 712 | ret = user_sdma_send_pkts(req, pcount); |
708 | if (unlikely(ret < 0 && ret != -EBUSY)) { | 713 | if (unlikely(ret < 0 && ret != -EBUSY)) { |
@@ -747,7 +752,8 @@ int hfi1_user_sdma_process_request(struct file *fp, struct iovec *iovec, | |||
747 | return 0; | 752 | return 0; |
748 | free_req: | 753 | free_req: |
749 | user_sdma_free_request(req, true); | 754 | user_sdma_free_request(req, true); |
750 | pq_update(pq); | 755 | if (req_queued) |
756 | pq_update(pq); | ||
751 | set_comp_state(pq, cq, info.comp_idx, ERROR, req->status); | 757 | set_comp_state(pq, cq, info.comp_idx, ERROR, req->status); |
752 | return ret; | 758 | return ret; |
753 | } | 759 | } |
@@ -1153,6 +1159,7 @@ retry: | |||
1153 | } | 1159 | } |
1154 | iovec->pages = node->pages; | 1160 | iovec->pages = node->pages; |
1155 | iovec->npages = npages; | 1161 | iovec->npages = npages; |
1162 | iovec->node = node; | ||
1156 | 1163 | ||
1157 | ret = hfi1_mmu_rb_insert(&req->pq->sdma_rb_root, &node->rb); | 1164 | ret = hfi1_mmu_rb_insert(&req->pq->sdma_rb_root, &node->rb); |
1158 | if (ret) { | 1165 | if (ret) { |
@@ -1519,18 +1526,13 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) | |||
1519 | } | 1526 | } |
1520 | if (req->data_iovs) { | 1527 | if (req->data_iovs) { |
1521 | struct sdma_mmu_node *node; | 1528 | struct sdma_mmu_node *node; |
1522 | struct mmu_rb_node *mnode; | ||
1523 | int i; | 1529 | int i; |
1524 | 1530 | ||
1525 | for (i = 0; i < req->data_iovs; i++) { | 1531 | for (i = 0; i < req->data_iovs; i++) { |
1526 | mnode = hfi1_mmu_rb_search( | 1532 | node = req->iovs[i].node; |
1527 | &req->pq->sdma_rb_root, | 1533 | if (!node) |
1528 | (unsigned long)req->iovs[i].iov.iov_base, | ||
1529 | req->iovs[i].iov.iov_len); | ||
1530 | if (!mnode || IS_ERR(mnode)) | ||
1531 | continue; | 1534 | continue; |
1532 | 1535 | ||
1533 | node = container_of(mnode, struct sdma_mmu_node, rb); | ||
1534 | if (unpin) | 1536 | if (unpin) |
1535 | hfi1_mmu_rb_remove(&req->pq->sdma_rb_root, | 1537 | hfi1_mmu_rb_remove(&req->pq->sdma_rb_root, |
1536 | &node->rb); | 1538 | &node->rb); |
diff --git a/drivers/staging/rdma/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h index b9240e351161..b9240e351161 100644 --- a/drivers/staging/rdma/hfi1/user_sdma.h +++ b/drivers/infiniband/hw/hfi1/user_sdma.h | |||
diff --git a/drivers/staging/rdma/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c index 9cdc85fa366f..849c4b9399d4 100644 --- a/drivers/staging/rdma/hfi1/verbs.c +++ b/drivers/infiniband/hw/hfi1/verbs.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <linux/utsname.h> | 52 | #include <linux/utsname.h> |
53 | #include <linux/rculist.h> | 53 | #include <linux/rculist.h> |
54 | #include <linux/mm.h> | 54 | #include <linux/mm.h> |
55 | #include <linux/random.h> | ||
56 | #include <linux/vmalloc.h> | 55 | #include <linux/vmalloc.h> |
57 | 56 | ||
58 | #include "hfi.h" | 57 | #include "hfi.h" |
@@ -336,6 +335,8 @@ const u8 hdr_len_by_opcode[256] = { | |||
336 | [IB_OPCODE_RC_ATOMIC_ACKNOWLEDGE] = 12 + 8 + 4, | 335 | [IB_OPCODE_RC_ATOMIC_ACKNOWLEDGE] = 12 + 8 + 4, |
337 | [IB_OPCODE_RC_COMPARE_SWAP] = 12 + 8 + 28, | 336 | [IB_OPCODE_RC_COMPARE_SWAP] = 12 + 8 + 28, |
338 | [IB_OPCODE_RC_FETCH_ADD] = 12 + 8 + 28, | 337 | [IB_OPCODE_RC_FETCH_ADD] = 12 + 8 + 28, |
338 | [IB_OPCODE_RC_SEND_LAST_WITH_INVALIDATE] = 12 + 8 + 4, | ||
339 | [IB_OPCODE_RC_SEND_ONLY_WITH_INVALIDATE] = 12 + 8 + 4, | ||
339 | /* UC */ | 340 | /* UC */ |
340 | [IB_OPCODE_UC_SEND_FIRST] = 12 + 8, | 341 | [IB_OPCODE_UC_SEND_FIRST] = 12 + 8, |
341 | [IB_OPCODE_UC_SEND_MIDDLE] = 12 + 8, | 342 | [IB_OPCODE_UC_SEND_MIDDLE] = 12 + 8, |
@@ -946,7 +947,6 @@ static int pio_wait(struct rvt_qp *qp, | |||
946 | 947 | ||
947 | dev->n_piowait += !!(flag & RVT_S_WAIT_PIO); | 948 | dev->n_piowait += !!(flag & RVT_S_WAIT_PIO); |
948 | dev->n_piodrain += !!(flag & RVT_S_WAIT_PIO_DRAIN); | 949 | dev->n_piodrain += !!(flag & RVT_S_WAIT_PIO_DRAIN); |
949 | dev->n_piowait++; | ||
950 | qp->s_flags |= flag; | 950 | qp->s_flags |= flag; |
951 | was_empty = list_empty(&sc->piowait); | 951 | was_empty = list_empty(&sc->piowait); |
952 | list_add_tail(&priv->s_iowait.list, &sc->piowait); | 952 | list_add_tail(&priv->s_iowait.list, &sc->piowait); |
diff --git a/drivers/staging/rdma/hfi1/verbs.h b/drivers/infiniband/hw/hfi1/verbs.h index 3ee223983b20..488356775627 100644 --- a/drivers/staging/rdma/hfi1/verbs.h +++ b/drivers/infiniband/hw/hfi1/verbs.h | |||
@@ -152,6 +152,7 @@ union ib_ehdrs { | |||
152 | } at; | 152 | } at; |
153 | __be32 imm_data; | 153 | __be32 imm_data; |
154 | __be32 aeth; | 154 | __be32 aeth; |
155 | __be32 ieth; | ||
155 | struct ib_atomic_eth atomic_eth; | 156 | struct ib_atomic_eth atomic_eth; |
156 | } __packed; | 157 | } __packed; |
157 | 158 | ||
diff --git a/drivers/staging/rdma/hfi1/verbs_txreq.c b/drivers/infiniband/hw/hfi1/verbs_txreq.c index bc95c4112c61..bc95c4112c61 100644 --- a/drivers/staging/rdma/hfi1/verbs_txreq.c +++ b/drivers/infiniband/hw/hfi1/verbs_txreq.c | |||
diff --git a/drivers/staging/rdma/hfi1/verbs_txreq.h b/drivers/infiniband/hw/hfi1/verbs_txreq.h index 1cf69b2fe4a5..1cf69b2fe4a5 100644 --- a/drivers/staging/rdma/hfi1/verbs_txreq.h +++ b/drivers/infiniband/hw/hfi1/verbs_txreq.h | |||
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 82d7c4bf5970..ce4034071f9c 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -1308,21 +1308,6 @@ static const struct qib_hwerror_msgs qib_7322p_error_msgs[] = { | |||
1308 | SYM_LSB(IntMask, fldname##17IntMask)), \ | 1308 | SYM_LSB(IntMask, fldname##17IntMask)), \ |
1309 | .msg = #fldname "_C", .sz = sizeof(#fldname "_C") } | 1309 | .msg = #fldname "_C", .sz = sizeof(#fldname "_C") } |
1310 | 1310 | ||
1311 | static const struct qib_hwerror_msgs qib_7322_intr_msgs[] = { | ||
1312 | INTR_AUTO_P(SDmaInt), | ||
1313 | INTR_AUTO_P(SDmaProgressInt), | ||
1314 | INTR_AUTO_P(SDmaIdleInt), | ||
1315 | INTR_AUTO_P(SDmaCleanupDone), | ||
1316 | INTR_AUTO_C(RcvUrg), | ||
1317 | INTR_AUTO_P(ErrInt), | ||
1318 | INTR_AUTO(ErrInt), /* non-port-specific errs */ | ||
1319 | INTR_AUTO(AssertGPIOInt), | ||
1320 | INTR_AUTO_P(SendDoneInt), | ||
1321 | INTR_AUTO(SendBufAvailInt), | ||
1322 | INTR_AUTO_C(RcvAvail), | ||
1323 | { .mask = 0, .sz = 0 } | ||
1324 | }; | ||
1325 | |||
1326 | #define TXSYMPTOM_AUTO_P(fldname) \ | 1311 | #define TXSYMPTOM_AUTO_P(fldname) \ |
1327 | { .mask = SYM_MASK(SendHdrErrSymptom_0, fldname), \ | 1312 | { .mask = SYM_MASK(SendHdrErrSymptom_0, fldname), \ |
1328 | .msg = #fldname, .sz = sizeof(#fldname) } | 1313 | .msg = #fldname, .sz = sizeof(#fldname) } |
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h index 6888f03c6d61..4f878151f81f 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.h +++ b/drivers/infiniband/hw/qib/qib_verbs.h | |||
@@ -159,6 +159,7 @@ struct qib_other_headers { | |||
159 | } at; | 159 | } at; |
160 | __be32 imm_data; | 160 | __be32 imm_data; |
161 | __be32 aeth; | 161 | __be32 aeth; |
162 | __be32 ieth; | ||
162 | struct ib_atomic_eth atomic_eth; | 163 | struct ib_atomic_eth atomic_eth; |
163 | } u; | 164 | } u; |
164 | } __packed; | 165 | } __packed; |
diff --git a/drivers/infiniband/sw/rdmavt/cq.c b/drivers/infiniband/sw/rdmavt/cq.c index b1ffc8b4a6c0..6ca6fa80dd6e 100644 --- a/drivers/infiniband/sw/rdmavt/cq.c +++ b/drivers/infiniband/sw/rdmavt/cq.c | |||
@@ -525,6 +525,7 @@ int rvt_driver_cq_init(struct rvt_dev_info *rdi) | |||
525 | return PTR_ERR(task); | 525 | return PTR_ERR(task); |
526 | } | 526 | } |
527 | 527 | ||
528 | set_user_nice(task, MIN_NICE); | ||
528 | cpu = cpumask_first(cpumask_of_node(rdi->dparms.node)); | 529 | cpu = cpumask_first(cpumask_of_node(rdi->dparms.node)); |
529 | kthread_bind(task, cpu); | 530 | kthread_bind(task, cpu); |
530 | wake_up_process(task); | 531 | wake_up_process(task); |
diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c index 0ff765bfd619..0f4d4500f45e 100644 --- a/drivers/infiniband/sw/rdmavt/mr.c +++ b/drivers/infiniband/sw/rdmavt/mr.c | |||
@@ -124,11 +124,13 @@ static int rvt_init_mregion(struct rvt_mregion *mr, struct ib_pd *pd, | |||
124 | int count) | 124 | int count) |
125 | { | 125 | { |
126 | int m, i = 0; | 126 | int m, i = 0; |
127 | struct rvt_dev_info *dev = ib_to_rvt(pd->device); | ||
127 | 128 | ||
128 | mr->mapsz = 0; | 129 | mr->mapsz = 0; |
129 | m = (count + RVT_SEGSZ - 1) / RVT_SEGSZ; | 130 | m = (count + RVT_SEGSZ - 1) / RVT_SEGSZ; |
130 | for (; i < m; i++) { | 131 | for (; i < m; i++) { |
131 | mr->map[i] = kzalloc(sizeof(*mr->map[0]), GFP_KERNEL); | 132 | mr->map[i] = kzalloc_node(sizeof(*mr->map[0]), GFP_KERNEL, |
133 | dev->dparms.node); | ||
132 | if (!mr->map[i]) { | 134 | if (!mr->map[i]) { |
133 | rvt_deinit_mregion(mr); | 135 | rvt_deinit_mregion(mr); |
134 | return -ENOMEM; | 136 | return -ENOMEM; |
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index 0f12c211c385..5fa4d4d81ee0 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c | |||
@@ -397,6 +397,7 @@ static void free_qpn(struct rvt_qpn_table *qpt, u32 qpn) | |||
397 | static void rvt_clear_mr_refs(struct rvt_qp *qp, int clr_sends) | 397 | static void rvt_clear_mr_refs(struct rvt_qp *qp, int clr_sends) |
398 | { | 398 | { |
399 | unsigned n; | 399 | unsigned n; |
400 | struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device); | ||
400 | 401 | ||
401 | if (test_and_clear_bit(RVT_R_REWIND_SGE, &qp->r_aflags)) | 402 | if (test_and_clear_bit(RVT_R_REWIND_SGE, &qp->r_aflags)) |
402 | rvt_put_ss(&qp->s_rdma_read_sge); | 403 | rvt_put_ss(&qp->s_rdma_read_sge); |
@@ -431,7 +432,7 @@ static void rvt_clear_mr_refs(struct rvt_qp *qp, int clr_sends) | |||
431 | if (qp->ibqp.qp_type != IB_QPT_RC) | 432 | if (qp->ibqp.qp_type != IB_QPT_RC) |
432 | return; | 433 | return; |
433 | 434 | ||
434 | for (n = 0; n < ARRAY_SIZE(qp->s_ack_queue); n++) { | 435 | for (n = 0; n < rvt_max_atomic(rdi); n++) { |
435 | struct rvt_ack_entry *e = &qp->s_ack_queue[n]; | 436 | struct rvt_ack_entry *e = &qp->s_ack_queue[n]; |
436 | 437 | ||
437 | if (e->opcode == IB_OPCODE_RC_RDMA_READ_REQUEST && | 438 | if (e->opcode == IB_OPCODE_RC_RDMA_READ_REQUEST && |
@@ -569,7 +570,12 @@ static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, | |||
569 | qp->s_ssn = 1; | 570 | qp->s_ssn = 1; |
570 | qp->s_lsn = 0; | 571 | qp->s_lsn = 0; |
571 | qp->s_mig_state = IB_MIG_MIGRATED; | 572 | qp->s_mig_state = IB_MIG_MIGRATED; |
572 | memset(qp->s_ack_queue, 0, sizeof(qp->s_ack_queue)); | 573 | if (qp->s_ack_queue) |
574 | memset( | ||
575 | qp->s_ack_queue, | ||
576 | 0, | ||
577 | rvt_max_atomic(rdi) * | ||
578 | sizeof(*qp->s_ack_queue)); | ||
573 | qp->r_head_ack_queue = 0; | 579 | qp->r_head_ack_queue = 0; |
574 | qp->s_tail_ack_queue = 0; | 580 | qp->s_tail_ack_queue = 0; |
575 | qp->s_num_rd_atomic = 0; | 581 | qp->s_num_rd_atomic = 0; |
@@ -653,9 +659,9 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, | |||
653 | if (gfp == GFP_NOIO) | 659 | if (gfp == GFP_NOIO) |
654 | swq = __vmalloc( | 660 | swq = __vmalloc( |
655 | (init_attr->cap.max_send_wr + 1) * sz, | 661 | (init_attr->cap.max_send_wr + 1) * sz, |
656 | gfp, PAGE_KERNEL); | 662 | gfp | __GFP_ZERO, PAGE_KERNEL); |
657 | else | 663 | else |
658 | swq = vmalloc_node( | 664 | swq = vzalloc_node( |
659 | (init_attr->cap.max_send_wr + 1) * sz, | 665 | (init_attr->cap.max_send_wr + 1) * sz, |
660 | rdi->dparms.node); | 666 | rdi->dparms.node); |
661 | if (!swq) | 667 | if (!swq) |
@@ -677,6 +683,16 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, | |||
677 | goto bail_swq; | 683 | goto bail_swq; |
678 | 684 | ||
679 | RCU_INIT_POINTER(qp->next, NULL); | 685 | RCU_INIT_POINTER(qp->next, NULL); |
686 | if (init_attr->qp_type == IB_QPT_RC) { | ||
687 | qp->s_ack_queue = | ||
688 | kzalloc_node( | ||
689 | sizeof(*qp->s_ack_queue) * | ||
690 | rvt_max_atomic(rdi), | ||
691 | gfp, | ||
692 | rdi->dparms.node); | ||
693 | if (!qp->s_ack_queue) | ||
694 | goto bail_qp; | ||
695 | } | ||
680 | 696 | ||
681 | /* | 697 | /* |
682 | * Driver needs to set up it's private QP structure and do any | 698 | * Driver needs to set up it's private QP structure and do any |
@@ -704,9 +720,9 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, | |||
704 | qp->r_rq.wq = __vmalloc( | 720 | qp->r_rq.wq = __vmalloc( |
705 | sizeof(struct rvt_rwq) + | 721 | sizeof(struct rvt_rwq) + |
706 | qp->r_rq.size * sz, | 722 | qp->r_rq.size * sz, |
707 | gfp, PAGE_KERNEL); | 723 | gfp | __GFP_ZERO, PAGE_KERNEL); |
708 | else | 724 | else |
709 | qp->r_rq.wq = vmalloc_node( | 725 | qp->r_rq.wq = vzalloc_node( |
710 | sizeof(struct rvt_rwq) + | 726 | sizeof(struct rvt_rwq) + |
711 | qp->r_rq.size * sz, | 727 | qp->r_rq.size * sz, |
712 | rdi->dparms.node); | 728 | rdi->dparms.node); |
@@ -857,6 +873,7 @@ bail_driver_priv: | |||
857 | rdi->driver_f.qp_priv_free(rdi, qp); | 873 | rdi->driver_f.qp_priv_free(rdi, qp); |
858 | 874 | ||
859 | bail_qp: | 875 | bail_qp: |
876 | kfree(qp->s_ack_queue); | ||
860 | kfree(qp); | 877 | kfree(qp); |
861 | 878 | ||
862 | bail_swq: | 879 | bail_swq: |
@@ -1284,6 +1301,7 @@ int rvt_destroy_qp(struct ib_qp *ibqp) | |||
1284 | vfree(qp->r_rq.wq); | 1301 | vfree(qp->r_rq.wq); |
1285 | vfree(qp->s_wq); | 1302 | vfree(qp->s_wq); |
1286 | rdi->driver_f.qp_priv_free(rdi, qp); | 1303 | rdi->driver_f.qp_priv_free(rdi, qp); |
1304 | kfree(qp->s_ack_queue); | ||
1287 | kfree(qp); | 1305 | kfree(qp); |
1288 | return 0; | 1306 | return 0; |
1289 | } | 1307 | } |
diff --git a/drivers/staging/rdma/Kconfig b/drivers/staging/rdma/Kconfig index f1f3ecadf0fb..2c5b0188ebbf 100644 --- a/drivers/staging/rdma/Kconfig +++ b/drivers/staging/rdma/Kconfig | |||
@@ -22,6 +22,4 @@ menuconfig STAGING_RDMA | |||
22 | # Please keep entries in alphabetic order | 22 | # Please keep entries in alphabetic order |
23 | if STAGING_RDMA | 23 | if STAGING_RDMA |
24 | 24 | ||
25 | source "drivers/staging/rdma/hfi1/Kconfig" | ||
26 | |||
27 | endif | 25 | endif |
diff --git a/drivers/staging/rdma/Makefile b/drivers/staging/rdma/Makefile index 8c7fc1de48a7..b5e94f169101 100644 --- a/drivers/staging/rdma/Makefile +++ b/drivers/staging/rdma/Makefile | |||
@@ -1,2 +1 @@ | |||
1 | # Entries for RDMA_STAGING tree | # Entries for RDMA_STAGING tree | |
2 | obj-$(CONFIG_INFINIBAND_HFI1) += hfi1/ | ||
diff --git a/drivers/staging/rdma/hfi1/TODO b/drivers/staging/rdma/hfi1/TODO deleted file mode 100644 index 4c6f1d7d2eaf..000000000000 --- a/drivers/staging/rdma/hfi1/TODO +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | July, 2015 | ||
2 | |||
3 | - Remove unneeded file entries in sysfs | ||
4 | - Remove software processing of IB protocol and place in library for use | ||
5 | by qib, ipath (if still present), hfi1, and eventually soft-roce | ||
6 | - Replace incorrect uAPI | ||
diff --git a/drivers/staging/rdma/hfi1/diag.c b/drivers/staging/rdma/hfi1/diag.c deleted file mode 100644 index bb2409ad891a..000000000000 --- a/drivers/staging/rdma/hfi1/diag.c +++ /dev/null | |||
@@ -1,1925 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright(c) 2015, 2016 Intel Corporation. | ||
3 | * | ||
4 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
5 | * redistributing this file, you may do so under either license. | ||
6 | * | ||
7 | * GPL LICENSE SUMMARY | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of version 2 of the GNU General Public License as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * BSD LICENSE | ||
19 | * | ||
20 | * Redistribution and use in source and binary forms, with or without | ||
21 | * modification, are permitted provided that the following conditions | ||
22 | * are met: | ||
23 | * | ||
24 | * - Redistributions of source code must retain the above copyright | ||
25 | * notice, this list of conditions and the following disclaimer. | ||
26 | * - Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * - Neither the name of Intel Corporation nor the names of its | ||
31 | * contributors may be used to endorse or promote products derived | ||
32 | * from this software without specific prior written permission. | ||
33 | * | ||
34 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
35 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
36 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
37 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
38 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
39 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
40 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
41 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
42 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
43 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
44 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | /* | ||
49 | * This file contains support for diagnostic functions. It is accessed by | ||
50 | * opening the hfi1_diag device, normally minor number 129. Diagnostic use | ||
51 | * of the chip may render the chip or board unusable until the driver | ||
52 | * is unloaded, or in some cases, until the system is rebooted. | ||
53 | * | ||
54 | * Accesses to the chip through this interface are not similar to going | ||
55 | * through the /sys/bus/pci resource mmap interface. | ||
56 | */ | ||
57 | |||
58 | #include <linux/io.h> | ||
59 | #include <linux/pci.h> | ||
60 | #include <linux/poll.h> | ||
61 | #include <linux/vmalloc.h> | ||
62 | #include <linux/export.h> | ||
63 | #include <linux/fs.h> | ||
64 | #include <linux/uaccess.h> | ||
65 | #include <linux/module.h> | ||
66 | #include <rdma/ib_smi.h> | ||
67 | #include "hfi.h" | ||
68 | #include "device.h" | ||
69 | #include "common.h" | ||
70 | #include "verbs_txreq.h" | ||
71 | #include "trace.h" | ||
72 | |||
73 | #undef pr_fmt | ||
74 | #define pr_fmt(fmt) DRIVER_NAME ": " fmt | ||
75 | #define snoop_dbg(fmt, ...) \ | ||
76 | hfi1_cdbg(SNOOP, fmt, ##__VA_ARGS__) | ||
77 | |||
78 | /* Snoop option mask */ | ||
79 | #define SNOOP_DROP_SEND BIT(0) | ||
80 | #define SNOOP_USE_METADATA BIT(1) | ||
81 | #define SNOOP_SET_VL0TOVL15 BIT(2) | ||
82 | |||
83 | static u8 snoop_flags; | ||
84 | |||
85 | /* | ||
86 | * Extract packet length from LRH header. | ||
87 | * This is in Dwords so multiply by 4 to get size in bytes | ||
88 | */ | ||
89 | #define HFI1_GET_PKT_LEN(x) (((be16_to_cpu((x)->lrh[2]) & 0xFFF)) << 2) | ||
90 | |||
91 | enum hfi1_filter_status { | ||
92 | HFI1_FILTER_HIT, | ||
93 | HFI1_FILTER_ERR, | ||
94 | HFI1_FILTER_MISS | ||
95 | }; | ||
96 | |||
97 | /* snoop processing functions */ | ||
98 | rhf_rcv_function_ptr snoop_rhf_rcv_functions[8] = { | ||
99 | [RHF_RCV_TYPE_EXPECTED] = snoop_recv_handler, | ||
100 | [RHF_RCV_TYPE_EAGER] = snoop_recv_handler, | ||
101 | [RHF_RCV_TYPE_IB] = snoop_recv_handler, | ||
102 | [RHF_RCV_TYPE_ERROR] = snoop_recv_handler, | ||
103 | [RHF_RCV_TYPE_BYPASS] = snoop_recv_handler, | ||
104 | [RHF_RCV_TYPE_INVALID5] = process_receive_invalid, | ||
105 | [RHF_RCV_TYPE_INVALID6] = process_receive_invalid, | ||
106 | [RHF_RCV_TYPE_INVALID7] = process_receive_invalid | ||
107 | }; | ||
108 | |||
109 | /* Snoop packet structure */ | ||
110 | struct snoop_packet { | ||
111 | struct list_head list; | ||
112 | u32 total_len; | ||
113 | u8 data[]; | ||
114 | }; | ||
115 | |||
116 | /* Do not make these an enum or it will blow up the capture_md */ | ||
117 | #define PKT_DIR_EGRESS 0x0 | ||
118 | #define PKT_DIR_INGRESS 0x1 | ||
119 | |||
120 | /* Packet capture metadata returned to the user with the packet. */ | ||
121 | struct capture_md { | ||
122 | u8 port; | ||
123 | u8 dir; | ||
124 | u8 reserved[6]; | ||
125 | union { | ||
126 | u64 pbc; | ||
127 | u64 rhf; | ||
128 | } u; | ||
129 | }; | ||
130 | |||
131 | static atomic_t diagpkt_count = ATOMIC_INIT(0); | ||
132 | static struct cdev diagpkt_cdev; | ||
133 | static struct device *diagpkt_device; | ||
134 | |||
135 | static ssize_t diagpkt_write(struct file *fp, const char __user *data, | ||
136 | size_t count, loff_t *off); | ||
137 | |||
138 | static const struct file_operations diagpkt_file_ops = { | ||
139 | .owner = THIS_MODULE, | ||
140 | .write = diagpkt_write, | ||
141 | .llseek = noop_llseek, | ||
142 | }; | ||
143 | |||
144 | /* | ||
145 | * This is used for communication with user space for snoop extended IOCTLs | ||
146 | */ | ||
147 | struct hfi1_link_info { | ||
148 | __be64 node_guid; | ||
149 | u8 port_mode; | ||
150 | u8 port_state; | ||
151 | u16 link_speed_active; | ||
152 | u16 link_width_active; | ||
153 | u16 vl15_init; | ||
154 | u8 port_number; | ||
155 | /* | ||
156 | * Add padding to make this a full IB SMP payload. Note: changing the | ||
157 | * size of this structure will make the IOCTLs created with _IOWR | ||
158 | * change. | ||
159 | * Be sure to run tests on all IOCTLs when making changes to this | ||
160 | * structure. | ||
161 | */ | ||
162 | u8 res[47]; | ||
163 | }; | ||
164 | |||
165 | /* | ||
166 | * This starts our ioctl sequence numbers *way* off from the ones | ||
167 | * defined in ib_core. | ||
168 | */ | ||
169 | #define SNOOP_CAPTURE_VERSION 0x1 | ||
170 | |||
171 | #define IB_IOCTL_MAGIC 0x1b /* See Documentation/ioctl-number.txt */ | ||
172 | #define HFI1_SNOOP_IOC_MAGIC IB_IOCTL_MAGIC | ||
173 | #define HFI1_SNOOP_IOC_BASE_SEQ 0x80 | ||
174 | |||
175 | #define HFI1_SNOOP_IOCGETLINKSTATE \ | ||
176 | _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ) | ||
177 | #define HFI1_SNOOP_IOCSETLINKSTATE \ | ||
178 | _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 1) | ||
179 | #define HFI1_SNOOP_IOCCLEARQUEUE \ | ||
180 | _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 2) | ||
181 | #define HFI1_SNOOP_IOCCLEARFILTER \ | ||
182 | _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 3) | ||
183 | #define HFI1_SNOOP_IOCSETFILTER \ | ||
184 | _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 4) | ||
185 | #define HFI1_SNOOP_IOCGETVERSION \ | ||
186 | _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 5) | ||
187 | #define HFI1_SNOOP_IOCSET_OPTS \ | ||
188 | _IO(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 6) | ||
189 | |||
190 | /* | ||
191 | * These offsets +6/+7 could change, but these are already known and used | ||
192 | * IOCTL numbers so don't change them without a good reason. | ||
193 | */ | ||
194 | #define HFI1_SNOOP_IOCGETLINKSTATE_EXTRA \ | ||
195 | _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 6, \ | ||
196 | struct hfi1_link_info) | ||
197 | #define HFI1_SNOOP_IOCSETLINKSTATE_EXTRA \ | ||
198 | _IOWR(HFI1_SNOOP_IOC_MAGIC, HFI1_SNOOP_IOC_BASE_SEQ + 7, \ | ||
199 | struct hfi1_link_info) | ||
200 | |||
201 | static int hfi1_snoop_open(struct inode *in, struct file *fp); | ||
202 | static ssize_t hfi1_snoop_read(struct file *fp, char __user *data, | ||
203 | size_t pkt_len, loff_t *off); | ||
204 | static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data, | ||
205 | size_t count, loff_t *off); | ||
206 | static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg); | ||
207 | static unsigned int hfi1_snoop_poll(struct file *fp, | ||
208 | struct poll_table_struct *wait); | ||
209 | static int hfi1_snoop_release(struct inode *in, struct file *fp); | ||
210 | |||
211 | struct hfi1_packet_filter_command { | ||
212 | int opcode; | ||
213 | int length; | ||
214 | void *value_ptr; | ||
215 | }; | ||
216 | |||
217 | /* Can't re-use PKT_DIR_*GRESS here because 0 means no packets for this */ | ||
218 | #define HFI1_SNOOP_INGRESS 0x1 | ||
219 | #define HFI1_SNOOP_EGRESS 0x2 | ||
220 | |||
221 | enum hfi1_packet_filter_opcodes { | ||
222 | FILTER_BY_LID, | ||
223 | FILTER_BY_DLID, | ||
224 | FILTER_BY_MAD_MGMT_CLASS, | ||
225 | FILTER_BY_QP_NUMBER, | ||
226 | FILTER_BY_PKT_TYPE, | ||
227 | FILTER_BY_SERVICE_LEVEL, | ||
228 | FILTER_BY_PKEY, | ||
229 | FILTER_BY_DIRECTION, | ||
230 | }; | ||
231 | |||
232 | static const struct file_operations snoop_file_ops = { | ||
233 | .owner = THIS_MODULE, | ||
234 | .open = hfi1_snoop_open, | ||
235 | .read = hfi1_snoop_read, | ||
236 | .unlocked_ioctl = hfi1_ioctl, | ||
237 | .poll = hfi1_snoop_poll, | ||
238 | .write = hfi1_snoop_write, | ||
239 | .release = hfi1_snoop_release | ||
240 | }; | ||
241 | |||
242 | struct hfi1_filter_array { | ||
243 | int (*filter)(void *, void *, void *); | ||
244 | }; | ||
245 | |||
246 | static int hfi1_filter_lid(void *ibhdr, void *packet_data, void *value); | ||
247 | static int hfi1_filter_dlid(void *ibhdr, void *packet_data, void *value); | ||
248 | static int hfi1_filter_mad_mgmt_class(void *ibhdr, void *packet_data, | ||
249 | void *value); | ||
250 | static int hfi1_filter_qp_number(void *ibhdr, void *packet_data, void *value); | ||
251 | static int hfi1_filter_ibpacket_type(void *ibhdr, void *packet_data, | ||
252 | void *value); | ||
253 | static int hfi1_filter_ib_service_level(void *ibhdr, void *packet_data, | ||
254 | void *value); | ||
255 | static int hfi1_filter_ib_pkey(void *ibhdr, void *packet_data, void *value); | ||
256 | static int hfi1_filter_direction(void *ibhdr, void *packet_data, void *value); | ||
257 | |||
258 | static const struct hfi1_filter_array hfi1_filters[] = { | ||
259 | { hfi1_filter_lid }, | ||
260 | { hfi1_filter_dlid }, | ||
261 | { hfi1_filter_mad_mgmt_class }, | ||
262 | { hfi1_filter_qp_number }, | ||
263 | { hfi1_filter_ibpacket_type }, | ||
264 | { hfi1_filter_ib_service_level }, | ||
265 | { hfi1_filter_ib_pkey }, | ||
266 | { hfi1_filter_direction }, | ||
267 | }; | ||
268 | |||
269 | #define HFI1_MAX_FILTERS ARRAY_SIZE(hfi1_filters) | ||
270 | #define HFI1_DIAG_MINOR_BASE 129 | ||
271 | |||
272 | static int hfi1_snoop_add(struct hfi1_devdata *dd, const char *name); | ||
273 | |||
274 | int hfi1_diag_add(struct hfi1_devdata *dd) | ||
275 | { | ||
276 | char name[16]; | ||
277 | int ret = 0; | ||
278 | |||
279 | snprintf(name, sizeof(name), "%s_diagpkt%d", class_name(), | ||
280 | dd->unit); | ||
281 | /* | ||
282 | * Do this for each device as opposed to the normal diagpkt | ||
283 | * interface which is one per host | ||
284 | */ | ||
285 | ret = hfi1_snoop_add(dd, name); | ||
286 | if (ret) | ||
287 | dd_dev_err(dd, "Unable to init snoop/capture device"); | ||
288 | |||
289 | snprintf(name, sizeof(name), "%s_diagpkt", class_name()); | ||
290 | if (atomic_inc_return(&diagpkt_count) == 1) { | ||
291 | ret = hfi1_cdev_init(HFI1_DIAGPKT_MINOR, name, | ||
292 | &diagpkt_file_ops, &diagpkt_cdev, | ||
293 | &diagpkt_device, false); | ||
294 | } | ||
295 | |||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | /* this must be called w/ dd->snoop_in_lock held */ | ||
300 | static void drain_snoop_list(struct list_head *queue) | ||
301 | { | ||
302 | struct list_head *pos, *q; | ||
303 | struct snoop_packet *packet; | ||
304 | |||
305 | list_for_each_safe(pos, q, queue) { | ||
306 | packet = list_entry(pos, struct snoop_packet, list); | ||
307 | list_del(pos); | ||
308 | kfree(packet); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | static void hfi1_snoop_remove(struct hfi1_devdata *dd) | ||
313 | { | ||
314 | unsigned long flags = 0; | ||
315 | |||
316 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
317 | drain_snoop_list(&dd->hfi1_snoop.queue); | ||
318 | hfi1_cdev_cleanup(&dd->hfi1_snoop.cdev, &dd->hfi1_snoop.class_dev); | ||
319 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
320 | } | ||
321 | |||
322 | void hfi1_diag_remove(struct hfi1_devdata *dd) | ||
323 | { | ||
324 | hfi1_snoop_remove(dd); | ||
325 | if (atomic_dec_and_test(&diagpkt_count)) | ||
326 | hfi1_cdev_cleanup(&diagpkt_cdev, &diagpkt_device); | ||
327 | hfi1_cdev_cleanup(&dd->diag_cdev, &dd->diag_device); | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * Allocated structure shared between the credit return mechanism and | ||
332 | * diagpkt_send(). | ||
333 | */ | ||
334 | struct diagpkt_wait { | ||
335 | struct completion credits_returned; | ||
336 | int code; | ||
337 | atomic_t count; | ||
338 | }; | ||
339 | |||
340 | /* | ||
341 | * When each side is finished with the structure, they call this. | ||
342 | * The last user frees the structure. | ||
343 | */ | ||
344 | static void put_diagpkt_wait(struct diagpkt_wait *wait) | ||
345 | { | ||
346 | if (atomic_dec_and_test(&wait->count)) | ||
347 | kfree(wait); | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * Callback from the credit return code. Set the complete, which | ||
352 | * will let diapkt_send() continue. | ||
353 | */ | ||
354 | static void diagpkt_complete(void *arg, int code) | ||
355 | { | ||
356 | struct diagpkt_wait *wait = (struct diagpkt_wait *)arg; | ||
357 | |||
358 | wait->code = code; | ||
359 | complete(&wait->credits_returned); | ||
360 | put_diagpkt_wait(wait); /* finished with the structure */ | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * diagpkt_send - send a packet | ||
365 | * @dp: diag packet descriptor | ||
366 | */ | ||
367 | static ssize_t diagpkt_send(struct diag_pkt *dp) | ||
368 | { | ||
369 | struct hfi1_devdata *dd; | ||
370 | struct send_context *sc; | ||
371 | struct pio_buf *pbuf; | ||
372 | u32 *tmpbuf = NULL; | ||
373 | ssize_t ret = 0; | ||
374 | u32 pkt_len, total_len; | ||
375 | pio_release_cb credit_cb = NULL; | ||
376 | void *credit_arg = NULL; | ||
377 | struct diagpkt_wait *wait = NULL; | ||
378 | int trycount = 0; | ||
379 | |||
380 | dd = hfi1_lookup(dp->unit); | ||
381 | if (!dd || !(dd->flags & HFI1_PRESENT) || !dd->kregbase) { | ||
382 | ret = -ENODEV; | ||
383 | goto bail; | ||
384 | } | ||
385 | if (!(dd->flags & HFI1_INITTED)) { | ||
386 | /* no hardware, freeze, etc. */ | ||
387 | ret = -ENODEV; | ||
388 | goto bail; | ||
389 | } | ||
390 | |||
391 | if (dp->version != _DIAG_PKT_VERS) { | ||
392 | dd_dev_err(dd, "Invalid version %u for diagpkt_write\n", | ||
393 | dp->version); | ||
394 | ret = -EINVAL; | ||
395 | goto bail; | ||
396 | } | ||
397 | |||
398 | /* send count must be an exact number of dwords */ | ||
399 | if (dp->len & 3) { | ||
400 | ret = -EINVAL; | ||
401 | goto bail; | ||
402 | } | ||
403 | |||
404 | /* there is only port 1 */ | ||
405 | if (dp->port != 1) { | ||
406 | ret = -EINVAL; | ||
407 | goto bail; | ||
408 | } | ||
409 | |||
410 | /* need a valid context */ | ||
411 | if (dp->sw_index >= dd->num_send_contexts) { | ||
412 | ret = -EINVAL; | ||
413 | goto bail; | ||
414 | } | ||
415 | /* can only use kernel contexts */ | ||
416 | if (dd->send_contexts[dp->sw_index].type != SC_KERNEL && | ||
417 | dd->send_contexts[dp->sw_index].type != SC_VL15) { | ||
418 | ret = -EINVAL; | ||
419 | goto bail; | ||
420 | } | ||
421 | /* must be allocated */ | ||
422 | sc = dd->send_contexts[dp->sw_index].sc; | ||
423 | if (!sc) { | ||
424 | ret = -EINVAL; | ||
425 | goto bail; | ||
426 | } | ||
427 | /* must be enabled */ | ||
428 | if (!(sc->flags & SCF_ENABLED)) { | ||
429 | ret = -EINVAL; | ||
430 | goto bail; | ||
431 | } | ||
432 | |||
433 | /* allocate a buffer and copy the data in */ | ||
434 | tmpbuf = vmalloc(dp->len); | ||
435 | if (!tmpbuf) { | ||
436 | ret = -ENOMEM; | ||
437 | goto bail; | ||
438 | } | ||
439 | |||
440 | if (copy_from_user(tmpbuf, | ||
441 | (const void __user *)(unsigned long)dp->data, | ||
442 | dp->len)) { | ||
443 | ret = -EFAULT; | ||
444 | goto bail; | ||
445 | } | ||
446 | |||
447 | /* | ||
448 | * pkt_len is how much data we have to write, includes header and data. | ||
449 | * total_len is length of the packet in Dwords plus the PBC should not | ||
450 | * include the CRC. | ||
451 | */ | ||
452 | pkt_len = dp->len >> 2; | ||
453 | total_len = pkt_len + 2; /* PBC + packet */ | ||
454 | |||
455 | /* if 0, fill in a default */ | ||
456 | if (dp->pbc == 0) { | ||
457 | struct hfi1_pportdata *ppd = dd->pport; | ||
458 | |||
459 | hfi1_cdbg(PKT, "Generating PBC"); | ||
460 | dp->pbc = create_pbc(ppd, 0, 0, 0, total_len); | ||
461 | } else { | ||
462 | hfi1_cdbg(PKT, "Using passed in PBC"); | ||
463 | } | ||
464 | |||
465 | hfi1_cdbg(PKT, "Egress PBC content is 0x%llx", dp->pbc); | ||
466 | |||
467 | /* | ||
468 | * The caller wants to wait until the packet is sent and to | ||
469 | * check for errors. The best we can do is wait until | ||
470 | * the buffer credits are returned and check if any packet | ||
471 | * error has occurred. If there are any late errors, this | ||
472 | * could miss it. If there are other senders who generate | ||
473 | * an error, this may find it. However, in general, it | ||
474 | * should catch most. | ||
475 | */ | ||
476 | if (dp->flags & F_DIAGPKT_WAIT) { | ||
477 | /* always force a credit return */ | ||
478 | dp->pbc |= PBC_CREDIT_RETURN; | ||
479 | /* turn on credit return interrupts */ | ||
480 | sc_add_credit_return_intr(sc); | ||
481 | wait = kmalloc(sizeof(*wait), GFP_KERNEL); | ||
482 | if (!wait) { | ||
483 | ret = -ENOMEM; | ||
484 | goto bail; | ||
485 | } | ||
486 | init_completion(&wait->credits_returned); | ||
487 | atomic_set(&wait->count, 2); | ||
488 | wait->code = PRC_OK; | ||
489 | |||
490 | credit_cb = diagpkt_complete; | ||
491 | credit_arg = wait; | ||
492 | } | ||
493 | |||
494 | retry: | ||
495 | pbuf = sc_buffer_alloc(sc, total_len, credit_cb, credit_arg); | ||
496 | if (!pbuf) { | ||
497 | if (trycount == 0) { | ||
498 | /* force a credit return and try again */ | ||
499 | sc_return_credits(sc); | ||
500 | trycount = 1; | ||
501 | goto retry; | ||
502 | } | ||
503 | /* | ||
504 | * No send buffer means no credit callback. Undo | ||
505 | * the wait set-up that was done above. We free wait | ||
506 | * because the callback will never be called. | ||
507 | */ | ||
508 | if (dp->flags & F_DIAGPKT_WAIT) { | ||
509 | sc_del_credit_return_intr(sc); | ||
510 | kfree(wait); | ||
511 | wait = NULL; | ||
512 | } | ||
513 | ret = -ENOSPC; | ||
514 | goto bail; | ||
515 | } | ||
516 | |||
517 | pio_copy(dd, pbuf, dp->pbc, tmpbuf, pkt_len); | ||
518 | /* no flush needed as the HW knows the packet size */ | ||
519 | |||
520 | ret = sizeof(*dp); | ||
521 | |||
522 | if (dp->flags & F_DIAGPKT_WAIT) { | ||
523 | /* wait for credit return */ | ||
524 | ret = wait_for_completion_interruptible( | ||
525 | &wait->credits_returned); | ||
526 | /* | ||
527 | * If the wait returns an error, the wait was interrupted, | ||
528 | * e.g. with a ^C in the user program. The callback is | ||
529 | * still pending. This is OK as the wait structure is | ||
530 | * kmalloc'ed and the structure will free itself when | ||
531 | * all users are done with it. | ||
532 | * | ||
533 | * A context disable occurs on a send context restart, so | ||
534 | * include that in the list of errors below to check for. | ||
535 | * NOTE: PRC_FILL_ERR is at best informational and cannot | ||
536 | * be depended on. | ||
537 | */ | ||
538 | if (!ret && (((wait->code & PRC_STATUS_ERR) || | ||
539 | (wait->code & PRC_FILL_ERR) || | ||
540 | (wait->code & PRC_SC_DISABLE)))) | ||
541 | ret = -EIO; | ||
542 | |||
543 | put_diagpkt_wait(wait); /* finished with the structure */ | ||
544 | sc_del_credit_return_intr(sc); | ||
545 | } | ||
546 | |||
547 | bail: | ||
548 | vfree(tmpbuf); | ||
549 | return ret; | ||
550 | } | ||
551 | |||
552 | static ssize_t diagpkt_write(struct file *fp, const char __user *data, | ||
553 | size_t count, loff_t *off) | ||
554 | { | ||
555 | struct hfi1_devdata *dd; | ||
556 | struct send_context *sc; | ||
557 | u8 vl; | ||
558 | |||
559 | struct diag_pkt dp; | ||
560 | |||
561 | if (count != sizeof(dp)) | ||
562 | return -EINVAL; | ||
563 | |||
564 | if (copy_from_user(&dp, data, sizeof(dp))) | ||
565 | return -EFAULT; | ||
566 | |||
567 | /* | ||
568 | * The Send Context is derived from the PbcVL value | ||
569 | * if PBC is populated | ||
570 | */ | ||
571 | if (dp.pbc) { | ||
572 | dd = hfi1_lookup(dp.unit); | ||
573 | if (!dd) | ||
574 | return -ENODEV; | ||
575 | vl = (dp.pbc >> PBC_VL_SHIFT) & PBC_VL_MASK; | ||
576 | sc = dd->vld[vl].sc; | ||
577 | if (sc) { | ||
578 | dp.sw_index = sc->sw_index; | ||
579 | hfi1_cdbg( | ||
580 | PKT, | ||
581 | "Packet sent over VL %d via Send Context %u(%u)", | ||
582 | vl, sc->sw_index, sc->hw_context); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | return diagpkt_send(&dp); | ||
587 | } | ||
588 | |||
589 | static int hfi1_snoop_add(struct hfi1_devdata *dd, const char *name) | ||
590 | { | ||
591 | int ret = 0; | ||
592 | |||
593 | dd->hfi1_snoop.mode_flag = 0; | ||
594 | spin_lock_init(&dd->hfi1_snoop.snoop_lock); | ||
595 | INIT_LIST_HEAD(&dd->hfi1_snoop.queue); | ||
596 | init_waitqueue_head(&dd->hfi1_snoop.waitq); | ||
597 | |||
598 | ret = hfi1_cdev_init(HFI1_SNOOP_CAPTURE_BASE + dd->unit, name, | ||
599 | &snoop_file_ops, | ||
600 | &dd->hfi1_snoop.cdev, &dd->hfi1_snoop.class_dev, | ||
601 | false); | ||
602 | |||
603 | if (ret) { | ||
604 | dd_dev_err(dd, "Couldn't create %s device: %d", name, ret); | ||
605 | hfi1_cdev_cleanup(&dd->hfi1_snoop.cdev, | ||
606 | &dd->hfi1_snoop.class_dev); | ||
607 | } | ||
608 | |||
609 | return ret; | ||
610 | } | ||
611 | |||
612 | static struct hfi1_devdata *hfi1_dd_from_sc_inode(struct inode *in) | ||
613 | { | ||
614 | int unit = iminor(in) - HFI1_SNOOP_CAPTURE_BASE; | ||
615 | struct hfi1_devdata *dd; | ||
616 | |||
617 | dd = hfi1_lookup(unit); | ||
618 | return dd; | ||
619 | } | ||
620 | |||
621 | /* clear or restore send context integrity checks */ | ||
622 | static void adjust_integrity_checks(struct hfi1_devdata *dd) | ||
623 | { | ||
624 | struct send_context *sc; | ||
625 | unsigned long sc_flags; | ||
626 | int i; | ||
627 | |||
628 | spin_lock_irqsave(&dd->sc_lock, sc_flags); | ||
629 | for (i = 0; i < dd->num_send_contexts; i++) { | ||
630 | int enable; | ||
631 | |||
632 | sc = dd->send_contexts[i].sc; | ||
633 | |||
634 | if (!sc) | ||
635 | continue; /* not allocated */ | ||
636 | |||
637 | enable = likely(!HFI1_CAP_IS_KSET(NO_INTEGRITY)) && | ||
638 | dd->hfi1_snoop.mode_flag != HFI1_PORT_SNOOP_MODE; | ||
639 | |||
640 | set_pio_integrity(sc); | ||
641 | |||
642 | if (enable) /* take HFI_CAP_* flags into account */ | ||
643 | hfi1_init_ctxt(sc); | ||
644 | } | ||
645 | spin_unlock_irqrestore(&dd->sc_lock, sc_flags); | ||
646 | } | ||
647 | |||
648 | static int hfi1_snoop_open(struct inode *in, struct file *fp) | ||
649 | { | ||
650 | int ret; | ||
651 | int mode_flag = 0; | ||
652 | unsigned long flags = 0; | ||
653 | struct hfi1_devdata *dd; | ||
654 | struct list_head *queue; | ||
655 | |||
656 | mutex_lock(&hfi1_mutex); | ||
657 | |||
658 | dd = hfi1_dd_from_sc_inode(in); | ||
659 | if (!dd) { | ||
660 | ret = -ENODEV; | ||
661 | goto bail; | ||
662 | } | ||
663 | |||
664 | /* | ||
665 | * File mode determines snoop or capture. Some existing user | ||
666 | * applications expect the capture device to be able to be opened RDWR | ||
667 | * because they expect a dedicated capture device. For this reason we | ||
668 | * support a module param to force capture mode even if the file open | ||
669 | * mode matches snoop. | ||
670 | */ | ||
671 | if ((fp->f_flags & O_ACCMODE) == O_RDONLY) { | ||
672 | snoop_dbg("Capture Enabled"); | ||
673 | mode_flag = HFI1_PORT_CAPTURE_MODE; | ||
674 | } else if ((fp->f_flags & O_ACCMODE) == O_RDWR) { | ||
675 | snoop_dbg("Snoop Enabled"); | ||
676 | mode_flag = HFI1_PORT_SNOOP_MODE; | ||
677 | } else { | ||
678 | snoop_dbg("Invalid"); | ||
679 | ret = -EINVAL; | ||
680 | goto bail; | ||
681 | } | ||
682 | queue = &dd->hfi1_snoop.queue; | ||
683 | |||
684 | /* | ||
685 | * We are not supporting snoop and capture at the same time. | ||
686 | */ | ||
687 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
688 | if (dd->hfi1_snoop.mode_flag) { | ||
689 | ret = -EBUSY; | ||
690 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
691 | goto bail; | ||
692 | } | ||
693 | |||
694 | dd->hfi1_snoop.mode_flag = mode_flag; | ||
695 | drain_snoop_list(queue); | ||
696 | |||
697 | dd->hfi1_snoop.filter_callback = NULL; | ||
698 | dd->hfi1_snoop.filter_value = NULL; | ||
699 | |||
700 | /* | ||
701 | * Send side packet integrity checks are not helpful when snooping so | ||
702 | * disable and re-enable when we stop snooping. | ||
703 | */ | ||
704 | if (mode_flag == HFI1_PORT_SNOOP_MODE) { | ||
705 | /* clear after snoop mode is on */ | ||
706 | adjust_integrity_checks(dd); /* clear */ | ||
707 | |||
708 | /* | ||
709 | * We also do not want to be doing the DLID LMC check for | ||
710 | * ingressed packets. | ||
711 | */ | ||
712 | dd->hfi1_snoop.dcc_cfg = read_csr(dd, DCC_CFG_PORT_CONFIG1); | ||
713 | write_csr(dd, DCC_CFG_PORT_CONFIG1, | ||
714 | (dd->hfi1_snoop.dcc_cfg >> 32) << 32); | ||
715 | } | ||
716 | |||
717 | /* | ||
718 | * As soon as we set these function pointers the recv and send handlers | ||
719 | * are active. This is a race condition so we must make sure to drain | ||
720 | * the queue and init filter values above. Technically we should add | ||
721 | * locking here but all that will happen is on recv a packet will get | ||
722 | * allocated and get stuck on the snoop_lock before getting added to the | ||
723 | * queue. Same goes for send. | ||
724 | */ | ||
725 | dd->rhf_rcv_function_map = snoop_rhf_rcv_functions; | ||
726 | dd->process_pio_send = snoop_send_pio_handler; | ||
727 | dd->process_dma_send = snoop_send_pio_handler; | ||
728 | dd->pio_inline_send = snoop_inline_pio_send; | ||
729 | |||
730 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
731 | ret = 0; | ||
732 | |||
733 | bail: | ||
734 | mutex_unlock(&hfi1_mutex); | ||
735 | |||
736 | return ret; | ||
737 | } | ||
738 | |||
739 | static int hfi1_snoop_release(struct inode *in, struct file *fp) | ||
740 | { | ||
741 | unsigned long flags = 0; | ||
742 | struct hfi1_devdata *dd; | ||
743 | int mode_flag; | ||
744 | |||
745 | dd = hfi1_dd_from_sc_inode(in); | ||
746 | if (!dd) | ||
747 | return -ENODEV; | ||
748 | |||
749 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
750 | |||
751 | /* clear the snoop mode before re-adjusting send context CSRs */ | ||
752 | mode_flag = dd->hfi1_snoop.mode_flag; | ||
753 | dd->hfi1_snoop.mode_flag = 0; | ||
754 | |||
755 | /* | ||
756 | * Drain the queue and clear the filters we are done with it. Don't | ||
757 | * forget to restore the packet integrity checks | ||
758 | */ | ||
759 | drain_snoop_list(&dd->hfi1_snoop.queue); | ||
760 | if (mode_flag == HFI1_PORT_SNOOP_MODE) { | ||
761 | /* restore after snoop mode is clear */ | ||
762 | adjust_integrity_checks(dd); /* restore */ | ||
763 | |||
764 | /* | ||
765 | * Also should probably reset the DCC_CONFIG1 register for DLID | ||
766 | * checking on incoming packets again. Use the value saved when | ||
767 | * opening the snoop device. | ||
768 | */ | ||
769 | write_csr(dd, DCC_CFG_PORT_CONFIG1, dd->hfi1_snoop.dcc_cfg); | ||
770 | } | ||
771 | |||
772 | dd->hfi1_snoop.filter_callback = NULL; | ||
773 | kfree(dd->hfi1_snoop.filter_value); | ||
774 | dd->hfi1_snoop.filter_value = NULL; | ||
775 | |||
776 | /* | ||
777 | * User is done snooping and capturing, return control to the normal | ||
778 | * handler. Re-enable SDMA handling. | ||
779 | */ | ||
780 | dd->rhf_rcv_function_map = dd->normal_rhf_rcv_functions; | ||
781 | dd->process_pio_send = hfi1_verbs_send_pio; | ||
782 | dd->process_dma_send = hfi1_verbs_send_dma; | ||
783 | dd->pio_inline_send = pio_copy; | ||
784 | |||
785 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
786 | |||
787 | snoop_dbg("snoop/capture device released"); | ||
788 | |||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static unsigned int hfi1_snoop_poll(struct file *fp, | ||
793 | struct poll_table_struct *wait) | ||
794 | { | ||
795 | int ret = 0; | ||
796 | unsigned long flags = 0; | ||
797 | |||
798 | struct hfi1_devdata *dd; | ||
799 | |||
800 | dd = hfi1_dd_from_sc_inode(fp->f_inode); | ||
801 | if (!dd) | ||
802 | return -ENODEV; | ||
803 | |||
804 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
805 | |||
806 | poll_wait(fp, &dd->hfi1_snoop.waitq, wait); | ||
807 | if (!list_empty(&dd->hfi1_snoop.queue)) | ||
808 | ret |= POLLIN | POLLRDNORM; | ||
809 | |||
810 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
811 | return ret; | ||
812 | } | ||
813 | |||
814 | static ssize_t hfi1_snoop_write(struct file *fp, const char __user *data, | ||
815 | size_t count, loff_t *off) | ||
816 | { | ||
817 | struct diag_pkt dpkt; | ||
818 | struct hfi1_devdata *dd; | ||
819 | size_t ret; | ||
820 | u8 byte_two, sl, sc5, sc4, vl, byte_one; | ||
821 | struct send_context *sc; | ||
822 | u32 len; | ||
823 | u64 pbc; | ||
824 | struct hfi1_ibport *ibp; | ||
825 | struct hfi1_pportdata *ppd; | ||
826 | |||
827 | dd = hfi1_dd_from_sc_inode(fp->f_inode); | ||
828 | if (!dd) | ||
829 | return -ENODEV; | ||
830 | |||
831 | ppd = dd->pport; | ||
832 | snoop_dbg("received %lu bytes from user", count); | ||
833 | |||
834 | memset(&dpkt, 0, sizeof(struct diag_pkt)); | ||
835 | dpkt.version = _DIAG_PKT_VERS; | ||
836 | dpkt.unit = dd->unit; | ||
837 | dpkt.port = 1; | ||
838 | |||
839 | if (likely(!(snoop_flags & SNOOP_USE_METADATA))) { | ||
840 | /* | ||
841 | * We need to generate the PBC and not let diagpkt_send do it, | ||
842 | * to do this we need the VL and the length in dwords. | ||
843 | * The VL can be determined by using the SL and looking up the | ||
844 | * SC. Then the SC can be converted into VL. The exception to | ||
845 | * this is those packets which are from an SMI queue pair. | ||
846 | * Since we can't detect anything about the QP here we have to | ||
847 | * rely on the SC. If its 0xF then we assume its SMI and | ||
848 | * do not look at the SL. | ||
849 | */ | ||
850 | if (copy_from_user(&byte_one, data, 1)) | ||
851 | return -EINVAL; | ||
852 | |||
853 | if (copy_from_user(&byte_two, data + 1, 1)) | ||
854 | return -EINVAL; | ||
855 | |||
856 | sc4 = (byte_one >> 4) & 0xf; | ||
857 | if (sc4 == 0xF) { | ||
858 | snoop_dbg("Detected VL15 packet ignoring SL in packet"); | ||
859 | vl = sc4; | ||
860 | } else { | ||
861 | sl = (byte_two >> 4) & 0xf; | ||
862 | ibp = to_iport(&dd->verbs_dev.rdi.ibdev, 1); | ||
863 | sc5 = ibp->sl_to_sc[sl]; | ||
864 | vl = sc_to_vlt(dd, sc5); | ||
865 | if (vl != sc4) { | ||
866 | snoop_dbg("VL %d does not match SC %d of packet", | ||
867 | vl, sc4); | ||
868 | return -EINVAL; | ||
869 | } | ||
870 | } | ||
871 | |||
872 | sc = dd->vld[vl].sc; /* Look up the context based on VL */ | ||
873 | if (sc) { | ||
874 | dpkt.sw_index = sc->sw_index; | ||
875 | snoop_dbg("Sending on context %u(%u)", sc->sw_index, | ||
876 | sc->hw_context); | ||
877 | } else { | ||
878 | snoop_dbg("Could not find context for vl %d", vl); | ||
879 | return -EINVAL; | ||
880 | } | ||
881 | |||
882 | len = (count >> 2) + 2; /* Add in PBC */ | ||
883 | pbc = create_pbc(ppd, 0, 0, vl, len); | ||
884 | } else { | ||
885 | if (copy_from_user(&pbc, data, sizeof(pbc))) | ||
886 | return -EINVAL; | ||
887 | vl = (pbc >> PBC_VL_SHIFT) & PBC_VL_MASK; | ||
888 | sc = dd->vld[vl].sc; /* Look up the context based on VL */ | ||
889 | if (sc) { | ||
890 | dpkt.sw_index = sc->sw_index; | ||
891 | } else { | ||
892 | snoop_dbg("Could not find context for vl %d", vl); | ||
893 | return -EINVAL; | ||
894 | } | ||
895 | data += sizeof(pbc); | ||
896 | count -= sizeof(pbc); | ||
897 | } | ||
898 | dpkt.len = count; | ||
899 | dpkt.data = (unsigned long)data; | ||
900 | |||
901 | snoop_dbg("PBC: vl=0x%llx Length=0x%llx", | ||
902 | (pbc >> 12) & 0xf, | ||
903 | (pbc & 0xfff)); | ||
904 | |||
905 | dpkt.pbc = pbc; | ||
906 | ret = diagpkt_send(&dpkt); | ||
907 | /* | ||
908 | * diagpkt_send only returns number of bytes in the diagpkt so patch | ||
909 | * that up here before returning. | ||
910 | */ | ||
911 | if (ret == sizeof(dpkt)) | ||
912 | return count; | ||
913 | |||
914 | return ret; | ||
915 | } | ||
916 | |||
917 | static ssize_t hfi1_snoop_read(struct file *fp, char __user *data, | ||
918 | size_t pkt_len, loff_t *off) | ||
919 | { | ||
920 | ssize_t ret = 0; | ||
921 | unsigned long flags = 0; | ||
922 | struct snoop_packet *packet = NULL; | ||
923 | struct hfi1_devdata *dd; | ||
924 | |||
925 | dd = hfi1_dd_from_sc_inode(fp->f_inode); | ||
926 | if (!dd) | ||
927 | return -ENODEV; | ||
928 | |||
929 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
930 | |||
931 | while (list_empty(&dd->hfi1_snoop.queue)) { | ||
932 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
933 | |||
934 | if (fp->f_flags & O_NONBLOCK) | ||
935 | return -EAGAIN; | ||
936 | |||
937 | if (wait_event_interruptible( | ||
938 | dd->hfi1_snoop.waitq, | ||
939 | !list_empty(&dd->hfi1_snoop.queue))) | ||
940 | return -EINTR; | ||
941 | |||
942 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
943 | } | ||
944 | |||
945 | if (!list_empty(&dd->hfi1_snoop.queue)) { | ||
946 | packet = list_entry(dd->hfi1_snoop.queue.next, | ||
947 | struct snoop_packet, list); | ||
948 | list_del(&packet->list); | ||
949 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
950 | if (pkt_len >= packet->total_len) { | ||
951 | if (copy_to_user(data, packet->data, | ||
952 | packet->total_len)) | ||
953 | ret = -EFAULT; | ||
954 | else | ||
955 | ret = packet->total_len; | ||
956 | } else { | ||
957 | ret = -EINVAL; | ||
958 | } | ||
959 | |||
960 | kfree(packet); | ||
961 | } else { | ||
962 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
963 | } | ||
964 | |||
965 | return ret; | ||
966 | } | ||
967 | |||
968 | /** | ||
969 | * hfi1_assign_snoop_link_credits -- Set up credits for VL15 and others | ||
970 | * @ppd : ptr to hfi1 port data | ||
971 | * @value : options from user space | ||
972 | * | ||
973 | * Assumes the rest of the CM credit registers are zero from a | ||
974 | * previous global or credit reset. | ||
975 | * Leave shared count at zero for both global and all vls. | ||
976 | * In snoop mode ideally we don't use shared credits | ||
977 | * Reserve 8.5k for VL15 | ||
978 | * If total credits less than 8.5kbytes return error. | ||
979 | * Divide the rest of the credits across VL0 to VL7 and if | ||
980 | * each of these levels has less than 34 credits (at least 2048 + 128 bytes) | ||
981 | * return with an error. | ||
982 | * The credit registers will be reset to zero on link negotiation or link up | ||
983 | * so this function should be activated from user space only if the port has | ||
984 | * gone past link negotiation and link up. | ||
985 | * | ||
986 | * Return -- 0 if successful else error condition | ||
987 | * | ||
988 | */ | ||
989 | static long hfi1_assign_snoop_link_credits(struct hfi1_pportdata *ppd, | ||
990 | int value) | ||
991 | { | ||
992 | #define OPA_MIN_PER_VL_CREDITS 34 /* 2048 + 128 bytes */ | ||
993 | struct buffer_control t; | ||
994 | int i; | ||
995 | struct hfi1_devdata *dd = ppd->dd; | ||
996 | u16 total_credits = (value >> 16) & 0xffff; | ||
997 | u16 vl15_credits = dd->vl15_init / 2; | ||
998 | u16 per_vl_credits; | ||
999 | __be16 be_per_vl_credits; | ||
1000 | |||
1001 | if (!(ppd->host_link_state & HLS_UP)) | ||
1002 | goto err_exit; | ||
1003 | if (total_credits < vl15_credits) | ||
1004 | goto err_exit; | ||
1005 | |||
1006 | per_vl_credits = (total_credits - vl15_credits) / TXE_NUM_DATA_VL; | ||
1007 | |||
1008 | if (per_vl_credits < OPA_MIN_PER_VL_CREDITS) | ||
1009 | goto err_exit; | ||
1010 | |||
1011 | memset(&t, 0, sizeof(t)); | ||
1012 | be_per_vl_credits = cpu_to_be16(per_vl_credits); | ||
1013 | |||
1014 | for (i = 0; i < TXE_NUM_DATA_VL; i++) | ||
1015 | t.vl[i].dedicated = be_per_vl_credits; | ||
1016 | |||
1017 | t.vl[15].dedicated = cpu_to_be16(vl15_credits); | ||
1018 | return set_buffer_control(ppd, &t); | ||
1019 | |||
1020 | err_exit: | ||
1021 | snoop_dbg("port_state = 0x%x, total_credits = %d, vl15_credits = %d", | ||
1022 | ppd->host_link_state, total_credits, vl15_credits); | ||
1023 | |||
1024 | return -EINVAL; | ||
1025 | } | ||
1026 | |||
1027 | static long hfi1_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) | ||
1028 | { | ||
1029 | struct hfi1_devdata *dd; | ||
1030 | void *filter_value = NULL; | ||
1031 | long ret = 0; | ||
1032 | int value = 0; | ||
1033 | u8 phys_state = 0; | ||
1034 | u8 link_state = 0; | ||
1035 | u16 dev_state = 0; | ||
1036 | unsigned long flags = 0; | ||
1037 | unsigned long *argp = NULL; | ||
1038 | struct hfi1_packet_filter_command filter_cmd = {0}; | ||
1039 | int mode_flag = 0; | ||
1040 | struct hfi1_pportdata *ppd = NULL; | ||
1041 | unsigned int index; | ||
1042 | struct hfi1_link_info link_info; | ||
1043 | int read_cmd, write_cmd, read_ok, write_ok; | ||
1044 | |||
1045 | dd = hfi1_dd_from_sc_inode(fp->f_inode); | ||
1046 | if (!dd) | ||
1047 | return -ENODEV; | ||
1048 | |||
1049 | mode_flag = dd->hfi1_snoop.mode_flag; | ||
1050 | read_cmd = _IOC_DIR(cmd) & _IOC_READ; | ||
1051 | write_cmd = _IOC_DIR(cmd) & _IOC_WRITE; | ||
1052 | write_ok = access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); | ||
1053 | read_ok = access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); | ||
1054 | |||
1055 | if ((read_cmd && !write_ok) || (write_cmd && !read_ok)) | ||
1056 | return -EFAULT; | ||
1057 | |||
1058 | if (!capable(CAP_SYS_ADMIN)) | ||
1059 | return -EPERM; | ||
1060 | |||
1061 | if ((mode_flag & HFI1_PORT_CAPTURE_MODE) && | ||
1062 | (cmd != HFI1_SNOOP_IOCCLEARQUEUE) && | ||
1063 | (cmd != HFI1_SNOOP_IOCCLEARFILTER) && | ||
1064 | (cmd != HFI1_SNOOP_IOCSETFILTER)) | ||
1065 | /* Capture devices are allowed only 3 operations | ||
1066 | * 1.Clear capture queue | ||
1067 | * 2.Clear capture filter | ||
1068 | * 3.Set capture filter | ||
1069 | * Other are invalid. | ||
1070 | */ | ||
1071 | return -EINVAL; | ||
1072 | |||
1073 | switch (cmd) { | ||
1074 | case HFI1_SNOOP_IOCSETLINKSTATE_EXTRA: | ||
1075 | memset(&link_info, 0, sizeof(link_info)); | ||
1076 | |||
1077 | if (copy_from_user(&link_info, | ||
1078 | (struct hfi1_link_info __user *)arg, | ||
1079 | sizeof(link_info))) | ||
1080 | return -EFAULT; | ||
1081 | |||
1082 | value = link_info.port_state; | ||
1083 | index = link_info.port_number; | ||
1084 | if (index > dd->num_pports - 1) | ||
1085 | return -EINVAL; | ||
1086 | |||
1087 | ppd = &dd->pport[index]; | ||
1088 | if (!ppd) | ||
1089 | return -EINVAL; | ||
1090 | |||
1091 | /* What we want to transition to */ | ||
1092 | phys_state = (value >> 4) & 0xF; | ||
1093 | link_state = value & 0xF; | ||
1094 | snoop_dbg("Setting link state 0x%x", value); | ||
1095 | |||
1096 | switch (link_state) { | ||
1097 | case IB_PORT_NOP: | ||
1098 | if (phys_state == 0) | ||
1099 | break; | ||
1100 | /* fall through */ | ||
1101 | case IB_PORT_DOWN: | ||
1102 | switch (phys_state) { | ||
1103 | case 0: | ||
1104 | dev_state = HLS_DN_DOWNDEF; | ||
1105 | break; | ||
1106 | case 2: | ||
1107 | dev_state = HLS_DN_POLL; | ||
1108 | break; | ||
1109 | case 3: | ||
1110 | dev_state = HLS_DN_DISABLE; | ||
1111 | break; | ||
1112 | default: | ||
1113 | return -EINVAL; | ||
1114 | } | ||
1115 | ret = set_link_state(ppd, dev_state); | ||
1116 | break; | ||
1117 | case IB_PORT_ARMED: | ||
1118 | ret = set_link_state(ppd, HLS_UP_ARMED); | ||
1119 | if (!ret) | ||
1120 | send_idle_sma(dd, SMA_IDLE_ARM); | ||
1121 | break; | ||
1122 | case IB_PORT_ACTIVE: | ||
1123 | ret = set_link_state(ppd, HLS_UP_ACTIVE); | ||
1124 | if (!ret) | ||
1125 | send_idle_sma(dd, SMA_IDLE_ACTIVE); | ||
1126 | break; | ||
1127 | default: | ||
1128 | return -EINVAL; | ||
1129 | } | ||
1130 | |||
1131 | if (ret) | ||
1132 | break; | ||
1133 | /* fall through */ | ||
1134 | case HFI1_SNOOP_IOCGETLINKSTATE: | ||
1135 | case HFI1_SNOOP_IOCGETLINKSTATE_EXTRA: | ||
1136 | if (cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) { | ||
1137 | memset(&link_info, 0, sizeof(link_info)); | ||
1138 | if (copy_from_user(&link_info, | ||
1139 | (struct hfi1_link_info __user *)arg, | ||
1140 | sizeof(link_info))) | ||
1141 | return -EFAULT; | ||
1142 | index = link_info.port_number; | ||
1143 | } else { | ||
1144 | ret = __get_user(index, (int __user *)arg); | ||
1145 | if (ret != 0) | ||
1146 | break; | ||
1147 | } | ||
1148 | |||
1149 | if (index > dd->num_pports - 1) | ||
1150 | return -EINVAL; | ||
1151 | |||
1152 | ppd = &dd->pport[index]; | ||
1153 | if (!ppd) | ||
1154 | return -EINVAL; | ||
1155 | |||
1156 | value = hfi1_ibphys_portstate(ppd); | ||
1157 | value <<= 4; | ||
1158 | value |= driver_lstate(ppd); | ||
1159 | |||
1160 | snoop_dbg("Link port | Link State: %d", value); | ||
1161 | |||
1162 | if ((cmd == HFI1_SNOOP_IOCGETLINKSTATE_EXTRA) || | ||
1163 | (cmd == HFI1_SNOOP_IOCSETLINKSTATE_EXTRA)) { | ||
1164 | link_info.port_state = value; | ||
1165 | link_info.node_guid = cpu_to_be64(ppd->guid); | ||
1166 | link_info.link_speed_active = | ||
1167 | ppd->link_speed_active; | ||
1168 | link_info.link_width_active = | ||
1169 | ppd->link_width_active; | ||
1170 | if (copy_to_user((struct hfi1_link_info __user *)arg, | ||
1171 | &link_info, sizeof(link_info))) | ||
1172 | return -EFAULT; | ||
1173 | } else { | ||
1174 | ret = __put_user(value, (int __user *)arg); | ||
1175 | } | ||
1176 | break; | ||
1177 | |||
1178 | case HFI1_SNOOP_IOCCLEARQUEUE: | ||
1179 | snoop_dbg("Clearing snoop queue"); | ||
1180 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
1181 | drain_snoop_list(&dd->hfi1_snoop.queue); | ||
1182 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
1183 | break; | ||
1184 | |||
1185 | case HFI1_SNOOP_IOCCLEARFILTER: | ||
1186 | snoop_dbg("Clearing filter"); | ||
1187 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
1188 | if (dd->hfi1_snoop.filter_callback) { | ||
1189 | /* Drain packets first */ | ||
1190 | drain_snoop_list(&dd->hfi1_snoop.queue); | ||
1191 | dd->hfi1_snoop.filter_callback = NULL; | ||
1192 | } | ||
1193 | kfree(dd->hfi1_snoop.filter_value); | ||
1194 | dd->hfi1_snoop.filter_value = NULL; | ||
1195 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
1196 | break; | ||
1197 | |||
1198 | case HFI1_SNOOP_IOCSETFILTER: | ||
1199 | snoop_dbg("Setting filter"); | ||
1200 | /* just copy command structure */ | ||
1201 | argp = (unsigned long *)arg; | ||
1202 | if (copy_from_user(&filter_cmd, (void __user *)argp, | ||
1203 | sizeof(filter_cmd))) | ||
1204 | return -EFAULT; | ||
1205 | |||
1206 | if (filter_cmd.opcode >= HFI1_MAX_FILTERS) { | ||
1207 | pr_alert("Invalid opcode in request\n"); | ||
1208 | return -EINVAL; | ||
1209 | } | ||
1210 | |||
1211 | snoop_dbg("Opcode %d Len %d Ptr %p", | ||
1212 | filter_cmd.opcode, filter_cmd.length, | ||
1213 | filter_cmd.value_ptr); | ||
1214 | |||
1215 | filter_value = kcalloc(filter_cmd.length, sizeof(u8), | ||
1216 | GFP_KERNEL); | ||
1217 | if (!filter_value) | ||
1218 | return -ENOMEM; | ||
1219 | |||
1220 | /* copy remaining data from userspace */ | ||
1221 | if (copy_from_user((u8 *)filter_value, | ||
1222 | (void __user *)filter_cmd.value_ptr, | ||
1223 | filter_cmd.length)) { | ||
1224 | kfree(filter_value); | ||
1225 | return -EFAULT; | ||
1226 | } | ||
1227 | /* Drain packets first */ | ||
1228 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
1229 | drain_snoop_list(&dd->hfi1_snoop.queue); | ||
1230 | dd->hfi1_snoop.filter_callback = | ||
1231 | hfi1_filters[filter_cmd.opcode].filter; | ||
1232 | /* just in case we see back to back sets */ | ||
1233 | kfree(dd->hfi1_snoop.filter_value); | ||
1234 | dd->hfi1_snoop.filter_value = filter_value; | ||
1235 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
1236 | break; | ||
1237 | case HFI1_SNOOP_IOCGETVERSION: | ||
1238 | value = SNOOP_CAPTURE_VERSION; | ||
1239 | snoop_dbg("Getting version: %d", value); | ||
1240 | ret = __put_user(value, (int __user *)arg); | ||
1241 | break; | ||
1242 | case HFI1_SNOOP_IOCSET_OPTS: | ||
1243 | snoop_flags = 0; | ||
1244 | ret = __get_user(value, (int __user *)arg); | ||
1245 | if (ret != 0) | ||
1246 | break; | ||
1247 | |||
1248 | snoop_dbg("Setting snoop option %d", value); | ||
1249 | if (value & SNOOP_DROP_SEND) | ||
1250 | snoop_flags |= SNOOP_DROP_SEND; | ||
1251 | if (value & SNOOP_USE_METADATA) | ||
1252 | snoop_flags |= SNOOP_USE_METADATA; | ||
1253 | if (value & (SNOOP_SET_VL0TOVL15)) { | ||
1254 | ppd = &dd->pport[0]; /* first port will do */ | ||
1255 | ret = hfi1_assign_snoop_link_credits(ppd, value); | ||
1256 | } | ||
1257 | break; | ||
1258 | default: | ||
1259 | return -ENOTTY; | ||
1260 | } | ||
1261 | |||
1262 | return ret; | ||
1263 | } | ||
1264 | |||
1265 | static void snoop_list_add_tail(struct snoop_packet *packet, | ||
1266 | struct hfi1_devdata *dd) | ||
1267 | { | ||
1268 | unsigned long flags = 0; | ||
1269 | |||
1270 | spin_lock_irqsave(&dd->hfi1_snoop.snoop_lock, flags); | ||
1271 | if (likely((dd->hfi1_snoop.mode_flag & HFI1_PORT_SNOOP_MODE) || | ||
1272 | (dd->hfi1_snoop.mode_flag & HFI1_PORT_CAPTURE_MODE))) { | ||
1273 | list_add_tail(&packet->list, &dd->hfi1_snoop.queue); | ||
1274 | snoop_dbg("Added packet to list"); | ||
1275 | } | ||
1276 | |||
1277 | /* | ||
1278 | * Technically we can could have closed the snoop device while waiting | ||
1279 | * on the above lock and it is gone now. The snoop mode_flag will | ||
1280 | * prevent us from adding the packet to the queue though. | ||
1281 | */ | ||
1282 | |||
1283 | spin_unlock_irqrestore(&dd->hfi1_snoop.snoop_lock, flags); | ||
1284 | wake_up_interruptible(&dd->hfi1_snoop.waitq); | ||
1285 | } | ||
1286 | |||
1287 | static inline int hfi1_filter_check(void *val, const char *msg) | ||
1288 | { | ||
1289 | if (!val) { | ||
1290 | snoop_dbg("Error invalid %s value for filter", msg); | ||
1291 | return HFI1_FILTER_ERR; | ||
1292 | } | ||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | static int hfi1_filter_lid(void *ibhdr, void *packet_data, void *value) | ||
1297 | { | ||
1298 | struct hfi1_ib_header *hdr; | ||
1299 | int ret; | ||
1300 | |||
1301 | ret = hfi1_filter_check(ibhdr, "header"); | ||
1302 | if (ret) | ||
1303 | return ret; | ||
1304 | ret = hfi1_filter_check(value, "user"); | ||
1305 | if (ret) | ||
1306 | return ret; | ||
1307 | hdr = (struct hfi1_ib_header *)ibhdr; | ||
1308 | |||
1309 | if (*((u16 *)value) == be16_to_cpu(hdr->lrh[3])) /* matches slid */ | ||
1310 | return HFI1_FILTER_HIT; /* matched */ | ||
1311 | |||
1312 | return HFI1_FILTER_MISS; /* Not matched */ | ||
1313 | } | ||
1314 | |||
1315 | static int hfi1_filter_dlid(void *ibhdr, void *packet_data, void *value) | ||
1316 | { | ||
1317 | struct hfi1_ib_header *hdr; | ||
1318 | int ret; | ||
1319 | |||
1320 | ret = hfi1_filter_check(ibhdr, "header"); | ||
1321 | if (ret) | ||
1322 | return ret; | ||
1323 | ret = hfi1_filter_check(value, "user"); | ||
1324 | if (ret) | ||
1325 | return ret; | ||
1326 | |||
1327 | hdr = (struct hfi1_ib_header *)ibhdr; | ||
1328 | |||
1329 | if (*((u16 *)value) == be16_to_cpu(hdr->lrh[1])) | ||
1330 | return HFI1_FILTER_HIT; | ||
1331 | |||
1332 | return HFI1_FILTER_MISS; | ||
1333 | } | ||
1334 | |||
1335 | /* Not valid for outgoing packets, send handler passes null for data*/ | ||
1336 | static int hfi1_filter_mad_mgmt_class(void *ibhdr, void *packet_data, | ||
1337 | void *value) | ||
1338 | { | ||
1339 | struct hfi1_ib_header *hdr; | ||
1340 | struct hfi1_other_headers *ohdr = NULL; | ||
1341 | struct ib_smp *smp = NULL; | ||
1342 | u32 qpn = 0; | ||
1343 | int ret; | ||
1344 | |||
1345 | ret = hfi1_filter_check(ibhdr, "header"); | ||
1346 | if (ret) | ||
1347 | return ret; | ||
1348 | ret = hfi1_filter_check(packet_data, "packet_data"); | ||
1349 | if (ret) | ||
1350 | return ret; | ||
1351 | ret = hfi1_filter_check(value, "user"); | ||
1352 | if (ret) | ||
1353 | return ret; | ||
1354 | |||
1355 | hdr = (struct hfi1_ib_header *)ibhdr; | ||
1356 | |||
1357 | /* Check for GRH */ | ||
1358 | if ((be16_to_cpu(hdr->lrh[0]) & 3) == HFI1_LRH_BTH) | ||
1359 | ohdr = &hdr->u.oth; /* LRH + BTH + DETH */ | ||
1360 | else | ||
1361 | ohdr = &hdr->u.l.oth; /* LRH + GRH + BTH + DETH */ | ||
1362 | |||
1363 | qpn = be32_to_cpu(ohdr->bth[1]) & 0x00FFFFFF; | ||
1364 | if (qpn <= 1) { | ||
1365 | smp = (struct ib_smp *)packet_data; | ||
1366 | if (*((u8 *)value) == smp->mgmt_class) | ||
1367 | return HFI1_FILTER_HIT; | ||
1368 | else | ||
1369 | return HFI1_FILTER_MISS; | ||
1370 | } | ||
1371 | return HFI1_FILTER_ERR; | ||
1372 | } | ||
1373 | |||
1374 | static int hfi1_filter_qp_number(void *ibhdr, void *packet_data, void *value) | ||
1375 | { | ||
1376 | struct hfi1_ib_header *hdr; | ||
1377 | struct hfi1_other_headers *ohdr = NULL; | ||
1378 | int ret; | ||
1379 | |||
1380 | ret = hfi1_filter_check(ibhdr, "header"); | ||
1381 | if (ret) | ||
1382 | return ret; | ||
1383 | ret = hfi1_filter_check(value, "user"); | ||
1384 | if (ret) | ||
1385 | return ret; | ||
1386 | |||
1387 | hdr = (struct hfi1_ib_header *)ibhdr; | ||
1388 | |||
1389 | /* Check for GRH */ | ||
1390 | if ((be16_to_cpu(hdr->lrh[0]) & 3) == HFI1_LRH_BTH) | ||
1391 | ohdr = &hdr->u.oth; /* LRH + BTH + DETH */ | ||
1392 | else | ||
1393 | ohdr = &hdr->u.l.oth; /* LRH + GRH + BTH + DETH */ | ||
1394 | if (*((u32 *)value) == (be32_to_cpu(ohdr->bth[1]) & 0x00FFFFFF)) | ||
1395 | return HFI1_FILTER_HIT; | ||
1396 | |||
1397 | return HFI1_FILTER_MISS; | ||
1398 | } | ||
1399 | |||
1400 | static int hfi1_filter_ibpacket_type(void *ibhdr, void *packet_data, | ||
1401 | void *value) | ||
1402 | { | ||
1403 | u32 lnh = 0; | ||
1404 | u8 opcode = 0; | ||
1405 | struct hfi1_ib_header *hdr; | ||
1406 | struct hfi1_other_headers *ohdr = NULL; | ||
1407 | int ret; | ||
1408 | |||
1409 | ret = hfi1_filter_check(ibhdr, "header"); | ||
1410 | if (ret) | ||
1411 | return ret; | ||
1412 | ret = hfi1_filter_check(value, "user"); | ||
1413 | if (ret) | ||
1414 | return ret; | ||
1415 | |||
1416 | hdr = (struct hfi1_ib_header *)ibhdr; | ||
1417 | |||
1418 | lnh = (be16_to_cpu(hdr->lrh[0]) & 3); | ||
1419 | |||
1420 | if (lnh == HFI1_LRH_BTH) | ||
1421 | ohdr = &hdr->u.oth; | ||
1422 | else if (lnh == HFI1_LRH_GRH) | ||
1423 | ohdr = &hdr->u.l.oth; | ||
1424 | else | ||
1425 | return HFI1_FILTER_ERR; | ||
1426 | |||
1427 | opcode = be32_to_cpu(ohdr->bth[0]) >> 24; | ||
1428 | |||
1429 | if (*((u8 *)value) == ((opcode >> 5) & 0x7)) | ||
1430 | return HFI1_FILTER_HIT; | ||
1431 | |||
1432 | return HFI1_FILTER_MISS; | ||
1433 | } | ||
1434 | |||
1435 | static int hfi1_filter_ib_service_level(void *ibhdr, void *packet_data, | ||
1436 | void *value) | ||
1437 | { | ||
1438 | struct hfi1_ib_header *hdr; | ||
1439 | int ret; | ||
1440 | |||
1441 | ret = hfi1_filter_check(ibhdr, "header"); | ||
1442 | if (ret) | ||
1443 | return ret; | ||
1444 | ret = hfi1_filter_check(value, "user"); | ||
1445 | if (ret) | ||
1446 | return ret; | ||
1447 | |||
1448 | hdr = (struct hfi1_ib_header *)ibhdr; | ||
1449 | |||
1450 | if ((*((u8 *)value)) == ((be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF)) | ||
1451 | return HFI1_FILTER_HIT; | ||
1452 | |||
1453 | return HFI1_FILTER_MISS; | ||
1454 | } | ||
1455 | |||
1456 | static int hfi1_filter_ib_pkey(void *ibhdr, void *packet_data, void *value) | ||
1457 | { | ||
1458 | u32 lnh = 0; | ||
1459 | struct hfi1_ib_header *hdr; | ||
1460 | struct hfi1_other_headers *ohdr = NULL; | ||
1461 | int ret; | ||
1462 | |||
1463 | ret = hfi1_filter_check(ibhdr, "header"); | ||
1464 | if (ret) | ||
1465 | return ret; | ||
1466 | ret = hfi1_filter_check(value, "user"); | ||
1467 | if (ret) | ||
1468 | return ret; | ||
1469 | |||
1470 | hdr = (struct hfi1_ib_header *)ibhdr; | ||
1471 | |||
1472 | lnh = (be16_to_cpu(hdr->lrh[0]) & 3); | ||
1473 | if (lnh == HFI1_LRH_BTH) | ||
1474 | ohdr = &hdr->u.oth; | ||
1475 | else if (lnh == HFI1_LRH_GRH) | ||
1476 | ohdr = &hdr->u.l.oth; | ||
1477 | else | ||
1478 | return HFI1_FILTER_ERR; | ||
1479 | |||
1480 | /* P_key is 16-bit entity, however top most bit indicates | ||
1481 | * type of membership. 0 for limited and 1 for Full. | ||
1482 | * Limited members cannot accept information from other | ||
1483 | * Limited members, but communication is allowed between | ||
1484 | * every other combination of membership. | ||
1485 | * Hence we'll omit comparing top-most bit while filtering | ||
1486 | */ | ||
1487 | |||
1488 | if ((*(u16 *)value & 0x7FFF) == | ||
1489 | ((be32_to_cpu(ohdr->bth[0])) & 0x7FFF)) | ||
1490 | return HFI1_FILTER_HIT; | ||
1491 | |||
1492 | return HFI1_FILTER_MISS; | ||
1493 | } | ||
1494 | |||
1495 | /* | ||
1496 | * If packet_data is NULL then this is coming from one of the send functions. | ||
1497 | * Thus we know if its an ingressed or egressed packet. | ||
1498 | */ | ||
1499 | static int hfi1_filter_direction(void *ibhdr, void *packet_data, void *value) | ||
1500 | { | ||
1501 | u8 user_dir = *(u8 *)value; | ||
1502 | int ret; | ||
1503 | |||
1504 | ret = hfi1_filter_check(value, "user"); | ||
1505 | if (ret) | ||
1506 | return ret; | ||
1507 | |||
1508 | if (packet_data) { | ||
1509 | /* Incoming packet */ | ||
1510 | if (user_dir & HFI1_SNOOP_INGRESS) | ||
1511 | return HFI1_FILTER_HIT; | ||
1512 | } else { | ||
1513 | /* Outgoing packet */ | ||
1514 | if (user_dir & HFI1_SNOOP_EGRESS) | ||
1515 | return HFI1_FILTER_HIT; | ||
1516 | } | ||
1517 | |||
1518 | return HFI1_FILTER_MISS; | ||
1519 | } | ||
1520 | |||
1521 | /* | ||
1522 | * Allocate a snoop packet. The structure that is stored in the ring buffer, not | ||
1523 | * to be confused with an hfi packet type. | ||
1524 | */ | ||
1525 | static struct snoop_packet *allocate_snoop_packet(u32 hdr_len, | ||
1526 | u32 data_len, | ||
1527 | u32 md_len) | ||
1528 | { | ||
1529 | struct snoop_packet *packet; | ||
1530 | |||
1531 | packet = kzalloc(sizeof(*packet) + hdr_len + data_len | ||
1532 | + md_len, | ||
1533 | GFP_ATOMIC | __GFP_NOWARN); | ||
1534 | if (likely(packet)) | ||
1535 | INIT_LIST_HEAD(&packet->list); | ||
1536 | |||
1537 | return packet; | ||
1538 | } | ||
1539 | |||
1540 | /* | ||
1541 | * Instead of having snoop and capture code intermixed with the recv functions, | ||
1542 | * both the interrupt handler and hfi1_ib_rcv() we are going to hijack the call | ||
1543 | * and land in here for snoop/capture but if not enabled the call will go | ||
1544 | * through as before. This gives us a single point to constrain all of the snoop | ||
1545 | * snoop recv logic. There is nothing special that needs to happen for bypass | ||
1546 | * packets. This routine should not try to look into the packet. It just copied | ||
1547 | * it. There is no guarantee for filters when it comes to bypass packets as | ||
1548 | * there is no specific support. Bottom line is this routine does now even know | ||
1549 | * what a bypass packet is. | ||
1550 | */ | ||
1551 | int snoop_recv_handler(struct hfi1_packet *packet) | ||
1552 | { | ||
1553 | struct hfi1_pportdata *ppd = packet->rcd->ppd; | ||
1554 | struct hfi1_ib_header *hdr = packet->hdr; | ||
1555 | int header_size = packet->hlen; | ||
1556 | void *data = packet->ebuf; | ||
1557 | u32 tlen = packet->tlen; | ||
1558 | struct snoop_packet *s_packet = NULL; | ||
1559 | int ret; | ||
1560 | int snoop_mode = 0; | ||
1561 | u32 md_len = 0; | ||
1562 | struct capture_md md; | ||
1563 | |||
1564 | snoop_dbg("PACKET IN: hdr size %d tlen %d data %p", header_size, tlen, | ||
1565 | data); | ||
1566 | |||
1567 | trace_snoop_capture(ppd->dd, header_size, hdr, tlen - header_size, | ||
1568 | data); | ||
1569 | |||
1570 | if (!ppd->dd->hfi1_snoop.filter_callback) { | ||
1571 | snoop_dbg("filter not set"); | ||
1572 | ret = HFI1_FILTER_HIT; | ||
1573 | } else { | ||
1574 | ret = ppd->dd->hfi1_snoop.filter_callback(hdr, data, | ||
1575 | ppd->dd->hfi1_snoop.filter_value); | ||
1576 | } | ||
1577 | |||
1578 | switch (ret) { | ||
1579 | case HFI1_FILTER_ERR: | ||
1580 | snoop_dbg("Error in filter call"); | ||
1581 | break; | ||
1582 | case HFI1_FILTER_MISS: | ||
1583 | snoop_dbg("Filter Miss"); | ||
1584 | break; | ||
1585 | case HFI1_FILTER_HIT: | ||
1586 | |||
1587 | if (ppd->dd->hfi1_snoop.mode_flag & HFI1_PORT_SNOOP_MODE) | ||
1588 | snoop_mode = 1; | ||
1589 | if ((snoop_mode == 0) || | ||
1590 | unlikely(snoop_flags & SNOOP_USE_METADATA)) | ||
1591 | md_len = sizeof(struct capture_md); | ||
1592 | |||
1593 | s_packet = allocate_snoop_packet(header_size, | ||
1594 | tlen - header_size, | ||
1595 | md_len); | ||
1596 | |||
1597 | if (unlikely(!s_packet)) { | ||
1598 | dd_dev_warn_ratelimited(ppd->dd, "Unable to allocate snoop/capture packet\n"); | ||
1599 | break; | ||
1600 | } | ||
1601 | |||
1602 | if (md_len > 0) { | ||
1603 | memset(&md, 0, sizeof(struct capture_md)); | ||
1604 | md.port = 1; | ||
1605 | md.dir = PKT_DIR_INGRESS; | ||
1606 | md.u.rhf = packet->rhf; | ||
1607 | memcpy(s_packet->data, &md, md_len); | ||
1608 | } | ||
1609 | |||
1610 | /* We should always have a header */ | ||
1611 | if (hdr) { | ||
1612 | memcpy(s_packet->data + md_len, hdr, header_size); | ||
1613 | } else { | ||
1614 | dd_dev_err(ppd->dd, "Unable to copy header to snoop/capture packet\n"); | ||
1615 | kfree(s_packet); | ||
1616 | break; | ||
1617 | } | ||
1618 | |||
1619 | /* | ||
1620 | * Packets with no data are possible. If there is no data needed | ||
1621 | * to take care of the last 4 bytes which are normally included | ||
1622 | * with data buffers and are included in tlen. Since we kzalloc | ||
1623 | * the buffer we do not need to set any values but if we decide | ||
1624 | * not to use kzalloc we should zero them. | ||
1625 | */ | ||
1626 | if (data) | ||
1627 | memcpy(s_packet->data + header_size + md_len, data, | ||
1628 | tlen - header_size); | ||
1629 | |||
1630 | s_packet->total_len = tlen + md_len; | ||
1631 | snoop_list_add_tail(s_packet, ppd->dd); | ||
1632 | |||
1633 | /* | ||
1634 | * If we are snooping the packet not capturing then throw away | ||
1635 | * after adding to the list. | ||
1636 | */ | ||
1637 | snoop_dbg("Capturing packet"); | ||
1638 | if (ppd->dd->hfi1_snoop.mode_flag & HFI1_PORT_SNOOP_MODE) { | ||
1639 | snoop_dbg("Throwing packet away"); | ||
1640 | /* | ||
1641 | * If we are dropping the packet we still may need to | ||
1642 | * handle the case where error flags are set, this is | ||
1643 | * normally done by the type specific handler but that | ||
1644 | * won't be called in this case. | ||
1645 | */ | ||
1646 | if (unlikely(rhf_err_flags(packet->rhf))) | ||
1647 | handle_eflags(packet); | ||
1648 | |||
1649 | /* throw the packet on the floor */ | ||
1650 | return RHF_RCV_CONTINUE; | ||
1651 | } | ||
1652 | break; | ||
1653 | default: | ||
1654 | break; | ||
1655 | } | ||
1656 | |||
1657 | /* | ||
1658 | * We do not care what type of packet came in here - just pass it off | ||
1659 | * to the normal handler. | ||
1660 | */ | ||
1661 | return ppd->dd->normal_rhf_rcv_functions[rhf_rcv_type(packet->rhf)] | ||
1662 | (packet); | ||
1663 | } | ||
1664 | |||
1665 | /* | ||
1666 | * Handle snooping and capturing packets when sdma is being used. | ||
1667 | */ | ||
1668 | int snoop_send_dma_handler(struct rvt_qp *qp, struct hfi1_pkt_state *ps, | ||
1669 | u64 pbc) | ||
1670 | { | ||
1671 | pr_alert("Snooping/Capture of Send DMA Packets Is Not Supported!\n"); | ||
1672 | snoop_dbg("Unsupported Operation"); | ||
1673 | return hfi1_verbs_send_dma(qp, ps, 0); | ||
1674 | } | ||
1675 | |||
1676 | /* | ||
1677 | * Handle snooping and capturing packets when pio is being used. Does not handle | ||
1678 | * bypass packets. The only way to send a bypass packet currently is to use the | ||
1679 | * diagpkt interface. When that interface is enable snoop/capture is not. | ||
1680 | */ | ||
1681 | int snoop_send_pio_handler(struct rvt_qp *qp, struct hfi1_pkt_state *ps, | ||
1682 | u64 pbc) | ||
1683 | { | ||
1684 | u32 hdrwords = qp->s_hdrwords; | ||
1685 | struct rvt_sge_state *ss = qp->s_cur_sge; | ||
1686 | u32 len = qp->s_cur_size; | ||
1687 | u32 dwords = (len + 3) >> 2; | ||
1688 | u32 plen = hdrwords + dwords + 2; /* includes pbc */ | ||
1689 | struct hfi1_pportdata *ppd = ps->ppd; | ||
1690 | struct snoop_packet *s_packet = NULL; | ||
1691 | u32 *hdr = (u32 *)&ps->s_txreq->phdr.hdr; | ||
1692 | u32 length = 0; | ||
1693 | struct rvt_sge_state temp_ss; | ||
1694 | void *data = NULL; | ||
1695 | void *data_start = NULL; | ||
1696 | int ret; | ||
1697 | int snoop_mode = 0; | ||
1698 | int md_len = 0; | ||
1699 | struct capture_md md; | ||
1700 | u32 vl; | ||
1701 | u32 hdr_len = hdrwords << 2; | ||
1702 | u32 tlen = HFI1_GET_PKT_LEN(&ps->s_txreq->phdr.hdr); | ||
1703 | |||
1704 | md.u.pbc = 0; | ||
1705 | |||
1706 | snoop_dbg("PACKET OUT: hdrword %u len %u plen %u dwords %u tlen %u", | ||
1707 | hdrwords, len, plen, dwords, tlen); | ||
1708 | if (ppd->dd->hfi1_snoop.mode_flag & HFI1_PORT_SNOOP_MODE) | ||
1709 | snoop_mode = 1; | ||
1710 | if ((snoop_mode == 0) || | ||
1711 | unlikely(snoop_flags & SNOOP_USE_METADATA)) | ||
1712 | md_len = sizeof(struct capture_md); | ||
1713 | |||
1714 | /* not using ss->total_len as arg 2 b/c that does not count CRC */ | ||
1715 | s_packet = allocate_snoop_packet(hdr_len, tlen - hdr_len, md_len); | ||
1716 | |||
1717 | if (unlikely(!s_packet)) { | ||
1718 | dd_dev_warn_ratelimited(ppd->dd, "Unable to allocate snoop/capture packet\n"); | ||
1719 | goto out; | ||
1720 | } | ||
1721 | |||
1722 | s_packet->total_len = tlen + md_len; | ||
1723 | |||
1724 | if (md_len > 0) { | ||
1725 | memset(&md, 0, sizeof(struct capture_md)); | ||
1726 | md.port = 1; | ||
1727 | md.dir = PKT_DIR_EGRESS; | ||
1728 | if (likely(pbc == 0)) { | ||
1729 | vl = be16_to_cpu(ps->s_txreq->phdr.hdr.lrh[0]) >> 12; | ||
1730 | md.u.pbc = create_pbc(ppd, 0, qp->s_srate, vl, plen); | ||
1731 | } else { | ||
1732 | md.u.pbc = 0; | ||
1733 | } | ||
1734 | memcpy(s_packet->data, &md, md_len); | ||
1735 | } else { | ||
1736 | md.u.pbc = pbc; | ||
1737 | } | ||
1738 | |||
1739 | /* Copy header */ | ||
1740 | if (likely(hdr)) { | ||
1741 | memcpy(s_packet->data + md_len, hdr, hdr_len); | ||
1742 | } else { | ||
1743 | dd_dev_err(ppd->dd, | ||
1744 | "Unable to copy header to snoop/capture packet\n"); | ||
1745 | kfree(s_packet); | ||
1746 | goto out; | ||
1747 | } | ||
1748 | |||
1749 | if (ss) { | ||
1750 | data = s_packet->data + hdr_len + md_len; | ||
1751 | data_start = data; | ||
1752 | |||
1753 | /* | ||
1754 | * Copy SGE State | ||
1755 | * The update_sge() function below will not modify the | ||
1756 | * individual SGEs in the array. It will make a copy each time | ||
1757 | * and operate on that. So we only need to copy this instance | ||
1758 | * and it won't impact PIO. | ||
1759 | */ | ||
1760 | temp_ss = *ss; | ||
1761 | length = len; | ||
1762 | |||
1763 | snoop_dbg("Need to copy %d bytes", length); | ||
1764 | while (length) { | ||
1765 | void *addr = temp_ss.sge.vaddr; | ||
1766 | u32 slen = temp_ss.sge.length; | ||
1767 | |||
1768 | if (slen > length) { | ||
1769 | slen = length; | ||
1770 | snoop_dbg("slen %d > len %d", slen, length); | ||
1771 | } | ||
1772 | snoop_dbg("copy %d to %p", slen, addr); | ||
1773 | memcpy(data, addr, slen); | ||
1774 | update_sge(&temp_ss, slen); | ||
1775 | length -= slen; | ||
1776 | data += slen; | ||
1777 | snoop_dbg("data is now %p bytes left %d", data, length); | ||
1778 | } | ||
1779 | snoop_dbg("Completed SGE copy"); | ||
1780 | } | ||
1781 | |||
1782 | /* | ||
1783 | * Why do the filter check down here? Because the event tracing has its | ||
1784 | * own filtering and we need to have the walked the SGE list. | ||
1785 | */ | ||
1786 | if (!ppd->dd->hfi1_snoop.filter_callback) { | ||
1787 | snoop_dbg("filter not set\n"); | ||
1788 | ret = HFI1_FILTER_HIT; | ||
1789 | } else { | ||
1790 | ret = ppd->dd->hfi1_snoop.filter_callback( | ||
1791 | &ps->s_txreq->phdr.hdr, | ||
1792 | NULL, | ||
1793 | ppd->dd->hfi1_snoop.filter_value); | ||
1794 | } | ||
1795 | |||
1796 | switch (ret) { | ||
1797 | case HFI1_FILTER_ERR: | ||
1798 | snoop_dbg("Error in filter call"); | ||
1799 | /* fall through */ | ||
1800 | case HFI1_FILTER_MISS: | ||
1801 | snoop_dbg("Filter Miss"); | ||
1802 | kfree(s_packet); | ||
1803 | break; | ||
1804 | case HFI1_FILTER_HIT: | ||
1805 | snoop_dbg("Capturing packet"); | ||
1806 | snoop_list_add_tail(s_packet, ppd->dd); | ||
1807 | |||
1808 | if (unlikely((snoop_flags & SNOOP_DROP_SEND) && | ||
1809 | (ppd->dd->hfi1_snoop.mode_flag & | ||
1810 | HFI1_PORT_SNOOP_MODE))) { | ||
1811 | unsigned long flags; | ||
1812 | |||
1813 | snoop_dbg("Dropping packet"); | ||
1814 | if (qp->s_wqe) { | ||
1815 | spin_lock_irqsave(&qp->s_lock, flags); | ||
1816 | hfi1_send_complete( | ||
1817 | qp, | ||
1818 | qp->s_wqe, | ||
1819 | IB_WC_SUCCESS); | ||
1820 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
1821 | } else if (qp->ibqp.qp_type == IB_QPT_RC) { | ||
1822 | spin_lock_irqsave(&qp->s_lock, flags); | ||
1823 | hfi1_rc_send_complete(qp, | ||
1824 | &ps->s_txreq->phdr.hdr); | ||
1825 | spin_unlock_irqrestore(&qp->s_lock, flags); | ||
1826 | } | ||
1827 | |||
1828 | /* | ||
1829 | * If snoop is dropping the packet we need to put the | ||
1830 | * txreq back because no one else will. | ||
1831 | */ | ||
1832 | hfi1_put_txreq(ps->s_txreq); | ||
1833 | return 0; | ||
1834 | } | ||
1835 | break; | ||
1836 | default: | ||
1837 | kfree(s_packet); | ||
1838 | break; | ||
1839 | } | ||
1840 | out: | ||
1841 | return hfi1_verbs_send_pio(qp, ps, md.u.pbc); | ||
1842 | } | ||
1843 | |||
1844 | /* | ||
1845 | * Callers of this must pass a hfi1_ib_header type for the from ptr. Currently | ||
1846 | * this can be used anywhere, but the intention is for inline ACKs for RC and | ||
1847 | * CCA packets. We don't restrict this usage though. | ||
1848 | */ | ||
1849 | void snoop_inline_pio_send(struct hfi1_devdata *dd, struct pio_buf *pbuf, | ||
1850 | u64 pbc, const void *from, size_t count) | ||
1851 | { | ||
1852 | int snoop_mode = 0; | ||
1853 | int md_len = 0; | ||
1854 | struct capture_md md; | ||
1855 | struct snoop_packet *s_packet = NULL; | ||
1856 | |||
1857 | /* | ||
1858 | * count is in dwords so we need to convert to bytes. | ||
1859 | * We also need to account for CRC which would be tacked on by hardware. | ||
1860 | */ | ||
1861 | int packet_len = (count << 2) + 4; | ||
1862 | int ret; | ||
1863 | |||
1864 | snoop_dbg("ACK OUT: len %d", packet_len); | ||
1865 | |||
1866 | if (!dd->hfi1_snoop.filter_callback) { | ||
1867 | snoop_dbg("filter not set"); | ||
1868 | ret = HFI1_FILTER_HIT; | ||
1869 | } else { | ||
1870 | ret = dd->hfi1_snoop.filter_callback( | ||
1871 | (struct hfi1_ib_header *)from, | ||
1872 | NULL, | ||
1873 | dd->hfi1_snoop.filter_value); | ||
1874 | } | ||
1875 | |||
1876 | switch (ret) { | ||
1877 | case HFI1_FILTER_ERR: | ||
1878 | snoop_dbg("Error in filter call"); | ||
1879 | /* fall through */ | ||
1880 | case HFI1_FILTER_MISS: | ||
1881 | snoop_dbg("Filter Miss"); | ||
1882 | break; | ||
1883 | case HFI1_FILTER_HIT: | ||
1884 | snoop_dbg("Capturing packet"); | ||
1885 | if (dd->hfi1_snoop.mode_flag & HFI1_PORT_SNOOP_MODE) | ||
1886 | snoop_mode = 1; | ||
1887 | if ((snoop_mode == 0) || | ||
1888 | unlikely(snoop_flags & SNOOP_USE_METADATA)) | ||
1889 | md_len = sizeof(struct capture_md); | ||
1890 | |||
1891 | s_packet = allocate_snoop_packet(packet_len, 0, md_len); | ||
1892 | |||
1893 | if (unlikely(!s_packet)) { | ||
1894 | dd_dev_warn_ratelimited(dd, "Unable to allocate snoop/capture packet\n"); | ||
1895 | goto inline_pio_out; | ||
1896 | } | ||
1897 | |||
1898 | s_packet->total_len = packet_len + md_len; | ||
1899 | |||
1900 | /* Fill in the metadata for the packet */ | ||
1901 | if (md_len > 0) { | ||
1902 | memset(&md, 0, sizeof(struct capture_md)); | ||
1903 | md.port = 1; | ||
1904 | md.dir = PKT_DIR_EGRESS; | ||
1905 | md.u.pbc = pbc; | ||
1906 | memcpy(s_packet->data, &md, md_len); | ||
1907 | } | ||
1908 | |||
1909 | /* Add the packet data which is a single buffer */ | ||
1910 | memcpy(s_packet->data + md_len, from, packet_len); | ||
1911 | |||
1912 | snoop_list_add_tail(s_packet, dd); | ||
1913 | |||
1914 | if (unlikely((snoop_flags & SNOOP_DROP_SEND) && snoop_mode)) { | ||
1915 | snoop_dbg("Dropping packet"); | ||
1916 | return; | ||
1917 | } | ||
1918 | break; | ||
1919 | default: | ||
1920 | break; | ||
1921 | } | ||
1922 | |||
1923 | inline_pio_out: | ||
1924 | pio_copy(dd, pbuf, pbc, from, count); | ||
1925 | } | ||
diff --git a/drivers/staging/rdma/hfi1/eprom.c b/drivers/staging/rdma/hfi1/eprom.c deleted file mode 100644 index bd8771570f81..000000000000 --- a/drivers/staging/rdma/hfi1/eprom.c +++ /dev/null | |||
@@ -1,471 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright(c) 2015, 2016 Intel Corporation. | ||
3 | * | ||
4 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
5 | * redistributing this file, you may do so under either license. | ||
6 | * | ||
7 | * GPL LICENSE SUMMARY | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of version 2 of the GNU General Public License as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * BSD LICENSE | ||
19 | * | ||
20 | * Redistribution and use in source and binary forms, with or without | ||
21 | * modification, are permitted provided that the following conditions | ||
22 | * are met: | ||
23 | * | ||
24 | * - Redistributions of source code must retain the above copyright | ||
25 | * notice, this list of conditions and the following disclaimer. | ||
26 | * - Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * - Neither the name of Intel Corporation nor the names of its | ||
31 | * contributors may be used to endorse or promote products derived | ||
32 | * from this software without specific prior written permission. | ||
33 | * | ||
34 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
35 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
36 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
37 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
38 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
39 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
40 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
41 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
42 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
43 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
44 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
45 | * | ||
46 | */ | ||
47 | #include <linux/delay.h> | ||
48 | #include "hfi.h" | ||
49 | #include "common.h" | ||
50 | #include "eprom.h" | ||
51 | |||
52 | /* | ||
53 | * The EPROM is logically divided into three partitions: | ||
54 | * partition 0: the first 128K, visible from PCI ROM BAR | ||
55 | * partition 1: 4K config file (sector size) | ||
56 | * partition 2: the rest | ||
57 | */ | ||
58 | #define P0_SIZE (128 * 1024) | ||
59 | #define P1_SIZE (4 * 1024) | ||
60 | #define P1_START P0_SIZE | ||
61 | #define P2_START (P0_SIZE + P1_SIZE) | ||
62 | |||
63 | /* erase sizes supported by the controller */ | ||
64 | #define SIZE_4KB (4 * 1024) | ||
65 | #define MASK_4KB (SIZE_4KB - 1) | ||
66 | |||
67 | #define SIZE_32KB (32 * 1024) | ||
68 | #define MASK_32KB (SIZE_32KB - 1) | ||
69 | |||
70 | #define SIZE_64KB (64 * 1024) | ||
71 | #define MASK_64KB (SIZE_64KB - 1) | ||
72 | |||
73 | /* controller page size, in bytes */ | ||
74 | #define EP_PAGE_SIZE 256 | ||
75 | #define EEP_PAGE_MASK (EP_PAGE_SIZE - 1) | ||
76 | |||
77 | /* controller commands */ | ||
78 | #define CMD_SHIFT 24 | ||
79 | #define CMD_NOP (0) | ||
80 | #define CMD_PAGE_PROGRAM(addr) ((0x02 << CMD_SHIFT) | addr) | ||
81 | #define CMD_READ_DATA(addr) ((0x03 << CMD_SHIFT) | addr) | ||
82 | #define CMD_READ_SR1 ((0x05 << CMD_SHIFT)) | ||
83 | #define CMD_WRITE_ENABLE ((0x06 << CMD_SHIFT)) | ||
84 | #define CMD_SECTOR_ERASE_4KB(addr) ((0x20 << CMD_SHIFT) | addr) | ||
85 | #define CMD_SECTOR_ERASE_32KB(addr) ((0x52 << CMD_SHIFT) | addr) | ||
86 | #define CMD_CHIP_ERASE ((0x60 << CMD_SHIFT)) | ||
87 | #define CMD_READ_MANUF_DEV_ID ((0x90 << CMD_SHIFT)) | ||
88 | #define CMD_RELEASE_POWERDOWN_NOID ((0xab << CMD_SHIFT)) | ||
89 | #define CMD_SECTOR_ERASE_64KB(addr) ((0xd8 << CMD_SHIFT) | addr) | ||
90 | |||
91 | /* controller interface speeds */ | ||
92 | #define EP_SPEED_FULL 0x2 /* full speed */ | ||
93 | |||
94 | /* controller status register 1 bits */ | ||
95 | #define SR1_BUSY 0x1ull /* the BUSY bit in SR1 */ | ||
96 | |||
97 | /* sleep length while waiting for controller */ | ||
98 | #define WAIT_SLEEP_US 100 /* must be larger than 5 (see usage) */ | ||
99 | #define COUNT_DELAY_SEC(n) ((n) * (1000000 / WAIT_SLEEP_US)) | ||
100 | |||
101 | /* GPIO pins */ | ||
102 | #define EPROM_WP_N BIT_ULL(14) /* EPROM write line */ | ||
103 | |||
104 | /* | ||
105 | * How long to wait for the EPROM to become available, in ms. | ||
106 | * The spec 32 Mb EPROM takes around 40s to erase then write. | ||
107 | * Double it for safety. | ||
108 | */ | ||
109 | #define EPROM_TIMEOUT 80000 /* ms */ | ||
110 | |||
111 | /* | ||
112 | * Turn on external enable line that allows writing on the flash. | ||
113 | */ | ||
114 | static void write_enable(struct hfi1_devdata *dd) | ||
115 | { | ||
116 | /* raise signal */ | ||
117 | write_csr(dd, ASIC_GPIO_OUT, read_csr(dd, ASIC_GPIO_OUT) | EPROM_WP_N); | ||
118 | /* raise enable */ | ||
119 | write_csr(dd, ASIC_GPIO_OE, read_csr(dd, ASIC_GPIO_OE) | EPROM_WP_N); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Turn off external enable line that allows writing on the flash. | ||
124 | */ | ||
125 | static void write_disable(struct hfi1_devdata *dd) | ||
126 | { | ||
127 | /* lower signal */ | ||
128 | write_csr(dd, ASIC_GPIO_OUT, read_csr(dd, ASIC_GPIO_OUT) & ~EPROM_WP_N); | ||
129 | /* lower enable */ | ||
130 | write_csr(dd, ASIC_GPIO_OE, read_csr(dd, ASIC_GPIO_OE) & ~EPROM_WP_N); | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Wait for the device to become not busy. Must be called after all | ||
135 | * write or erase operations. | ||
136 | */ | ||
137 | static int wait_for_not_busy(struct hfi1_devdata *dd) | ||
138 | { | ||
139 | unsigned long count = 0; | ||
140 | u64 reg; | ||
141 | int ret = 0; | ||
142 | |||
143 | /* starts page mode */ | ||
144 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_READ_SR1); | ||
145 | while (1) { | ||
146 | udelay(WAIT_SLEEP_US); | ||
147 | usleep_range(WAIT_SLEEP_US - 5, WAIT_SLEEP_US + 5); | ||
148 | count++; | ||
149 | reg = read_csr(dd, ASIC_EEP_DATA); | ||
150 | if ((reg & SR1_BUSY) == 0) | ||
151 | break; | ||
152 | /* 200s is the largest time for a 128Mb device */ | ||
153 | if (count > COUNT_DELAY_SEC(200)) { | ||
154 | dd_dev_err(dd, "waited too long for SPI FLASH busy to clear - failing\n"); | ||
155 | ret = -ETIMEDOUT; | ||
156 | break; /* break, not goto - must stop page mode */ | ||
157 | } | ||
158 | } | ||
159 | |||
160 | /* stop page mode with a NOP */ | ||
161 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_NOP); | ||
162 | |||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * Read the device ID from the SPI controller. | ||
168 | */ | ||
169 | static u32 read_device_id(struct hfi1_devdata *dd) | ||
170 | { | ||
171 | /* read the Manufacture Device ID */ | ||
172 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_READ_MANUF_DEV_ID); | ||
173 | return (u32)read_csr(dd, ASIC_EEP_DATA); | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Erase the whole flash. | ||
178 | */ | ||
179 | static int erase_chip(struct hfi1_devdata *dd) | ||
180 | { | ||
181 | int ret; | ||
182 | |||
183 | write_enable(dd); | ||
184 | |||
185 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_WRITE_ENABLE); | ||
186 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_CHIP_ERASE); | ||
187 | ret = wait_for_not_busy(dd); | ||
188 | |||
189 | write_disable(dd); | ||
190 | |||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * Erase a range. | ||
196 | */ | ||
197 | static int erase_range(struct hfi1_devdata *dd, u32 start, u32 len) | ||
198 | { | ||
199 | u32 end = start + len; | ||
200 | int ret = 0; | ||
201 | |||
202 | if (end < start) | ||
203 | return -EINVAL; | ||
204 | |||
205 | /* check the end points for the minimum erase */ | ||
206 | if ((start & MASK_4KB) || (end & MASK_4KB)) { | ||
207 | dd_dev_err(dd, | ||
208 | "%s: non-aligned range (0x%x,0x%x) for a 4KB erase\n", | ||
209 | __func__, start, end); | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | write_enable(dd); | ||
214 | |||
215 | while (start < end) { | ||
216 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_WRITE_ENABLE); | ||
217 | /* check in order of largest to smallest */ | ||
218 | if (((start & MASK_64KB) == 0) && (start + SIZE_64KB <= end)) { | ||
219 | write_csr(dd, ASIC_EEP_ADDR_CMD, | ||
220 | CMD_SECTOR_ERASE_64KB(start)); | ||
221 | start += SIZE_64KB; | ||
222 | } else if (((start & MASK_32KB) == 0) && | ||
223 | (start + SIZE_32KB <= end)) { | ||
224 | write_csr(dd, ASIC_EEP_ADDR_CMD, | ||
225 | CMD_SECTOR_ERASE_32KB(start)); | ||
226 | start += SIZE_32KB; | ||
227 | } else { /* 4KB will work */ | ||
228 | write_csr(dd, ASIC_EEP_ADDR_CMD, | ||
229 | CMD_SECTOR_ERASE_4KB(start)); | ||
230 | start += SIZE_4KB; | ||
231 | } | ||
232 | ret = wait_for_not_busy(dd); | ||
233 | if (ret) | ||
234 | goto done; | ||
235 | } | ||
236 | |||
237 | done: | ||
238 | write_disable(dd); | ||
239 | |||
240 | return ret; | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * Read a 256 byte (64 dword) EPROM page. | ||
245 | * All callers have verified the offset is at a page boundary. | ||
246 | */ | ||
247 | static void read_page(struct hfi1_devdata *dd, u32 offset, u32 *result) | ||
248 | { | ||
249 | int i; | ||
250 | |||
251 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_READ_DATA(offset)); | ||
252 | for (i = 0; i < EP_PAGE_SIZE / sizeof(u32); i++) | ||
253 | result[i] = (u32)read_csr(dd, ASIC_EEP_DATA); | ||
254 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_NOP); /* close open page */ | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * Read length bytes starting at offset. Copy to user address addr. | ||
259 | */ | ||
260 | static int read_length(struct hfi1_devdata *dd, u32 start, u32 len, u64 addr) | ||
261 | { | ||
262 | u32 offset; | ||
263 | u32 buffer[EP_PAGE_SIZE / sizeof(u32)]; | ||
264 | int ret = 0; | ||
265 | |||
266 | /* reject anything not on an EPROM page boundary */ | ||
267 | if ((start & EEP_PAGE_MASK) || (len & EEP_PAGE_MASK)) | ||
268 | return -EINVAL; | ||
269 | |||
270 | for (offset = 0; offset < len; offset += EP_PAGE_SIZE) { | ||
271 | read_page(dd, start + offset, buffer); | ||
272 | if (copy_to_user((void __user *)(addr + offset), | ||
273 | buffer, EP_PAGE_SIZE)) { | ||
274 | ret = -EFAULT; | ||
275 | goto done; | ||
276 | } | ||
277 | } | ||
278 | |||
279 | done: | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * Write a 256 byte (64 dword) EPROM page. | ||
285 | * All callers have verified the offset is at a page boundary. | ||
286 | */ | ||
287 | static int write_page(struct hfi1_devdata *dd, u32 offset, u32 *data) | ||
288 | { | ||
289 | int i; | ||
290 | |||
291 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_WRITE_ENABLE); | ||
292 | write_csr(dd, ASIC_EEP_DATA, data[0]); | ||
293 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_PAGE_PROGRAM(offset)); | ||
294 | for (i = 1; i < EP_PAGE_SIZE / sizeof(u32); i++) | ||
295 | write_csr(dd, ASIC_EEP_DATA, data[i]); | ||
296 | /* will close the open page */ | ||
297 | return wait_for_not_busy(dd); | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * Write length bytes starting at offset. Read from user address addr. | ||
302 | */ | ||
303 | static int write_length(struct hfi1_devdata *dd, u32 start, u32 len, u64 addr) | ||
304 | { | ||
305 | u32 offset; | ||
306 | u32 buffer[EP_PAGE_SIZE / sizeof(u32)]; | ||
307 | int ret = 0; | ||
308 | |||
309 | /* reject anything not on an EPROM page boundary */ | ||
310 | if ((start & EEP_PAGE_MASK) || (len & EEP_PAGE_MASK)) | ||
311 | return -EINVAL; | ||
312 | |||
313 | write_enable(dd); | ||
314 | |||
315 | for (offset = 0; offset < len; offset += EP_PAGE_SIZE) { | ||
316 | if (copy_from_user(buffer, (void __user *)(addr + offset), | ||
317 | EP_PAGE_SIZE)) { | ||
318 | ret = -EFAULT; | ||
319 | goto done; | ||
320 | } | ||
321 | ret = write_page(dd, start + offset, buffer); | ||
322 | if (ret) | ||
323 | goto done; | ||
324 | } | ||
325 | |||
326 | done: | ||
327 | write_disable(dd); | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | /* convert an range composite to a length, in bytes */ | ||
332 | static inline u32 extract_rlen(u32 composite) | ||
333 | { | ||
334 | return (composite & 0xffff) * EP_PAGE_SIZE; | ||
335 | } | ||
336 | |||
337 | /* convert an range composite to a start, in bytes */ | ||
338 | static inline u32 extract_rstart(u32 composite) | ||
339 | { | ||
340 | return (composite >> 16) * EP_PAGE_SIZE; | ||
341 | } | ||
342 | |||
343 | /* | ||
344 | * Perform the given operation on the EPROM. Called from user space. The | ||
345 | * user credentials have already been checked. | ||
346 | * | ||
347 | * Return 0 on success, -ERRNO on error | ||
348 | */ | ||
349 | int handle_eprom_command(struct file *fp, const struct hfi1_cmd *cmd) | ||
350 | { | ||
351 | struct hfi1_devdata *dd; | ||
352 | u32 dev_id; | ||
353 | u32 rlen; /* range length */ | ||
354 | u32 rstart; /* range start */ | ||
355 | int i_minor; | ||
356 | int ret = 0; | ||
357 | |||
358 | /* | ||
359 | * Map the device file to device data using the relative minor. | ||
360 | * The device file minor number is the unit number + 1. 0 is | ||
361 | * the generic device file - reject it. | ||
362 | */ | ||
363 | i_minor = iminor(file_inode(fp)) - HFI1_USER_MINOR_BASE; | ||
364 | if (i_minor <= 0) | ||
365 | return -EINVAL; | ||
366 | dd = hfi1_lookup(i_minor - 1); | ||
367 | if (!dd) { | ||
368 | pr_err("%s: cannot find unit %d!\n", __func__, i_minor); | ||
369 | return -EINVAL; | ||
370 | } | ||
371 | |||
372 | /* some devices do not have an EPROM */ | ||
373 | if (!dd->eprom_available) | ||
374 | return -EOPNOTSUPP; | ||
375 | |||
376 | ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); | ||
377 | if (ret) { | ||
378 | dd_dev_err(dd, "%s: unable to acquire EPROM resource\n", | ||
379 | __func__); | ||
380 | goto done_asic; | ||
381 | } | ||
382 | |||
383 | dd_dev_info(dd, "%s: cmd: type %d, len 0x%x, addr 0x%016llx\n", | ||
384 | __func__, cmd->type, cmd->len, cmd->addr); | ||
385 | |||
386 | switch (cmd->type) { | ||
387 | case HFI1_CMD_EP_INFO: | ||
388 | if (cmd->len != sizeof(u32)) { | ||
389 | ret = -ERANGE; | ||
390 | break; | ||
391 | } | ||
392 | dev_id = read_device_id(dd); | ||
393 | /* addr points to a u32 user buffer */ | ||
394 | if (copy_to_user((void __user *)cmd->addr, &dev_id, | ||
395 | sizeof(u32))) | ||
396 | ret = -EFAULT; | ||
397 | break; | ||
398 | |||
399 | case HFI1_CMD_EP_ERASE_CHIP: | ||
400 | ret = erase_chip(dd); | ||
401 | break; | ||
402 | |||
403 | case HFI1_CMD_EP_ERASE_RANGE: | ||
404 | rlen = extract_rlen(cmd->len); | ||
405 | rstart = extract_rstart(cmd->len); | ||
406 | ret = erase_range(dd, rstart, rlen); | ||
407 | break; | ||
408 | |||
409 | case HFI1_CMD_EP_READ_RANGE: | ||
410 | rlen = extract_rlen(cmd->len); | ||
411 | rstart = extract_rstart(cmd->len); | ||
412 | ret = read_length(dd, rstart, rlen, cmd->addr); | ||
413 | break; | ||
414 | |||
415 | case HFI1_CMD_EP_WRITE_RANGE: | ||
416 | rlen = extract_rlen(cmd->len); | ||
417 | rstart = extract_rstart(cmd->len); | ||
418 | ret = write_length(dd, rstart, rlen, cmd->addr); | ||
419 | break; | ||
420 | |||
421 | default: | ||
422 | dd_dev_err(dd, "%s: unexpected command %d\n", | ||
423 | __func__, cmd->type); | ||
424 | ret = -EINVAL; | ||
425 | break; | ||
426 | } | ||
427 | |||
428 | release_chip_resource(dd, CR_EPROM); | ||
429 | done_asic: | ||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * Initialize the EPROM handler. | ||
435 | */ | ||
436 | int eprom_init(struct hfi1_devdata *dd) | ||
437 | { | ||
438 | int ret = 0; | ||
439 | |||
440 | /* only the discrete chip has an EPROM */ | ||
441 | if (dd->pcidev->device != PCI_DEVICE_ID_INTEL0) | ||
442 | return 0; | ||
443 | |||
444 | /* | ||
445 | * It is OK if both HFIs reset the EPROM as long as they don't | ||
446 | * do it at the same time. | ||
447 | */ | ||
448 | ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); | ||
449 | if (ret) { | ||
450 | dd_dev_err(dd, | ||
451 | "%s: unable to acquire EPROM resource, no EPROM support\n", | ||
452 | __func__); | ||
453 | goto done_asic; | ||
454 | } | ||
455 | |||
456 | /* reset EPROM to be sure it is in a good state */ | ||
457 | |||
458 | /* set reset */ | ||
459 | write_csr(dd, ASIC_EEP_CTL_STAT, ASIC_EEP_CTL_STAT_EP_RESET_SMASK); | ||
460 | /* clear reset, set speed */ | ||
461 | write_csr(dd, ASIC_EEP_CTL_STAT, | ||
462 | EP_SPEED_FULL << ASIC_EEP_CTL_STAT_RATE_SPI_SHIFT); | ||
463 | |||
464 | /* wake the device with command "release powerdown NoID" */ | ||
465 | write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_RELEASE_POWERDOWN_NOID); | ||
466 | |||
467 | dd->eprom_available = true; | ||
468 | release_chip_resource(dd, CR_EPROM); | ||
469 | done_asic: | ||
470 | return ret; | ||
471 | } | ||
diff --git a/include/rdma/ib_pack.h b/include/rdma/ib_pack.h index 0f3daae44bf9..b13419ce99ff 100644 --- a/include/rdma/ib_pack.h +++ b/include/rdma/ib_pack.h | |||
@@ -103,6 +103,9 @@ enum { | |||
103 | IB_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12, | 103 | IB_OPCODE_ATOMIC_ACKNOWLEDGE = 0x12, |
104 | IB_OPCODE_COMPARE_SWAP = 0x13, | 104 | IB_OPCODE_COMPARE_SWAP = 0x13, |
105 | IB_OPCODE_FETCH_ADD = 0x14, | 105 | IB_OPCODE_FETCH_ADD = 0x14, |
106 | /* opcode 0x15 is reserved */ | ||
107 | IB_OPCODE_SEND_LAST_WITH_INVALIDATE = 0x16, | ||
108 | IB_OPCODE_SEND_ONLY_WITH_INVALIDATE = 0x17, | ||
106 | 109 | ||
107 | /* real constants follow -- see comment about above IB_OPCODE() | 110 | /* real constants follow -- see comment about above IB_OPCODE() |
108 | macro for more details */ | 111 | macro for more details */ |
@@ -129,6 +132,8 @@ enum { | |||
129 | IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE), | 132 | IB_OPCODE(RC, ATOMIC_ACKNOWLEDGE), |
130 | IB_OPCODE(RC, COMPARE_SWAP), | 133 | IB_OPCODE(RC, COMPARE_SWAP), |
131 | IB_OPCODE(RC, FETCH_ADD), | 134 | IB_OPCODE(RC, FETCH_ADD), |
135 | IB_OPCODE(RC, SEND_LAST_WITH_INVALIDATE), | ||
136 | IB_OPCODE(RC, SEND_ONLY_WITH_INVALIDATE), | ||
132 | 137 | ||
133 | /* UC */ | 138 | /* UC */ |
134 | IB_OPCODE(UC, SEND_FIRST), | 139 | IB_OPCODE(UC, SEND_FIRST), |
diff --git a/include/rdma/rdma_vt.h b/include/rdma/rdma_vt.h index d57ceee90d26..16274e2133cd 100644 --- a/include/rdma/rdma_vt.h +++ b/include/rdma/rdma_vt.h | |||
@@ -149,15 +149,15 @@ struct rvt_driver_params { | |||
149 | int qpn_res_end; | 149 | int qpn_res_end; |
150 | int nports; | 150 | int nports; |
151 | int npkeys; | 151 | int npkeys; |
152 | u8 qos_shift; | ||
153 | char cq_name[RVT_CQN_MAX]; | 152 | char cq_name[RVT_CQN_MAX]; |
154 | int node; | 153 | int node; |
155 | int max_rdma_atomic; | ||
156 | int psn_mask; | 154 | int psn_mask; |
157 | int psn_shift; | 155 | int psn_shift; |
158 | int psn_modify_mask; | 156 | int psn_modify_mask; |
159 | u32 core_cap_flags; | 157 | u32 core_cap_flags; |
160 | u32 max_mad_size; | 158 | u32 max_mad_size; |
159 | u8 qos_shift; | ||
160 | u8 max_rdma_atomic; | ||
161 | }; | 161 | }; |
162 | 162 | ||
163 | /* Protection domain */ | 163 | /* Protection domain */ |
@@ -426,6 +426,15 @@ static inline unsigned rvt_get_npkeys(struct rvt_dev_info *rdi) | |||
426 | } | 426 | } |
427 | 427 | ||
428 | /* | 428 | /* |
429 | * Return the max atomic suitable for determining | ||
430 | * the size of the ack ring buffer in a QP. | ||
431 | */ | ||
432 | static inline unsigned int rvt_max_atomic(struct rvt_dev_info *rdi) | ||
433 | { | ||
434 | return rdi->dparms.max_rdma_atomic + 1; | ||
435 | } | ||
436 | |||
437 | /* | ||
429 | * Return the indexed PKEY from the port PKEY table. | 438 | * Return the indexed PKEY from the port PKEY table. |
430 | */ | 439 | */ |
431 | static inline u16 rvt_get_pkey(struct rvt_dev_info *rdi, | 440 | static inline u16 rvt_get_pkey(struct rvt_dev_info *rdi, |
diff --git a/include/rdma/rdmavt_qp.h b/include/rdma/rdmavt_qp.h index 0e1ff2abfe92..6d23b879416a 100644 --- a/include/rdma/rdmavt_qp.h +++ b/include/rdma/rdmavt_qp.h | |||
@@ -211,8 +211,6 @@ struct rvt_mmap_info { | |||
211 | unsigned size; | 211 | unsigned size; |
212 | }; | 212 | }; |
213 | 213 | ||
214 | #define RVT_MAX_RDMA_ATOMIC 16 | ||
215 | |||
216 | /* | 214 | /* |
217 | * This structure holds the information that the send tasklet needs | 215 | * This structure holds the information that the send tasklet needs |
218 | * to send a RDMA read response or atomic operation. | 216 | * to send a RDMA read response or atomic operation. |
@@ -282,8 +280,7 @@ struct rvt_qp { | |||
282 | atomic_t refcount ____cacheline_aligned_in_smp; | 280 | atomic_t refcount ____cacheline_aligned_in_smp; |
283 | wait_queue_head_t wait; | 281 | wait_queue_head_t wait; |
284 | 282 | ||
285 | struct rvt_ack_entry s_ack_queue[RVT_MAX_RDMA_ATOMIC + 1] | 283 | struct rvt_ack_entry *s_ack_queue; |
286 | ____cacheline_aligned_in_smp; | ||
287 | struct rvt_sge_state s_rdma_read_sge; | 284 | struct rvt_sge_state s_rdma_read_sge; |
288 | 285 | ||
289 | spinlock_t r_lock ____cacheline_aligned_in_smp; /* used for APM */ | 286 | spinlock_t r_lock ____cacheline_aligned_in_smp; /* used for APM */ |
diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h index a533cecab14f..98bebf8bef55 100644 --- a/include/uapi/rdma/hfi/hfi1_user.h +++ b/include/uapi/rdma/hfi/hfi1_user.h | |||
@@ -66,7 +66,7 @@ | |||
66 | * The major version changes when data structures change in an incompatible | 66 | * The major version changes when data structures change in an incompatible |
67 | * way. The driver must be the same for initialization to succeed. | 67 | * way. The driver must be the same for initialization to succeed. |
68 | */ | 68 | */ |
69 | #define HFI1_USER_SWMAJOR 5 | 69 | #define HFI1_USER_SWMAJOR 6 |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Minor version differences are always compatible | 72 | * Minor version differences are always compatible |
@@ -75,7 +75,12 @@ | |||
75 | * may not be implemented; the user code must deal with this if it | 75 | * may not be implemented; the user code must deal with this if it |
76 | * cares, or it must abort after initialization reports the difference. | 76 | * cares, or it must abort after initialization reports the difference. |
77 | */ | 77 | */ |
78 | #define HFI1_USER_SWMINOR 0 | 78 | #define HFI1_USER_SWMINOR 1 |
79 | |||
80 | /* | ||
81 | * We will encode the major/minor inside a single 32bit version number. | ||
82 | */ | ||
83 | #define HFI1_SWMAJOR_SHIFT 16 | ||
79 | 84 | ||
80 | /* | 85 | /* |
81 | * Set of HW and driver capability/feature bits. | 86 | * Set of HW and driver capability/feature bits. |
@@ -107,19 +112,6 @@ | |||
107 | #define HFI1_RCVHDR_ENTSIZE_16 (1UL << 1) | 112 | #define HFI1_RCVHDR_ENTSIZE_16 (1UL << 1) |
108 | #define HFI1_RCVDHR_ENTSIZE_32 (1UL << 2) | 113 | #define HFI1_RCVDHR_ENTSIZE_32 (1UL << 2) |
109 | 114 | ||
110 | /* | ||
111 | * If the unit is specified via open, HFI choice is fixed. If port is | ||
112 | * specified, it's also fixed. Otherwise we try to spread contexts | ||
113 | * across ports and HFIs, using different algorithms. WITHIN is | ||
114 | * the old default, prior to this mechanism. | ||
115 | */ | ||
116 | #define HFI1_ALG_ACROSS 0 /* round robin contexts across HFIs, then | ||
117 | * ports; this is the default */ | ||
118 | #define HFI1_ALG_WITHIN 1 /* use all contexts on an HFI (round robin | ||
119 | * active ports within), then next HFI */ | ||
120 | #define HFI1_ALG_COUNT 2 /* number of algorithm choices */ | ||
121 | |||
122 | |||
123 | /* User commands. */ | 115 | /* User commands. */ |
124 | #define HFI1_CMD_ASSIGN_CTXT 1 /* allocate HFI and context */ | 116 | #define HFI1_CMD_ASSIGN_CTXT 1 /* allocate HFI and context */ |
125 | #define HFI1_CMD_CTXT_INFO 2 /* find out what resources we got */ | 117 | #define HFI1_CMD_CTXT_INFO 2 /* find out what resources we got */ |
@@ -127,7 +119,6 @@ | |||
127 | #define HFI1_CMD_TID_UPDATE 4 /* update expected TID entries */ | 119 | #define HFI1_CMD_TID_UPDATE 4 /* update expected TID entries */ |
128 | #define HFI1_CMD_TID_FREE 5 /* free expected TID entries */ | 120 | #define HFI1_CMD_TID_FREE 5 /* free expected TID entries */ |
129 | #define HFI1_CMD_CREDIT_UPD 6 /* force an update of PIO credit */ | 121 | #define HFI1_CMD_CREDIT_UPD 6 /* force an update of PIO credit */ |
130 | #define HFI1_CMD_SDMA_STATUS_UPD 7 /* force update of SDMA status ring */ | ||
131 | 122 | ||
132 | #define HFI1_CMD_RECV_CTRL 8 /* control receipt of packets */ | 123 | #define HFI1_CMD_RECV_CTRL 8 /* control receipt of packets */ |
133 | #define HFI1_CMD_POLL_TYPE 9 /* set the kind of polling we want */ | 124 | #define HFI1_CMD_POLL_TYPE 9 /* set the kind of polling we want */ |
@@ -135,13 +126,46 @@ | |||
135 | #define HFI1_CMD_SET_PKEY 11 /* set context's pkey */ | 126 | #define HFI1_CMD_SET_PKEY 11 /* set context's pkey */ |
136 | #define HFI1_CMD_CTXT_RESET 12 /* reset context's HW send context */ | 127 | #define HFI1_CMD_CTXT_RESET 12 /* reset context's HW send context */ |
137 | #define HFI1_CMD_TID_INVAL_READ 13 /* read TID cache invalidations */ | 128 | #define HFI1_CMD_TID_INVAL_READ 13 /* read TID cache invalidations */ |
138 | /* separate EPROM commands from normal PSM commands */ | 129 | #define HFI1_CMD_GET_VERS 14 /* get the version of the user cdev */ |
139 | #define HFI1_CMD_EP_INFO 64 /* read EPROM device ID */ | 130 | |
140 | #define HFI1_CMD_EP_ERASE_CHIP 65 /* erase whole EPROM */ | 131 | /* |
141 | /* range 66-74 no longer used */ | 132 | * User IOCTLs can not go above 128 if they do then see common.h and change the |
142 | #define HFI1_CMD_EP_ERASE_RANGE 75 /* erase EPROM range */ | 133 | * base for the snoop ioctl |
143 | #define HFI1_CMD_EP_READ_RANGE 76 /* read EPROM range */ | 134 | */ |
144 | #define HFI1_CMD_EP_WRITE_RANGE 77 /* write EPROM range */ | 135 | #define IB_IOCTL_MAGIC 0x1b /* See Documentation/ioctl/ioctl-number.txt */ |
136 | |||
137 | /* | ||
138 | * Make the ioctls occupy the last 0xf0-0xff portion of the IB range | ||
139 | */ | ||
140 | #define __NUM(cmd) (HFI1_CMD_##cmd + 0xe0) | ||
141 | |||
142 | struct hfi1_cmd; | ||
143 | #define HFI1_IOCTL_ASSIGN_CTXT \ | ||
144 | _IOWR(IB_IOCTL_MAGIC, __NUM(ASSIGN_CTXT), struct hfi1_user_info) | ||
145 | #define HFI1_IOCTL_CTXT_INFO \ | ||
146 | _IOW(IB_IOCTL_MAGIC, __NUM(CTXT_INFO), struct hfi1_ctxt_info) | ||
147 | #define HFI1_IOCTL_USER_INFO \ | ||
148 | _IOW(IB_IOCTL_MAGIC, __NUM(USER_INFO), struct hfi1_base_info) | ||
149 | #define HFI1_IOCTL_TID_UPDATE \ | ||
150 | _IOWR(IB_IOCTL_MAGIC, __NUM(TID_UPDATE), struct hfi1_tid_info) | ||
151 | #define HFI1_IOCTL_TID_FREE \ | ||
152 | _IOWR(IB_IOCTL_MAGIC, __NUM(TID_FREE), struct hfi1_tid_info) | ||
153 | #define HFI1_IOCTL_CREDIT_UPD \ | ||
154 | _IO(IB_IOCTL_MAGIC, __NUM(CREDIT_UPD)) | ||
155 | #define HFI1_IOCTL_RECV_CTRL \ | ||
156 | _IOW(IB_IOCTL_MAGIC, __NUM(RECV_CTRL), int) | ||
157 | #define HFI1_IOCTL_POLL_TYPE \ | ||
158 | _IOW(IB_IOCTL_MAGIC, __NUM(POLL_TYPE), int) | ||
159 | #define HFI1_IOCTL_ACK_EVENT \ | ||
160 | _IOW(IB_IOCTL_MAGIC, __NUM(ACK_EVENT), unsigned long) | ||
161 | #define HFI1_IOCTL_SET_PKEY \ | ||
162 | _IOW(IB_IOCTL_MAGIC, __NUM(SET_PKEY), __u16) | ||
163 | #define HFI1_IOCTL_CTXT_RESET \ | ||
164 | _IO(IB_IOCTL_MAGIC, __NUM(CTXT_RESET)) | ||
165 | #define HFI1_IOCTL_TID_INVAL_READ \ | ||
166 | _IOWR(IB_IOCTL_MAGIC, __NUM(TID_INVAL_READ), struct hfi1_tid_info) | ||
167 | #define HFI1_IOCTL_GET_VERS \ | ||
168 | _IOR(IB_IOCTL_MAGIC, __NUM(GET_VERS), int) | ||
145 | 169 | ||
146 | #define _HFI1_EVENT_FROZEN_BIT 0 | 170 | #define _HFI1_EVENT_FROZEN_BIT 0 |
147 | #define _HFI1_EVENT_LINKDOWN_BIT 1 | 171 | #define _HFI1_EVENT_LINKDOWN_BIT 1 |
@@ -199,9 +223,7 @@ struct hfi1_user_info { | |||
199 | * Should be set to HFI1_USER_SWVERSION. | 223 | * Should be set to HFI1_USER_SWVERSION. |
200 | */ | 224 | */ |
201 | __u32 userversion; | 225 | __u32 userversion; |
202 | __u16 pad; | 226 | __u32 pad; |
203 | /* HFI selection algorithm, if unit has not selected */ | ||
204 | __u16 hfi1_alg; | ||
205 | /* | 227 | /* |
206 | * If two or more processes wish to share a context, each process | 228 | * If two or more processes wish to share a context, each process |
207 | * must set the subcontext_cnt and subcontext_id to the same | 229 | * must set the subcontext_cnt and subcontext_id to the same |
@@ -243,12 +265,6 @@ struct hfi1_tid_info { | |||
243 | __u32 length; | 265 | __u32 length; |
244 | }; | 266 | }; |
245 | 267 | ||
246 | struct hfi1_cmd { | ||
247 | __u32 type; /* command type */ | ||
248 | __u32 len; /* length of struct pointed to by add */ | ||
249 | __u64 addr; /* pointer to user structure */ | ||
250 | }; | ||
251 | |||
252 | enum hfi1_sdma_comp_state { | 268 | enum hfi1_sdma_comp_state { |
253 | FREE = 0, | 269 | FREE = 0, |
254 | QUEUED, | 270 | QUEUED, |