* Re: [PATCH 0/3] infiniband: IB/hns: Hisilicon RoCE support
From: oulijun @ 2016-03-19 11:13 UTC (permalink / raw)
To: dledford, sean.hefty, hal.rosenstock, davem, jeffrey.t.kirsher,
jiri, ogerlitz, linux-rdma, linux-kernel, netdev, gongyangming,
xiaokun, tangchaofei, haifeng.wei, yisen.zhuang, yankejian,
lisheng011, charles.chenxin, linuxarm
In-Reply-To: <20160312102051.GC11383@leon.nu>
On 2016/3/12 18:20, Leon Romanovsky wrote:
> On Fri, Mar 11, 2016 at 06:37:08PM +0800, Lijun Ou wrote:
>
> 1) It is redundant to write "infiniband" and "IB" in one title to mention
> relevant subsystem, since it is the same.
>
> Please take a look on the other submissions here on the list and use
> similar construction.
>
> 2) Please use version number in the titles [PATCH vXXX]
>
Hi dledford, thanks for reviewing
I have modified it, I will send a new patch at soon
thanks
Lijun Ou
>> The Hisilicon Network Substem(hns) is a long term evolution IP which is
>> supposed to be used in Hisilicon ICT SoC. RoCE is a feature of hns.
>> The driver for Hisilicon RoCE engine is a platform driver.
>> The driver will support mulitple versions of hns. Currently only "v1"
>> for hip06 SOC is supported.
>>
>>
>> Changes v1 -> v2:
>> 1. adjust the formats of roce driver code by the experts reviewing
>> 2. modify the bindings file with roce dts. add the attribute named
>> interrput-names.
>> 3. modify the way of defining port mode in hns_dsaf_main.c
>> 4. move the Kconfig file into the hns directory and send it with roce
>> driver code file together.
>>
>>
>> Lijun Ou (3):
>> infiniband: IB/hns: add Hisilicon RoCE support
>> net: hns: add Hisilicon RoCE support
>> infiniband: IB/hns: add Hisilicon RoCE support with bindings
>>
>
> .
>
^ permalink raw reply
* Re: [PATCH 1/3] infiniband: IB/hns: add Hisilicon RoCE support
From: oulijun @ 2016-03-19 11:11 UTC (permalink / raw)
To: Jiri Pirko, dledford, sean.hefty, hal.rosenstock, davem,
jeffrey.t.kirsher, jiri, ogerlitz, linux-rdma, linux-kernel,
netdev, gongyangming, xiaokun, tangchaofei, haifeng.wei,
yisen.zhuang, yankejian, lisheng011, charles.chenxin, linuxarm
In-Reply-To: <20160317064359.GA25216@leon.nu>
On 2016/3/17 14:43, Leon Romanovsky wrote:
> On Wed, Mar 16, 2016 at 11:36:38AM +0100, Jiri Pirko wrote:
>>> so, I continue to have it.
>>
>> I will continue to bash on your odd codingstyle. Please fix it!
>
> Jiri,
>
> Checkpatch errors is an easiest issue with this patch.
>
> It is full of functions without use, unconnected macros and
> if you replace "hsi" to name of other well known driver, you will get
> same code :).
>
> They need to redesign the whole driver before resubmission.
>
> Thanks.
>
> .
>
Hi, Leon Romanovsky
Firstly, thanks for reviewing.
I have checked the patch v2, surely, some funtions without use and unconnected
macros exist. I have removed it according to analyse. I will leave few marcos as follow:
#define CQ_STATE_INVALID 0
#define CQ_STATE_RESERV 1
#define CQ_STATE_VALID 2
#define CQ_STATE_ERR 3
I thought that these are defined for hardware information. So, I reserved these macros.
In addtion, I didn't completly understand your review as below:
if you replace "hsi" to name of other well known driver, you will get > same code :).
thanks
Lijun Ou
^ permalink raw reply
* [PATCH v3 3/3] IB/hns: Add binding document for HiSilicon RoCE driver
From: Lijun Ou @ 2016-03-19 10:50 UTC (permalink / raw)
To: dledford-H+wXaHxf7aLQT0dZR+AlfA,
sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
jiri-VPRAkNaXOzVWk0Htik3J/w, ogerlitz-VPRAkNaXOzVWk0Htik3J/w
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
gongyangming-hv44wF8Li93QT0dZR+AlfA,
xiaokun-hv44wF8Li93QT0dZR+AlfA,
tangchaofei-hv44wF8Li93QT0dZR+AlfA,
oulijun-hv44wF8Li93QT0dZR+AlfA,
haifeng.wei-hv44wF8Li93QT0dZR+AlfA,
yisen.zhuang-hv44wF8Li93QT0dZR+AlfA,
yankejian-hv44wF8Li93QT0dZR+AlfA,
lisheng011-hv44wF8Li93QT0dZR+AlfA,
charles.chenxin-hv44wF8Li93QT0dZR+AlfA,
linuxarm-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <1458384658-16759-1-git-send-email-oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
This patch adds related DTS binding document for HiSilicon RoCE driver.
Signed-off-by: Lijun Ou <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Wei Hu(Xavier) <xavier.huwei-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
.../bindings/infiniband/hisilicon-hns-roce.txt | 107 +++++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt
diff --git a/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt b/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt
new file mode 100644
index 0000000..5180fef
--- /dev/null
+++ b/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt
@@ -0,0 +1,107 @@
+HiSilicon RoCE DT description
+
+HiSilicon RoCE engine is a part of network subsystem.
+It works depending on other part of network wubsytem, such as, gmac and
+dsa fabric.
+
+Additional properties are described here:
+
+Required properties:
+- compatible: Should contain "hisilicon,hns-roce-v1".
+- reg: Physical base address of the roce driver and
+length of memory mapped region.
+- eth-handle: phandle, specifies a reference to a node
+representing a ethernet device.
+- dsaf-handle: phandle, specifies a reference to a node
+representing a dsaf device.
+- #address-cells: must be 2
+- #size-cells: must be 2
+Optional properties:
+- dma-coherent: Present if DMA operations are coherent.
+- interrupt-parent: the interrupt parent of this device.
+- interrupts: should contain 32 completion event irq,1 async event irq
+and 1 event overflow irq.
+- interrupt-names:should be one of 34 irqs for roce device
+ - roce_ce0_irq ~ roce_ce31_irq: 32 complete event irq
+ - roce_ae_irq: 1 async event irq
+ - roce_common_irq: named common exception warning irq
+Example:
+ infiniband@c4000000 {
+ compatible = "hisilicon,hns-roce-v1";
+ reg = <0x0 0xc4000000 0x0 0x100000>;
+ dma-coherent;
+ eth-handle = <ð2 ð3 ð4 ð5 ð6 ð7>;
+ dsaf-handle = <&soc0_dsa>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&mbigen_dsa>;
+ interrupts = <722 1>,
+ <723 1>,
+ <724 1>,
+ <725 1>,
+ <726 1>,
+ <727 1>,
+ <728 1>,
+ <729 1>,
+ <730 1>,
+ <731 1>,
+ <732 1>,
+ <733 1>,
+ <734 1>,
+ <735 1>,
+ <736 1>,
+ <737 1>,
+ <738 1>,
+ <739 1>,
+ <740 1>,
+ <741 1>,
+ <742 1>,
+ <743 1>,
+ <744 1>,
+ <745 1>,
+ <746 1>,
+ <747 1>,
+ <748 1>,
+ <749 1>,
+ <750 1>,
+ <751 1>,
+ <752 1>,
+ <753 1>,
+ <785 1>,
+ <754 4>;
+
+ interrupt-names = "roce_ce0_irq",
+ "roce_ce1_irq",
+ "roce_ce2_irq",
+ "roce_ce3_irq",
+ "roce_ce4_irq",
+ "roce_ce5_irq",
+ "roce_ce6_irq",
+ "roce_ce7_irq",
+ "roce_ce8_irq",
+ "roce_ce9_irq",
+ "roce_ce10_irq",
+ "roce_ce11_irq",
+ "roce_ce12_irq",
+ "roce_ce13_irq",
+ "roce_ce14_irq",
+ "roce_ce15_irq",
+ "roce_ce16_irq",
+ "roce_ce17_irq",
+ "roce_ce18_irq",
+ "roce_ce19_irq",
+ "roce_ce20_irq",
+ "roce_ce21_irq",
+ "roce_ce22_irq",
+ "roce_ce23_irq",
+ "roce_ce24_irq",
+ "roce_ce25_irq",
+ "roce_ce26_irq",
+ "roce_ce27_irq",
+ "roce_ce28_irq",
+ "roce_ce29_irq",
+ "roce_ce30_irq",
+ "roce_ce31_irq",
+ "roce_ae_irq",
+ "roce_common_irq";
+ };
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 2/3] IB/hns: Add HiSilicon RoCE driver support
From: Lijun Ou @ 2016-03-19 10:50 UTC (permalink / raw)
To: dledford-H+wXaHxf7aLQT0dZR+AlfA,
sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
davem-fT/PcQaiUtIeIZ0/mPfg9Q,
jeffrey.t.kirsher-ral2JQCrhuEAvxtiuMwx3w,
jiri-VPRAkNaXOzVWk0Htik3J/w, ogerlitz-VPRAkNaXOzVWk0Htik3J/w
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
gongyangming-hv44wF8Li93QT0dZR+AlfA,
xiaokun-hv44wF8Li93QT0dZR+AlfA,
tangchaofei-hv44wF8Li93QT0dZR+AlfA,
oulijun-hv44wF8Li93QT0dZR+AlfA,
haifeng.wei-hv44wF8Li93QT0dZR+AlfA,
yisen.zhuang-hv44wF8Li93QT0dZR+AlfA,
yankejian-hv44wF8Li93QT0dZR+AlfA,
lisheng011-hv44wF8Li93QT0dZR+AlfA,
charles.chenxin-hv44wF8Li93QT0dZR+AlfA,
linuxarm-hv44wF8Li93QT0dZR+AlfA
In-Reply-To: <1458384658-16759-1-git-send-email-oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
The driver for HiSilicon RoCE is a platform driver.
The driver will support multiple versions of hardware. Currently only "v1"
for hip06 SoC is supported.
The driver includes two parts: common driver and hardware-specific
operations. hns_roce_v1_hw.c and hns_roce_v1_hw.h are files for
hardware-specific operations only for v1 engine, and other files(.c and .h)
for common algorithm and common hardware operations.
Signed-off-by: Lijun Ou <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Wei Hu(Xavier) <xavier.huwei-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Signed-off-by: Znlong <zhaonenglong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
MAINTAINERS | 8 +
drivers/infiniband/Kconfig | 1 +
drivers/infiniband/hw/Makefile | 1 +
drivers/infiniband/hw/hisilicon/hns/Kconfig | 10 +
drivers/infiniband/hw/hisilicon/hns/Makefile | 9 +
drivers/infiniband/hw/hisilicon/hns/hns_roce_ah.c | 110 +
.../infiniband/hw/hisilicon/hns/hns_roce_alloc.c | 239 ++
drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.c | 338 +++
drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.h | 80 +
.../infiniband/hw/hisilicon/hns/hns_roce_common.h | 308 +++
drivers/infiniband/hw/hisilicon/hns/hns_roce_cq.c | 436 +++
.../infiniband/hw/hisilicon/hns/hns_roce_device.h | 794 ++++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.c | 758 ++++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.h | 133 +
drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.c | 578 ++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.h | 112 +
.../infiniband/hw/hisilicon/hns/hns_roce_main.c | 1097 ++++++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_mr.c | 605 +++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_pd.c | 124 +
drivers/infiniband/hw/hisilicon/hns/hns_roce_qp.c | 841 ++++++
.../infiniband/hw/hisilicon/hns/hns_roce_user.h | 31 +
.../infiniband/hw/hisilicon/hns/hns_roce_v1_hw.c | 2835 ++++++++++++++++++++
.../infiniband/hw/hisilicon/hns/hns_roce_v1_hw.h | 986 +++++++
23 files changed, 10434 insertions(+)
create mode 100644 drivers/infiniband/hw/hisilicon/hns/Kconfig
create mode 100644 drivers/infiniband/hw/hisilicon/hns/Makefile
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_ah.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_alloc.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_common.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_cq.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_device.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_main.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_mr.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_pd.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_qp.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_user.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 2933d90..0c7fac5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9878,6 +9878,14 @@ W: http://www.emulex.com
S: Supported
F: drivers/infiniband/hw/ocrdma/
+HISILICON ROCE DRIVER
+M: Wei Hu(Xavier) <xavier.huwei-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
+M: Lijun Ou <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
+L: linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
+S: Maintained
+F: drivers/infiniband/hw/hisilicon/
+F: Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt
+
SFC NETWORK DRIVER
M: Solarflare linux maintainers <linux-net-drivers-s/n/eUQHGBpZroRs9YW3xA@public.gmane.org>
M: Shradha Shah <sshah-s/n/eUQHGBpZroRs9YW3xA@public.gmane.org>
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 8a8440c..02eca75 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -73,6 +73,7 @@ source "drivers/infiniband/hw/mlx5/Kconfig"
source "drivers/infiniband/hw/nes/Kconfig"
source "drivers/infiniband/hw/ocrdma/Kconfig"
source "drivers/infiniband/hw/usnic/Kconfig"
+source "drivers/infiniband/hw/hisilicon/hns/Kconfig"
source "drivers/infiniband/ulp/ipoib/Kconfig"
diff --git a/drivers/infiniband/hw/Makefile b/drivers/infiniband/hw/Makefile
index aded2a5..ddbbf715 100644
--- a/drivers/infiniband/hw/Makefile
+++ b/drivers/infiniband/hw/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_MLX5_INFINIBAND) += mlx5/
obj-$(CONFIG_INFINIBAND_NES) += nes/
obj-$(CONFIG_INFINIBAND_OCRDMA) += ocrdma/
obj-$(CONFIG_INFINIBAND_USNIC) += usnic/
+obj-$(CONFIG_INFINIBAND_HISILICON_HNS) += hisilicon/hns/
diff --git a/drivers/infiniband/hw/hisilicon/hns/Kconfig b/drivers/infiniband/hw/hisilicon/hns/Kconfig
new file mode 100644
index 0000000..e66e0aa
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/Kconfig
@@ -0,0 +1,10 @@
+config INFINIBAND_HISILICON_HNS
+ tristate "Hisilicon Hns ROCE Driver"
+ depends on NET_VENDOR_HISILICON
+ depends on ARM64 && HNS && HNS_DSAF && HNS_ENET
+ ---help---
+ This is a ROCE/RDMA driver for the Hisilicon RoCE engine. The engine
+ is used in Hisilicon Hi1610 and more further ICT SoC.
+
+ To compile this driver as a module, choose M here: the module
+ will be called roce.
diff --git a/drivers/infiniband/hw/hisilicon/hns/Makefile b/drivers/infiniband/hw/hisilicon/hns/Makefile
new file mode 100644
index 0000000..bdf58ce
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the HISILICON RoCE drivers.
+#
+
+obj-$(CONFIG_INFINIBAND_HISILICON_HNS) += roce.o
+roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_eq.o hns_roce_pd.o \
+ hns_roce_ah.o hns_roce_icm.o hns_roce_mr.o hns_roce_qp.o \
+ hns_roce_cq.o hns_roce_alloc.o hns_roce_v1_hw.o
+
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_ah.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_ah.c
new file mode 100644
index 0000000..cd040e1
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_ah.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/inet.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_cache.h>
+#include "hns_roce_common.h"
+#include "hns_roce_device.h"
+
+#define HNS_ROCE_PORT_NUM_SHIFT 24
+#define HNS_ROCE_VLAN_SL_BIT_MASK 7
+#define HNS_ROCE_VLAN_SL_SHIFT 13
+
+struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *ah_attr)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct ib_gid_attr gid_attr;
+ struct hns_roce_ah *ah;
+ u16 vlan_tag = 0xffff;
+ struct in6_addr in6;
+ union ib_gid sgid;
+ int ret;
+
+ ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
+ if (!ah)
+ return ERR_PTR(-ENOMEM);
+
+ /* Get mac address */
+ memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(ah_attr->grh.dgid.raw));
+ if (rdma_is_multicast_addr(&in6))
+ rdma_get_mcast_mac(&in6, ah->av.mac);
+ else
+ memcpy(ah->av.mac, ah_attr->dmac, sizeof(ah_attr->dmac));
+
+ /* Get source gid */
+ ret = ib_get_cached_gid(ibpd->device, ah_attr->port_num,
+ ah_attr->grh.sgid_index, &sgid, &gid_attr);
+ if (ret) {
+ dev_err(dev, "get sgid failed! ret = %d\n", ret);
+ kfree(ah);
+ return ERR_PTR(ret);
+ }
+
+ if (gid_attr.ndev) {
+ if (is_vlan_dev(gid_attr.ndev))
+ vlan_tag = vlan_dev_vlan_id(gid_attr.ndev);
+ dev_put(gid_attr.ndev);
+ }
+
+ if (vlan_tag < 0x1000)
+ vlan_tag |= (ah_attr->sl & HNS_ROCE_VLAN_SL_BIT_MASK) <<
+ HNS_ROCE_VLAN_SL_SHIFT;
+
+ ah->av.port_pd = cpu_to_be32(to_hr_pd(ibpd)->pdn | (ah_attr->port_num <<
+ HNS_ROCE_PORT_NUM_SHIFT));
+ ah->av.gid_index = ah_attr->grh.sgid_index;
+ ah->av.vlan = cpu_to_le16(vlan_tag);
+ dev_dbg(dev, "gid_index = 0x%x,vlan = 0x%x\n", ah->av.gid_index,
+ ah->av.vlan);
+
+ if (ah_attr->static_rate)
+ ah->av.stat_rate = IB_RATE_10_GBPS;
+
+ memcpy(ah->av.dgid, ah_attr->grh.dgid.raw, HNS_ROCE_GID_SIZE);
+ ah->av.sl_tclass_flowlabel = cpu_to_le32(ah_attr->sl <<
+ HNS_ROCE_SL_SHIFT);
+
+ return &ah->ibah;
+}
+
+int hns_roce_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
+{
+ struct hns_roce_ah *ah = to_hr_ah(ibah);
+
+ memset(ah_attr, 0, sizeof(*ah_attr));
+
+ ah_attr->sl = le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
+ HNS_ROCE_SL_SHIFT;
+ ah_attr->port_num = le32_to_cpu(ah->av.port_pd) >>
+ HNS_ROCE_PORT_NUM_SHIFT;
+ ah_attr->dlid = 0;
+ ah_attr->static_rate = ah->av.stat_rate;
+ ah_attr->ah_flags = IB_AH_GRH;
+ ah_attr->grh.traffic_class = le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
+ HNS_ROCE_TCLASS_SHIFT;
+ ah_attr->grh.flow_label = le32_to_cpu(ah->av.sl_tclass_flowlabel) &
+ HNS_ROCE_FLOW_LABLE_MASK;
+ ah_attr->grh.hop_limit = ah->av.hop_limit;
+ ah_attr->grh.sgid_index = ah->av.gid_index;
+ memcpy(ah_attr->grh.dgid.raw, ah->av.dgid, HNS_ROCE_GID_SIZE);
+
+ return 0;
+}
+
+int hns_roce_destroy_ah(struct ib_ah *ah)
+{
+ kfree(to_hr_ah(ah));
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_alloc.c
new file mode 100644
index 0000000..1fd36f2
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_alloc.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/bitmap.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include "hns_roce_device.h"
+
+int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, u32 *obj)
+{
+ int ret = 0;
+
+ spin_lock(&bitmap->lock);
+ *obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
+ if (*obj >= bitmap->max) {
+ bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
+ & bitmap->mask;
+ *obj = find_first_zero_bit(bitmap->table, bitmap->max);
+ }
+
+ if (*obj < bitmap->max) {
+ set_bit(*obj, bitmap->table);
+ bitmap->last = (*obj + 1);
+ if (bitmap->last == bitmap->max)
+ bitmap->last = 0;
+ *obj |= bitmap->top;
+ } else {
+ ret = -1;
+ }
+
+ spin_unlock(&bitmap->lock);
+
+ return ret;
+}
+
+void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, u32 obj)
+{
+ hns_roce_bitmap_free_range(bitmap, obj, 1);
+}
+
+int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
+ int align, u32 *obj)
+{
+ int ret = 0;
+ int i;
+
+ if (likely(cnt == 1 && align == 1))
+ return hns_roce_bitmap_alloc(bitmap, obj);
+
+ spin_lock(&bitmap->lock);
+
+ *obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
+ bitmap->last, cnt, align - 1);
+ if (*obj >= bitmap->max) {
+ bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
+ & bitmap->mask;
+ *obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max, 0,
+ cnt, align - 1);
+ }
+
+ if (*obj < bitmap->max) {
+ for (i = 0; i < cnt; i++)
+ set_bit(*obj + i, bitmap->table);
+
+ if (*obj == bitmap->last) {
+ bitmap->last = (*obj + cnt);
+ if (bitmap->last >= bitmap->max)
+ bitmap->last = 0;
+ }
+ *obj |= bitmap->top;
+ } else {
+ ret = -1;
+ }
+
+ spin_unlock(&bitmap->lock);
+
+ return ret;
+}
+
+void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap, u32 obj,
+ int cnt)
+{
+ int i;
+
+ obj &= bitmap->max + bitmap->reserved_top - 1;
+
+ spin_lock(&bitmap->lock);
+ for (i = 0; i < cnt; i++)
+ clear_bit(obj + i, bitmap->table);
+
+ bitmap->last = min(bitmap->last, obj);
+ bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
+ & bitmap->mask;
+ spin_unlock(&bitmap->lock);
+}
+
+int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
+ u32 reserved_bot, u32 reserved_top)
+{
+ u32 i;
+
+ if (num != roundup_pow_of_two(num))
+ return -EINVAL;
+
+ bitmap->last = 0;
+ bitmap->top = 0;
+ bitmap->max = num - reserved_top;
+ bitmap->mask = mask;
+ bitmap->reserved_top = reserved_top;
+ spin_lock_init(&bitmap->lock);
+ bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long),
+ GFP_KERNEL);
+ if (!bitmap->table)
+ return -ENOMEM;
+
+ for (i = 0; i < reserved_bot; ++i)
+ set_bit(i, bitmap->table);
+
+ return 0;
+}
+
+void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap)
+{
+ kfree(bitmap->table);
+}
+
+void hns_roce_buf_free(struct hns_roce_dev *hr_dev, u32 size,
+ struct hns_roce_buf *buf)
+{
+ int i;
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 bits_per_long = BITS_PER_LONG;
+
+ if (buf->nbufs == 1) {
+ dma_free_coherent(dev, size, buf->direct.buf, buf->direct.map);
+ } else {
+ if (bits_per_long == 64)
+ vunmap(buf->direct.buf);
+
+ for (i = 0; i < buf->nbufs; ++i)
+ if (buf->page_list[i].buf)
+ dma_free_coherent(&hr_dev->pdev->dev, PAGE_SIZE,
+ buf->page_list[i].buf,
+ buf->page_list[i].map);
+ kfree(buf->page_list);
+ }
+}
+
+int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct,
+ struct hns_roce_buf *buf)
+{
+ int i = 0;
+ dma_addr_t t;
+ struct page **pages;
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 bits_per_long = BITS_PER_LONG;
+
+ /* SQ/RQ buf lease than one page, SQ + RQ = 8K */
+ if (size <= max_direct) {
+ buf->nbufs = 1;
+ /* Npages calculated by page_size */
+ buf->npages = 1 << get_order(size);
+ buf->page_shift = PAGE_SHIFT;
+ /* MTT PA must be recorded in 4k alignment, t is 4k aligned */
+ buf->direct.buf = dma_alloc_coherent(dev, size, &t, GFP_KERNEL);
+ if (!buf->direct.buf)
+ return -ENOMEM;
+
+ buf->direct.map = t;
+
+ while (t & ((1 << buf->page_shift) - 1)) {
+ --buf->page_shift;
+ buf->npages *= 2;
+ }
+
+ memset(buf->direct.buf, 0, size);
+ } else {
+ buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+ buf->npages = buf->nbufs;
+ buf->page_shift = PAGE_SHIFT;
+ buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list),
+ GFP_KERNEL);
+
+ if (!buf->page_list)
+ return -ENOMEM;
+
+ for (i = 0; i < buf->nbufs; ++i) {
+ buf->page_list[i].buf = dma_alloc_coherent(dev,
+ PAGE_SIZE, &t,
+ GFP_KERNEL);
+
+ if (!buf->page_list[i].buf)
+ goto err_free;
+
+ buf->page_list[i].map = t;
+ memset(buf->page_list[i].buf, 0, PAGE_SIZE);
+ }
+
+ if (bits_per_long == 64) {
+ pages = kmalloc_array(buf->nbufs, sizeof(*pages),
+ GFP_KERNEL);
+ if (!pages)
+ goto err_free;
+
+ for (i = 0; i < buf->nbufs; ++i)
+ pages[i] = virt_to_page(buf->page_list[i].buf);
+
+ buf->direct.buf = vmap(pages, buf->nbufs, VM_MAP,
+ PAGE_KERNEL);
+ kfree(pages);
+ if (!buf->direct.buf)
+ goto err_free;
+ }
+ }
+
+ return 0;
+
+err_free:
+ hns_roce_buf_free(hr_dev, size, buf);
+ return -ENOMEM;
+}
+
+void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev)
+{
+ hns_roce_cleanup_qp_table(hr_dev);
+ hns_roce_cleanup_cq_table(hr_dev);
+ hns_roce_cleanup_mr_table(hr_dev);
+ hns_roce_cleanup_pd_table(hr_dev);
+ hns_roce_cleanup_uar_table(hr_dev);
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.c
new file mode 100644
index 0000000..59d53f8
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include "hns_roce_common.h"
+#include "hns_roce_device.h"
+#include "hns_roce_cmd.h"
+#include "hns_roce_eq.h"
+
+#define CMD_POLL_TOKEN 0xffff
+#define CMD_MAX_NUM 32
+#define STATUS_MASK 0xff
+
+enum {
+ HCR_OUT_PARAM_OFFSET = 0x08,
+ HCR_TOKEN_OFFSET = 0x14,
+ HCR_STATUS_OFFSET = 0x18,
+ HCR_GO_BIT = 15,
+};
+
+enum {
+ GO_BIT_TIMEOUT_MSECS = 10000
+};
+
+static int hns_roce_status_to_errno(u8 orig_status)
+{
+ if (orig_status == HNS_ROCE_CMD_SUCCESS)
+ return 0;
+ else
+ return -EIO;
+}
+
+static int cmd_pending(struct hns_roce_dev *hr_dev)
+{
+ u32 status = roce_readl(hr_dev->cmd.hcr + HCR_TOKEN_OFFSET);
+
+ return (!!(status & (1 << HCR_GO_BIT)));
+}
+
+static int hns_roce_cmd_post(struct hns_roce_dev *hr_dev, u64 in_param,
+ u64 out_param, u32 in_modifier, u8 op_modifier,
+ u16 op, u16 token, int event)
+{
+ struct hns_roce_cmdq *cmd = &hr_dev->cmd;
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 __iomem *hcr = cmd->hcr;
+ int ret = -EAGAIN;
+ unsigned long end;
+ u32 val = 0;
+
+ mutex_lock(&cmd->hcr_mutex);
+
+ end = msecs_to_jiffies(GO_BIT_TIMEOUT_MSECS) + jiffies;
+ while (cmd_pending(hr_dev)) {
+ if (time_after(jiffies, end)) {
+ dev_dbg(dev, "jiffies=%d end=%d\n", (int)jiffies,
+ (int)end);
+ goto out;
+ }
+ cond_resched();
+ }
+
+ roce_set_field(val, ROCEE_MB6_ROCEE_MB_CMD_M, ROCEE_MB6_ROCEE_MB_CMD_S,
+ op);
+ roce_set_field(val, ROCEE_MB6_ROCEE_MB_CMD_MDF_M,
+ ROCEE_MB6_ROCEE_MB_CMD_MDF_S, op_modifier);
+ roce_set_bit(val, ROCEE_MB6_ROCEE_MB_EVENT_S, event);
+ roce_set_bit(val, ROCEE_MB6_ROCEE_MB_HW_RUN_S, 1);
+ roce_set_field(val, ROCEE_MB6_ROCEE_MB_TOKEN_M,
+ ROCEE_MB6_ROCEE_MB_TOKEN_S, token);
+
+ __raw_writeq(cpu_to_le64(in_param), hcr + 0);
+ __raw_writeq(cpu_to_le64(out_param), hcr + 2);
+ __raw_writel(cpu_to_le32(in_modifier), hcr + 4);
+ /* Memory barrier */
+ wmb();
+
+ __raw_writel(cpu_to_le32(val), hcr + 5);
+
+ mmiowb();
+ ret = 0;
+
+out:
+ mutex_unlock(&cmd->hcr_mutex);
+ return ret;
+}
+
+static int hns_roce_cmd_poll(struct hns_roce_dev *hr_dev, u64 in_param,
+ u64 *out_param, int out_is_imm, u32 in_modifier,
+ u8 op_modifier, u16 op, unsigned long timeout)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ void __iomem *hcr = hr_dev->cmd.hcr;
+ unsigned long end = 0;
+ u32 status = 0;
+ int ret;
+
+ down(&hr_dev->cmd.poll_sem);
+
+ ret = hns_roce_cmd_post(hr_dev, in_param, out_param ? *out_param : 0,
+ in_modifier, op_modifier, op, CMD_POLL_TOKEN,
+ 0);
+ if (ret) {
+ dev_err(dev, "[cmd_poll]hns_roce_cmd_post failed\n");
+ goto out;
+ }
+
+ end = msecs_to_jiffies(timeout) + jiffies;
+ while (cmd_pending(hr_dev) && time_before(jiffies, end))
+ cond_resched();
+
+ if (cmd_pending(hr_dev)) {
+ dev_err(dev, "[cmd_poll]hw run cmd TIMEDOUT!\n");
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+
+ if (out_is_imm)
+ *out_param = (u64) le32_to_cpu((__force __be32)
+ __raw_readl(hcr + HCR_OUT_PARAM_OFFSET)) << 32 |
+ (u64) le32_to_cpu((__force __be32)
+ __raw_readl(hcr + HCR_OUT_PARAM_OFFSET + 4));
+
+ status = le32_to_cpu((__force __be32)
+ __raw_readl(hcr + HCR_STATUS_OFFSET));
+ if ((status & STATUS_MASK) != 0x1) {
+ dev_err(dev, "mailbox status 0x%x!\n", status);
+ ret = -EBUSY;
+ goto out;
+ }
+
+out:
+ up(&hr_dev->cmd.poll_sem);
+ return ret;
+}
+
+void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status,
+ u64 out_param)
+{
+ struct hns_roce_cmd_context
+ *context = &hr_dev->cmd.context[token & hr_dev->cmd.token_mask];
+
+ if (token != context->token)
+ return;
+
+ context->result = hns_roce_status_to_errno(status);
+ context->out_param = out_param;
+ complete(&context->done);
+}
+
+static int hns_roce_cmd_wait(struct hns_roce_dev *hr_dev, u64 in_param,
+ u64 *out_param, int out_is_imm, u32 in_modifier,
+ u8 op_modifier, u16 op, unsigned long timeout)
+{
+ struct hns_roce_cmdq *cmd = &hr_dev->cmd;
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_cmd_context *context;
+ int ret = 0;
+
+ down(&cmd->event_sem);
+
+ spin_lock(&cmd->context_lock);
+ WARN_ON(cmd->free_head < 0);
+ context = &cmd->context[cmd->free_head];
+ context->token += cmd->token_mask + 1;
+ cmd->free_head = context->next;
+ spin_unlock(&cmd->context_lock);
+
+ init_completion(&context->done);
+
+ ret = hns_roce_cmd_post(hr_dev, in_param, out_param ? *out_param : 0,
+ in_modifier, op_modifier, op, context->token,
+ 1);
+ if (ret)
+ goto out;
+
+ /*
+ * It is timeout when wait_for_completion_timeout return 0
+ * The return value is the time limit set in advance
+ * how many seconds showing
+ */
+ if (!wait_for_completion_timeout(&context->done,
+ msecs_to_jiffies(timeout))) {
+ dev_err(dev, "[cmd]wait_for_completion_timeout timeout\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ret = context->result;
+ if (ret) {
+ dev_err(dev, "[cmd]event mod cmd process error!err=%d\n", ret);
+ goto out;
+ }
+
+ if (out_is_imm)
+ *out_param = context->out_param;
+
+out:
+ spin_lock(&cmd->context_lock);
+ context->next = cmd->free_head;
+ cmd->free_head = context - cmd->context;
+ spin_unlock(&cmd->context_lock);
+
+ up(&cmd->event_sem);
+ return ret;
+}
+
+int __hns_roce_cmd(struct hns_roce_dev *hr_dev, u64 in_param, u64 *out_param,
+ int out_is_imm, u32 in_modifier, u8 op_modifier, u16 op,
+ unsigned long timeout)
+{
+ if (hr_dev->cmd.use_events)
+ return hns_roce_cmd_wait(hr_dev, in_param, out_param,
+ out_is_imm, in_modifier, op_modifier,
+ op, timeout);
+ else
+ return hns_roce_cmd_poll(hr_dev, in_param, out_param,
+ out_is_imm, in_modifier, op_modifier,
+ op, timeout);
+}
+
+int hns_roce_cmd_init(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+
+ mutex_init(&hr_dev->cmd.hcr_mutex);
+ sema_init(&hr_dev->cmd.poll_sem, 1);
+ hr_dev->cmd.use_events = 0;
+ hr_dev->cmd.toggle = 1;
+ hr_dev->cmd.max_cmds = CMD_MAX_NUM;
+ hr_dev->cmd.hcr = hr_dev->reg_base + ROCEE_MB1_REG;
+ hr_dev->cmd.pool = dma_pool_create("hns_roce_cmd", dev,
+ HNS_ROCE_MAILBOX_SIZE,
+ HNS_ROCE_MAILBOX_SIZE, 0);
+ if (!hr_dev->cmd.pool) {
+ dev_err(dev, "Couldn't create mailbox pool for cmd.\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void hns_roce_cmd_cleanup(struct hns_roce_dev *hr_dev)
+{
+ dma_pool_destroy(hr_dev->cmd.pool);
+}
+
+int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_cmdq *hr_cmd = &hr_dev->cmd;
+ int i;
+
+ hr_cmd->context = kmalloc(hr_cmd->max_cmds *
+ sizeof(struct hns_roce_cmd_context),
+ GFP_KERNEL);
+ if (!hr_cmd->context)
+ return -ENOMEM;
+
+ for (i = 0; i < hr_cmd->max_cmds; ++i) {
+ hr_cmd->context[i].token = i;
+ hr_cmd->context[i].next = i + 1;
+ }
+
+ hr_cmd->context[hr_cmd->max_cmds - 1].next = -1;
+ hr_cmd->free_head = 0;
+
+ sema_init(&hr_cmd->event_sem, hr_cmd->max_cmds);
+ spin_lock_init(&hr_cmd->context_lock);
+
+ for (hr_cmd->token_mask = 1;
+ hr_cmd->token_mask < hr_cmd->max_cmds;
+ hr_cmd->token_mask <<= 1)
+ ;
+ --hr_cmd->token_mask;
+
+ hr_cmd->use_events = 1;
+
+ down(&hr_cmd->poll_sem);
+
+ return 0;
+}
+
+void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_cmdq *hr_cmd = &hr_dev->cmd;
+ int i;
+
+ hr_cmd->use_events = 0;
+
+ for (i = 0; i < hr_cmd->max_cmds; ++i)
+ down(&hr_cmd->event_sem);
+
+ kfree(hr_cmd->context);
+ up(&hr_cmd->poll_sem);
+}
+
+struct hns_roce_cmd_mailbox
+ *hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_cmd_mailbox *mailbox;
+
+ mailbox = kmalloc(sizeof(*mailbox), GFP_KERNEL);
+ if (!mailbox)
+ return ERR_PTR(-ENOMEM);
+
+ mailbox->buf = dma_pool_alloc(hr_dev->cmd.pool, GFP_KERNEL,
+ &mailbox->dma);
+ if (!mailbox->buf) {
+ kfree(mailbox);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ return mailbox;
+}
+
+void hns_roce_free_cmd_mailbox(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cmd_mailbox *mailbox)
+{
+ if (!mailbox)
+ return;
+
+ dma_pool_free(hr_dev->cmd.pool, mailbox->buf, mailbox->dma);
+ kfree(mailbox);
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.h b/drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.h
new file mode 100644
index 0000000..16901a4
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _HNS_ROCE_CMD_H
+#define _HNS_ROCE_CMD_H
+
+#include <linux/dma-mapping.h>
+
+enum {
+ /* TPT commands */
+ HNS_ROCE_CMD_SW2HW_MPT = 0xd,
+ HNS_ROCE_CMD_HW2SW_MPT = 0xf,
+
+ /* CQ commands */
+ HNS_ROCE_CMD_SW2HW_CQ = 0x16,
+ HNS_ROCE_CMD_HW2SW_CQ = 0x17,
+
+ /* QP/EE commands */
+ HNS_ROCE_CMD_RST2INIT_QP = 0x19,
+ HNS_ROCE_CMD_INIT2RTR_QP = 0x1a,
+ HNS_ROCE_CMD_RTR2RTS_QP = 0x1b,
+ HNS_ROCE_CMD_RTS2RTS_QP = 0x1c,
+ HNS_ROCE_CMD_2ERR_QP = 0x1e,
+ HNS_ROCE_CMD_RTS2SQD_QP = 0x1f,
+ HNS_ROCE_CMD_SQD2SQD_QP = 0x38,
+ HNS_ROCE_CMD_SQD2RTS_QP = 0x20,
+ HNS_ROCE_CMD_2RST_QP = 0x21,
+ HNS_ROCE_CMD_QUERY_QP = 0x22,
+};
+
+enum {
+ HNS_ROCE_CMD_TIME_CLASS_A = 10000,
+ HNS_ROCE_CMD_TIME_CLASS_B = 10000,
+ HNS_ROCE_CMD_TIME_CLASS_C = 10000,
+};
+
+enum {
+ HNS_ROCE_MAILBOX_SIZE = 4096
+};
+
+struct hns_roce_cmd_mailbox {
+ void *buf;
+ dma_addr_t dma;
+};
+
+int __hns_roce_cmd(struct hns_roce_dev *hr_dev, u64 in_param, u64 *out_param,
+ int out_is_imm, u32 in_modifier, u8 op_modifier, u16 op,
+ unsigned long timeout);
+
+/* Invoke a command with no output parameter */
+static inline int hns_roce_cmd(struct hns_roce_dev *hr_dev, u64 in_param,
+ u32 in_modifier, u8 op_modifier, u16 op,
+ unsigned long timeout)
+{
+ return __hns_roce_cmd(hr_dev, in_param, NULL, 0, in_modifier,
+ op_modifier, op, timeout);
+}
+
+/* Invoke a command with an output mailbox */
+static inline int hns_roce_cmd_box(struct hns_roce_dev *hr_dev, u64 in_param,
+ u64 out_param, u32 in_modifier,
+ u8 op_modifier, u16 op,
+ unsigned long timeout)
+{
+ return __hns_roce_cmd(hr_dev, in_param, &out_param, 0, in_modifier,
+ op_modifier, op, timeout);
+}
+
+struct hns_roce_cmd_mailbox
+ *hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev);
+void hns_roce_free_cmd_mailbox(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cmd_mailbox *mailbox);
+
+#endif /* _HNS_ROCE_CMD_H */
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_common.h b/drivers/infiniband/hw/hisilicon/hns/hns_roce_common.h
new file mode 100644
index 0000000..26570ac
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_common.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _HNS_ROCE_COMMON_H
+#define _HNS_ROCE_COMMON_H
+
+#ifndef assert
+#define assert(cond)
+#endif
+
+#define roce_writel(value, addr) writel((value), (addr))
+#define roce_readl(addr) readl((addr))
+#define roce_raw_write(value, addr) \
+ __raw_writel((__force u32)cpu_to_le32(value), (addr))
+
+#define roce_get_field(origin, mask, shift) \
+ (((origin) & (mask)) >> (shift))
+
+#define roce_get_bit(origin, shift) \
+ roce_get_field((origin), (1ul << (shift)), (shift))
+
+#define roce_set_field(origin, mask, shift, val) \
+ do { \
+ (origin) &= (~(mask)); \
+ (origin) |= (((val) << (shift)) & (mask)); \
+ } while (0)
+
+#define roce_set_bit(origin, shift, val) \
+ roce_set_field((origin), (1ul << (shift)), (shift), (val))
+
+#define ROCEE_GLB_CFG_ROCEE_DB_SQ_MODE_S 3
+
+#define ROCEE_GLB_CFG_ROCEE_DB_OTH_MODE_S 4
+
+#define ROCEE_GLB_CFG_SQ_EXT_DB_MODE_S 5
+
+#define ROCEE_GLB_CFG_OTH_EXT_DB_MODE_S 6
+
+#define ROCEE_GLB_CFG_ROCEE_PORT_ST_S 10
+#define ROCEE_GLB_CFG_ROCEE_PORT_ST_M \
+ (((1UL << 6) - 1) << ROCEE_GLB_CFG_ROCEE_PORT_ST_S)
+
+#define ROCEE_GLB_CFG_TRP_RAQ_DROP_EN_S 16
+
+#define ROCEE_DMAE_USER_CFG1_ROCEE_STREAM_ID_TB_CFG_S 0
+#define ROCEE_DMAE_USER_CFG1_ROCEE_STREAM_ID_TB_CFG_M \
+ (((1UL << 24) - 1) << ROCEE_DMAE_USER_CFG1_ROCEE_STREAM_ID_TB_CFG_S)
+
+#define ROCEE_DMAE_USER_CFG1_ROCEE_CACHE_TB_CFG_S 24
+#define ROCEE_DMAE_USER_CFG1_ROCEE_CACHE_TB_CFG_M \
+ (((1UL << 4) - 1) << ROCEE_DMAE_USER_CFG1_ROCEE_CACHE_TB_CFG_S)
+
+#define ROCEE_DMAE_USER_CFG2_ROCEE_STREAM_ID_PKT_CFG_S 0
+#define ROCEE_DMAE_USER_CFG2_ROCEE_STREAM_ID_PKT_CFG_M \
+ (((1UL << 24) - 1) << ROCEE_DMAE_USER_CFG2_ROCEE_STREAM_ID_PKT_CFG_S)
+
+#define ROCEE_DMAE_USER_CFG2_ROCEE_CACHE_PKT_CFG_S 24
+#define ROCEE_DMAE_USER_CFG2_ROCEE_CACHE_PKT_CFG_M \
+ (((1UL << 4) - 1) << ROCEE_DMAE_USER_CFG2_ROCEE_CACHE_PKT_CFG_S)
+
+#define ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_S 0
+#define ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_M \
+ (((1UL << 16) - 1) << ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_S)
+
+#define ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_EMPTY_S 16
+#define ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_EMPTY_M \
+ (((1UL << 16) - 1) << ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_EMPTY_S)
+
+#define ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_S 0
+#define ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_M \
+ (((1UL << 16) - 1) << ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_S)
+
+#define ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_EMPTY_S 16
+#define ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_EMPTY_M \
+ (((1UL << 16) - 1) << ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_EMPTY_S)
+
+#define ROCEE_RAQ_WL_ROCEE_RAQ_WL_S 0
+#define ROCEE_RAQ_WL_ROCEE_RAQ_WL_M \
+ (((1UL << 8) - 1) << ROCEE_RAQ_WL_ROCEE_RAQ_WL_S)
+
+#define ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_POL_TIME_INTERVAL_S 0
+#define ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_POL_TIME_INTERVAL_M \
+ (((1UL << 15) - 1) << \
+ ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_POL_TIME_INTERVAL_S)
+
+#define ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_RAQ_TIMEOUT_CHK_CFG_S 16
+#define ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_RAQ_TIMEOUT_CHK_CFG_M \
+ (((1UL << 4) - 1) << \
+ ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_RAQ_TIMEOUT_CHK_CFG_S)
+
+#define ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_RAQ_TIMEOUT_CHK_EN_S 20
+
+#define ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_EXT_RAQ_MODE 21
+
+#define ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_SHIFT_S 0
+#define ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_SHIFT_M \
+ (((1UL << 5) - 1) << ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_SHIFT_S)
+
+#define ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_BA_H_S 5
+#define ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_BA_H_M \
+ (((1UL << 5) - 1) << ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_BA_H_S)
+
+#define ROCEE_EXT_DB_OTH_H_EXT_DB_OTH_SHIFT_S 0
+#define ROCEE_EXT_DB_OTH_H_EXT_DB_OTH_SHIFT_M \
+ (((1UL << 5) - 1) << ROCEE_EXT_DB_OTH_H_EXT_DB_OTH_SHIFT_S)
+
+#define ROCEE_EXT_DB_SQ_H_EXT_DB_OTH_BA_H_S 5
+#define ROCEE_EXT_DB_SQ_H_EXT_DB_OTH_BA_H_M \
+ (((1UL << 5) - 1) << ROCEE_EXT_DB_SQ_H_EXT_DB_OTH_BA_H_S)
+
+#define ROCEE_EXT_RAQ_H_EXT_RAQ_SHIFT_S 0
+#define ROCEE_EXT_RAQ_H_EXT_RAQ_SHIFT_M \
+ (((1UL << 5) - 1) << ROCEE_EXT_RAQ_H_EXT_RAQ_SHIFT_S)
+
+#define ROCEE_EXT_RAQ_H_EXT_RAQ_BA_H_S 8
+#define ROCEE_EXT_RAQ_H_EXT_RAQ_BA_H_M \
+ (((1UL << 5) - 1) << ROCEE_EXT_RAQ_H_EXT_RAQ_BA_H_S)
+
+#define ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S 0
+#define ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M \
+ (((1UL << 19) - 1) << ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S)
+
+#define ROCEE_BT_CMD_H_ROCEE_BT_CMD_S 19
+
+#define ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S 20
+#define ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M \
+ (((1UL << 2) - 1) << ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S)
+
+#define ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S 22
+#define ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M \
+ (((1UL << 5) - 1) << ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S)
+
+#define ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S 31
+
+#define ROCEE_QP1C_CFG0_0_ROCEE_QP1C_QP_ST_S 0
+#define ROCEE_QP1C_CFG0_0_ROCEE_QP1C_QP_ST_M \
+ (((1UL << 3) - 1) << ROCEE_QP1C_CFG0_0_ROCEE_QP1C_QP_ST_S)
+
+#define ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S 0
+#define ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M \
+ (((1UL << 15) - 1) << ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S)
+
+#define ROCEE_MB6_ROCEE_MB_CMD_S 0
+#define ROCEE_MB6_ROCEE_MB_CMD_M \
+ (((1UL << 8) - 1) << ROCEE_MB6_ROCEE_MB_CMD_S)
+
+#define ROCEE_MB6_ROCEE_MB_CMD_MDF_S 8
+#define ROCEE_MB6_ROCEE_MB_CMD_MDF_M \
+ (((1UL << 4) - 1) << ROCEE_MB6_ROCEE_MB_CMD_MDF_S)
+
+#define ROCEE_MB6_ROCEE_MB_EVENT_S 14
+
+#define ROCEE_MB6_ROCEE_MB_HW_RUN_S 15
+
+#define ROCEE_MB6_ROCEE_MB_TOKEN_S 16
+#define ROCEE_MB6_ROCEE_MB_TOKEN_M \
+ (((1UL << 16) - 1) << ROCEE_MB6_ROCEE_MB_TOKEN_S)
+
+#define ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_INP_H_S 0
+#define ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_INP_H_M \
+ (((1UL << 24) - 1) << ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_INP_H_S)
+
+#define ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_MDF_S 24
+#define ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_MDF_M \
+ (((1UL << 4) - 1) << ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_MDF_S)
+
+#define ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_S 28
+#define ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_M \
+ (((1UL << 3) - 1) << ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_S)
+
+#define ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S 31
+
+#define ROCEE_SMAC_H_ROCEE_SMAC_H_S 0
+#define ROCEE_SMAC_H_ROCEE_SMAC_H_M \
+ (((1UL << 16) - 1) << ROCEE_SMAC_H_ROCEE_SMAC_H_S)
+
+#define ROCEE_SMAC_H_ROCEE_PORT_MTU_S 16
+#define ROCEE_SMAC_H_ROCEE_PORT_MTU_M \
+ (((1UL << 4) - 1) << ROCEE_SMAC_H_ROCEE_PORT_MTU_S)
+
+#define ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_S 0
+#define ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_M \
+ (((1UL << 2) - 1) << ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_S)
+
+#define ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_AEQE_SHIFT_S 8
+#define ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_AEQE_SHIFT_M \
+ (((1UL << 4) - 1) << ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_AEQE_SHIFT_S)
+
+#define ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQ_ALM_OVF_INT_ST_S 17
+
+#define ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQ_BT_H_S 0
+#define ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQ_BT_H_M \
+ (((1UL << 5) - 1) << ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQ_BT_H_S)
+
+#define ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQE_CUR_IDX_S 16
+#define ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQE_CUR_IDX_M \
+ (((1UL << 16) - 1) << ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQE_CUR_IDX_S)
+
+#define ROCEE_CAEP_AEQE_CONS_IDX_CAEP_AEQE_CONS_IDX_S 0
+#define ROCEE_CAEP_AEQE_CONS_IDX_CAEP_AEQE_CONS_IDX_M \
+ (((1UL << 16) - 1) << ROCEE_CAEP_AEQE_CONS_IDX_CAEP_AEQE_CONS_IDX_S)
+
+#define ROCEE_CAEP_CEQC_SHIFT_CAEP_CEQ_ALM_OVF_INT_ST_S 16
+#define ROCEE_CAEP_CE_IRQ_MASK_CAEP_CE_IRQ_MASK_S 0
+#define ROCEE_CAEP_CE_IRQ_MASK_CAEP_CEQ_ALM_OVF_MASK_S 1
+#define ROCEE_CAEP_CEQ_ALM_OVF_CAEP_CEQ_ALM_OVF_S 0
+
+#define ROCEE_CAEP_AE_MASK_CAEP_AEQ_ALM_OVF_MASK_S 0
+#define ROCEE_CAEP_AE_MASK_CAEP_AE_IRQ_MASK_S 1
+
+#define ROCEE_CAEP_AE_ST_CAEP_AEQ_ALM_OVF_S 0
+#define ROCEE_CAEP_AE_ST_CAEP_AE_IRQ_ST_S 1
+
+#define ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_S 0
+#define ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_M \
+ (((1UL << 28) - 1) << ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_S)
+
+#define ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S 0
+#define ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M \
+ (((1UL << 28) - 1) << ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S)
+
+#define ROCEE_SDB_INV_CNT_SDB_INV_CNT_S 0
+#define ROCEE_SDB_INV_CNT_SDB_INV_CNT_M \
+ (((1UL << 16) - 1) << ROCEE_SDB_INV_CNT_SDB_INV_CNT_S)
+
+#define ROCE_DEV_IOBASE 0xc4000000
+
+/**********ROCEE_REG DEFINITION****************/
+
+#define ROCEE_VENDOR_ID_REG 0x0
+#define ROCEE_VENDOR_PART_ID_REG 0x4
+
+#define ROCEE_HW_VERSION_REG 0x8
+
+#define ROCEE_SYS_IMAGE_GUID_L_REG 0xC
+#define ROCEE_SYS_IMAGE_GUID_H_REG 0x10
+
+#define ROCEE_PORT_GID_L_0_REG 0x50
+#define ROCEE_PORT_GID_ML_0_REG 0x54
+#define ROCEE_PORT_GID_MH_0_REG 0x58
+#define ROCEE_PORT_GID_H_0_REG 0x5C
+
+#define ROCEE_BT_CMD_H_REG 0x204
+
+#define ROCEE_SMAC_L_0_REG 0x240
+#define ROCEE_SMAC_H_0_REG 0x244
+
+#define ROCEE_QP1C_CFG3_0_REG 0x27C
+
+#define ROCEE_CAEP_AEQE_CONS_IDX_REG 0x3AC
+#define ROCEE_CAEP_CEQC_CONS_IDX_0_REG 0x3BC
+
+#define ROCEE_ECC_UCERR_ALM1_REG 0xB38
+#define ROCEE_ECC_UCERR_ALM2_REG 0xB3C
+#define ROCEE_ECC_CERR_ALM1_REG 0xB44
+#define ROCEE_ECC_CERR_ALM2_REG 0xB48
+
+#define ROCEE_ACK_DELAY_REG 0x14
+#define ROCEE_GLB_CFG_REG 0x18
+
+#define ROCEE_DMAE_USER_CFG1_REG 0x40
+#define ROCEE_DMAE_USER_CFG2_REG 0x44
+
+#define ROCEE_DB_SQ_WL_REG 0x154
+#define ROCEE_DB_OTHERS_WL_REG 0x158
+#define ROCEE_RAQ_WL_REG 0x15C
+#define ROCEE_WRMS_POL_TIME_INTERVAL_REG 0x160
+#define ROCEE_EXT_DB_SQ_REG 0x164
+#define ROCEE_EXT_DB_SQ_H_REG 0x168
+#define ROCEE_EXT_DB_OTH_REG 0x16C
+
+#define ROCEE_EXT_DB_OTH_H_REG 0x170
+#define ROCEE_EXT_DB_SQ_WL_EMPTY_REG 0x174
+#define ROCEE_EXT_DB_SQ_WL_REG 0x178
+#define ROCEE_EXT_DB_OTHERS_WL_EMPTY_REG 0x17C
+#define ROCEE_EXT_DB_OTHERS_WL_REG 0x180
+#define ROCEE_EXT_RAQ_REG 0x184
+#define ROCEE_EXT_RAQ_H_REG 0x188
+
+#define ROCEE_CAEP_CE_INTERVAL_CFG_REG 0x190
+#define ROCEE_CAEP_CE_BURST_NUM_CFG_REG 0x194
+#define ROCEE_BT_CMD_L_REG 0x200
+
+#define ROCEE_MB1_REG 0x210
+#define ROCEE_DB_SQ_L_0_REG 0x230
+#define ROCEE_DB_OTHERS_L_0_REG 0x238
+#define ROCEE_QP1C_CFG0_0_REG 0x270
+
+#define ROCEE_CAEP_AEQC_AEQE_SHIFT_REG 0x3A0
+#define ROCEE_CAEP_CEQC_SHIFT_0_REG 0x3B0
+#define ROCEE_CAEP_CE_IRQ_MASK_0_REG 0x3C0
+#define ROCEE_CAEP_CEQ_ALM_OVF_0_REG 0x3C4
+#define ROCEE_CAEP_AE_MASK_REG 0x6C8
+#define ROCEE_CAEP_AE_ST_REG 0x6CC
+
+#define ROCEE_SDB_ISSUE_PTR_REG 0x758
+#define ROCEE_SDB_SEND_PTR_REG 0x75C
+#define ROCEE_SDB_INV_CNT_REG 0x9A4
+#define ROCEE_ECC_UCERR_ALM0_REG 0xB34
+#define ROCEE_ECC_CERR_ALM0_REG 0xB40
+
+#endif /* _HNS_ROCE_COMMON_H */
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_cq.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_cq.c
new file mode 100644
index 0000000..f05cb2a
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_cq.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/hardirq.h>
+#include <linux/log2.h>
+#include <linux/slab.h>
+#include "hns_roce_device.h"
+#include "hns_roce_cmd.h"
+#include "hns_roce_icm.h"
+#include "hns_roce_user.h"
+#include "hns_roce_common.h"
+
+#define PAGE_OFFSET_4K 0x1000
+
+static void hns_roce_ib_cq_comp(struct hns_roce_cq *hr_cq)
+{
+ struct ib_cq *ibcq = &hr_cq->ib_cq;
+
+ ibcq->comp_handler(ibcq, ibcq->cq_context);
+}
+
+static void hns_roce_ib_cq_event(struct hns_roce_cq *hr_cq,
+ enum hns_roce_event event_type)
+{
+ struct hns_roce_dev *hr_dev;
+ struct ib_event event;
+ struct ib_cq *ibcq;
+
+ ibcq = &hr_cq->ib_cq;
+ hr_dev = to_hr_dev(ibcq->device);
+
+ if (event_type != HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID &&
+ event_type != HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR &&
+ event_type != HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW) {
+ dev_err(&hr_dev->pdev->dev,
+ "hns_roce_ib: Unexpected event type 0x%x on CQ %06x\n",
+ event_type, hr_cq->cqn);
+ return;
+ }
+
+ if (ibcq->event_handler) {
+ event.device = ibcq->device;
+ event.event = IB_EVENT_CQ_ERR;
+ event.element.cq = ibcq;
+ ibcq->event_handler(&event, ibcq->cq_context);
+ }
+}
+
+static int hns_roce_sw2hw_cq(struct hns_roce_dev *dev,
+ struct hns_roce_cmd_mailbox *mailbox, int cq_num)
+{
+ return hns_roce_cmd(dev, mailbox->dma, cq_num, 0,
+ HNS_ROCE_CMD_SW2HW_CQ, HNS_ROCE_CMD_TIME_CLASS_A);
+}
+
+static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent,
+ struct hns_roce_mtt *hr_mtt,
+ struct hns_roce_uar *hr_uar,
+ struct hns_roce_cq *hr_cq, int vector,
+ int collapsed)
+{
+ struct hns_roce_cmd_mailbox *mailbox = NULL;
+ struct hns_roce_cq_table *cq_table = NULL;
+ struct device *dev = &hr_dev->pdev->dev;
+ dma_addr_t dma_handle;
+ u64 *mtts = NULL;
+ int ret = 0;
+
+ cq_table = &hr_dev->cq_table;
+
+ /* Get the physical address of cq buf */
+ mtts = hns_roce_table_find(&hr_dev->mr_table.mtt_table,
+ hr_mtt->first_seg, &dma_handle);
+ if (!mtts) {
+ dev_err(dev, "CQ alloc.Failed to find cq buf addr.\n");
+ return -EINVAL;
+ }
+
+ if (vector >= hr_dev->caps.num_comp_vectors) {
+ dev_err(dev, "CQ alloc.Invalid vector.\n");
+ return -EINVAL;
+ }
+ hr_cq->vector = vector;
+
+ ret = hns_roce_bitmap_alloc(&cq_table->bitmap, &hr_cq->cqn);
+ if (ret == -1) {
+ dev_err(dev, "CQ alloc.Failed to alloc index.\n");
+ return -ENOMEM;
+ }
+
+ /* Get CQC memory icm table */
+ ret = hns_roce_table_get(hr_dev, &cq_table->table, hr_cq->cqn);
+ if (ret) {
+ dev_err(dev, "CQ alloc.Failed to get context mem.\n");
+ goto err_out;
+ }
+
+ /* The cq insert radix tree */
+ spin_lock_irq(&cq_table->lock);
+ /* Radix_tree: The associated pointer and long integer key value like */
+ ret = radix_tree_insert(&cq_table->tree, hr_cq->cqn, hr_cq);
+ spin_unlock_irq(&cq_table->lock);
+ if (ret) {
+ dev_err(dev, "CQ alloc.Failed to radix_tree_insert.\n");
+ goto err_put;
+ }
+
+ /* Applicate mailbox memory */
+ mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
+ if (IS_ERR(mailbox)) {
+ dev_err(dev, "CQ alloc.Failed to alloc mailbox.\n");
+ ret = PTR_ERR(mailbox);
+ goto err_radix;
+ }
+
+ hr_dev->hw->write_cqc(hr_dev, hr_cq, mailbox->buf, mtts, dma_handle,
+ nent, vector);
+
+ /* CQ instructions which sw send to hw be transimited via mailbox */
+ ret = hns_roce_sw2hw_cq(hr_dev, mailbox, hr_cq->cqn);
+ hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+ if (ret) {
+ dev_err(dev, "CQ alloc.Failed to cmd mailbox.\n");
+ goto err_radix;
+ }
+
+ hr_cq->cons_index = 0;
+ hr_cq->uar = hr_uar;
+
+ return 0;
+
+err_radix:
+ spin_lock_irq(&cq_table->lock);
+ (void)radix_tree_delete(&cq_table->tree, hr_cq->cqn);
+ spin_unlock_irq(&cq_table->lock);
+
+err_put:
+ hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);
+
+err_out:
+ hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn);
+ return ret;
+}
+
+static int hns_roce_hw2sw_cq(struct hns_roce_dev *dev,
+ struct hns_roce_cmd_mailbox *mailbox, int cq_num)
+{
+ return hns_roce_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, cq_num,
+ mailbox ? 0 : 1, HNS_ROCE_CMD_HW2SW_CQ,
+ HNS_ROCE_CMD_TIME_CLASS_A);
+}
+
+void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
+{
+ struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
+ struct device *dev = &hr_dev->pdev->dev;
+ int ret;
+
+ ret = hns_roce_hw2sw_cq(hr_dev, NULL, hr_cq->cqn);
+ if (ret)
+ dev_err(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", ret,
+ hr_cq->cqn);
+
+ /* Waiting interrupt process procedure carried out */
+ synchronize_irq(hr_dev->eq_table.eq[hr_cq->vector].irq);
+
+ spin_lock_irq(&cq_table->lock);
+ (void)radix_tree_delete(&cq_table->tree, hr_cq->cqn);
+ spin_unlock_irq(&cq_table->lock);
+
+ hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);
+ hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn);
+}
+
+static int hns_roce_ib_get_cq_umem(struct hns_roce_dev *hr_dev,
+ struct ib_ucontext *context,
+ struct hns_roce_cq_buf *buf,
+ struct ib_umem **umem, u64 buf_addr, int cqe)
+{
+ int ret;
+
+ /* Get and mapping user space */
+ *umem = ib_umem_get(context, buf_addr, cqe * hr_dev->caps.cq_entry_sz,
+ IB_ACCESS_LOCAL_WRITE, 1);
+ if (IS_ERR(*umem))
+ return PTR_ERR(*umem);
+
+ ret = hns_roce_mtt_init(hr_dev, ib_umem_page_count(*umem),
+ ilog2((*umem)->page_size), &buf->hr_mtt);
+ if (ret)
+ goto err_buf;
+
+ ret = hns_roce_ib_umem_write_mtt(hr_dev, &buf->hr_mtt, *umem);
+ if (ret)
+ goto err_mtt;
+
+ return 0;
+
+err_mtt:
+ hns_roce_mtt_cleanup(hr_dev, &buf->hr_mtt);
+
+err_buf:
+ ib_umem_release(*umem);
+ return ret;
+}
+
+static int hns_roce_ib_alloc_cq_buf(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cq_buf *buf, u32 nent)
+{
+ int ret;
+
+ ret = hns_roce_buf_alloc(hr_dev, nent * hr_dev->caps.cq_entry_sz,
+ PAGE_SIZE * 2, &buf->hr_buf);
+ if (ret)
+ goto out;
+
+ ret = hns_roce_mtt_init(hr_dev, buf->hr_buf.npages,
+ buf->hr_buf.page_shift, &buf->hr_mtt);
+ if (ret)
+ goto err_buf;
+
+ ret = hns_roce_buf_write_mtt(hr_dev, &buf->hr_mtt, &buf->hr_buf);
+ if (ret)
+ goto err_mtt;
+
+ return 0;
+
+err_mtt:
+ hns_roce_mtt_cleanup(hr_dev, &buf->hr_mtt);
+
+err_buf:
+ hns_roce_buf_free(hr_dev, nent * hr_dev->caps.cq_entry_sz,
+ &buf->hr_buf);
+out:
+ return ret;
+}
+
+static void hns_roce_ib_free_cq_buf(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cq_buf *buf, int cqe)
+{
+ hns_roce_buf_free(hr_dev, (cqe + 1) * hr_dev->caps.cq_entry_sz,
+ &buf->hr_buf);
+}
+
+struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_ucontext *context,
+ struct ib_udata *udata)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_ib_create_cq ucmd;
+ struct hns_roce_cq *hr_cq = NULL;
+ struct hns_roce_uar *uar = NULL;
+ int vector = attr->comp_vector;
+ int cq_entries = attr->cqe;
+ int ret = 0;
+
+ if (cq_entries < 1 || cq_entries > hr_dev->caps.max_cqes) {
+ dev_err(dev, "Creat CQ failed. entries=%d, max=%d\n",
+ cq_entries, hr_dev->caps.max_cqes);
+ return ERR_PTR(-EINVAL);
+ }
+
+ hr_cq = kmalloc(sizeof(*hr_cq), GFP_KERNEL);
+ if (!hr_cq)
+ return ERR_PTR(-ENOMEM);
+
+ /* In v1 engine, parameter verification */
+ if (cq_entries < HNS_ROCE_MIN_CQE_NUM)
+ cq_entries = HNS_ROCE_MIN_CQE_NUM;
+
+ cq_entries = roundup_pow_of_two(cq_entries);
+ hr_cq->ib_cq.cqe = cq_entries - 1;
+ mutex_init(&hr_cq->resize_mutex);
+ spin_lock_init(&hr_cq->lock);
+ hr_cq->hr_resize_buf = NULL;
+ hr_cq->resize_umem = NULL;
+
+ if (context) {
+ if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
+ dev_err(dev, "Failed to copy_from_udata.\n");
+ ret = -EFAULT;
+ goto err_cq;
+ }
+
+ /* Get user space address, write it into mtt table */
+ ret = hns_roce_ib_get_cq_umem(hr_dev, context, &hr_cq->hr_buf,
+ &hr_cq->umem, ucmd.buf_addr,
+ cq_entries);
+ if (ret) {
+ dev_err(dev, "Failed to get_cq_umem.\n");
+ goto err_cq;
+ }
+
+ /* Get user space parameters */
+ uar = &to_hr_ucontext(context)->uar;
+ } else {
+ /* Init mmt table and write buff address to mtt table */
+ ret = hns_roce_ib_alloc_cq_buf(hr_dev, &hr_cq->hr_buf,
+ cq_entries);
+ if (ret) {
+ dev_err(dev, "Failed to alloc_cq_buf.\n");
+ goto err_cq;
+ }
+
+ uar = &hr_dev->priv_uar;
+ hr_cq->cq_db_l = hr_dev->reg_base + ROCEE_DB_OTHERS_L_0_REG +
+ PAGE_OFFSET_4K * uar->index;
+ }
+
+ /* Allocate cq index, fill cq_context */
+ ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt,
+ uar, hr_cq, vector, 0);
+ if (ret) {
+ dev_err(dev, "Creat CQ .Failed to cq_alloc.\n");
+ goto err_mtt;
+ }
+
+ /* Get created cq handler and carry out event */
+ hr_cq->comp = hns_roce_ib_cq_comp;
+ hr_cq->event = hns_roce_ib_cq_event;
+ hr_cq->cq_depth = cq_entries;
+
+ if (context) {
+ if (ib_copy_to_udata(udata, &(hr_cq->cqn), sizeof(__u32))) {
+ ret = -EFAULT;
+ goto err_mtt;
+ }
+ }
+
+ return &hr_cq->ib_cq;
+
+err_mtt:
+ hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
+ if (context)
+ ib_umem_release(hr_cq->umem);
+ else
+ hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
+ hr_cq->ib_cq.cqe);
+
+err_cq:
+ kfree(hr_cq);
+ return ERR_PTR(ret);
+}
+
+int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
+ struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
+
+ hns_roce_free_cq(hr_dev, hr_cq);
+ hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
+
+ if (ib_cq->uobject)
+ ib_umem_release(hr_cq->umem);
+ else
+ /* Free the buff of stored cq */
+ hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf, ib_cq->cqe);
+
+ kfree(hr_cq);
+
+ return 0;
+}
+
+void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_cq *cq;
+
+ cq = radix_tree_lookup(&hr_dev->cq_table.tree,
+ cqn & (hr_dev->caps.num_cqs - 1));
+ if (!cq) {
+ dev_warn(dev, "Completion event for bogus CQ 0x%08x\n", cqn);
+ return;
+ }
+
+ cq->comp(cq);
+}
+
+void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type)
+{
+ struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_cq *cq;
+
+ spin_lock(&cq_table->lock);
+
+ cq = radix_tree_lookup(&cq_table->tree,
+ cqn & (hr_dev->caps.num_cqs - 1));
+ if (cq)
+ atomic_inc(&cq->refcount);
+
+ spin_unlock(&cq_table->lock);
+
+ if (!cq) {
+ dev_warn(dev, "Async event for bogus CQ %08x\n", cqn);
+ return;
+ }
+
+ cq->event(cq, (enum hns_roce_event)event_type);
+
+ if (atomic_dec_and_test(&cq->refcount))
+ complete(&cq->free);
+}
+
+int hns_roce_init_cq_table(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
+ struct device *dev = &hr_dev->pdev->dev;
+ int ret;
+
+ spin_lock_init(&cq_table->lock);
+ INIT_RADIX_TREE(&cq_table->tree, GFP_ATOMIC);
+
+ ret = hns_roce_bitmap_init(&cq_table->bitmap, hr_dev->caps.num_cqs,
+ hr_dev->caps.num_cqs - 1,
+ hr_dev->caps.reserved_cqs, 0);
+ if (ret) {
+ dev_err(dev, "init_cq_table.Failed to bitmap_init.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+void hns_roce_cleanup_cq_table(struct hns_roce_dev *hr_dev)
+{
+ hns_roce_bitmap_cleanup(&hr_dev->cq_table.bitmap);
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_device.h b/drivers/infiniband/hw/hisilicon/hns/hns_roce_device.h
new file mode 100644
index 0000000..809baa4
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_device.h
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _HNS_ROCE_DEVICE_H
+#define _HNS_ROCE_DEVICE_H
+
+#include <linux/platform_device.h>
+#include <linux/radix-tree.h>
+#include <linux/semaphore.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_umem.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_verbs.h>
+
+#define DRV_NAME "hns_roce"
+
+#define ROCE_VERSION_1 ('1' << 24 | '6' << 16 | '1' << 8 | '0')
+#define ROCE_VERSION_2 ('1' << 24 | '6' << 16 | '2' << 8 | '0')
+#define ROCE_IS_VER2(ver) ((ver) == ROCE_VERSION_1)
+
+#define MAC_ADDR_OCTET_NUM 6
+#define HNS_ROCE_MAX_MSG_LEN 0x80000000
+
+#define HNS_ROCE_ALOGN_UP(a, b) ((((a) + (b) - 1) / (b)) * (b))
+
+#define HNS_ROCE_IB_MIN_SQ_STRIDE 6
+
+#define HNS_ROCE_BA_SIZE (32 * 4096)
+
+/* Hardware specification only for v1 engine */
+#define HNS_ROCE_MIN_CQE_NUM 0x40
+#define HNS_ROCE_MIN_WQE_NUM 0x20
+
+/* Hardware specification only for v1 engine */
+#define HNS_ROCE_MAX_INNER_MTPT_NUM 0x7
+#define HNS_ROCE_MAX_MTPT_PBL_NUM 0x100000
+
+#define HNS_ROCE_MAX_IRQ_NUM 34
+#define HNS_ROCE_COMP_VEC_NUM 32
+#define HNS_ROCE_AEQE_VEC_NUM 1
+#define HNS_ROCE_AEQE_OF_VEC_NUM 1
+
+/* 4G/4K = 1M */
+#define HNS_ROCE_SL_SHIFT 29
+#define HNS_ROCE_TCLASS_SHIFT 20
+#define HNS_ROCE_FLOW_LABLE_MASK 0xfffff
+
+#define HNS_ROCE_MAX_PORTS 6
+#define HNS_ROCE_MAX_GID_NUM 16
+#define HNS_ROCE_GID_SIZE 16
+
+#define MR_TYPE_MR 0x00
+#define MR_TYPE_PMR 0x01
+#define MR_TYPE_MW 0x02
+#define MR_TYPE_DMA 0x03
+
+#define PKEY_ID 0xffff
+#define NODE_DESC_SIZE 64
+
+#define SERV_TYPE_RC 0
+#define SERV_TYPE_RD 1
+#define SERV_TYPE_UC 2
+#define SERV_TYPE_UD 3
+
+#define ADDR_SHIFT_12 12
+#define ADDR_SHIFT_32 32
+#define ADDR_SHIFT_44 44
+
+#define PAGES_SHIFT_8 8
+#define PAGES_SHIFT_16 16
+#define PAGES_SHIFT_24 24
+#define PAGES_SHIFT_32 32
+
+enum hns_roce_qp_state {
+ HNS_ROCE_QP_STATE_RST = 0,
+ HNS_ROCE_QP_STATE_INIT = 1,
+ HNS_ROCE_QP_STATE_RTR = 2,
+ HNS_ROCE_QP_STATE_RTS = 3,
+ HNS_ROCE_QP_STATE_SQD = 4,
+ HNS_ROCE_QP_STATE_ERR = 5,
+ HNS_ROCE_QP_NUM_STATE
+};
+
+enum hns_roce_event {
+ HNS_ROCE_EVENT_TYPE_PATH_MIG = 0x01,
+ HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED = 0x02,
+ HNS_ROCE_EVENT_TYPE_COMM_EST = 0x03,
+ HNS_ROCE_EVENT_TYPE_SQ_DRAINED = 0x04,
+ HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR = 0x05,
+ HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR = 0x06,
+ HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR = 0x07,
+ HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH = 0x08,
+ HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH = 0x09,
+ HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR = 0x0a,
+ HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR = 0x0b,
+ HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW = 0x0c,
+ HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID = 0x0d,
+ HNS_ROCE_EVENT_TYPE_PORT_ACTIVE = 0x0e,
+ HNS_ROCE_EVENT_TYPE_PORT_CHANGE = 0x0f,
+ HNS_ROCE_EVENT_TYPE_LOCAL_CATAS_ERROR = 0x10,
+ HNS_ROCE_EVENT_TYPE_PORT_ERROR = 0x11,
+ HNS_ROCE_EVENT_TYPE_DB_OVERFLOW = 0x12,
+ HNS_ROCE_EVENT_TYPE_MB = 0x13,
+ HNS_ROCE_EVENT_TYPE_CEQ_OVERFLOW = 0x14
+};
+
+/* Local Work Queue Catastrophic Error,SUBTYPE 0x5 */
+enum {
+ HNS_ROCE_LWQCE_QPC_ERROR = 1,
+ HNS_ROCE_LWQCE_MTU_ERROR = 2,
+ HNS_ROCE_LWQCE_WQE_BA_ADDR_ERROR = 3,
+ HNS_ROCE_LWQCE_WQE_ADDR_ERROR = 4,
+ HNS_ROCE_LWQCE_SQ_WQE_SHIFT_ERROR = 5,
+ HNS_ROCE_LWQCE_SL_ERROR = 6,
+ HNS_ROCE_LWQCE_PORT_ERROR = 7
+};
+
+/* Local Access Violation Work Queue Error,SUBTYPE 0x7 */
+enum {
+ HNS_ROCE_LAVWQE_R_KEY_VIOLATION = 1,
+ HNS_ROCE_LAVWQE_LENGTH_ERROR = 2,
+ HNS_ROCE_LAVWQE_VA_ERROR = 3,
+ HNS_ROCE_LAVWQE_PD_ERROR = 4,
+ HNS_ROCE_LAVWQE_RW_ACC_ERROR = 5,
+ HNS_ROCE_LAVWQE_KEY_STATE_ERROR = 6,
+ HNS_ROCE_LAVWQE_MR_OPERATION_ERROR = 7
+};
+
+/* DOORBELL overflow subtype */
+enum {
+ HNS_ROCE_DB_SUBTYPE_SDB_OVF = 1,
+ HNS_ROCE_DB_SUBTYPE_SDB_ALM_OVF = 2,
+ HNS_ROCE_DB_SUBTYPE_ODB_OVF = 3,
+ HNS_ROCE_DB_SUBTYPE_ODB_ALM_OVF = 4,
+ HNS_ROCE_DB_SUBTYPE_SDB_ALM_EMP = 5,
+ HNS_ROCE_DB_SUBTYPE_ODB_ALM_EMP = 6
+};
+
+enum {
+ HNS_ROCE_CMD_SUCCESS = 1
+};
+
+enum {
+ /* RQ&SRQ related operations */
+ HNS_ROCE_OPCODE_SEND_DATA_RECEIVE = 0x06,
+ HNS_ROCE_OPCODE_RDMA_WITH_IMM_RECEIVE = 0x07,
+};
+
+#define HNS_ROCE_PORT_DOWN 0
+#define HNS_ROCE_PORT_UP 1
+
+#define HNS_ROCE_MTT_ENTRY_PER_SEG 8
+
+#define PAGE_ADDR_SHIFT 12
+
+struct hns_roce_uar {
+ u64 pfn;
+ u32 index;
+};
+
+struct hns_roce_ucontext {
+ struct ib_ucontext ibucontext;
+ struct hns_roce_uar uar;
+};
+
+struct hns_roce_pd {
+ struct ib_pd ibpd;
+ u32 pdn;
+};
+
+struct hns_roce_bitmap {
+ /* Bitmap Traversal last a bit which is 1 */
+ u32 last;
+ u32 top;
+ u32 max;
+ u32 reserved_top;
+ u32 mask;
+ spinlock_t lock;
+ unsigned long *table;
+};
+
+/* Order bitmap length -- bit num compute formula: 1 << (max_order - order) */
+/* Order = 0: bitmap is biggest, order = max bitmap is least (only a bit) */
+/* Every bit repesent to a partner free/used status in bitmap */
+/*
+* Initial, bits of other bitmap are all 0 except that a bit of max_order is 1
+* Bit = 1 represent to idle and available; bit = 0: not available
+*/
+struct hns_roce_buddy {
+ /* Members point to every order level bitmap */
+ unsigned long **bits;
+ /* Represent to avail bits of the order level bitmap */
+ u32 *num_free;
+ int max_order;
+ spinlock_t lock;
+};
+
+struct hns_roce_icm_table {
+ /* ICM type: 0 = qpc 1 = mtt 2 = cqc 3 = srq 4 = other */
+ u32 type;
+ /* ICM array elment num */
+ int num_icm;
+ /* ICM entry record obj total num */
+ int num_obj;
+ /*Single obj size */
+ int obj_size;
+ int lowmem;
+ int coherent;
+ struct mutex mutex;
+ struct hns_roce_icm **icm;
+};
+
+struct hns_roce_mtt {
+ u32 first_seg;
+ int order;
+ int page_shift;
+};
+
+/* Only support 4K page size for mr register */
+#define MR_SIZE_4K 0
+
+struct hns_roce_mr {
+ struct ib_mr ibmr;
+ struct ib_umem *umem;
+ struct hns_roce_mtt mtt; /* MTT entry of mr */
+ u64 iova; /* MR's virtual orignal addr */
+ u64 size; /* Address range of MR */
+ u32 key; /* Key of MR */
+ u32 pd; /* PD num of MR */
+ u32 access;/* Access permission of MR */
+ int enabled; /* MR's active status */
+ int type; /* MR's register type */
+ u64 *pbl_buf;/* MR's PBL space */
+ dma_addr_t pbl_dma_addr; /* MR's PBL space PA */
+};
+
+struct hns_roce_mr_table {
+ struct hns_roce_bitmap mtpt_bitmap;
+ struct hns_roce_buddy mtt_buddy;
+ u64 mtt_base;
+ u64 mtpt_base;
+ struct hns_roce_icm_table mtt_table;
+ struct hns_roce_icm_table mtpt_table;
+};
+
+struct hns_roce_wq {
+ u64 *wrid; /* Work request ID */
+ spinlock_t lock;
+ int wqe_cnt; /* WQE num */
+ u32 max_post;
+ int max_gs;
+ int offset;
+ int wqe_shift;/* WQE size */
+ u32 head;
+ u32 tail;
+ void __iomem *db_reg_l;
+ void __iomem *db_reg_h;
+};
+
+struct hns_roce_buf_list {
+ void *buf;
+ dma_addr_t map;
+};
+
+struct hns_roce_buf {
+ struct hns_roce_buf_list direct;
+ struct hns_roce_buf_list *page_list;
+ int nbufs;
+ u32 npages;
+ int page_shift;
+};
+
+struct hns_roce_cq_buf {
+ struct hns_roce_buf hr_buf;
+ struct hns_roce_mtt hr_mtt;
+};
+
+struct hns_roce_cq_resize {
+ struct hns_roce_cq_buf hr_buf;
+ int cqe;
+};
+
+struct hns_roce_cq {
+ struct ib_cq ib_cq;
+ struct hns_roce_cq_buf hr_buf;
+ /* pointer to store information after resize*/
+ struct hns_roce_cq_resize *hr_resize_buf;
+ spinlock_t lock;
+ struct mutex resize_mutex;
+ struct ib_umem *umem;
+ struct ib_umem *resize_umem;
+ void (*comp)(struct hns_roce_cq *);
+ void (*event)(struct hns_roce_cq *, enum hns_roce_event);
+
+ struct hns_roce_uar *uar;
+ u32 cq_depth;
+ u32 cons_index;
+ void __iomem *cq_db_l;
+ void __iomem *tptr_addr;
+ u32 cqn;
+ u32 vector;
+ atomic_t refcount;
+ struct completion free;
+};
+
+struct hns_roce_srq {
+ struct ib_srq ibsrq;
+ struct hns_roce_buf buf;
+ void __iomem *db;
+ u64 *wrid;
+ spinlock_t lock;
+ int head;
+ int tail;
+ u16 wqe_ctr;
+ struct ib_umem *umem;
+ struct mutex mutex;
+
+ void (*event)(struct hns_roce_srq *, enum hns_roce_event);
+
+ int srqn;
+ int max; /* Max wr nums*/
+ int max_gs; /* Max sge nums */
+ int wqe_shift;
+
+ atomic_t refcount;
+ struct completion free;
+};
+
+struct hns_roce_uar_table {
+ struct hns_roce_bitmap bitmap;
+};
+
+struct hns_roce_qp_table {
+ struct hns_roce_bitmap bitmap;
+ u32 rdmarcbase;
+ int rdmarcshift;
+ spinlock_t lock;
+ struct hns_roce_icm_table qp_table;
+ struct hns_roce_icm_table irrl_table;
+};
+
+struct hns_roce_cq_table {
+ struct hns_roce_bitmap bitmap;
+ spinlock_t lock;
+ struct radix_tree_root tree;
+ struct hns_roce_icm_table table;
+};
+
+struct hns_roce_raq_table {
+ int e_raq_depth;
+ void __iomem *e_raq_addr;
+ void __iomem *e_raq_wl_addr;
+ void __iomem *e_raq_shift_addr;
+ struct hns_roce_buf_list *e_raq_buf;
+};
+
+struct hns_roce_av {
+ __le32 port_pd;
+ u8 reserved1;
+ u8 smac_index;
+ u16 reserved2;
+ u8 reserved3;
+ u8 gid_index;
+ u8 stat_rate;
+ u8 hop_limit;
+ __le32 sl_tclass_flowlabel;
+ u8 dgid[HNS_ROCE_GID_SIZE];
+ u32 reserved4[2];
+ u8 mac[6];
+ __le16 vlan;
+};
+
+struct hns_roce_ah {
+ struct ib_ah ibah;
+ struct hns_roce_av av;
+};
+
+struct hns_roce_cmd_context {
+ struct completion done;
+ int result;
+ int next;
+ u64 out_param;
+ u16 token;
+};
+
+struct hns_roce_cmdq {
+ struct dma_pool *pool;
+ void __iomem *hcr;
+ struct mutex hcr_mutex;
+ struct semaphore poll_sem;
+ /*
+ * Event mode: cmd register mutex protection,
+ * ensure to not exceed max_cmds and user use limit region
+ */
+ struct semaphore event_sem;
+ int max_cmds;
+ spinlock_t context_lock;
+ int free_head;
+ struct hns_roce_cmd_context *context;
+ /*
+ * Result of get integer part
+ * which max_comds compute according a power of 2
+ */
+ u16 token_mask;
+ /*
+ * Process whether use event mode, init default non-zero
+ * After the event queue of cmd event ready,
+ * can switch into event mode
+ * close device, switch into poll mode(non event mode)
+ */
+ u8 use_events;
+ u8 toggle;
+};
+
+struct hns_roce_dev;
+
+struct hns_roce_qp {
+ struct ib_qp ibqp;
+ struct hns_roce_buf hr_buf;
+ struct hns_roce_wq rq;
+ __le32 doorbell_qpn;
+ __le32 sq_signal_bits;
+ u32 sq_next_wqe;
+ int sq_max_wqes_per_wr;
+ int sq_spare_wqes;
+ struct hns_roce_wq sq;
+
+ struct ib_umem *umem;
+ struct hns_roce_mtt mtt;
+ u32 buff_size;
+ struct mutex mutex;
+ u32 flags;
+ u8 port;
+ u8 sl;
+ u8 alt_port;
+ u8 atomic_rd_en;
+ u8 resp_depth;
+ u8 sq_no_prefetch;
+ u8 state;
+ u32 access_flags;
+ u32 pkey_index;
+ void (*event)(struct hns_roce_qp *,
+ enum hns_roce_event);
+ int qpn;
+
+ atomic_t refcount;
+ struct completion free;
+};
+
+struct hns_roce_sqp {
+ struct hns_roce_qp hr_qp;
+ u32 send_psn;
+};
+
+struct hns_roce_ib_iboe {
+ spinlock_t lock;
+ struct net_device *netdevs[HNS_ROCE_MAX_PORTS];
+ struct notifier_block nb;
+ struct notifier_block nb_inet;
+ struct notifier_block nb_inet6;
+ /* 16 GID is shared by 6 port in v1 engine. */
+ union ib_gid gid_table[HNS_ROCE_MAX_GID_NUM];
+ u8 phy_port[HNS_ROCE_MAX_PORTS];
+};
+
+struct hns_roce_eq {
+ struct hns_roce_dev *hr_dev;
+ void __iomem *doorbell;
+
+ int type_flag;/* Aeq:1 ceq:0 */
+ int eqn;
+ int entries;
+ int log_entries;
+ int eqe_size;
+ int irq;
+ u16 have_irq;
+ int log_page_size;
+ int cons_index;
+ struct hns_roce_buf_list *buf_list;
+};
+
+struct hns_roce_eq_table {
+ char *irq_names;
+ struct hns_roce_eq *eq;
+ void __iomem **eqc_base;
+ int have_irq;
+};
+
+struct hns_roce_caps {
+ u64 fw_ver;
+ u8 num_ports;
+ int gid_table_len[HNS_ROCE_MAX_PORTS];
+ int pkey_table_len[HNS_ROCE_MAX_PORTS];
+ int local_ca_ack_delay;
+ int num_uars;
+ u32 phy_num_uars;
+ u32 max_sq_sg; /* 2 */
+ u32 max_sq_inline; /* 32 */
+ u32 max_rq_sg; /* 2 */
+ int num_qps; /* 256k */
+ u32 max_wqes; /* 16k */
+ int max_sq_desc_sz; /* 64 */
+ int max_rq_desc_sz; /* 64 */
+ int max_qp_init_rdma;
+ int max_qp_dest_rdma;
+ int sqp_start;
+ int num_srqs;
+ int max_srq_wqes;
+ int max_srq_sge;
+ int reserved_srqs;
+ int num_cqs;
+ int max_cqes;
+ int reserved_cqs;
+ int num_aeq_vectors; /* 1 */
+ int num_comp_vectors; /* 32 ceq */
+ int num_other_vectors;
+ int num_mtpts;
+ int num_mtt_segs;
+ int fmr_reserved_mtts;
+ int reserved_mtts;
+ int reserved_mrws;
+ int reserved_uars;
+ int num_pds;
+ int reserved_pds;
+ u32 mtt_entry_sz;
+ u32 cq_entry_sz;
+ u32 max_msg_sz;
+ u32 page_size_cap;
+ u32 flags;
+ u32 reserved_lkey;
+ u16 stat_rate_support;
+ u8 port_width_cap[HNS_ROCE_MAX_PORTS];
+ int max_gso_sz;
+ int reserved_qps_cnt;
+ int reserved_qps;
+ int reserved_qps_base;
+ int log_num_macs;
+ int log_num_prios;
+ int mtpt_entry_sz;
+ int qpc_entry_sz;
+ int irrl_entry_sz;
+ int cqc_entry_sz;
+ int aeqe_depth;
+ int ceqe_depth[HNS_ROCE_COMP_VEC_NUM];
+ enum ib_mtu max_mtu;
+};
+
+struct hns_roce_hw {
+ int (*reset)(struct hns_roce_dev *hr_dev, u32 val);
+ void (*hw_profile)(struct hns_roce_dev *hr_dev);
+ int (*hw_init)(struct hns_roce_dev *hr_dev);
+ void (*hw_uninit)(struct hns_roce_dev *hr_dev);
+ void (*set_gid)(struct hns_roce_dev *hr_dev, u8 port, int gid_index,
+ union ib_gid *gid);
+ void (*set_mac)(struct hns_roce_dev *hr_dev, u8 phy_port, u8 *addr);
+ void (*set_mtu)(struct hns_roce_dev *hr_dev, u8 phy_port,
+ enum ib_mtu mtu);
+ int (*write_mtpt)(void *mb_buf, struct hns_roce_mr *mr, int mtpt_idx);
+ void (*write_cqc)(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts,
+ dma_addr_t dma_handle, int nent, u32 vector);
+ int (*query_qp)(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr);
+ int (*modify_qp)(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
+ int attr_mask, enum ib_qp_state cur_state,
+ enum ib_qp_state new_state);
+ int (*destroy_qp)(struct ib_qp *ibqp);
+ int (*post_send)(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr);
+ int (*post_recv)(struct ib_qp *qp, struct ib_recv_wr *recv_wr,
+ struct ib_recv_wr **bad_recv_wr);
+ int (*req_notify_cq)(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
+ int (*poll_cq)(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
+ void *priv;
+};
+
+struct hns_roce_dev {
+ struct ib_device ib_dev;
+ struct platform_device *pdev;
+ struct hns_roce_uar priv_uar;
+ struct ib_mad_agent *send_agent[HNS_ROCE_MAX_PORTS][2];
+ struct ib_ah *sm_ah[HNS_ROCE_MAX_PORTS];
+ spinlock_t sm_lock;
+ spinlock_t cq_db_lock;
+ spinlock_t bt_cmd_lock;
+ struct hns_roce_ib_iboe iboe;
+
+ int irq[HNS_ROCE_MAX_IRQ_NUM];
+ void __iomem *reg_base;
+ struct hns_roce_caps caps;
+ struct radix_tree_root qp_table_tree;
+
+ unsigned char dev_addr[HNS_ROCE_MAX_PORTS][MAC_ADDR_OCTET_NUM];
+ u64 fw_ver;
+ u64 sys_image_guid;
+ u32 vendor_id;
+ u32 vendor_part_id;
+ u32 hw_rev;
+ void __iomem *priv_addr;
+
+ struct hns_roce_cmdq cmd;
+ struct hns_roce_bitmap pd_bitmap;
+ struct hns_roce_uar_table uar_table;
+ struct hns_roce_mr_table mr_table;
+ struct hns_roce_cq_table cq_table;
+ struct hns_roce_qp_table qp_table;
+ struct hns_roce_eq_table eq_table;
+
+ int cmd_mod;
+ int loop_idc;
+
+ u32 ver;
+ struct hns_roce_hw *hw;
+};
+
+static inline struct hns_roce_dev *to_hr_dev(struct ib_device *ib_dev)
+{
+ return container_of(ib_dev, struct hns_roce_dev, ib_dev);
+}
+
+static inline struct hns_roce_ucontext
+ *to_hr_ucontext(struct ib_ucontext *ibucontext)
+{
+ return container_of(ibucontext, struct hns_roce_ucontext, ibucontext);
+}
+
+static inline struct hns_roce_pd *to_hr_pd(struct ib_pd *ibpd)
+{
+ return container_of(ibpd, struct hns_roce_pd, ibpd);
+}
+
+static inline struct hns_roce_ah *to_hr_ah(struct ib_ah *ibah)
+{
+ return container_of(ibah, struct hns_roce_ah, ibah);
+}
+
+static inline struct hns_roce_mr *to_hr_mr(struct ib_mr *ibmr)
+{
+ return container_of(ibmr, struct hns_roce_mr, ibmr);
+}
+
+static inline struct hns_roce_qp *to_hr_qp(struct ib_qp *ibqp)
+{
+ return container_of(ibqp, struct hns_roce_qp, ibqp);
+}
+
+static inline struct hns_roce_cq *to_hr_cq(struct ib_cq *ib_cq)
+{
+ return container_of(ib_cq, struct hns_roce_cq, ib_cq);
+}
+
+static inline struct hns_roce_srq *to_hr_srq(struct ib_srq *ibsrq)
+{
+ return container_of(ibsrq, struct hns_roce_srq, ibsrq);
+}
+
+static inline struct hns_roce_sqp *hr_to_hr_sqp(struct hns_roce_qp *hr_qp)
+{
+ return container_of(hr_qp, struct hns_roce_sqp, hr_qp);
+}
+
+static inline void hns_roce_write64_k(__be32 val[2], void __iomem *dest)
+{
+ __raw_writeq(*(u64 *) val, dest);
+}
+
+static inline struct hns_roce_qp
+ *__hns_roce_qp_lookup(struct hns_roce_dev *hr_dev, u32 qpn)
+{
+ return radix_tree_lookup(&hr_dev->qp_table_tree,
+ qpn & (hr_dev->caps.num_qps - 1));
+}
+
+static inline void *hns_roce_buf_offset(struct hns_roce_buf *buf, int offset)
+{
+ u32 bits_per_long_val = BITS_PER_LONG;
+
+ if (bits_per_long_val == 64 || buf->nbufs == 1)
+ return (char *)(buf->direct.buf) + offset;
+ else
+ return (char *)(buf->page_list[offset >> PAGE_SHIFT].buf) +
+ (offset & (PAGE_SIZE - 1));
+}
+
+int hns_roce_init_uar_table(struct hns_roce_dev *dev);
+int hns_roce_uar_alloc(struct hns_roce_dev *dev, struct hns_roce_uar *uar);
+void hns_roce_uar_free(struct hns_roce_dev *dev, struct hns_roce_uar *uar);
+void hns_roce_cleanup_uar_table(struct hns_roce_dev *dev);
+
+int hns_roce_cmd_init(struct hns_roce_dev *hr_dev);
+void hns_roce_cmd_cleanup(struct hns_roce_dev *hr_dev);
+void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status,
+ u64 out_param);
+int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev);
+void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev);
+
+int hns_roce_mtt_init(struct hns_roce_dev *hr_dev, int npages, int page_shift,
+ struct hns_roce_mtt *mtt);
+void hns_roce_mtt_cleanup(struct hns_roce_dev *hr_dev,
+ struct hns_roce_mtt *mtt);
+int hns_roce_buf_write_mtt(struct hns_roce_dev *hr_dev,
+ struct hns_roce_mtt *mtt, struct hns_roce_buf *buf);
+
+int hns_roce_init_pd_table(struct hns_roce_dev *hr_dev);
+int hns_roce_init_mr_table(struct hns_roce_dev *hr_dev);
+int hns_roce_init_eq_table(struct hns_roce_dev *hr_dev);
+int hns_roce_init_cq_table(struct hns_roce_dev *hr_dev);
+int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev);
+
+void hns_roce_cleanup_pd_table(struct hns_roce_dev *hr_dev);
+void hns_roce_cleanup_mr_table(struct hns_roce_dev *hr_dev);
+void hns_roce_cleanup_eq_table(struct hns_roce_dev *hr_dev);
+void hns_roce_cleanup_cq_table(struct hns_roce_dev *hr_dev);
+void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev);
+
+int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, u32 *obj);
+void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, u32 obj);
+int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
+ u32 reserved_bot, u32 resetrved_top);
+void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap);
+void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev);
+int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
+ int align, u32 *obj);
+void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap, u32 obj,
+ int cnt);
+
+struct ib_ah *hns_roce_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
+int hns_roce_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
+int hns_roce_destroy_ah(struct ib_ah *ah);
+
+struct ib_pd *hns_roce_alloc_pd(struct ib_device *ib_dev,
+ struct ib_ucontext *context,
+ struct ib_udata *udata);
+int hns_roce_pd_alloc(struct hns_roce_dev *hr_dev, u32 *pdn);
+void hns_roce_pd_free(struct hns_roce_dev *hr_dev, u32 pdn);
+int hns_roce_dealloc_pd(struct ib_pd *pd);
+
+struct ib_mr *hns_roce_get_dma_mr(struct ib_pd *pd, int acc);
+struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ u64 virt_addr, int access_flags,
+ struct ib_udata *udata);
+int hns_roce_dereg_mr(struct ib_mr *ibmr);
+
+void hns_roce_buf_free(struct hns_roce_dev *hr_dev, u32 size,
+ struct hns_roce_buf *buf);
+int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct,
+ struct hns_roce_buf *buf);
+
+int hns_roce_ib_umem_write_mtt(struct hns_roce_dev *hr_dev,
+ struct hns_roce_mtt *mtt, struct ib_umem *umem);
+
+struct ib_qp *hns_roce_create_qp(struct ib_pd *ib_pd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata);
+int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata);
+void *get_recv_wqe(struct hns_roce_qp *hr_qp, int n);
+void *get_send_wqe(struct hns_roce_qp *hr_qp, int n);
+bool hns_roce_wq_overflow(struct hns_roce_wq *hr_wq, int nreq,
+ struct ib_cq *ib_cq);
+enum hns_roce_qp_state to_hns_roce_state(enum ib_qp_state state);
+void hns_roce_lock_cqs(struct hns_roce_cq *send_cq,
+ struct hns_roce_cq *recv_cq);
+void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq,
+ struct hns_roce_cq *recv_cq);
+void hns_roce_qp_remove(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp);
+void hns_roce_qp_free(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp);
+void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn,
+ int cnt);
+__be32 send_ieth(struct ib_send_wr *wr);
+int to_hr_qp_type(int qp_type);
+
+struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
+ const struct ib_cq_init_attr *attr,
+ struct ib_ucontext *context,
+ struct ib_udata *udata);
+
+int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq);
+
+void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn);
+void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type);
+void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type);
+int hns_get_gid_index(struct hns_roce_dev *hr_dev, u8 port, int gid_index);
+
+extern struct hns_roce_hw hns_roce_v1_hw;
+
+#endif /* _HNS_ROCE_DEVICE_H */
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.c
new file mode 100644
index 0000000..879ab74
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.c
@@ -0,0 +1,758 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include "hns_roce_common.h"
+#include "hns_roce_device.h"
+#include "hns_roce_eq.h"
+
+static void eq_set_cons_index(struct hns_roce_eq *eq, int req_not)
+{
+ __raw_writel((__force u32)
+ cpu_to_le32((eq->cons_index & CONS_INDEX_MASK) |
+ (req_not << eq->log_entries)), eq->doorbell);
+ /* Memory barrier */
+ mb();
+}
+
+static struct hns_roce_aeqe *get_aeqe(struct hns_roce_eq *eq, u32 entry)
+{
+ unsigned long off = (entry & (eq->entries - 1)) *
+ HNS_ROCE_AEQ_ENTRY_SIZE;
+
+ return eq->buf_list[off / HNS_ROCE_BA_SIZE].buf +
+ off % HNS_ROCE_BA_SIZE;
+}
+
+static struct hns_roce_aeqe *next_aeqe_sw(struct hns_roce_eq *eq)
+{
+ struct hns_roce_aeqe *aeqe = get_aeqe(eq, eq->cons_index);
+
+ return (!!(roce_get_bit(aeqe->asyn, HNS_ROCE_AEQE_U32_4_OWNER_S)) ^
+ !!(eq->cons_index & eq->entries)) ? aeqe : NULL;
+}
+
+static int hns_roce_aeq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_aeqe *aeqe;
+ int aeqes_found = 0;
+ int qpn = 0;
+
+ while ((aeqe = next_aeqe_sw(eq))) {
+ dev_dbg(dev, "aeqe = %p, aeqe->asyn.event_type = 0x%lx\n", aeqe,
+ roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+ /* Memory barrier */
+ rmb();
+
+ switch (roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S)) {
+ case HNS_ROCE_EVENT_TYPE_PATH_MIG:
+ dev_warn(dev, "PATH MIG not supported\n");
+ break;
+ case HNS_ROCE_EVENT_TYPE_COMM_EST:
+ dev_warn(dev, "COMMUNICATION ESTABLISHED\n");
+ break;
+ case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
+ dev_warn(dev, "SQ DRAINED not supported\n");
+ break;
+ case HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED:
+ dev_warn(dev, "PATH MIG FAILED\n");
+ break;
+ case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
+ dev_warn(dev, "qpn = 0x%lx\n",
+ roce_get_field(aeqe->event.qp_event.qp,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S));
+ hns_roce_qp_event(hr_dev,
+ roce_get_field(aeqe->event.qp_event.qp,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S),
+ roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+ break;
+ case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
+ qpn = roce_get_field(aeqe->event.qp_event.qp,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S);
+ dev_warn(dev, "Local Work Queue Catastrophic Error.\n");
+ switch (roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) {
+ case HNS_ROCE_LWQCE_QPC_ERROR:
+ dev_warn(dev, "QP %d, QPC error.\n", qpn);
+ break;
+ case HNS_ROCE_LWQCE_MTU_ERROR:
+ dev_warn(dev, "QP %d, MTU error.\n", qpn);
+ break;
+ case HNS_ROCE_LWQCE_WQE_BA_ADDR_ERROR:
+ dev_warn(dev, "QP %d, WQE BA addr error.\n",
+ qpn);
+ break;
+ case HNS_ROCE_LWQCE_WQE_ADDR_ERROR:
+ dev_warn(dev, "QP %d, WQE addr error.\n", qpn);
+ break;
+ case HNS_ROCE_LWQCE_SQ_WQE_SHIFT_ERROR:
+ dev_warn(dev, "QP %d, WQE shift error\n", qpn);
+ break;
+ case HNS_ROCE_LWQCE_SL_ERROR:
+ dev_warn(dev, "QP %d, SL error.\n", qpn);
+ break;
+ case HNS_ROCE_LWQCE_PORT_ERROR:
+ dev_warn(dev, "QP %d, port error.\n", qpn);
+ break;
+ default:
+ break;
+ }
+
+ hns_roce_qp_event(hr_dev,
+ roce_get_field(aeqe->event.qp_event.qp,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S),
+ roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+ break;
+ case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
+ qpn = roce_get_field(aeqe->event.qp_event.qp,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S);
+ dev_warn(dev, "Local Access Violation Work Queue Error.\n");
+ switch (roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) {
+ case HNS_ROCE_LAVWQE_R_KEY_VIOLATION:
+ dev_warn(dev, "QP %d, R_key violation.\n", qpn);
+ break;
+ case HNS_ROCE_LAVWQE_LENGTH_ERROR:
+ dev_warn(dev, "QP %d, length error.\n", qpn);
+ break;
+ case HNS_ROCE_LAVWQE_VA_ERROR:
+ dev_warn(dev, "QP %d, VA error.\n", qpn);
+ break;
+ case HNS_ROCE_LAVWQE_PD_ERROR:
+ dev_err(dev, "QP %d, PD error.\n", qpn);
+ break;
+ case HNS_ROCE_LAVWQE_RW_ACC_ERROR:
+ dev_warn(dev, "QP %d, rw acc error.\n", qpn);
+ break;
+ case HNS_ROCE_LAVWQE_KEY_STATE_ERROR:
+ dev_warn(dev, "QP %d, key state error.\n", qpn);
+ break;
+ case HNS_ROCE_LAVWQE_MR_OPERATION_ERROR:
+ dev_warn(dev, "QP %d, MR operation error.\n",
+ qpn);
+ break;
+ default:
+ break;
+ }
+
+ hns_roce_qp_event(hr_dev,
+ roce_get_field(aeqe->event.qp_event.qp,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
+ HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S),
+ roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+ break;
+ case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH:
+ case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
+ case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH:
+ dev_warn(dev, "SRQ not support!\n");
+ break;
+ case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
+ dev_warn(dev, "CQ 0x%lx access err.\n",
+ roce_get_field(aeqe->event.cq_event.cq,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S));
+ hns_roce_cq_event(hr_dev,
+ le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)),
+ roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+ break;
+ case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
+ dev_warn(dev, "CQ 0x%lx overflow\n",
+ roce_get_field(aeqe->event.cq_event.cq,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S));
+ hns_roce_cq_event(hr_dev,
+ le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)),
+ roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+ break;
+ case HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID:
+ dev_warn(dev, "CQ ID invalid.\n");
+ hns_roce_cq_event(hr_dev,
+ le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
+ HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)),
+ roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+ break;
+ case HNS_ROCE_EVENT_TYPE_PORT_CHANGE:
+ dev_warn(dev, "port change.\n");
+ break;
+ case HNS_ROCE_EVENT_TYPE_MB:
+ hns_roce_cmd_event(hr_dev,
+ le16_to_cpu(aeqe->event.cmd.token),
+ aeqe->event.cmd.status,
+ le64_to_cpu(aeqe->event.cmd.out_param
+ ));
+ break;
+ case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
+ switch (roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) {
+ case HNS_ROCE_DB_SUBTYPE_SDB_OVF:
+ dev_warn(dev, "SDB overflow.\n");
+ break;
+ case HNS_ROCE_DB_SUBTYPE_SDB_ALM_OVF:
+ dev_warn(dev, "SDB almost overflow.\n");
+ break;
+ case HNS_ROCE_DB_SUBTYPE_SDB_ALM_EMP:
+ dev_warn(dev, "SDB almost empty.\n");
+ break;
+ case HNS_ROCE_DB_SUBTYPE_ODB_OVF:
+ dev_warn(dev, "ODB overflow.\n");
+ break;
+ case HNS_ROCE_DB_SUBTYPE_ODB_ALM_OVF:
+ dev_warn(dev, "ODB almost overflow.\n");
+ break;
+ case HNS_ROCE_DB_SUBTYPE_ODB_ALM_EMP:
+ dev_warn(dev, "SDB almost empty.\n");
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case HNS_ROCE_EVENT_TYPE_CEQ_OVERFLOW:
+ dev_warn(dev, "CEQ 0x%lx OVERFLOW EVENT.\n",
+ roce_get_field(aeqe->event.ce_event.ceqe,
+ HNS_ROCE_AEQE_EVENT_CE_EVENT_CEQE_CEQN_M,
+ HNS_ROCE_AEQE_EVENT_CE_EVENT_CEQE_CEQN_S));
+ break;
+ default:
+ dev_warn(dev, "Unhandled event 0x%lx on EQ %d at index %u\n",
+ roce_get_field(aeqe->asyn,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+ HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S),
+ eq->eqn, eq->cons_index);
+ break;
+ };
+
+ eq->cons_index++;
+ aeqes_found = 1;
+
+ if (eq->cons_index > 2 * hr_dev->caps.aeqe_depth - 1) {
+ dev_warn(dev, "cons_index overflow, set back to zero\n"
+ );
+ eq->cons_index = 0;
+ }
+ }
+
+ eq_set_cons_index(eq, 0);
+
+ return aeqes_found;
+}
+
+static struct hns_roce_ceqe *get_ceqe(struct hns_roce_eq *eq, u32 entry)
+{
+ unsigned long off = (entry & (eq->entries - 1)) *
+ HNS_ROCE_CEQ_ENTRY_SIZE;
+
+ return (struct hns_roce_ceqe *)((u8 *)
+ (eq->buf_list[off / HNS_ROCE_BA_SIZE].buf) +
+ off % HNS_ROCE_BA_SIZE);
+}
+
+static struct hns_roce_ceqe *next_ceqe_sw(struct hns_roce_eq *eq)
+{
+ struct hns_roce_ceqe *ceqe = get_ceqe(eq, eq->cons_index);
+
+ return ((!!(roce_get_bit(ceqe->ceqe.comp,
+ HNS_ROCE_CEQE_CEQE_COMP_OWNER_S))) ^
+ (!!(eq->cons_index & eq->entries)) ? ceqe : NULL);
+}
+
+static int hns_roce_ceq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
+{
+ struct hns_roce_ceqe *ceqe;
+ int ceqes_found = 0;
+ int cqn;
+
+ while ((ceqe = next_ceqe_sw(eq))) {
+ /* Memory barrier */
+ rmb();
+ cqn = roce_get_field(ceqe->ceqe.comp,
+ HNS_ROCE_CEQE_CEQE_COMP_CQN_M,
+ HNS_ROCE_CEQE_CEQE_COMP_CQN_S);
+ hns_roce_cq_completion(hr_dev, cqn);
+
+ ++eq->cons_index;
+ ceqes_found = 1;
+
+ if (eq->cons_index > 2 * hr_dev->caps.ceqe_depth[eq->eqn] - 1) {
+ dev_warn(&eq->hr_dev->pdev->dev,
+ "cons_index overflow, set back to zero\n");
+ eq->cons_index = 0;
+ }
+ }
+
+ eq_set_cons_index(eq, 0);
+
+ return ceqes_found;
+
+}
+
+static int hns_roce_aeq_ovf_int(struct hns_roce_dev *hr_dev,
+ struct hns_roce_eq *eq)
+{
+ struct device *dev = &eq->hr_dev->pdev->dev;
+ int eqovf_found = 0;
+ u32 caepaemask_val;
+ u32 cealmovf_val;
+ u32 caepaest_val;
+ u32 aeshift_val;
+ u32 ceshift_val;
+ u32 cemask_val;
+ int i = 0;
+
+ /**
+ * AEQ overflow ECC mult bit err CEQ overflow alarm
+ * must clear interrupt, mask irq, clear irq, cancel mask operation
+ */
+ aeshift_val = roce_readl(hr_dev->reg_base +
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_REG);
+ if (roce_get_bit(aeshift_val,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQ_ALM_OVF_INT_ST_S) == 1) {
+ dev_warn(dev, "AEQ overflow!\n");
+
+ /* Set mask */
+ caepaemask_val = roce_readl(hr_dev->reg_base +
+ ROCEE_CAEP_AE_MASK_REG);
+ roce_set_bit(caepaemask_val,
+ ROCEE_CAEP_AE_MASK_CAEP_AEQ_ALM_OVF_MASK_S,
+ HNS_ROCE_INT_MASK_ENABLE);
+ roce_writel(caepaemask_val,
+ hr_dev->reg_base + ROCEE_CAEP_AE_MASK_REG);
+
+ /* Clear int state(INT_WC : write 1 clear) */
+ caepaest_val = roce_readl(hr_dev->reg_base +
+ ROCEE_CAEP_AE_ST_REG);
+ roce_set_bit(caepaest_val,
+ ROCEE_CAEP_AE_ST_CAEP_AEQ_ALM_OVF_S, 1);
+ roce_writel(caepaest_val, hr_dev->reg_base +
+ ROCEE_CAEP_AE_ST_REG);
+
+ /* Clear mask */
+ caepaemask_val = roce_readl(hr_dev->reg_base +
+ ROCEE_CAEP_AE_MASK_REG);
+ roce_set_bit(caepaemask_val,
+ ROCEE_CAEP_AE_MASK_CAEP_AEQ_ALM_OVF_MASK_S,
+ HNS_ROCE_INT_MASK_DISABLE);
+ roce_writel(caepaemask_val, hr_dev->reg_base +
+ ROCEE_CAEP_AE_MASK_REG);
+ }
+
+ /* CEQ almost overflow */
+ for (i = 0; i < hr_dev->caps.num_comp_vectors; i++) {
+ ceshift_val = roce_readl(hr_dev->reg_base +
+ ROCEE_CAEP_CEQC_SHIFT_0_REG + i * CEQ_REG_OFFSET);
+ if (roce_get_bit(ceshift_val,
+ ROCEE_CAEP_CEQC_SHIFT_CAEP_CEQ_ALM_OVF_INT_ST_S) == 1) {
+ dev_warn(dev, "CEQ[%d] almost overflow!\n", i);
+ eqovf_found++;
+
+ /* Set mask */
+ cemask_val = roce_readl(hr_dev->reg_base +
+ ROCEE_CAEP_CE_IRQ_MASK_0_REG +
+ i * CEQ_REG_OFFSET);
+ roce_set_bit(cemask_val,
+ ROCEE_CAEP_CE_IRQ_MASK_CAEP_CEQ_ALM_OVF_MASK_S,
+ HNS_ROCE_INT_MASK_ENABLE);
+ roce_writel(cemask_val, hr_dev->reg_base +
+ ROCEE_CAEP_CE_IRQ_MASK_0_REG +
+ i * CEQ_REG_OFFSET);
+
+ /* Clear int state(INT_WC : write 1 clear) */
+ cealmovf_val = roce_readl(hr_dev->reg_base +
+ ROCEE_CAEP_CEQ_ALM_OVF_0_REG +
+ i * CEQ_REG_OFFSET);
+ roce_set_bit(cealmovf_val,
+ ROCEE_CAEP_CEQ_ALM_OVF_CAEP_CEQ_ALM_OVF_S,
+ 1);
+ roce_writel(cealmovf_val, hr_dev->reg_base +
+ ROCEE_CAEP_CEQ_ALM_OVF_0_REG +
+ i * CEQ_REG_OFFSET);
+
+ /* Clear mask */
+ cemask_val = roce_readl(hr_dev->reg_base +
+ ROCEE_CAEP_CE_IRQ_MASK_0_REG +
+ i * CEQ_REG_OFFSET);
+ roce_set_bit(cemask_val,
+ ROCEE_CAEP_CE_IRQ_MASK_CAEP_CEQ_ALM_OVF_MASK_S,
+ HNS_ROCE_INT_MASK_DISABLE);
+ roce_writel(cemask_val, hr_dev->reg_base +
+ ROCEE_CAEP_CE_IRQ_MASK_0_REG +
+ i * CEQ_REG_OFFSET);
+ }
+ }
+
+ /* ECC multi-bit error alarm */
+ dev_warn(dev, "ECC UCERR ALARM: 0x%x, 0x%x, 0x%x\n",
+ roce_readl(hr_dev->reg_base + ROCEE_ECC_UCERR_ALM0_REG),
+ roce_readl(hr_dev->reg_base + ROCEE_ECC_UCERR_ALM1_REG),
+ roce_readl(hr_dev->reg_base + ROCEE_ECC_UCERR_ALM2_REG));
+ dev_warn(dev, "ECC CERR ALARM: 0x%x, 0x%x, 0x%x\n",
+ roce_readl(hr_dev->reg_base + ROCEE_ECC_CERR_ALM0_REG),
+ roce_readl(hr_dev->reg_base + ROCEE_ECC_CERR_ALM1_REG),
+ roce_readl(hr_dev->reg_base + ROCEE_ECC_CERR_ALM2_REG));
+
+ return eqovf_found;
+}
+
+static int hns_roce_eq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
+{
+ int eqes_found = 0;
+
+ if (likely(eq->type_flag == HNS_ROCE_CEQ))
+ /* CEQ irq routine, CEQ is pulse irq, not clear */
+ eqes_found = hns_roce_ceq_int(hr_dev, eq);
+ else if (likely(eq->type_flag == HNS_ROCE_AEQ))
+ /* AEQ irq routine, AEQ is pulse irq, not clear */
+ eqes_found = hns_roce_aeq_int(hr_dev, eq);
+ else
+ /* AEQ queue overflow irq */
+ eqes_found = hns_roce_aeq_ovf_int(hr_dev, eq);
+
+ return eqes_found;
+}
+
+static irqreturn_t hns_roce_msi_x_interrupt(int irq, void *eq_ptr)
+{
+ struct hns_roce_eq *eq = eq_ptr;
+ struct hns_roce_dev *hr_dev = eq->hr_dev;
+
+ (void)hns_roce_eq_int(hr_dev, eq);
+
+ return IRQ_HANDLED;
+}
+
+static void hns_roce_enable_eq(struct hns_roce_dev *hr_dev, int eq_num,
+ int enable_flag)
+{
+ void __iomem *eqc = hr_dev->eq_table.eqc_base[eq_num];
+ u32 val;
+
+ val = roce_readl(eqc);
+ if (enable_flag)
+ roce_set_field(val,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_M,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_S,
+ HNS_ROCE_EQ_STAT_VALID);
+ else
+ roce_set_field(val,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_M,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_S,
+ HNS_ROCE_EQ_STAT_INVALID);
+ roce_writel(val, eqc);
+}
+
+static int hns_roce_create_eq(struct hns_roce_dev *hr_dev,
+ struct hns_roce_eq *eq)
+{
+ void __iomem *eqc = hr_dev->eq_table.eqc_base[eq->eqn];
+ struct device *dev = &hr_dev->pdev->dev;
+ dma_addr_t tmp_dma_addr;
+ u32 eqconsindx_val = 0;
+ u32 eqcuridx_val = 0;
+ u32 eqshift_val = 0;
+ int num_bas = 0;
+ int ret;
+ int i;
+
+ num_bas = (PAGE_ALIGN(eq->entries * eq->eqe_size) +
+ HNS_ROCE_BA_SIZE - 1) / HNS_ROCE_BA_SIZE;
+
+ if ((eq->entries * eq->eqe_size) > HNS_ROCE_BA_SIZE) {
+ dev_err(dev, "[error]eq buf %d gt ba size(%d) need bas=%d\n",
+ (eq->entries * eq->eqe_size), HNS_ROCE_BA_SIZE,
+ num_bas);
+ dev_err(dev, "only support 32k CQ use CEQ!\n");
+ return -EINVAL;
+ }
+
+ eq->buf_list = kcalloc(num_bas, sizeof(*eq->buf_list), GFP_KERNEL);
+ if (!eq->buf_list)
+ return -ENOMEM;
+
+ for (i = 0; i < num_bas; ++i) {
+ eq->buf_list[i].buf = dma_alloc_coherent(dev, HNS_ROCE_BA_SIZE,
+ &tmp_dma_addr,
+ GFP_KERNEL);
+ if (!eq->buf_list[i].buf) {
+ ret = -ENOMEM;
+ dev_err(dev, "eq buf_list buf alloc failed!\n");
+ goto err_out_free_pages;
+ }
+
+ eq->buf_list[i].map = tmp_dma_addr;
+ memset(eq->buf_list[i].buf, 0, HNS_ROCE_BA_SIZE);
+ }
+ eq->cons_index = 0;
+ roce_set_field(eqshift_val,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_M,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_S,
+ HNS_ROCE_EQ_STAT_INVALID);
+ roce_set_field(eqshift_val,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_AEQE_SHIFT_M,
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_AEQE_SHIFT_S,
+ eq->log_entries);
+ roce_writel(eqshift_val, eqc);
+
+ /* Configure eq extended address 12~44bit */
+ roce_writel((u32)(eq->buf_list[0].map >> ADDR_SHIFT_12), eqc + 4);
+
+ /* Configure eq extended address 45~49 bit, producer index */
+ roce_set_field(eqcuridx_val, ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQ_BT_H_M,
+ ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQ_BT_H_S,
+ eq->buf_list[0].map >> ADDR_SHIFT_44);
+ roce_set_field(eqcuridx_val,
+ ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQE_CUR_IDX_M,
+ ROCEE_CAEP_AEQE_CUR_IDX_CAEP_AEQE_CUR_IDX_S, 0);
+ roce_writel(eqcuridx_val, eqc + 8);
+
+ /* Configure eq consumer index */
+ roce_set_field(eqconsindx_val,
+ ROCEE_CAEP_AEQE_CONS_IDX_CAEP_AEQE_CONS_IDX_M,
+ ROCEE_CAEP_AEQE_CONS_IDX_CAEP_AEQE_CONS_IDX_S, 0);
+ roce_writel(eqconsindx_val, eqc + 0xc);
+ return 0;
+
+err_out_free_pages:
+ for (i = 0; i < num_bas; ++i)
+ if (eq->buf_list[i].buf)
+ dma_free_coherent(dev, HNS_ROCE_BA_SIZE,
+ eq->buf_list[i].buf,
+ eq->buf_list[i].map);
+
+ kfree(eq->buf_list);
+ return ret;
+}
+
+static void hns_roce_free_eq(struct hns_roce_dev *hr_dev,
+ struct hns_roce_eq *eq)
+{
+ int i = 0;
+ int npages = (PAGE_ALIGN(eq->eqe_size * eq->entries) +
+ HNS_ROCE_BA_SIZE - 1) / HNS_ROCE_BA_SIZE;
+
+ if (!eq->buf_list)
+ return;
+
+ for (i = 0; i < npages; ++i)
+ if (eq->buf_list[i].buf)
+ dma_free_coherent(&hr_dev->pdev->dev, HNS_ROCE_BA_SIZE,
+ eq->buf_list[i].buf,
+ eq->buf_list[i].map);
+ kfree(eq->buf_list);
+}
+
+void hns_roce_int_mask_en(struct hns_roce_dev *hr_dev)
+{
+ void __iomem *reg_caepceirqmsk;
+ void __iomem *reg_caepaemsk;
+ int i = 0;
+ u32 aemask_val;
+ int masken = 0;
+
+ /* AEQ INT */
+ reg_caepaemsk = (void *)((char *)hr_dev->reg_base +
+ ROCEE_CAEP_AE_MASK_REG);
+ aemask_val = roce_readl(reg_caepaemsk);
+ roce_set_bit(aemask_val, ROCEE_CAEP_AE_MASK_CAEP_AEQ_ALM_OVF_MASK_S,
+ masken);
+ roce_set_bit(aemask_val, ROCEE_CAEP_AE_MASK_CAEP_AE_IRQ_MASK_S, masken);
+ roce_writel(aemask_val, reg_caepaemsk);
+
+ /* CEQ INT */
+ for (i = 0; i < hr_dev->caps.num_comp_vectors; i++) {
+
+ /* IRQ mask */
+ reg_caepceirqmsk = (void *)((char *)hr_dev->reg_base +
+ ROCEE_CAEP_CE_IRQ_MASK_0_REG +
+ i * CEQ_REG_OFFSET);
+ roce_writel(masken, reg_caepceirqmsk);
+ }
+}
+
+void hns_roce_ce_int_default_cfg(struct hns_roce_dev *hr_dev)
+{
+ /* Configure ce int interval */
+ roce_writel(HNS_ROCE_CEQ_DEFAULT_INTERVAL,
+ hr_dev->reg_base + ROCEE_CAEP_CE_INTERVAL_CFG_REG);
+ /* Configure ce int burst num */
+ roce_writel(HNS_ROCE_CEQ_DEFAULT_BURST_NUM,
+ hr_dev->reg_base + ROCEE_CAEP_CE_BURST_NUM_CFG_REG);
+}
+
+int hns_roce_init_eq_table(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_eq_table *eq_table = &hr_dev->eq_table;
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_eq *eq = NULL;
+ const char *eq_name = NULL;
+ int eq_num = 0;
+ int ret = 0;
+ int i = 0;
+
+ eq_num = hr_dev->caps.num_comp_vectors + hr_dev->caps.num_aeq_vectors;
+ eq_table->eq = kcalloc(eq_num, sizeof(*eq_table->eq), GFP_KERNEL);
+ if (!eq_table->eq) {
+ dev_err(dev, "eq alloc failed!\n");
+ return -ENOMEM;
+ }
+
+ eq_table->eqc_base = kcalloc(eq_num, sizeof(*eq_table->eqc_base),
+ GFP_KERNEL);
+ if (!eq_table->eqc_base) {
+ ret = -ENOMEM;
+ dev_err(dev, "eqc_base alloc failed!\n");
+ goto err_eqc_base_alloc_fail;
+ }
+
+ eq_table->irq_names = kzalloc(eq_num * IRQ_NAMES_LEN, GFP_KERNEL);
+ if (!eq_table->irq_names) {
+ ret = -ENOMEM;
+ dev_err(dev, "irq_names alloc failed!\n");
+ goto err_irq_name_alloc_fail;
+ }
+
+ for (i = 0; i < eq_num; i++) {
+ eq = &eq_table->eq[i];
+ eq->hr_dev = hr_dev;
+ eq->eqn = i;
+ eq->irq = hr_dev->irq[i];
+ eq->log_page_size = PAGE_SHIFT;
+
+ if (i < hr_dev->caps.num_comp_vectors) {
+ /* CEQ */
+ eq_table->eqc_base[i] = hr_dev->reg_base +
+ ROCEE_CAEP_CEQC_SHIFT_0_REG +
+ HNS_ROCE_CEQC_REG_OFFSET * i;
+ snprintf(eq_table->irq_names + i * IRQ_NAMES_LEN,
+ IRQ_NAMES_LEN, "hns-roce-comp-%d", i);
+ eq->type_flag = HNS_ROCE_CEQ;
+ eq->doorbell = hr_dev->reg_base +
+ ROCEE_CAEP_CEQC_CONS_IDX_0_REG +
+ HNS_ROCE_CEQC_REG_OFFSET * i;
+ eq->entries = hr_dev->caps.ceqe_depth[i];
+ eq->log_entries = ilog2(eq->entries);
+ eq->eqe_size = sizeof(struct hns_roce_ceqe);
+ } else {
+ /* AEQ */
+ eq_table->eqc_base[i] = hr_dev->reg_base +
+ ROCEE_CAEP_AEQC_AEQE_SHIFT_REG;
+ snprintf(eq_table->irq_names + i * IRQ_NAMES_LEN,
+ IRQ_NAMES_LEN, "hns-roce-async-%d",
+ i - hr_dev->caps.num_comp_vectors);
+ eq->type_flag = HNS_ROCE_AEQ;
+ eq->doorbell = hr_dev->reg_base +
+ ROCEE_CAEP_AEQE_CONS_IDX_REG;
+ eq->entries = hr_dev->caps.aeqe_depth;
+ eq->log_entries = ilog2(eq->entries);
+ eq->eqe_size = sizeof(struct hns_roce_aeqe);
+ }
+ }
+
+ /* Disable irq */
+ hns_roce_int_mask_en(hr_dev);
+
+ /* Configure CE irq interval and burst num */
+ hns_roce_ce_int_default_cfg(hr_dev);
+
+ for (i = 0; i < eq_num; i++) {
+ ret = hns_roce_create_eq(hr_dev, &eq_table->eq[i]);
+ if (ret) {
+ dev_err(dev, "eq create failed\n");
+ goto err_create_eq_fail;
+ }
+
+ eq_name = eq_table->irq_names + i * IRQ_NAMES_LEN;
+ ret = request_irq(eq_table->eq[i].irq, hns_roce_msi_x_interrupt,
+ 0, eq_name, eq_table->eq + i);
+ if (ret) {
+ dev_err(dev, "request irq error!\n");
+ goto err_create_eq_fail;
+ }
+
+ eq_table->eq[i].have_irq = 1;
+
+ hns_roce_enable_eq(hr_dev, i, EQ_ENABLE);
+ }
+
+ return 0;
+
+err_create_eq_fail:
+ for (i = 0; i < eq_num; i++) {
+ /* Disable EQ */
+ hns_roce_enable_eq(hr_dev, i, EQ_DISABLE);
+
+ if (eq_table->eq[i].have_irq)
+ free_irq(eq_table->eq[i].irq, eq_table->eq + i);
+
+ hns_roce_free_eq(hr_dev, &eq_table->eq[i]);
+ }
+
+ kfree(eq_table->irq_names);
+
+err_irq_name_alloc_fail:
+ kfree(eq_table->eqc_base);
+
+err_eqc_base_alloc_fail:
+ kfree(eq_table->eq);
+ return ret;
+}
+
+void hns_roce_cleanup_eq_table(struct hns_roce_dev *hr_dev)
+{
+ int i;
+ int eq_num;
+ struct hns_roce_eq_table *eq_table = &hr_dev->eq_table;
+
+ eq_num = hr_dev->caps.num_comp_vectors + hr_dev->caps.num_aeq_vectors;
+ for (i = 0; i < eq_num; i++) {
+ /* Disable EQ */
+ hns_roce_enable_eq(hr_dev, i, EQ_DISABLE);
+
+ if (eq_table->eq[i].have_irq)
+ free_irq(eq_table->eq[i].irq, eq_table->eq + i);
+
+ hns_roce_free_eq(hr_dev, &eq_table->eq[i]);
+ }
+
+ kfree(eq_table->irq_names);
+ kfree(eq_table->eqc_base);
+ kfree(eq_table->eq);
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.h b/drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.h
new file mode 100644
index 0000000..f0cac99
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _HNS_ROCE_EQ_H
+#define _HNS_ROCE_EQ_H
+
+#define HNS_ROCE_CEQ 1
+#define HNS_ROCE_AEQ 2
+#define HNS_ROCE_AEQ_OVF 3
+
+#define HNS_ROCE_CEQ_ENTRY_SIZE 0x4
+#define HNS_ROCE_AEQ_ENTRY_SIZE 0x10
+#define HNS_ROCE_CEQC_REG_OFFSET 0x18
+
+#define HNS_ROCE_CEQ_DEFAULT_INTERVAL 0x10
+#define HNS_ROCE_CEQ_DEFAULT_BURST_NUM 0x10
+
+#define HNS_ROCE_ASYNC_EVENT_MASK \
+ ((1ULL << HNS_ROCE_EVENT_TYPE_PATH_MIG) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_COMM_EST) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_SQ_DRAINED) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_PORT_ACTIVE) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_PORT_CHANGE) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_LOCAL_CATAS_ERROR) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_PORT_ERROR) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_DB_OVERFLOW) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_MB) | \
+ (1ULL << HNS_ROCE_EVENT_TYPE_CEQ_OVERFLOW))
+
+#define HNS_ROCE_INT_MASK_DISABLE 0
+#define HNS_ROCE_INT_MASK_ENABLE 1
+
+#define IRQ_NAMES_LEN 32
+#define EQ_ENABLE 1
+#define EQ_DISABLE 0
+#define CONS_INDEX_MASK 0xffff
+
+#define CEQ_REG_OFFSET 0x18
+
+enum {
+ HNS_ROCE_EQ_STAT_INVALID = 0,
+ HNS_ROCE_EQ_STAT_VALID = 2,
+ HNS_ROCE_EQ_STAT_ERR = 3
+};
+
+struct hns_roce_aeqe {
+
+ u32 asyn;
+ union {
+ struct {
+ u32 qp;
+ u32 rsv0;
+ u32 rsv1;
+ } qp_event;
+
+ struct {
+ u32 cq;
+ u32 rsv0;
+ u32 rsv1;
+ } cq_event;
+
+ struct {
+ u32 port;
+ u32 rsv0;
+ u32 rsv1;
+ } port_event;
+
+ struct {
+ u32 ceqe;
+ u32 rsv0;
+ u32 rsv1;
+ } ce_event;
+
+ struct {
+ __le64 out_param;
+ __le16 token;
+ u8 status;
+ u8 rsv0;
+ } __packed cmd;
+ } event;
+};
+#define HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S 16
+#define HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M \
+ (((1UL << 8) - 1) << HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S)
+
+#define HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S 24
+#define HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M \
+ (((1UL << 7) - 1) << HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)
+
+#define HNS_ROCE_AEQE_U32_4_OWNER_S 31
+
+#define HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S 0
+#define HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M \
+ (((1UL << 24) - 1) << HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S)
+
+#define HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S 0
+#define HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M \
+ (((1UL << 16) - 1) << HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)
+
+#define HNS_ROCE_AEQE_EVENT_CE_EVENT_CEQE_CEQN_S 0
+#define HNS_ROCE_AEQE_EVENT_CE_EVENT_CEQE_CEQN_M \
+ (((1UL << 5) - 1) << HNS_ROCE_AEQE_EVENT_CE_EVENT_CEQE_CEQN_S)
+
+struct hns_roce_ceqe {
+ union {
+ int raw[1];
+ int comp;
+ } ceqe;
+};
+
+#define HNS_ROCE_CEQE_CEQE_COMP_OWNER_S 0
+
+#define HNS_ROCE_CEQE_CEQE_COMP_CQN_S 16
+#define HNS_ROCE_CEQE_CEQE_COMP_CQN_M \
+ (((1UL << 16) - 1) << HNS_ROCE_CEQE_CEQE_COMP_CQN_S)
+
+#endif /* _HNS_ROCE_EQ_H */
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.c
new file mode 100644
index 0000000..7089ffb
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include "hns_roce_device.h"
+#include "hns_roce_cmd.h"
+#include "hns_roce_icm.h"
+#include "hns_roce_common.h"
+
+#define HW_SYNC_TIMEOUT_MSECS 500
+
+#define HNS_ROCE_ICM_ALLOC_SIZE (1 << 17)
+#define HNS_ROCE_TABLE_CHUNK_SIZE (1 << 17)
+
+#define DMA_ADDR_T_SHIFT 12
+#define BT_CMD_SYNC_SHIFT 31
+#define BT_BA_SHIFT 32
+
+static void hns_roce_free_icm_pages(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_chunk *chunk)
+{
+ int i;
+
+ if (chunk->nsg > 0)
+ dma_unmap_sg(&hr_dev->pdev->dev, chunk->mem, chunk->npages,
+ (enum dma_data_direction)0);
+
+ for (i = 0; i < chunk->npages; ++i)
+ __free_pages(sg_page(&chunk->mem[i]),
+ get_order(chunk->mem[i].length));
+}
+
+static void hns_roce_free_icm_coherent(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_chunk *chunk)
+{
+ int i;
+
+ for (i = 0; i < chunk->npages; ++i)
+ dma_free_coherent(&hr_dev->pdev->dev, chunk->mem[i].length,
+ lowmem_page_address(sg_page(&chunk->mem[i])),
+ sg_dma_address(&chunk->mem[i]));
+}
+
+void hns_roce_free_icm(struct hns_roce_dev *hr_dev, struct hns_roce_icm *icm,
+ int coherent)
+{
+ struct hns_roce_icm_chunk *chunk, *tmp;
+
+ if (!icm)
+ return;
+
+ list_for_each_entry_safe(chunk, tmp, &icm->chunk_list, list) {
+ if (coherent)
+ hns_roce_free_icm_coherent(hr_dev, chunk);
+ else
+ hns_roce_free_icm_pages(hr_dev, chunk);
+
+ kfree(chunk);
+ }
+
+ kfree(icm);
+}
+
+static int hns_roce_alloc_icm_pages(struct scatterlist *mem, int order,
+ gfp_t gfp_mask)
+{
+ struct page *page;
+
+ page = alloc_pages(gfp_mask, order);
+ if (!page)
+ return -ENOMEM;
+
+ sg_set_page(mem, page, PAGE_SIZE << order, 0);
+
+ return 0;
+}
+
+static int hns_roce_alloc_icm_coherent(struct device *dev,
+ struct scatterlist *mem, int order,
+ gfp_t gfp_mask)
+{
+ void *buf = dma_alloc_coherent(dev, PAGE_SIZE << order,
+ &sg_dma_address(mem), gfp_mask);
+ if (!buf) {
+ dev_err(dev, "alloc coherent icm pages failed.\n");
+ return -ENOMEM;
+ }
+
+ sg_set_buf(mem, buf, PAGE_SIZE << order);
+ WARN_ON(mem->offset);
+ sg_dma_len(mem) = PAGE_SIZE << order;
+ return 0;
+}
+
+struct hns_roce_icm *hns_roce_alloc_icm(struct hns_roce_dev *hr_dev, int npages,
+ gfp_t gfp_mask, int coherent)
+{
+ struct hns_roce_icm_chunk *chunk = NULL;
+ struct hns_roce_icm *icm;
+ int cur_order;
+ int ret;
+
+ WARN_ON(coherent && (gfp_mask & __GFP_HIGHMEM));
+
+ icm = kmalloc(sizeof(*icm),
+ gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
+ if (!icm)
+ return NULL;
+
+ icm->refcount = 0;
+ INIT_LIST_HEAD(&icm->chunk_list);
+
+ cur_order = get_order(HNS_ROCE_ICM_ALLOC_SIZE);
+
+ while (npages > 0) {
+ if (!chunk) {
+ chunk = kmalloc(sizeof(*chunk),
+ gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
+ if (!chunk)
+ goto fail;
+
+ sg_init_table(chunk->mem, HNS_ROCE_ICM_CHUNK_LEN);
+ chunk->npages = 0;
+ chunk->nsg = 0;
+ list_add_tail(&chunk->list, &icm->chunk_list);
+ }
+
+ while (1 << cur_order > npages)
+ --cur_order;
+
+ if (coherent)
+ ret = hns_roce_alloc_icm_coherent(&hr_dev->pdev->dev,
+ &chunk->mem[chunk->npages],
+ cur_order, gfp_mask);
+ else
+ ret = hns_roce_alloc_icm_pages(
+ &chunk->mem[chunk->npages],
+ cur_order, gfp_mask);
+ if (!ret) {
+ ++chunk->npages;
+ if (coherent) {
+ ++chunk->nsg;
+ } else if (chunk->npages == HNS_ROCE_ICM_CHUNK_LEN) {
+ chunk->nsg = dma_map_sg(&hr_dev->pdev->dev,
+ chunk->mem, chunk->npages,
+ (enum dma_data_direction)0);
+ if (chunk->nsg <= 0)
+ goto fail;
+
+ chunk = NULL;
+ }
+ npages -= 1 << cur_order;
+ } else {
+ /*
+ * If failed on alloc 128k memory one time,
+ * no alloc small block memory,
+ * directly return fail
+ */
+ dev_err(&hr_dev->pdev->dev, "**alloc 128K phy mem failed**\n");
+ goto fail;
+ }
+ }
+
+ if (!coherent && chunk) {
+ chunk->nsg = dma_map_sg(&hr_dev->pdev->dev, chunk->mem,
+ chunk->npages,
+ (enum dma_data_direction)0);
+ if (chunk->nsg <= 0)
+ goto fail;
+ }
+
+ return icm;
+
+fail:
+ hns_roce_free_icm(hr_dev, icm, coherent);
+ return NULL;
+}
+
+int hns_roce_map_icm(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int obj)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ spinlock_t *lock = &hr_dev->bt_cmd_lock;
+ unsigned long end = 0, flags = 0;
+ struct hns_roce_icm_iter iter;
+ void __iomem *bt_cmd = NULL;
+ u32 bt_cmd_h_val = 0;
+ u32 bt_cmd_val[2];
+ u32 bt_cmd_l = 0;
+ u64 bt_ba = 0;
+ int ret = 0;
+
+ /* Find the icm entry */
+ int i = (obj & (table->num_obj - 1)) / (HNS_ROCE_TABLE_CHUNK_SIZE /
+ table->obj_size);
+
+ switch (table->type) {
+ case ICM_TYPE_QPC:
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, ICM_TYPE_QPC);
+ break;
+ case ICM_TYPE_MTPT:
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
+ ICM_TYPE_MTPT);
+ break;
+ case ICM_TYPE_CQC:
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, ICM_TYPE_CQC);
+ break;
+ case ICM_TYPE_SRQC:
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
+ ICM_TYPE_SRQC);
+ break;
+ default:
+ return ret;
+ }
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
+ roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
+ roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
+
+ /* Currently iter only a chunk */
+ for (hns_roce_icm_first(table->icm[i], &iter);
+ !hns_roce_icm_last(&iter); hns_roce_icm_next(&iter)) {
+ bt_ba = hns_roce_icm_addr(&iter) >> DMA_ADDR_T_SHIFT;
+
+ spin_lock_irqsave(lock, flags);
+
+ bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
+
+ end = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies;
+ while (1) {
+ if (roce_readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) {
+ if (!(time_before(jiffies, end))) {
+ dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
+ spin_unlock_irqrestore(lock, flags);
+ ret = -EBUSY;
+ return ret;
+ }
+ } else {
+ break;
+ }
+ }
+
+ bt_cmd_l = (u32)bt_ba;
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S,
+ bt_ba >> BT_BA_SHIFT);
+
+ bt_cmd_val[0] = bt_cmd_l;
+ bt_cmd_val[1] = bt_cmd_h_val;
+ hns_roce_write64_k(bt_cmd_val,
+ hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
+ spin_unlock_irqrestore(lock, flags);
+ }
+
+ return ret;
+}
+
+int hns_roce_unmap_icm(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int obj)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ unsigned long end = 0, flags = 0;
+ void __iomem *bt_cmd = NULL;
+ uint32_t bt_cmd_val[2];
+ u32 bt_cmd_h_val = 0;
+ int ret = 0;
+
+ switch (table->type) {
+ case ICM_TYPE_QPC:
+ dev_dbg(dev, "UNMAP QPC BT :\n");
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, ICM_TYPE_QPC);
+ break;
+ case ICM_TYPE_MTPT:
+ dev_dbg(dev, "UNMAP MTPT BT :\n");
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
+ ICM_TYPE_MTPT);
+ break;
+ case ICM_TYPE_CQC:
+ dev_dbg(dev, "UNMAP CQC BT :\n");
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, ICM_TYPE_CQC);
+ break;
+ case ICM_TYPE_SRQC:
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
+ ICM_TYPE_SRQC);
+ break;
+ default:
+ return ret;
+ }
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
+ roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 1);
+ roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
+ roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
+ ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S, 0);
+
+ spin_lock_irqsave(&hr_dev->bt_cmd_lock, flags);
+
+ bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
+
+ end = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies;
+ while (1) {
+ if (roce_readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) {
+ if (!(time_before(jiffies, end))) {
+ dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
+ spin_unlock_irqrestore(&hr_dev->bt_cmd_lock,
+ flags);
+ return -EBUSY;
+ }
+ } else {
+ break;
+ }
+ }
+
+ bt_cmd_val[0] = 0;
+ bt_cmd_val[1] = bt_cmd_h_val;
+ hns_roce_write64_k(bt_cmd_val, hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
+ spin_unlock_irqrestore(&hr_dev->bt_cmd_lock, flags);
+
+ return ret;
+}
+
+int hns_roce_table_get(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int obj)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ int ret = 0;
+ int i;
+
+ i = (obj & (table->num_obj - 1)) / (HNS_ROCE_TABLE_CHUNK_SIZE /
+ table->obj_size);
+
+ mutex_lock(&table->mutex);
+
+ if (table->icm[i]) {
+ ++table->icm[i]->refcount;
+ goto out;
+ }
+
+ table->icm[i] = hns_roce_alloc_icm(hr_dev,
+ HNS_ROCE_TABLE_CHUNK_SIZE >> PAGE_SHIFT,
+ (table->lowmem ? GFP_KERNEL :
+ GFP_HIGHUSER) | __GFP_NOWARN,
+ table->coherent);
+ if (!table->icm[i]) {
+ ret = -ENOMEM;
+ dev_err(dev, "hns_roce_alloc_icm failed\n");
+ goto out;
+ }
+
+ /* Inform icm entry mem pa(128K/page, pa starting address)for hw */
+ if (hns_roce_map_icm(hr_dev, table, obj)) {
+ ret = -ENODEV;
+ dev_err(dev, "map icm table failed.\n");
+ goto out;
+ }
+
+ ++table->icm[i]->refcount;
+out:
+ mutex_unlock(&table->mutex);
+ return ret;
+}
+
+void hns_roce_table_put(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int obj)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ int i;
+
+ i = (obj & (table->num_obj - 1)) /
+ (HNS_ROCE_TABLE_CHUNK_SIZE / table->obj_size);
+
+ mutex_lock(&table->mutex);
+
+ if (--table->icm[i]->refcount == 0) {
+ /* Clear base address table */
+ if (hns_roce_unmap_icm(hr_dev, table, obj))
+ dev_warn(dev, "unmap icm table failed.\n");
+
+ hns_roce_free_icm(hr_dev, table->icm[i], table->coherent);
+ table->icm[i] = NULL;
+ }
+
+ mutex_unlock(&table->mutex);
+}
+
+void *hns_roce_table_find(struct hns_roce_icm_table *table, int obj,
+ dma_addr_t *dma_handle)
+{
+ struct hns_roce_icm_chunk *chunk;
+ int idx, i;
+ int offset, dma_offset;
+ struct hns_roce_icm *icm;
+ struct page *page = NULL;
+
+ if (!table->lowmem)
+ return NULL;
+
+ mutex_lock(&table->mutex);
+ idx = (obj & (table->num_obj - 1)) * table->obj_size;
+ icm = table->icm[idx / HNS_ROCE_TABLE_CHUNK_SIZE];
+ dma_offset = offset = idx % HNS_ROCE_TABLE_CHUNK_SIZE;
+
+ if (!icm)
+ goto out;
+
+ list_for_each_entry(chunk, &icm->chunk_list, list) {
+ for (i = 0; i < chunk->npages; ++i) {
+ if (dma_handle && dma_offset >= 0) {
+ if (sg_dma_len(&chunk->mem[i]) >
+ (u32)dma_offset)
+ *dma_handle = sg_dma_address(
+ &chunk->mem[i]) + dma_offset;
+ dma_offset -= sg_dma_len(&chunk->mem[i]);
+ }
+
+ if (chunk->mem[i].length > (u32)offset) {
+ page = sg_page(&chunk->mem[i]);
+ goto out;
+ }
+ offset -= chunk->mem[i].length;
+ }
+ }
+
+out:
+ mutex_unlock(&table->mutex);
+ return page ? lowmem_page_address(page) + offset : NULL;
+}
+
+int hns_roce_table_get_range(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int start,
+ int end)
+{
+ int inc = HNS_ROCE_TABLE_CHUNK_SIZE / table->obj_size;
+ int i = 0, ret = 0;
+
+ /* Allocate MTT entry memory according to chunk(128K) */
+ for (i = start; i <= end; i += inc) {
+ ret = hns_roce_table_get(hr_dev, table, i);
+ if (ret)
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ while (i > start) {
+ i -= inc;
+ hns_roce_table_put(hr_dev, table, i);
+ }
+ return ret;
+}
+
+void hns_roce_table_put_range(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int start,
+ int end)
+{
+ int i;
+
+ for (i = start; i <= end;
+ i += HNS_ROCE_TABLE_CHUNK_SIZE / table->obj_size)
+ hns_roce_table_put(hr_dev, table, i);
+}
+
+int hns_roce_init_icm_table(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, u32 type,
+ int obj_size, int nobj, int reserved,
+ int use_lowmem, int use_coherent)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 chunk_size;
+ int obj_per_chunk;
+ int num_icm;
+ int i;
+
+ obj_per_chunk = HNS_ROCE_TABLE_CHUNK_SIZE / obj_size;
+ num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk;
+
+ table->icm = kcalloc(num_icm, sizeof(*table->icm), GFP_KERNEL);
+ if (!table->icm)
+ return -ENOMEM;
+
+ table->type = type;
+ table->num_icm = num_icm;
+ table->num_obj = nobj;
+ table->obj_size = obj_size;
+ table->lowmem = use_lowmem;
+ table->coherent = use_coherent;
+ mutex_init(&table->mutex);
+
+ for (i = 0;
+ i * HNS_ROCE_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) {
+ chunk_size = HNS_ROCE_TABLE_CHUNK_SIZE;
+ if ((i + 1) * HNS_ROCE_TABLE_CHUNK_SIZE > nobj * obj_size)
+ chunk_size = PAGE_ALIGN(nobj * obj_size -
+ i * HNS_ROCE_TABLE_CHUNK_SIZE);
+
+ table->icm[i] = hns_roce_alloc_icm(hr_dev,
+ chunk_size >> PAGE_SHIFT, (use_lowmem ?
+ GFP_KERNEL : GFP_HIGHUSER) | __GFP_NOWARN,
+ use_coherent);
+ if (!table->icm[i])
+ goto _error_failed_alloc_icm;
+
+ if (hns_roce_map_icm(hr_dev, table,
+ i * HNS_ROCE_TABLE_CHUNK_SIZE / obj_size)) {
+ dev_err(dev, "map icm table failed.\n");
+ goto _error_failed_map_icm;
+ }
+
+ /*
+ * Add a reference to this ICM chunk so that it never
+ * Gets freed (since it contains reserved firmware objects).
+ */
+ ++table->icm[i]->refcount;
+ }
+
+ return 0;
+
+_error_failed_map_icm:
+_error_failed_alloc_icm:
+ for (i = 0; i < num_icm; ++i)
+ if (table->icm[i]) {
+ if (hns_roce_unmap_icm(hr_dev, table,
+ i * HNS_ROCE_TABLE_CHUNK_SIZE / obj_size))
+ dev_err(dev, "unmap icm table failed.\n");
+
+ hns_roce_free_icm(hr_dev, table->icm[i], use_coherent);
+ }
+
+ return -ENOMEM;
+}
+
+void hns_roce_cleanup_icm_table(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ int i;
+
+ for (i = 0; i < table->num_icm; ++i)
+ if (table->icm[i]) {
+ if (hns_roce_unmap_icm(hr_dev, table,
+ i * HNS_ROCE_TABLE_CHUNK_SIZE / table->obj_size))
+ dev_err(dev, "unmap icm table failed.\n");
+
+ hns_roce_free_icm(hr_dev, table->icm[i],
+ table->coherent);
+ }
+
+ kfree(table->icm);
+}
+
+void hns_roce_cleanup_icm(struct hns_roce_dev *hr_dev)
+{
+ hns_roce_cleanup_icm_table(hr_dev, &hr_dev->cq_table.table);
+ hns_roce_cleanup_icm_table(hr_dev, &hr_dev->qp_table.irrl_table);
+ hns_roce_cleanup_icm_table(hr_dev, &hr_dev->qp_table.qp_table);
+ hns_roce_cleanup_icm_table(hr_dev, &hr_dev->mr_table.mtpt_table);
+ hns_roce_cleanup_icm_table(hr_dev, &hr_dev->mr_table.mtt_table);
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.h b/drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.h
new file mode 100644
index 0000000..6007463
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _HNS_ROCE_ICM_H
+#define _HNS_ROCE_ICM_H
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+
+enum {
+ /* MAP ICM */
+ ICM_TYPE_QPC = 0,
+ ICM_TYPE_MTPT,
+ ICM_TYPE_CQC,
+ ICM_TYPE_SRQC,
+
+ /* UNMAP ICM */
+ ICM_TYPE_MTT,
+ ICM_TYPE_IRRL,
+};
+
+#define HNS_ROCE_ICM_CHUNK_LEN \
+ ((256 - sizeof(struct list_head) - 2 * sizeof(int)) / \
+ (sizeof(struct scatterlist)))
+
+enum {
+ HNS_ROCE_ICM_PAGE_SHIFT = 12,
+ HNS_ROCE_ICM_PAGE_SIZE = 1 << HNS_ROCE_ICM_PAGE_SHIFT,
+};
+
+struct hns_roce_icm_chunk {
+ struct list_head list;
+ int npages;
+ int nsg;
+ struct scatterlist mem[HNS_ROCE_ICM_CHUNK_LEN];
+};
+
+struct hns_roce_icm {
+ struct list_head chunk_list;
+ int refcount;
+};
+
+struct hns_roce_icm_iter {
+ struct hns_roce_icm *icm;
+ struct hns_roce_icm_chunk *chunk;
+ int page_idx;
+};
+
+void hns_roce_free_icm(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm *icm, int coherent);
+int hns_roce_table_get(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int obj);
+void hns_roce_table_put(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int obj);
+void *hns_roce_table_find(struct hns_roce_icm_table *table, int obj,
+ dma_addr_t *dma_handle);
+int hns_roce_table_get_range(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int start,
+ int end);
+void hns_roce_table_put_range(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, int start,
+ int end);
+int hns_roce_init_icm_table(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table, u32 type,
+ int obj_size, int nobj, int reserved,
+ int use_lowmem, int use_coherent);
+void hns_roce_cleanup_icm_table(struct hns_roce_dev *hr_dev,
+ struct hns_roce_icm_table *table);
+void hns_roce_cleanup_icm(struct hns_roce_dev *hr_dev);
+
+static inline void hns_roce_icm_first(struct hns_roce_icm *icm,
+ struct hns_roce_icm_iter *iter)
+{
+ iter->icm = icm;
+ iter->chunk = list_empty(&icm->chunk_list) ? NULL :
+ list_entry(icm->chunk_list.next,
+ struct hns_roce_icm_chunk, list);
+ iter->page_idx = 0;
+}
+
+static inline int hns_roce_icm_last(struct hns_roce_icm_iter *iter)
+{
+ return !iter->chunk;
+}
+
+static inline void hns_roce_icm_next(struct hns_roce_icm_iter *iter)
+{
+ if (++iter->page_idx >= iter->chunk->nsg) {
+ if (iter->chunk->list.next == &iter->icm->chunk_list) {
+ iter->chunk = NULL;
+ return;
+ }
+
+ iter->chunk = list_entry(iter->chunk->list.next,
+ struct hns_roce_icm_chunk, list);
+ iter->page_idx = 0;
+ }
+}
+
+static inline dma_addr_t hns_roce_icm_addr(struct hns_roce_icm_iter *iter)
+{
+ return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
+}
+
+#endif /*_HNS_ROCE_ICM_H*/
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_main.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_main.c
new file mode 100644
index 0000000..3674911
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_main.c
@@ -0,0 +1,1097 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * Authors: Wei Hu <xavier.huwei-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
+ * Authors: Znlong <zhaonenglong-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
+ * Authors: oulijun <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/cdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_umem.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_verbs.h>
+#include "hns_roce_common.h"
+#include "hns_roce_device.h"
+#include "hns_roce_user.h"
+#include "hns_roce_icm.h"
+
+/**
+ * hns_roce_addrconf_ifid_eui48 - Get default gid.
+ * @eui: eui.
+ * @vlan_id: gid
+ * @dev: net device
+ * Description:
+ * MAC convert to GID
+ * gid[0..7] = fe80 0000 0000 0000
+ * gid[8] = mac[0] ^ 2
+ * gid[9] = mac[1]
+ * gid[10] = mac[2]
+ * gid[11] = ff (VLAN ID high byte (4 MS bits))
+ * gid[12] = fe (VLAN ID low byte)
+ * gid[13] = mac[3]
+ * gid[14] = mac[4]
+ * gid[15] = mac[5]
+ */
+static void hns_roce_addrconf_ifid_eui48(u8 *eui, u16 vlan_id,
+ struct net_device *dev)
+{
+ memcpy(eui, dev->dev_addr, 3);
+ memcpy(eui + 5, dev->dev_addr + 3, 3);
+ if (vlan_id < 0x1000) {
+ eui[3] = vlan_id >> 8;
+ eui[4] = vlan_id & 0xff;
+ } else {
+ eui[3] = 0xff;
+ eui[4] = 0xfe;
+ }
+ eui[0] ^= 2;
+}
+
+void hns_roce_make_default_gid(struct net_device *dev, union ib_gid *gid)
+{
+ gid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
+ hns_roce_addrconf_ifid_eui48(&gid->raw[8], 0xffff, dev);
+}
+
+/**
+ * hns_get_gid_index - Get gid index.
+ * @hr_dev: pointer to structure hns_roce_dev.
+ * @port: port, value range: 0 ~ MAX
+ * @gid_index: gid_index, value range: 0 ~ MAX
+ * Description:
+ * N ports shared gids, allocation method as follow:
+ * GID[0][0], GID[1][0],.....GID[N - 1][0],
+ * GID[0][0], GID[1][0],.....GID[N - 1][0],
+ * And so on
+ */
+int hns_get_gid_index(struct hns_roce_dev *hr_dev, u8 port, int gid_index)
+{
+ return gid_index * hr_dev->caps.num_ports + port;
+}
+
+int hns_roce_set_gid(struct hns_roce_dev *hr_dev, u8 port, int gid_index,
+ union ib_gid *gid)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ u8 gid_idx = 0;
+
+ if (gid_index >= hr_dev->caps.gid_table_len[port]) {
+ dev_err(dev, "gid_index %d illegal, port %d gid range: 0~%d\n",
+ gid_index, port, hr_dev->caps.gid_table_len[port] - 1);
+ return -EINVAL;
+ }
+
+ gid_idx = hns_get_gid_index(hr_dev, port, gid_index);
+
+ if (!memcmp(gid, &hr_dev->iboe.gid_table[gid_idx], sizeof(*gid)))
+ return -EINVAL;
+
+ memcpy(&hr_dev->iboe.gid_table[gid_idx], gid, sizeof(*gid));
+
+ hr_dev->hw->set_gid(hr_dev, port, gid_index, gid);
+
+ return 0;
+}
+
+void hns_roce_set_mac(struct hns_roce_dev *hr_dev, u8 port, u8 *addr)
+{
+ u8 phy_port;
+ u32 i = 0;
+
+ if (!memcmp(hr_dev->dev_addr[port], addr, MAC_ADDR_OCTET_NUM))
+ return;
+
+ for (i = 0; i < MAC_ADDR_OCTET_NUM; i++)
+ hr_dev->dev_addr[port][i] = addr[i];
+
+ phy_port = hr_dev->iboe.phy_port[port];
+ hr_dev->hw->set_mac(hr_dev, phy_port, addr);
+}
+
+void hns_roce_set_mtu(struct hns_roce_dev *hr_dev, u8 port, int mtu)
+{
+ u8 phy_port = hr_dev->iboe.phy_port[port];
+ enum ib_mtu tmp;
+
+ tmp = iboe_get_mtu(mtu);
+ if (!tmp)
+ tmp = IB_MTU_256;
+
+ hr_dev->hw->set_mtu(hr_dev, phy_port, tmp);
+}
+
+void hns_roce_update_gids(struct hns_roce_dev *hr_dev, int port)
+{
+ struct ib_event event;
+
+ /* Refresh gid in ib_cache */
+ event.device = &hr_dev->ib_dev;
+ event.element.port_num = port + 1;
+ event.event = IB_EVENT_GID_CHANGE;
+ ib_dispatch_event(&event);
+}
+
+static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
+ unsigned long event)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct net_device *netdev;
+ unsigned long flags;
+ union ib_gid gid;
+ int ret = 0;
+
+ netdev = hr_dev->iboe.netdevs[port];
+ if (!netdev) {
+ dev_err(dev, "port(%d) can't find netdev\n", port);
+ return -ENODEV;
+ }
+
+ spin_lock_irqsave(&hr_dev->iboe.lock, flags);
+
+ switch (event) {
+ case NETDEV_UP:
+ case NETDEV_CHANGE:
+ case NETDEV_REGISTER:
+ case NETDEV_CHANGEADDR:
+ hns_roce_set_mac(hr_dev, port, netdev->dev_addr);
+ hns_roce_make_default_gid(netdev, &gid);
+ ret = hns_roce_set_gid(hr_dev, port, 0, &gid);
+ if (!ret)
+ hns_roce_update_gids(hr_dev, port);
+ break;
+ case NETDEV_DOWN:
+ /*
+ * In v1 engine, only support all ports closed together.
+ */
+ break;
+ default:
+ dev_dbg(dev, "NETDEV event = 0x%x!\n", (u32)(event));
+ break;
+ }
+
+ spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
+ return ret;
+}
+
+static int hns_roce_netdev_event(struct notifier_block *self,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct hns_roce_ib_iboe *iboe = NULL;
+ struct hns_roce_dev *hr_dev = NULL;
+ u8 port = 0;
+
+ hr_dev = container_of(self, struct hns_roce_dev, iboe.nb);
+ iboe = &hr_dev->iboe;
+
+ for (port = 0; port < hr_dev->caps.num_ports; port++) {
+ if (dev == iboe->netdevs[port]) {
+ (void)handle_en_event(hr_dev, port, event);
+ break;
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static void hns_roce_addr_event(int event, struct net_device *event_netdev,
+ struct hns_roce_dev *hr_dev, union ib_gid *gid)
+{
+ struct hns_roce_ib_iboe *iboe = NULL;
+ int gid_table_len = 0;
+ unsigned long flags;
+ union ib_gid zgid;
+ u8 gid_idx = 0;
+ u8 port = 0;
+ int i = 0;
+ int free;
+ struct net_device *real_dev = rdma_vlan_dev_real_dev(event_netdev) ?
+ rdma_vlan_dev_real_dev(event_netdev) :
+ event_netdev;
+
+ if (event != NETDEV_UP && event != NETDEV_DOWN)
+ return;
+
+ iboe = &hr_dev->iboe;
+ while (port < hr_dev->caps.num_ports) {
+ if (real_dev == iboe->netdevs[port])
+ break;
+ port++;
+ }
+
+ if (port >= hr_dev->caps.num_ports) {
+ dev_dbg(&hr_dev->pdev->dev, "can't find netdev\n");
+ return;
+ }
+
+ memset(zgid.raw, 0, sizeof(zgid.raw));
+ free = -1;
+ gid_table_len = hr_dev->caps.gid_table_len[port];
+
+ spin_lock_irqsave(&hr_dev->iboe.lock, flags);
+
+ for (i = 0; i < gid_table_len; i++) {
+ gid_idx = hns_get_gid_index(hr_dev, port, i);
+ if (!memcmp(gid->raw, iboe->gid_table[gid_idx].raw,
+ sizeof(gid->raw)))
+ break;
+ if (free < 0 && !memcmp(zgid.raw,
+ iboe->gid_table[gid_idx].raw, sizeof(zgid.raw)))
+ free = i;
+ }
+
+ if (i >= gid_table_len) {
+ if (free < 0) {
+ spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
+ dev_dbg(&hr_dev->pdev->dev,
+ "gid_index overflow, port(%d)\n", port);
+ return;
+ }
+ if (!hns_roce_set_gid(hr_dev, port, free, gid))
+ hns_roce_update_gids(hr_dev, port);
+ } else if (event == NETDEV_DOWN) {
+ if (!hns_roce_set_gid(hr_dev, port, i, &zgid))
+ hns_roce_update_gids(hr_dev, port);
+ }
+
+ spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
+}
+
+static int hns_roce_inet_event(struct notifier_block *self, unsigned long event,
+ void *ptr)
+{
+ struct in_ifaddr *ifa = ptr;
+ struct hns_roce_dev *hr_dev;
+ struct net_device *dev = ifa->ifa_dev->dev;
+ union ib_gid gid;
+
+ ipv6_addr_set_v4mapped(ifa->ifa_address, (struct in6_addr *)&gid);
+
+ hr_dev = container_of(self, struct hns_roce_dev, iboe.nb_inet);
+
+ hns_roce_addr_event(event, dev, hr_dev, &gid);
+
+ return NOTIFY_DONE;
+}
+
+int hns_roce_setup_mtu_gids(struct hns_roce_dev *hr_dev)
+{
+ struct in_ifaddr *ifa_list = NULL;
+ union ib_gid gid = {{0} };
+ u32 ipaddr = 0;
+ int index = 0;
+ u8 i = 0;
+
+ for (i = 0; i < hr_dev->caps.num_ports; i++) {
+ hns_roce_set_mtu(hr_dev, i,
+ ib_mtu_enum_to_int(hr_dev->caps.max_mtu));
+ hns_roce_set_mac(hr_dev, i, hr_dev->iboe.netdevs[i]->dev_addr);
+
+ if (hr_dev->iboe.netdevs[i]->ip_ptr) {
+ ifa_list = hr_dev->iboe.netdevs[i]->ip_ptr->ifa_list;
+ index = 1;
+ while (ifa_list) {
+ ipaddr = ifa_list->ifa_address;
+ ipv6_addr_set_v4mapped(ipaddr,
+ (struct in6_addr *)&gid);
+ (void)hns_roce_set_gid(hr_dev, i, index, &gid);
+ index++;
+ ifa_list = ifa_list->ifa_next;
+ }
+ hns_roce_update_gids(hr_dev, i);
+ }
+ }
+
+ return 0;
+}
+
+static int hns_roce_query_device(struct ib_device *ib_dev,
+ struct ib_device_attr *props,
+ struct ib_udata *uhw)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
+
+ memset(props, 0, sizeof(*props));
+
+ props->fw_ver = hr_dev->fw_ver;
+ props->sys_image_guid = hr_dev->sys_image_guid;
+ props->max_mr_size = (u64)(~(0ULL));
+ props->page_size_cap = hr_dev->caps.page_size_cap;
+ props->vendor_id = hr_dev->vendor_id;
+ props->vendor_part_id = hr_dev->vendor_part_id;
+ props->hw_ver = hr_dev->hw_rev;
+ props->max_qp = hr_dev->caps.num_qps;
+ props->max_qp_wr = hr_dev->caps.max_wqes;
+ props->device_cap_flags = (int)(IB_DEVICE_PORT_ACTIVE_EVENT) |
+ (int)(IB_DEVICE_RC_RNR_NAK_GEN) |
+ (int)(IB_DEVICE_LOCAL_DMA_LKEY);
+ props->max_sge = hr_dev->caps.max_sq_sg;
+ props->max_sge_rd = 1;
+ props->max_cq = hr_dev->caps.num_cqs;
+ props->max_cqe = hr_dev->caps.max_cqes;
+ props->max_mr = hr_dev->caps.num_mtpts;
+ props->max_pd = hr_dev->caps.num_pds;
+ props->max_qp_rd_atom = hr_dev->caps.max_qp_dest_rdma;
+ props->max_ee_rd_atom = 0;
+ props->max_res_rd_atom = 0;
+ props->max_qp_init_rd_atom = hr_dev->caps.max_qp_init_rdma;
+ props->max_ee_init_rd_atom = 0;
+ props->atomic_cap = IB_ATOMIC_NONE;
+ props->max_ee = 0;
+ props->max_rdd = 0;
+ props->max_mw = 0;
+ props->max_raw_ipv6_qp = 0;
+ props->max_raw_ethy_qp = 0;
+ props->max_mcast_grp = 0;
+ props->max_mcast_qp_attach = 0;
+ props->max_total_mcast_qp_attach = 0;
+ props->max_ah = 0;
+ props->max_fmr = 0;
+ props->max_map_per_fmr = 0;
+ props->max_srq = 0;
+ props->max_srq_wr = 0;
+ props->max_srq_sge = 0;
+ props->max_fast_reg_page_list_len = 0;
+ props->max_pkeys = 1;
+ props->local_ca_ack_delay = hr_dev->caps.local_ca_ack_delay;
+
+ return 0;
+}
+
+static int hns_roce_query_port(struct ib_device *ib_dev, u8 port_num,
+ struct ib_port_attr *props)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct net_device *net_dev;
+ unsigned long flags;
+ enum ib_mtu mtu;
+ u8 port;
+
+ assert(port_num > 0);
+ port = port_num - 1;
+
+ memset(props, 0, sizeof(*props));
+
+ props->max_mtu = hr_dev->caps.max_mtu;
+ props->gid_tbl_len = hr_dev->caps.gid_table_len[port];
+ props->port_cap_flags = (int)(IB_PORT_CM_SUP) |
+ (int)(IB_PORT_REINIT_SUP) |
+ (int)(IB_PORT_VENDOR_CLASS_SUP) |
+ (int)(IB_PORT_BOOT_MGMT_SUP);
+ props->max_msg_sz = HNS_ROCE_MAX_MSG_LEN;
+ props->bad_pkey_cntr = 0;
+ props->qkey_viol_cntr = 0;
+ props->pkey_tbl_len = 1;
+ props->lid = 0;
+ props->sm_lid = 0;
+ props->lmc = 0;
+ props->max_vl_num = 0;
+ props->sm_sl = 0;
+ props->subnet_timeout = 0;
+ props->init_type_reply = 0;
+ props->active_width = IB_WIDTH_4X;
+ props->active_speed = 1;
+
+ spin_lock_irqsave(&hr_dev->iboe.lock, flags);
+
+ net_dev = hr_dev->iboe.netdevs[port];
+ if (!net_dev) {
+ spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
+ dev_err(dev, "find netdev %d failed!\r\n", port);
+ return -EINVAL;
+ }
+
+ mtu = iboe_get_mtu(net_dev->mtu);
+ props->active_mtu = mtu ? min(props->max_mtu, mtu) : IB_MTU_256;
+ props->state = (netif_running(net_dev) && netif_carrier_ok(net_dev)) ?
+ IB_PORT_ACTIVE : IB_PORT_DOWN;
+ props->phys_state = (props->state == IB_PORT_ACTIVE) ? 5 : 3;
+
+ spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
+
+ return 0;
+}
+
+static enum rdma_link_layer hns_roce_get_link_layer(struct ib_device *device,
+ u8 port_num)
+{
+ return IB_LINK_LAYER_ETHERNET;
+}
+
+static int hns_roce_query_gid(struct ib_device *ib_dev, u8 port_num, int index,
+ union ib_gid *gid)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
+ struct device *dev = &hr_dev->pdev->dev;
+ u8 gid_idx = 0;
+ u8 port;
+
+ if (port_num < 1 || port_num > hr_dev->caps.num_ports ||
+ index >= hr_dev->caps.gid_table_len[port_num-1]) {
+ dev_err(dev,
+ "port_num %d index %d illegal! correct range: port_num 1~%d index 0~%d!\n",
+ port_num, index, hr_dev->caps.num_ports,
+ hr_dev->caps.gid_table_len[port_num-1] - 1);
+ return -EINVAL;
+ }
+
+ port = port_num - 1;
+ gid_idx = hns_get_gid_index(hr_dev, port, index);
+ if (gid_idx >= HNS_ROCE_MAX_GID_NUM) {
+ dev_err(dev, "port_num %d index %d illegal! total gid num %d!\n",
+ port_num, index, HNS_ROCE_MAX_GID_NUM);
+ return -EINVAL;
+ }
+
+ memcpy(gid->raw, hr_dev->iboe.gid_table[gid_idx].raw,
+ HNS_ROCE_GID_SIZE);
+
+ return 0;
+}
+
+static int hns_roce_query_pkey(struct ib_device *ib_dev, u8 port, u16 index,
+ u16 *pkey)
+{
+ *pkey = PKEY_ID;
+
+ return 0;
+}
+
+static int hns_roce_modify_device(struct ib_device *ib_dev, int mask,
+ struct ib_device_modify *props)
+{
+ unsigned long flags;
+
+ if (mask & ~IB_DEVICE_MODIFY_NODE_DESC)
+ return -EOPNOTSUPP;
+
+ if (mask & IB_DEVICE_MODIFY_NODE_DESC) {
+ spin_lock_irqsave(&to_hr_dev(ib_dev)->sm_lock, flags);
+ memcpy(ib_dev->node_desc, props->node_desc, NODE_DESC_SIZE);
+ spin_unlock_irqrestore(&to_hr_dev(ib_dev)->sm_lock, flags);
+ }
+
+ return 0;
+}
+
+static int hns_roce_modify_port(struct ib_device *ib_dev, u8 port_num, int mask,
+ struct ib_port_modify *props)
+{
+ return 0;
+}
+
+static struct ib_ucontext *hns_roce_alloc_ucontext(struct ib_device *ib_dev,
+ struct ib_udata *udata)
+{
+ int ret = 0;
+ struct hns_roce_ucontext *context;
+ struct hns_roce_ib_alloc_ucontext_resp resp;
+ struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
+
+ resp.qp_tab_size = hr_dev->caps.num_qps;
+
+ context = kmalloc(sizeof(*context), GFP_KERNEL);
+ if (!context)
+ return ERR_PTR(-ENOMEM);
+
+ ret = hns_roce_uar_alloc(hr_dev, &context->uar);
+ if (ret) {
+ kfree(context);
+ return ERR_PTR(ret);
+ }
+
+ ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
+ if (ret) {
+ kfree(context);
+ return ERR_PTR(-EFAULT);
+ }
+
+ return &context->ibucontext;
+}
+
+static int hns_roce_dealloc_ucontext(struct ib_ucontext *ibcontext)
+{
+ struct hns_roce_ucontext *context = to_hr_ucontext(ibcontext);
+
+ hns_roce_uar_free(to_hr_dev(ibcontext->device), &context->uar);
+ kfree(context);
+
+ return 0;
+}
+
+static int hns_roce_mmap(struct ib_ucontext *context,
+ struct vm_area_struct *vma)
+{
+ if (((vma->vm_end - vma->vm_start) % PAGE_SIZE) != 0)
+ return -EINVAL;
+
+ if (vma->vm_pgoff == 0) {
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (io_remap_pfn_range(vma, vma->vm_start,
+ to_hr_ucontext(context)->uar.pfn,
+ PAGE_SIZE, vma->vm_page_prot))
+ return -EAGAIN;
+
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void hns_roce_unregister_device(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_ib_iboe *iboe = &hr_dev->iboe;
+
+ (void)unregister_inetaddr_notifier(&iboe->nb_inet);
+ (void)unregister_netdevice_notifier(&iboe->nb);
+ ib_unregister_device(&hr_dev->ib_dev);
+}
+
+int hns_roce_register_device(struct hns_roce_dev *hr_dev)
+{
+ int ret;
+ struct hns_roce_ib_iboe *iboe = NULL;
+ struct ib_device *ib_dev = NULL;
+ struct device *dev = &hr_dev->pdev->dev;
+
+ iboe = &hr_dev->iboe;
+
+ ib_dev = &hr_dev->ib_dev;
+ strlcpy(ib_dev->name, "hisi_%d", IB_DEVICE_NAME_MAX);
+
+ ib_dev->owner = THIS_MODULE;
+ ib_dev->node_type = RDMA_NODE_IB_CA;
+ ib_dev->dma_device = dev;
+
+ ib_dev->phys_port_cnt = hr_dev->caps.num_ports;
+ ib_dev->local_dma_lkey = hr_dev->caps.reserved_lkey;
+ ib_dev->num_comp_vectors = hr_dev->caps.num_comp_vectors;
+ ib_dev->uverbs_abi_ver = 1;
+ ib_dev->uverbs_cmd_mask =
+ (1ULL << IB_USER_VERBS_CMD_GET_CONTEXT) |
+ (1ULL << IB_USER_VERBS_CMD_QUERY_DEVICE) |
+ (1ULL << IB_USER_VERBS_CMD_QUERY_PORT) |
+ (1ULL << IB_USER_VERBS_CMD_ALLOC_PD) |
+ (1ULL << IB_USER_VERBS_CMD_DEALLOC_PD) |
+ (1ULL << IB_USER_VERBS_CMD_REG_MR) |
+ (1ULL << IB_USER_VERBS_CMD_DEREG_MR) |
+ (1ULL << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
+ (1ULL << IB_USER_VERBS_CMD_CREATE_CQ) |
+ (1ULL << IB_USER_VERBS_CMD_DESTROY_CQ) |
+ (1ULL << IB_USER_VERBS_CMD_CREATE_QP) |
+ (1ULL << IB_USER_VERBS_CMD_MODIFY_QP) |
+ (1ULL << IB_USER_VERBS_CMD_QUERY_QP) |
+ (1ULL << IB_USER_VERBS_CMD_DESTROY_QP);
+
+ /* HCA||device||port */
+ ib_dev->modify_device = hns_roce_modify_device;
+ ib_dev->query_device = hns_roce_query_device;
+ ib_dev->query_port = hns_roce_query_port;
+ ib_dev->modify_port = hns_roce_modify_port;
+ ib_dev->get_link_layer = hns_roce_get_link_layer;
+ ib_dev->query_gid = hns_roce_query_gid;
+ ib_dev->query_pkey = hns_roce_query_pkey;
+ ib_dev->alloc_ucontext = hns_roce_alloc_ucontext;
+ ib_dev->dealloc_ucontext = hns_roce_dealloc_ucontext;
+ ib_dev->mmap = hns_roce_mmap;
+
+ /* PD */
+ ib_dev->alloc_pd = hns_roce_alloc_pd;
+ ib_dev->dealloc_pd = hns_roce_dealloc_pd;
+
+ /* AH */
+ ib_dev->create_ah = hns_roce_create_ah;
+ ib_dev->query_ah = hns_roce_query_ah;
+ ib_dev->destroy_ah = hns_roce_destroy_ah;
+
+ /* QP */
+ ib_dev->create_qp = hns_roce_create_qp;
+ ib_dev->modify_qp = hns_roce_modify_qp;
+ ib_dev->query_qp = hr_dev->hw->query_qp;
+ ib_dev->destroy_qp = hr_dev->hw->destroy_qp;
+ ib_dev->post_send = hr_dev->hw->post_send;
+ ib_dev->post_recv = hr_dev->hw->post_recv;
+
+ /* CQ */
+ ib_dev->create_cq = hns_roce_ib_create_cq;
+ ib_dev->destroy_cq = hns_roce_ib_destroy_cq;
+ ib_dev->req_notify_cq = hr_dev->hw->req_notify_cq;
+ ib_dev->poll_cq = hr_dev->hw->poll_cq;
+
+ /* MR */
+ ib_dev->get_dma_mr = hns_roce_get_dma_mr;
+ ib_dev->reg_user_mr = hns_roce_reg_user_mr;
+ ib_dev->dereg_mr = hns_roce_dereg_mr;
+
+ ret = ib_register_device(ib_dev, NULL);
+ if (ret) {
+ dev_err(dev, "ib_register_device failed!\n");
+ return ret;
+ }
+
+ ret = hns_roce_setup_mtu_gids(hr_dev);
+ if (ret) {
+ dev_err(dev, "roce_setup_mtu_gids failed!\n");
+ goto _error_failed_setup_mtu_gids;
+ }
+
+ spin_lock_init(&iboe->lock);
+
+ iboe->nb.notifier_call = hns_roce_netdev_event;
+ ret = register_netdevice_notifier(&iboe->nb);
+ if (ret) {
+ dev_err(dev, "register_netdevice_notifier failed!\n");
+ goto _error_failed_register_netdevice_notifier;
+ }
+
+ iboe->nb_inet.notifier_call = hns_roce_inet_event;
+ ret = register_inetaddr_notifier(&iboe->nb_inet);
+ if (ret) {
+ dev_err(dev, "register inet addr notifier failed!\n");
+ goto _error_failed_register_inetaddr_notifier;
+ }
+
+ return 0;
+
+_error_failed_register_inetaddr_notifier:
+ (void)unregister_netdevice_notifier(&iboe->nb);
+
+_error_failed_register_netdevice_notifier:
+_error_failed_setup_mtu_gids:
+ ib_unregister_device(ib_dev);
+
+ return ret;
+}
+
+int hns_roce_get_cfg(struct hns_roce_dev *hr_dev)
+{
+ int i;
+ int ret = 0;
+ u8 phy_port;
+ int port_cnt = 0;
+ struct device *dev = &hr_dev->pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *net_node;
+ struct net_device *netdev = NULL;
+ struct platform_device *pdev = NULL;
+
+ if (of_device_is_compatible(np, "hisilicon,hns-roce-v1")) {
+ hr_dev->ver = ROCE_VERSION_1;
+ hr_dev->hw = &hns_roce_v1_hw;
+ } else {
+ dev_err(dev, "device no compatible!\n");
+ return -EINVAL;
+ }
+
+ hr_dev->reg_base = of_iomap(np, 0);
+ if (!hr_dev->reg_base) {
+ dev_err(dev, "of_iomap failed!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < HNS_ROCE_MAX_PORTS; i++) {
+ net_node = of_parse_phandle(np, "eth-handle", i);
+ if (net_node) {
+ pdev = of_find_device_by_node(net_node);
+ netdev = platform_get_drvdata(pdev);
+ phy_port = (u8)i;
+ if (netdev) {
+ hr_dev->iboe.netdevs[port_cnt] = netdev;
+ hr_dev->iboe.phy_port[port_cnt] = phy_port;
+ } else {
+ ret = -ENODEV;
+ goto unmap_base_addr;
+ }
+ port_cnt++;
+ }
+ }
+
+ hr_dev->caps.num_ports = port_cnt;
+
+ /* Cmd issue mode: 0 is poll, 1 is event */
+ hr_dev->cmd_mod = 1;
+ hr_dev->loop_idc = 0;
+
+ for (i = 0; i < HNS_ROCE_MAX_IRQ_NUM; i++) {
+ hr_dev->irq[i] = platform_get_irq(hr_dev->pdev, i);
+ if (hr_dev->irq[i] <= 0) {
+ dev_err(dev, "Get No.%d irq resource failed!\n", i);
+ ret = -EINVAL;
+ goto unmap_base_addr;
+ }
+ }
+
+ return 0;
+
+unmap_base_addr:
+ if (hr_dev->reg_base)
+ iounmap(hr_dev->reg_base);
+
+ return ret;
+}
+
+void hns_roce_free_cfg(struct hns_roce_dev *hr_dev)
+{
+ if (hr_dev->reg_base)
+ iounmap(hr_dev->reg_base);
+}
+
+int hns_roce_engine_reset(struct hns_roce_dev *hr_dev, u32 val)
+{
+ return hr_dev->hw->reset(hr_dev, val);
+}
+
+void hns_roce_profile_init(struct hns_roce_dev *hr_dev)
+{
+ hr_dev->hw->hw_profile(hr_dev);
+}
+
+int hns_roce_init_icm(struct hns_roce_dev *hr_dev)
+{
+ int ret;
+ struct device *dev = &hr_dev->pdev->dev;
+
+ ret = hns_roce_init_icm_table(hr_dev,
+ (void *)&hr_dev->mr_table.mtt_table,
+ ICM_TYPE_MTT, hr_dev->caps.mtt_entry_sz,
+ hr_dev->caps.num_mtt_segs, 0, 1, 0);
+ if (ret) {
+ dev_err(dev, "Failed to map MTT context memory, aborting.\n");
+ return ret;
+ }
+
+ ret = hns_roce_init_icm_table(hr_dev,
+ (void *)&hr_dev->mr_table.mtpt_table,
+ ICM_TYPE_MTPT, hr_dev->caps.mtpt_entry_sz,
+ hr_dev->caps.num_mtpts, 0, 1, 1);
+ if (ret) {
+ dev_err(dev, "Failed to map dMPT context memory, aborting.\n");
+ goto err_unmap_mtt;
+ }
+
+ ret = hns_roce_init_icm_table(hr_dev,
+ (void *)&hr_dev->qp_table.qp_table,
+ ICM_TYPE_QPC, hr_dev->caps.qpc_entry_sz,
+ hr_dev->caps.num_qps, 0, 1, 0);
+ if (ret) {
+ dev_err(dev, "Failed to map QP context memory, aborting.\n");
+ goto err_unmap_dmpt;
+ }
+
+ ret = hns_roce_init_icm_table(hr_dev,
+ (void *)&hr_dev->qp_table.irrl_table,
+ ICM_TYPE_IRRL,
+ hr_dev->caps.irrl_entry_sz *
+ hr_dev->caps.max_qp_init_rdma,
+ hr_dev->caps.num_qps, 0, 1, 0);
+ if (ret) {
+ dev_err(dev, "Failed to map irrl_table memory, aborting.\n");
+ goto err_unmap_qp;
+ }
+
+ ret = hns_roce_init_icm_table(hr_dev,
+ (void *)&hr_dev->cq_table.table,
+ ICM_TYPE_CQC, hr_dev->caps.cqc_entry_sz,
+ hr_dev->caps.num_cqs, 0, 1, 0);
+ if (ret) {
+ dev_err(dev, "Failed to map CQ context memory, aborting.\n");
+ goto err_unmap_irrl;
+ }
+
+ return 0;
+
+err_unmap_irrl:
+ hns_roce_cleanup_icm_table(hr_dev,
+ (void *)&hr_dev->qp_table.irrl_table);
+
+err_unmap_qp:
+ hns_roce_cleanup_icm_table(hr_dev, (void *)&hr_dev->qp_table.qp_table);
+
+err_unmap_dmpt:
+ hns_roce_cleanup_icm_table(hr_dev,
+ (void *)&hr_dev->mr_table.mtpt_table);
+
+err_unmap_mtt:
+ hns_roce_cleanup_icm_table(hr_dev, (void *)&hr_dev->mr_table.mtt_table);
+
+ return ret;
+}
+
+int hns_roce_engine_init(struct hns_roce_dev *hr_dev)
+{
+ return hr_dev->hw->hw_init(hr_dev);
+}
+
+void hns_roce_engine_uninit(struct hns_roce_dev *hr_dev)
+{
+ hr_dev->hw->hw_uninit(hr_dev);
+}
+
+/**
+* hns_roce_setup_hca - setup host channel adapter
+* @hr_dev: pointer to hns roce device
+* Return : int
+*/
+int hns_roce_setup_hca(struct hns_roce_dev *hr_dev)
+{
+ int ret;
+ struct device *dev = &hr_dev->pdev->dev;
+
+ spin_lock_init(&hr_dev->sm_lock);
+ spin_lock_init(&hr_dev->cq_db_lock);
+ spin_lock_init(&hr_dev->bt_cmd_lock);
+
+ ret = hns_roce_init_uar_table(hr_dev);
+ if (ret) {
+ dev_err(dev, "Failed to initialize uar table. aborting\n");
+ return ret;
+ }
+
+ ret = hns_roce_uar_alloc(hr_dev, &hr_dev->priv_uar);
+ if (ret) {
+ dev_err(dev, "Failed to allocate priv_uar.\n");
+ goto err_uar_table_free;
+ }
+
+ ret = hns_roce_init_pd_table(hr_dev);
+ if (ret) {
+ dev_err(dev, "Failed to init protected domain table.\n");
+ goto err_uar_alloc_free;
+ }
+
+ ret = hns_roce_init_mr_table(hr_dev);
+ if (ret) {
+ dev_err(dev, "Failed to init memory region table.\n");
+ goto err_pd_table_free;
+ }
+
+ ret = hns_roce_init_cq_table(hr_dev);
+ if (ret) {
+ dev_err(dev, "Failed to init completion queue table.\n");
+ goto err_mr_table_free;
+ }
+
+ ret = hns_roce_init_qp_table(hr_dev);
+ if (ret) {
+ dev_err(dev, "Failed to init queue pair table.\n");
+ goto err_cq_table_free;
+ }
+
+ return 0;
+
+err_cq_table_free:
+ hns_roce_cleanup_cq_table(hr_dev);
+
+err_mr_table_free:
+ hns_roce_cleanup_mr_table(hr_dev);
+
+err_pd_table_free:
+ hns_roce_cleanup_pd_table(hr_dev);
+
+err_uar_alloc_free:
+ hns_roce_uar_free(hr_dev, &hr_dev->priv_uar);
+
+err_uar_table_free:
+ hns_roce_cleanup_uar_table(hr_dev);
+ return ret;
+}
+
+/**
+* hns_roce_probe - RoCE driver entrance
+* @pdev: pointer to platform device
+* Return : int
+*
+*/
+int hns_roce_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct hns_roce_dev *hr_dev;
+ struct device *dev = &pdev->dev;
+
+ hr_dev = (struct hns_roce_dev *)ib_alloc_device(sizeof(*hr_dev));
+ if (!hr_dev) {
+ dev_err(dev, "Device struct alloc failed, aborting.\n");
+ return -ENOMEM;
+ }
+
+ memset((void *)hr_dev + sizeof(struct ib_device), 0,
+ sizeof(struct hns_roce_dev) - sizeof(struct ib_device));
+
+ hr_dev->pdev = pdev;
+ platform_set_drvdata(pdev, hr_dev);
+
+ if (!dma_set_mask_and_coherent(dev, (u64)DMA_BIT_MASK(64ULL)))
+ dev_info(dev, "set mask to 64bit\n");
+ else
+ dev_err(dev, "set mask to 64bit fail!\n");
+
+ ret = hns_roce_get_cfg(hr_dev);
+ if (ret) {
+ dev_err(dev, "Get Configuration failed!\n");
+ goto error_failed_get_cfg;
+ }
+
+ ret = hns_roce_engine_reset(hr_dev, 1);
+ if (ret) {
+ dev_err(dev, "Reset roce engine failed!\n");
+ goto error_failed_reset_engine;
+ }
+
+ hns_roce_profile_init(hr_dev);
+
+ ret = hns_roce_cmd_init(hr_dev);
+ if (ret) {
+ dev_err(dev, "cmd init failed!\n");
+ goto error_failed_cmd_init;
+ }
+
+ ret = hns_roce_init_eq_table(hr_dev);
+ if (ret) {
+ dev_err(dev, "eq init failed!\n");
+ goto error_failed_eq_tabel;
+ }
+
+ if (hr_dev->cmd_mod) {
+ ret = hns_roce_cmd_use_events(hr_dev);
+ if (ret) {
+ dev_err(dev, "Switch to event-driven cmd failed!\n");
+ goto error_failed_use_event;
+ }
+ }
+
+ ret = hns_roce_init_icm(hr_dev);
+ if (ret) {
+ dev_err(dev, "init icm fail!\n");
+ goto error_failed_init_icm;
+ }
+
+ ret = hns_roce_setup_hca(hr_dev);
+ if (ret) {
+ dev_err(dev, "setup hca fail!\n");
+ goto error_failed_setup_hca;
+ }
+
+ ret = hns_roce_engine_init(hr_dev);
+ if (ret) {
+ dev_err(dev, "hw_init failed!\n");
+ goto error_failed_engine_init;
+ }
+
+ ret = hns_roce_register_device(hr_dev);
+ if (ret) {
+ dev_err(dev, "register_device failed!\n");
+ goto error_failed_register_device;
+ }
+
+ return 0;
+
+error_failed_register_device:
+ hns_roce_engine_uninit(hr_dev);
+
+error_failed_engine_init:
+ hns_roce_cleanup_bitmap(hr_dev);
+
+error_failed_setup_hca:
+ hns_roce_cleanup_icm(hr_dev);
+
+error_failed_init_icm:
+ if (hr_dev->cmd_mod)
+ hns_roce_cmd_use_polling(hr_dev);
+
+error_failed_use_event:
+ hns_roce_cleanup_eq_table(hr_dev);
+
+error_failed_eq_tabel:
+ hns_roce_cmd_cleanup(hr_dev);
+
+error_failed_cmd_init:
+ (void)hns_roce_engine_reset(hr_dev, 0);
+
+error_failed_reset_engine:
+ hns_roce_free_cfg(hr_dev);
+
+error_failed_get_cfg:
+ ib_dealloc_device(&hr_dev->ib_dev);
+ return ret;
+}
+
+/**
+* hns_roce_remove - remove roce device
+* @pdev: pointer to platform device
+*/
+int hns_roce_remove(struct platform_device *pdev)
+{
+ struct hns_roce_dev *hr_dev = platform_get_drvdata(pdev);
+
+ hns_roce_unregister_device(hr_dev);
+ hns_roce_engine_uninit(hr_dev);
+ hns_roce_cleanup_bitmap(hr_dev);
+ hns_roce_cleanup_icm(hr_dev);
+
+ if (hr_dev->cmd_mod)
+ hns_roce_cmd_use_polling(hr_dev);
+
+ hns_roce_cleanup_eq_table(hr_dev);
+ hns_roce_cmd_cleanup(hr_dev);
+
+ (void)hns_roce_engine_reset(hr_dev, 0);
+ hns_roce_free_cfg(hr_dev);
+ ib_dealloc_device(&hr_dev->ib_dev);
+
+ return 0;
+}
+
+static const struct of_device_id hns_roce_of_match[] = {
+ { .compatible = "hisilicon,hns-roce-v1",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, hns_roce_of_match);
+
+static struct platform_driver hns_roce_driver = {
+ .probe = hns_roce_probe,
+ .remove = hns_roce_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .of_match_table = hns_roce_of_match,
+ },
+};
+
+module_platform_driver(hns_roce_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Wei Hu <xavier.huwei-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>");
+MODULE_AUTHOR("Znlong <zhaonenglong-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>");
+MODULE_AUTHOR("oulijun <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("HISILICON RoCE driver");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_mr.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_mr.c
new file mode 100644
index 0000000..d1ed54a
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_mr.c
@@ -0,0 +1,605 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include "hns_roce_common.h"
+#include "hns_roce_device.h"
+#include "hns_roce_cmd.h"
+#include "hns_roce_icm.h"
+
+static u32 hw_index_to_key(u32 ind)
+{
+ return (ind >> 24) | (ind << 8);
+}
+
+static u32 key_to_hw_index(u32 key)
+{
+ return (key << 24) | (key >> 8);
+}
+
+static int hns_roce_sw2hw_mpt(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cmd_mailbox *mailbox,
+ int mpt_index)
+{
+ return hns_roce_cmd(hr_dev, mailbox->dma, mpt_index, 0,
+ HNS_ROCE_CMD_SW2HW_MPT, HNS_ROCE_CMD_TIME_CLASS_B);
+}
+
+static int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cmd_mailbox *mailbox,
+ int mpt_index)
+{
+ return hns_roce_cmd_box(hr_dev, 0, mailbox ? mailbox->dma : 0,
+ mpt_index, !mailbox, HNS_ROCE_CMD_HW2SW_MPT,
+ HNS_ROCE_CMD_TIME_CLASS_B);
+}
+
+static int hns_roce_buddy_alloc(struct hns_roce_buddy *buddy, int order,
+ u32 *seg)
+{
+ int o;
+ u32 m;
+
+ spin_lock(&buddy->lock);
+
+ for (o = order; o <= buddy->max_order; ++o) {
+ if (buddy->num_free[o]) {
+ m = 1 << (buddy->max_order - o);
+ *seg = find_first_bit(buddy->bits[o], m);
+ if (*seg < m)
+ goto found;
+ }
+ }
+ spin_unlock(&buddy->lock);
+ return -1;
+
+ found:
+ clear_bit(*seg, buddy->bits[o]);
+ --buddy->num_free[o];
+
+ while (o > order) {
+ --o;
+ *seg <<= 1;
+ set_bit(*seg ^ 1, buddy->bits[o]);
+ ++buddy->num_free[o];
+ }
+
+ spin_unlock(&buddy->lock);
+
+ *seg <<= order;
+ return 0;
+}
+
+static void hns_roce_buddy_free(struct hns_roce_buddy *buddy, u32 seg,
+ int order)
+{
+ seg >>= order;
+
+ spin_lock(&buddy->lock);
+
+ while (test_bit(seg ^ 1, buddy->bits[order])) {
+ clear_bit(seg ^ 1, buddy->bits[order]);
+ --buddy->num_free[order];
+ seg >>= 1;
+ ++order;
+ }
+
+ set_bit(seg, buddy->bits[order]);
+ ++buddy->num_free[order];
+
+ spin_unlock(&buddy->lock);
+}
+
+static int hns_roce_buddy_init(struct hns_roce_buddy *buddy, int max_order)
+{
+ int i, s;
+
+ buddy->max_order = max_order;
+ spin_lock_init(&buddy->lock);
+
+ buddy->bits = kzalloc((buddy->max_order + 1) * sizeof(long *),
+ GFP_KERNEL);
+ buddy->num_free = kzalloc((buddy->max_order + 1) * sizeof(int *),
+ GFP_KERNEL);
+ if (!buddy->bits || !buddy->num_free)
+ goto err_out;
+
+ for (i = 0; i <= buddy->max_order; ++i) {
+ s = BITS_TO_LONGS(1 << (buddy->max_order - i));
+ buddy->bits[i] = kmalloc_array(s, sizeof(long), GFP_KERNEL);
+ if (!buddy->bits[i])
+ goto err_out_free;
+
+ bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i));
+ }
+
+ set_bit(0, buddy->bits[buddy->max_order]);
+ buddy->num_free[buddy->max_order] = 1;
+
+ return 0;
+
+err_out_free:
+ for (i = 0; i <= buddy->max_order; ++i)
+ kfree(buddy->bits[i]);
+
+err_out:
+ kfree(buddy->bits);
+ kfree(buddy->num_free);
+ return -ENOMEM;
+}
+
+static void hns_roce_buddy_cleanup(struct hns_roce_buddy *buddy)
+{
+ int i;
+
+ for (i = 0; i <= buddy->max_order; ++i)
+ kfree(buddy->bits[i]);
+
+ kfree(buddy->bits);
+ kfree(buddy->num_free);
+}
+
+static int hns_roce_alloc_mtt_range(struct hns_roce_dev *hr_dev, int order,
+ u32 *seg)
+{
+ struct hns_roce_mr_table *mr_table = &hr_dev->mr_table;
+ int ret = 0;
+
+ ret = hns_roce_buddy_alloc(&mr_table->mtt_buddy, order, seg);
+ if (ret == -1)
+ return -1;
+
+ if (hns_roce_table_get_range(hr_dev, &mr_table->mtt_table, *seg,
+ *seg + (1 << order) - 1)) {
+ hns_roce_buddy_free(&mr_table->mtt_buddy, *seg, order);
+ return -1;
+ }
+
+ return 0;
+}
+
+int hns_roce_mtt_init(struct hns_roce_dev *hr_dev, int npages, int page_shift,
+ struct hns_roce_mtt *mtt)
+{
+ int ret = 0;
+ int i;
+
+ /* Page num is zero, correspond to DMA memory register */
+ if (!npages) {
+ mtt->order = -1;
+ mtt->page_shift = HNS_ROCE_ICM_PAGE_SHIFT;
+ return 0;
+ }
+
+ /* Note: if page_shift is zero, FAST memory regsiter */
+ mtt->page_shift = page_shift;
+
+ /* Compute MTT entry necessary */
+ for (mtt->order = 0, i = HNS_ROCE_MTT_ENTRY_PER_SEG; i < npages;
+ i <<= 1)
+ ++mtt->order;
+
+ /* Allocate MTT entry */
+ ret = hns_roce_alloc_mtt_range(hr_dev, mtt->order, &mtt->first_seg);
+ if (ret == -1)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void hns_roce_mtt_cleanup(struct hns_roce_dev *hr_dev, struct hns_roce_mtt *mtt)
+{
+ struct hns_roce_mr_table *mr_table = &hr_dev->mr_table;
+
+ if (mtt->order < 0)
+ return;
+
+ hns_roce_buddy_free(&mr_table->mtt_buddy, mtt->first_seg, mtt->order);
+ hns_roce_table_put_range(hr_dev, &mr_table->mtt_table, mtt->first_seg,
+ mtt->first_seg + (1 << mtt->order) - 1);
+}
+
+u64 hns_roce_mtt_addr(struct hns_roce_dev *hr_dev, struct hns_roce_mtt *mtt)
+{
+ return (u64) mtt->first_seg * hr_dev->caps.mtt_entry_sz;
+}
+
+int hns_roce_mr_alloc(struct hns_roce_dev *hr_dev, u32 pd, u64 iova, u64 size,
+ u32 access, int npages, struct hns_roce_mr *mr)
+{
+ u32 index = 0;
+ int ret = 0;
+ struct device *dev = &hr_dev->pdev->dev;
+
+ /* Allocate a key for mr from mr_table */
+ ret = hns_roce_bitmap_alloc(&hr_dev->mr_table.mtpt_bitmap, &index);
+ if (ret == -1)
+ return -ENOMEM;
+
+ mr->iova = iova; /* MR va starting addr */
+ mr->size = size; /* MR addr range */
+ mr->pd = pd; /* MR num */
+ mr->access = access; /* MR access permit */
+ mr->enabled = 0; /* MR active status */
+ mr->key = hw_index_to_key(index); /* MR key */
+
+ if (size == ~0ull) {
+ mr->type = MR_TYPE_DMA;
+ mr->pbl_buf = NULL;
+ mr->pbl_dma_addr = 0;
+ } else {
+ mr->type = MR_TYPE_MR;
+ mr->pbl_buf = dma_alloc_coherent(dev, npages * 8,
+ &(mr->pbl_dma_addr),
+ GFP_KERNEL);
+ if (!mr->pbl_buf) {
+ dev_err(dev, "alloc coherent pbl pages failed.\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+void hns_roce_mr_free(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ int ret;
+
+ if (mr->enabled) {
+ ret = hns_roce_hw2sw_mpt(hr_dev, NULL, key_to_hw_index(mr->key)
+ & (hr_dev->caps.num_mtpts - 1));
+ if (ret)
+ dev_warn(dev, "HW2SW_MPT failed (%d)\n", ret);
+ }
+
+ hns_roce_bitmap_free(&hr_dev->mr_table.mtpt_bitmap,
+ key_to_hw_index(mr->key));
+}
+
+int hns_roce_mr_enable(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr)
+{
+ int ret;
+ int mtpt_idx = key_to_hw_index(mr->key);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_cmd_mailbox *mailbox;
+ struct hns_roce_mr_table *mr_table = &hr_dev->mr_table;
+
+ /* Prepare ICM entry memory */
+ ret = hns_roce_table_get(hr_dev, &mr_table->mtpt_table, mtpt_idx);
+ if (ret)
+ return ret;
+
+ /* Applicate mailbox memory */
+ mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
+ if (IS_ERR(mailbox)) {
+ ret = PTR_ERR(mailbox);
+ goto err_table;
+ }
+
+ ret = hr_dev->hw->write_mtpt(mailbox->buf, mr, mtpt_idx);
+ if (ret) {
+ dev_err(dev, "Write mtpt fail!\n");
+ goto err_page;
+ }
+
+ ret = hns_roce_sw2hw_mpt(hr_dev, mailbox,
+ mtpt_idx & (hr_dev->caps.num_mtpts - 1));
+ if (ret) {
+ dev_err(dev, "SW2HW_MPT failed (%d)\n", ret);
+ goto err_cmd;
+ }
+
+ mr->enabled = 1;
+ hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+
+ return 0;
+
+err_cmd:
+err_page:
+ hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+
+err_table:
+ hns_roce_table_put(hr_dev, &mr_table->mtpt_table, mtpt_idx);
+ return ret;
+}
+
+static int hns_roce_write_mtt_chunk(struct hns_roce_dev *hr_dev,
+ struct hns_roce_mtt *mtt, u32 start_index,
+ u32 npages, u64 *page_list)
+{
+ u32 i = 0;
+ __le64 *mtts = NULL;
+ dma_addr_t dma_handle;
+ u32 s = start_index * sizeof(u64);
+
+ /* All MTTs must fit in the same page */
+ if (start_index / (PAGE_SIZE / sizeof(u64)) !=
+ (start_index + npages - 1) / (PAGE_SIZE / sizeof(u64)))
+ return -EINVAL;
+
+ if (start_index & (HNS_ROCE_MTT_ENTRY_PER_SEG - 1))
+ return -EINVAL;
+
+ mtts = hns_roce_table_find(&hr_dev->mr_table.mtt_table,
+ mtt->first_seg + s / hr_dev->caps.mtt_entry_sz,
+ &dma_handle);
+ if (!mtts)
+ return -ENOMEM;
+
+ /* Save page addr, low 12 bits : 0 */
+ for (i = 0; i < npages; ++i)
+ mtts[i] = (cpu_to_le64(page_list[i])) >> PAGE_ADDR_SHIFT;
+
+ return 0;
+}
+
+int hns_roce_write_mtt(struct hns_roce_dev *hr_dev, struct hns_roce_mtt *mtt,
+ u32 start_index, u32 npages, u64 *page_list)
+{
+ int chunk;
+ int ret;
+
+ if (mtt->order < 0)
+ return -EINVAL;
+
+ while (npages > 0) {
+ chunk = min_t(int, PAGE_SIZE / sizeof(u64), npages);
+
+ ret = hns_roce_write_mtt_chunk(hr_dev, mtt, start_index, chunk,
+ page_list);
+ if (ret)
+ return ret;
+
+ npages -= chunk;
+ start_index += chunk;
+ page_list += chunk;
+ }
+
+ return 0;
+}
+
+int hns_roce_buf_write_mtt(struct hns_roce_dev *hr_dev,
+ struct hns_roce_mtt *mtt, struct hns_roce_buf *buf)
+{
+ u32 i = 0;
+ int ret = 0;
+ u64 *page_list = NULL;
+
+ page_list = kmalloc_array(buf->npages, sizeof(*page_list), GFP_KERNEL);
+ if (!page_list)
+ return -ENOMEM;
+
+ for (i = 0; i < buf->npages; ++i) {
+ if (buf->nbufs == 1)
+ page_list[i] = buf->direct.map + (i << buf->page_shift);
+ else
+ page_list[i] = buf->page_list[i].map;
+
+ }
+ ret = hns_roce_write_mtt(hr_dev, mtt, 0, buf->npages, page_list);
+
+ kfree(page_list);
+
+ return ret;
+}
+
+int hns_roce_init_mr_table(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_mr_table *mr_table = &hr_dev->mr_table;
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 first_seg;
+ int ret = 0;
+
+ ret = hns_roce_bitmap_init(&mr_table->mtpt_bitmap,
+ hr_dev->caps.num_mtpts,
+ hr_dev->caps.num_mtpts - 1,
+ hr_dev->caps.reserved_mrws, 0);
+ if (ret)
+ return ret;
+
+ ret = hns_roce_buddy_init(&mr_table->mtt_buddy,
+ ilog2(hr_dev->caps.num_mtt_segs));
+ if (ret)
+ goto err_buddy;
+
+ if (hr_dev->caps.reserved_mtts) {
+ if (hns_roce_alloc_mtt_range(hr_dev,
+ fls(hr_dev->caps.reserved_mtts - 1),
+ &first_seg) == -1) {
+ dev_err(dev, "MTT table of order %d is too small.\n",
+ mr_table->mtt_buddy.max_order);
+ ret = -ENOMEM;
+ goto err_reserve_mtts;
+ }
+ }
+
+ return 0;
+
+err_reserve_mtts:
+ hns_roce_buddy_cleanup(&mr_table->mtt_buddy);
+
+err_buddy:
+ hns_roce_bitmap_cleanup(&mr_table->mtpt_bitmap);
+ return ret;
+}
+
+void hns_roce_cleanup_mr_table(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_mr_table *mr_table = &hr_dev->mr_table;
+
+ hns_roce_buddy_cleanup(&mr_table->mtt_buddy);
+ hns_roce_bitmap_cleanup(&mr_table->mtpt_bitmap);
+}
+
+struct ib_mr *hns_roce_get_dma_mr(struct ib_pd *pd, int acc)
+{
+ int ret = 0;
+ struct hns_roce_mr *mr = NULL;
+
+ mr = kmalloc(sizeof(*mr), GFP_KERNEL);
+ if (mr == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /* Allocate memory region key */
+ ret = hns_roce_mr_alloc(to_hr_dev(pd->device), to_hr_pd(pd)->pdn, 0,
+ ~0ULL, acc, 0, mr);
+ if (ret)
+ goto err_free;
+
+ ret = hns_roce_mr_enable(to_hr_dev(pd->device), mr);
+ if (ret)
+ goto err_mr;
+
+ mr->ibmr.rkey = mr->ibmr.lkey = mr->key;
+ mr->umem = NULL;
+
+ return &mr->ibmr;
+
+err_mr:
+ hns_roce_mr_free(to_hr_dev(pd->device), mr);
+
+err_free:
+ kfree(mr);
+ return ERR_PTR(ret);
+}
+
+int hns_roce_ib_umem_write_mtt(struct hns_roce_dev *hr_dev,
+ struct hns_roce_mtt *mtt, struct ib_umem *umem)
+{
+ struct scatterlist *sg;
+ int i, k, entry;
+ int ret = 0;
+ u64 *pages;
+ u32 n;
+ int len;
+
+ pages = (u64 *) __get_free_page(GFP_KERNEL);
+ if (!pages)
+ return -ENOMEM;
+
+ i = n = 0;
+
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) {
+ len = sg_dma_len(sg) >> mtt->page_shift;
+ for (k = 0; k < len; ++k) {
+ pages[i++] = sg_dma_address(sg) + umem->page_size * k;
+ if (i == PAGE_SIZE / sizeof(u64)) {
+ ret = hns_roce_write_mtt(hr_dev, mtt, n, i,
+ pages);
+ if (ret)
+ goto out;
+ n += i;
+ i = 0;
+ }
+ }
+ }
+
+ if (i)
+ ret = hns_roce_write_mtt(hr_dev, mtt, n, i, pages);
+
+out:
+ free_page((unsigned long) pages);
+ return ret;
+}
+
+static int hns_roce_ib_umem_write_mr(struct hns_roce_mr *mr,
+ struct ib_umem *umem)
+{
+ int i = 0;
+ int entry;
+ struct scatterlist *sg;
+
+ for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) {
+ mr->pbl_buf[i] = ((u64)sg_dma_address(sg)) >> 12;
+ i++;
+ }
+
+ /* Memory barrier */
+ mb();
+
+ return 0;
+}
+
+struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ u64 virt_addr, int access_flags,
+ struct ib_udata *udata)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_mr *mr = NULL;
+ int ret = 0;
+ int n = 0;
+
+ mr = kmalloc(sizeof(*mr), GFP_KERNEL);
+ if (!mr)
+ return ERR_PTR(-ENOMEM);
+
+ mr->umem = ib_umem_get(pd->uobject->context, start, length,
+ access_flags, 0);
+ if (IS_ERR(mr->umem)) {
+ ret = PTR_ERR(mr->umem);
+ goto err_free;
+ }
+
+ n = ib_umem_page_count(mr->umem);
+ if (mr->umem->page_size != HNS_ROCE_ICM_PAGE_SIZE) {
+ dev_err(dev, "Just support 4K page size but is 0x%x now!\n",
+ mr->umem->page_size);
+ }
+
+ if (n > HNS_ROCE_MAX_MTPT_PBL_NUM) {
+ dev_err(dev, " MR len %lld err. MR is limited to 4G at most!\n",
+ length);
+ goto err_free;
+ }
+
+ ret = hns_roce_mr_alloc(hr_dev, to_hr_pd(pd)->pdn, virt_addr, length,
+ access_flags, n, mr);
+ if (ret)
+ goto err_umem;
+
+ ret = hns_roce_ib_umem_write_mr(mr, mr->umem);
+ if (ret)
+ goto err_mr;
+
+ ret = hns_roce_mr_enable(hr_dev, mr);
+ if (ret)
+ goto err_mr;
+
+ mr->ibmr.rkey = mr->ibmr.lkey = mr->key;
+
+ return &mr->ibmr;
+
+err_mr:
+ hns_roce_mr_free(hr_dev, mr);
+
+err_umem:
+ ib_umem_release(mr->umem);
+
+err_free:
+ kfree(mr);
+ return ERR_PTR(ret);
+}
+
+int hns_roce_dereg_mr(struct ib_mr *ibmr)
+{
+ struct hns_roce_mr *mr = to_hr_mr(ibmr);
+
+ hns_roce_mr_free(to_hr_dev(ibmr->device), mr);
+ if (mr->umem)
+ ib_umem_release(mr->umem);
+
+ kfree(mr);
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_pd.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_pd.c
new file mode 100644
index 0000000..13ed3e4
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_pd.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <asm/page.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_umem.h>
+#include <rdma/ib_user_verbs.h>
+#include "hns_roce_common.h"
+#include "hns_roce_device.h"
+
+int hns_roce_pd_alloc(struct hns_roce_dev *hr_dev, u32 *pdn)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 pd_number;
+ int ret = 0;
+
+ ret = hns_roce_bitmap_alloc(&hr_dev->pd_bitmap, &pd_number);
+ if (ret == -1) {
+ dev_err(dev, "alloc pdn from pdbitmap failed\n");
+ return -ENOMEM;
+ }
+
+ *pdn = pd_number;
+
+ return 0;
+}
+
+void hns_roce_pd_free(struct hns_roce_dev *hr_dev, u32 pdn)
+{
+ hns_roce_bitmap_free(&hr_dev->pd_bitmap, pdn);
+}
+
+int hns_roce_init_pd_table(struct hns_roce_dev *hr_dev)
+{
+ return hns_roce_bitmap_init(&hr_dev->pd_bitmap, hr_dev->caps.num_pds,
+ hr_dev->caps.num_pds - 1,
+ hr_dev->caps.reserved_pds, 0);
+}
+
+void hns_roce_cleanup_pd_table(struct hns_roce_dev *hr_dev)
+{
+ hns_roce_bitmap_cleanup(&hr_dev->pd_bitmap);
+}
+
+struct ib_pd *hns_roce_alloc_pd(struct ib_device *ib_dev,
+ struct ib_ucontext *context,
+ struct ib_udata *udata)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_pd *pd;
+ int ret;
+
+ pd = kmalloc(sizeof(*pd), GFP_KERNEL);
+ if (!pd)
+ return ERR_PTR(-ENOMEM);
+
+ ret = hns_roce_pd_alloc(to_hr_dev(ib_dev), &pd->pdn);
+ if (ret) {
+ kfree(pd);
+ dev_err(dev, "[alloc_pd]hns_roce_pd_alloc failed!\n");
+ return ERR_PTR(ret);
+ }
+
+ if (context) {
+ if (ib_copy_to_udata(udata, &pd->pdn, sizeof(__u32))) {
+ hns_roce_pd_free(to_hr_dev(ib_dev), pd->pdn);
+ dev_err(dev, "[alloc_pd]ib_copy_to_udata failed!\n");
+ kfree(pd);
+ return ERR_PTR(-EFAULT);
+ }
+ }
+
+ return &pd->ibpd;
+}
+
+int hns_roce_dealloc_pd(struct ib_pd *pd)
+{
+ hns_roce_pd_free(to_hr_dev(pd->device), to_hr_pd(pd)->pdn);
+ kfree(to_hr_pd(pd));
+
+ return 0;
+}
+
+int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
+{
+ int ret = 0;
+ /* Using bitmap to manager UAR index */
+ ret = hns_roce_bitmap_alloc(&hr_dev->uar_table.bitmap, &uar->index);
+ if (ret == -1)
+ return -ENOMEM;
+
+ uar->index = (uar->index - 1) % hr_dev->caps.phy_num_uars + 1;
+ uar->pfn = (ROCE_DEV_IOBASE >> PAGE_SHIFT) + uar->index;
+
+ return 0;
+}
+
+void hns_roce_uar_free(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
+{
+ hns_roce_bitmap_free(&(hr_dev)->uar_table.bitmap, uar->index);
+}
+
+int hns_roce_init_uar_table(struct hns_roce_dev *hr_dev)
+{
+ return hns_roce_bitmap_init(&hr_dev->uar_table.bitmap,
+ hr_dev->caps.num_uars,
+ hr_dev->caps.num_uars - 1,
+ hr_dev->caps.reserved_uars, 0);
+}
+
+void hns_roce_cleanup_uar_table(struct hns_roce_dev *hr_dev)
+{
+ hns_roce_bitmap_cleanup(&hr_dev->uar_table.bitmap);
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_qp.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_qp.c
new file mode 100644
index 0000000..cda74be
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_qp.c
@@ -0,0 +1,841 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/log2.h>
+#include <linux/slab.h>
+#include <rdma/ib_cache.h>
+#include <rdma/ib_pack.h>
+#include "hns_roce_common.h"
+#include "hns_roce_device.h"
+#include "hns_roce_cmd.h"
+#include "hns_roce_icm.h"
+#include "hns_roce_user.h"
+
+#define DB_REG_OFFSET 0x1000
+#define SQP_NUM 12
+
+void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_qp *qp;
+
+ spin_lock(&qp_table->lock);
+
+ qp = __hns_roce_qp_lookup(hr_dev, qpn);
+ if (qp)
+ atomic_inc(&qp->refcount);
+
+ spin_unlock(&qp_table->lock);
+
+ if (!qp) {
+ dev_warn(dev, "Async event for bogus QP %08x\n", qpn);
+ return;
+ }
+
+ qp->event(qp, (enum hns_roce_event)event_type);
+
+ if (atomic_dec_and_test(&qp->refcount))
+ complete(&qp->free);
+}
+
+static void hns_roce_ib_qp_event(struct hns_roce_qp *hr_qp,
+ enum hns_roce_event type)
+{
+ struct ib_event event;
+ struct ib_qp *ibqp = &hr_qp->ibqp;
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct device *dev = &hr_dev->pdev->dev;
+
+ if (ibqp->event_handler) {
+ event.device = ibqp->device;
+ event.element.qp = ibqp;
+ switch (type) {
+ case HNS_ROCE_EVENT_TYPE_PATH_MIG:
+ event.event = IB_EVENT_PATH_MIG;
+ break;
+ case HNS_ROCE_EVENT_TYPE_COMM_EST:
+ event.event = IB_EVENT_COMM_EST;
+ break;
+ case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
+ event.event = IB_EVENT_SQ_DRAINED;
+ break;
+ case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH:
+ event.event = IB_EVENT_QP_LAST_WQE_REACHED;
+ break;
+ case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
+ event.event = IB_EVENT_QP_FATAL;
+ break;
+ case HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED:
+ event.event = IB_EVENT_PATH_MIG_ERR;
+ break;
+ case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
+ event.event = IB_EVENT_QP_REQ_ERR;
+ break;
+ case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
+ event.event = IB_EVENT_QP_ACCESS_ERR;
+ break;
+ default:
+ dev_dbg(dev, "roce_ib: Unexpected event type %d on QP %06x\n",
+ type, hr_qp->qpn);
+ return;
+ }
+
+ ibqp->event_handler(&event, ibqp->qp_context);
+ }
+}
+
+int hns_roce_reserve_range_qp(struct hns_roce_dev *hr_dev, int cnt, int align,
+ int *base)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+ int ret = 0;
+ u32 qpn;
+
+ ret = hns_roce_bitmap_alloc_range(&qp_table->bitmap, cnt, align, &qpn);
+ if (ret == -1)
+ return -ENOMEM;
+
+ *base = qpn;
+
+ return 0;
+}
+
+enum hns_roce_qp_state to_hns_roce_state(enum ib_qp_state state)
+{
+ switch (state) {
+ case IB_QPS_RESET:
+ return HNS_ROCE_QP_STATE_RST;
+ case IB_QPS_INIT:
+ return HNS_ROCE_QP_STATE_INIT;
+ case IB_QPS_RTR:
+ return HNS_ROCE_QP_STATE_RTR;
+ case IB_QPS_RTS:
+ return HNS_ROCE_QP_STATE_RTS;
+ case IB_QPS_SQD:
+ return HNS_ROCE_QP_STATE_SQD;
+ case IB_QPS_ERR:
+ return HNS_ROCE_QP_STATE_ERR;
+ default:
+ return HNS_ROCE_QP_NUM_STATE;
+ }
+}
+
+int hns_roce_gsi_qp_alloc(struct hns_roce_dev *hr_dev, int qpn,
+ struct hns_roce_qp *hr_qp)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+ int ret;
+
+ if (!qpn)
+ return -EINVAL;
+
+ hr_qp->qpn = qpn;
+
+ spin_lock_irq(&qp_table->lock);
+ ret = radix_tree_insert(&hr_dev->qp_table_tree,
+ hr_qp->qpn & (hr_dev->caps.num_qps - 1), hr_qp);
+ spin_unlock_irq(&qp_table->lock);
+ if (ret) {
+ dev_err(&hr_dev->pdev->dev, "QPC radix_tree_insert failed\n");
+ goto err_put_irrl;
+ }
+
+ atomic_set(&hr_qp->refcount, 1);
+ init_completion(&hr_qp->free);
+
+ return 0;
+
+err_put_irrl:
+
+ return ret;
+}
+
+int hns_roce_qp_alloc(struct hns_roce_dev *hr_dev, int qpn,
+ struct hns_roce_qp *hr_qp)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+ struct device *dev = &hr_dev->pdev->dev;
+ int ret;
+
+ if (!qpn)
+ return -EINVAL;
+
+ hr_qp->qpn = qpn;
+
+ /* Alloc memory for QPC */
+ ret = hns_roce_table_get(hr_dev, &qp_table->qp_table, hr_qp->qpn);
+ if (ret) {
+ dev_err(dev, "QPC table get failed\n");
+ goto err_out;
+ }
+
+ /* Alloc memory for IRRL */
+ ret = hns_roce_table_get(hr_dev, &qp_table->irrl_table, hr_qp->qpn);
+ if (ret) {
+ dev_err(dev, "IRRL table get failed\n");
+ goto err_put_qp;
+ }
+
+ spin_lock_irq(&qp_table->lock);
+ ret = radix_tree_insert(&hr_dev->qp_table_tree,
+ hr_qp->qpn & (hr_dev->caps.num_qps - 1), hr_qp);
+ spin_unlock_irq(&qp_table->lock);
+ if (ret) {
+ dev_err(dev, "QPC radix_tree_insert failed\n");
+ goto err_put_irrl;
+ }
+
+ atomic_set(&hr_qp->refcount, 1);
+ init_completion(&hr_qp->free);
+
+ return 0;
+
+err_put_irrl:
+ hns_roce_table_put(hr_dev, &qp_table->irrl_table, hr_qp->qpn);
+
+err_put_qp:
+ hns_roce_table_put(hr_dev, &qp_table->qp_table, hr_qp->qpn);
+
+err_out:
+ return ret;
+}
+
+void hns_roce_qp_remove(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+ unsigned long flags;
+
+ spin_lock_irqsave(&qp_table->lock, flags);
+ (void)radix_tree_delete(&hr_dev->qp_table_tree,
+ hr_qp->qpn & (hr_dev->caps.num_qps - 1));
+ spin_unlock_irqrestore(&qp_table->lock, flags);
+}
+
+void hns_roce_qp_free(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+
+ if (atomic_dec_and_test(&hr_qp->refcount))
+ complete(&hr_qp->free);
+ wait_for_completion(&hr_qp->free);
+
+ if ((hr_qp->ibqp.qp_type) != IB_QPT_GSI) {
+ hns_roce_table_put(hr_dev, &qp_table->irrl_table, hr_qp->qpn);
+ hns_roce_table_put(hr_dev, &qp_table->qp_table, hr_qp->qpn);
+ }
+}
+
+void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn,
+ int cnt)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+
+ if (base_qpn < (hr_dev->caps.sqp_start + 2 * hr_dev->caps.num_ports))
+ return;
+
+ hns_roce_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt);
+}
+
+int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap,
+ int is_user, int has_srq, struct hns_roce_qp *hr_qp)
+{
+ u32 max_cnt;
+ struct device *dev = &hr_dev->pdev->dev;
+
+ /* Check the validity of QP support capacity */
+ if (cap->max_recv_wr > hr_dev->caps.max_wqes ||
+ cap->max_recv_sge > hr_dev->caps.max_rq_sg) {
+ dev_err(dev, "RQ WR or sge error!max_recv_wr=%d max_recv_sge=%d\n",
+ cap->max_recv_wr, cap->max_recv_sge);
+ return -EINVAL;
+ }
+
+ /* If srq exit, set zero for relative number of rq */
+ if (has_srq) {
+ if (cap->max_recv_wr) {
+ dev_dbg(dev, "srq no need config max_recv_wr\n");
+ return -EINVAL;
+ }
+
+ hr_qp->rq.wqe_cnt = hr_qp->rq.max_gs = 0;
+ } else {
+ if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge)) {
+ dev_err(dev, "user space no need config max_recv_wr max_recv_sge\n");
+ return -EINVAL;
+ }
+
+ /* In v1 engine, parameter verification procession */
+ max_cnt = cap->max_recv_wr > HNS_ROCE_MIN_WQE_NUM ?
+ cap->max_recv_wr : HNS_ROCE_MIN_WQE_NUM;
+ hr_qp->rq.wqe_cnt = roundup_pow_of_two(max_cnt);
+
+ if ((u32)hr_qp->rq.wqe_cnt > hr_dev->caps.max_wqes) {
+ dev_err(dev, "hns_roce_set_rq_size rq.wqe_cnt too large\n");
+ return -EINVAL;
+ }
+
+ max_cnt = max(1U, cap->max_recv_sge);
+ hr_qp->rq.max_gs = roundup_pow_of_two(max_cnt);
+ /* WQE is fixed for 64B */
+ hr_qp->rq.wqe_shift = ilog2(hr_dev->caps.max_rq_desc_sz);
+ }
+
+ cap->max_recv_wr = hr_qp->rq.max_post = hr_qp->rq.wqe_cnt;
+ cap->max_recv_sge = hr_qp->rq.max_gs;
+
+ return 0;
+}
+
+int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
+ struct hns_roce_qp *hr_qp,
+ struct hns_roce_ib_create_qp *ucmd)
+{
+ u32 roundup_sq_stride = roundup_pow_of_two(hr_dev->caps.max_sq_desc_sz);
+ u8 max_sq_stride = ilog2(roundup_sq_stride);
+
+ /* Sanity check SQ size before proceeding */
+ if ((u32)(1 << ucmd->log_sq_bb_count) > hr_dev->caps.max_wqes ||
+ ucmd->log_sq_stride > max_sq_stride ||
+ ucmd->log_sq_stride < HNS_ROCE_IB_MIN_SQ_STRIDE) {
+ dev_err(&hr_dev->pdev->dev, "check SQ size error!\n");
+ return -EINVAL;
+ }
+
+ hr_qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count;
+ hr_qp->sq.wqe_shift = ucmd->log_sq_stride;
+
+ /* Get buf size, SQ and RQ are aligned to page_szie */
+ hr_qp->buff_size = HNS_ROCE_ALOGN_UP((hr_qp->rq.wqe_cnt <<
+ hr_qp->rq.wqe_shift), PAGE_SIZE) +
+ HNS_ROCE_ALOGN_UP((hr_qp->sq.wqe_cnt <<
+ hr_qp->sq.wqe_shift), PAGE_SIZE);
+
+ hr_qp->sq.offset = 0;
+ hr_qp->rq.offset = HNS_ROCE_ALOGN_UP((hr_qp->sq.wqe_cnt <<
+ hr_qp->sq.wqe_shift), PAGE_SIZE);
+
+ return 0;
+}
+
+int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev,
+ struct ib_qp_cap *cap, enum ib_qp_type type,
+ struct hns_roce_qp *hr_qp)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ u32 max_cnt;
+ (void)type;
+
+ if (cap->max_send_wr > hr_dev->caps.max_wqes ||
+ cap->max_send_sge > hr_dev->caps.max_sq_sg ||
+ cap->max_inline_data > hr_dev->caps.max_sq_inline) {
+ dev_err(dev, "hns_roce_set_kernel_sq_size error1\n");
+ return -EINVAL;
+ }
+
+ hr_qp->sq.wqe_shift = ilog2(hr_dev->caps.max_sq_desc_sz);
+ hr_qp->sq_max_wqes_per_wr = 1;
+ hr_qp->sq_spare_wqes = 0;
+
+ /* In v1 engine, parameter verification procession */
+ max_cnt = cap->max_send_wr > HNS_ROCE_MIN_WQE_NUM ?
+ cap->max_send_wr : HNS_ROCE_MIN_WQE_NUM;
+ hr_qp->sq.wqe_cnt = roundup_pow_of_two(max_cnt);
+ if ((u32)hr_qp->sq.wqe_cnt > hr_dev->caps.max_wqes) {
+ dev_err(dev, "hns_roce_set_kernel_sq_size sq.wqe_cnt too large\n");
+ return -EINVAL;
+ }
+
+ /* Get data_seg numbers */
+ max_cnt = max(1U, cap->max_send_sge);
+ hr_qp->sq.max_gs = roundup_pow_of_two(max_cnt);
+
+ /* Get buf size, SQ and RQ are aligned to page_szie */
+ hr_qp->buff_size = HNS_ROCE_ALOGN_UP((hr_qp->rq.wqe_cnt <<
+ hr_qp->rq.wqe_shift), PAGE_SIZE) +
+ HNS_ROCE_ALOGN_UP((hr_qp->sq.wqe_cnt <<
+ hr_qp->sq.wqe_shift), PAGE_SIZE);
+ hr_qp->sq.offset = 0;
+ hr_qp->rq.offset = HNS_ROCE_ALOGN_UP((hr_qp->sq.wqe_cnt <<
+ hr_qp->sq.wqe_shift), PAGE_SIZE);
+
+ /* Get wr and sge number which send */
+ cap->max_send_wr = hr_qp->sq.max_post = hr_qp->sq.wqe_cnt;
+ cap->max_send_sge = hr_qp->sq.max_gs;
+
+ /* We don't support inline sends for kernel QPs (yet) */
+ cap->max_inline_data = 0;
+
+ return 0;
+}
+
+static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
+ struct ib_pd *ib_pd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata, int sqpn,
+ struct hns_roce_qp *hr_qp)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_ib_create_qp ucmd;
+ int qpn = 0;
+ int ret = 0;
+
+ mutex_init(&hr_qp->mutex);
+ spin_lock_init(&hr_qp->sq.lock);
+ spin_lock_init(&hr_qp->rq.lock);
+
+ hr_qp->state = IB_QPS_RESET;
+
+ if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
+ hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR;
+ else
+ hr_qp->sq_signal_bits = IB_SIGNAL_REQ_WR;
+
+ ret = hns_roce_set_rq_size(hr_dev, &init_attr->cap, !!ib_pd->uobject,
+ !!init_attr->srq, hr_qp);
+ if (ret) {
+ dev_err(dev, "hns_roce_set_rq_size failed\n");
+ goto err_out;
+ }
+
+ if (ib_pd->uobject) {
+ if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
+ dev_err(dev, "ib_copy_from_udata error for create qp\n");
+ ret = -EFAULT;
+ goto err_out;
+ }
+
+ ret = hns_roce_set_user_sq_size(hr_dev, hr_qp, &ucmd);
+ if (ret) {
+ dev_err(dev, "hns_roce_set_user_sq_size error for create qp\n");
+ goto err_out;
+ }
+
+ hr_qp->umem = ib_umem_get(ib_pd->uobject->context,
+ ucmd.buf_addr, hr_qp->buff_size, 0,
+ 0);
+ if (IS_ERR(hr_qp->umem)) {
+ dev_err(dev, "ib_umem_get error for create qp\n");
+ ret = PTR_ERR(hr_qp->umem);
+ goto err_out;
+ }
+
+ ret = hns_roce_mtt_init(hr_dev, ib_umem_page_count(hr_qp->umem),
+ ilog2(hr_qp->umem->page_size),
+ &hr_qp->mtt);
+ if (ret) {
+ dev_err(dev, "hns_roce_mtt_init error for create qp\n");
+ goto err_buf;
+ }
+
+ ret = hns_roce_ib_umem_write_mtt(hr_dev, &hr_qp->mtt,
+ hr_qp->umem);
+ if (ret) {
+ dev_err(dev, "hns_roce_ib_umem_write_mtt error for create qp\n");
+ goto err_mtt;
+ }
+ } else {
+ if ((int)init_attr->create_flags &
+ (int)IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
+ dev_err(dev, "init_attr->create_flags error!\n");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ if ((int)init_attr->create_flags &
+ (int)IB_QP_CREATE_IPOIB_UD_LSO) {
+ dev_err(dev, "init_attr->create_flags error!\n");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ /* Set SQ size */
+ ret = hns_roce_set_kernel_sq_size(hr_dev, &init_attr->cap,
+ init_attr->qp_type, hr_qp);
+ if (ret) {
+ dev_err(dev, "hns_roce_set_kernel_sq_size error!\n");
+ goto err_out;
+ }
+
+ /* QP doorbell register address */
+ hr_qp->sq.db_reg_l = hr_dev->reg_base + ROCEE_DB_SQ_L_0_REG +
+ DB_REG_OFFSET * hr_dev->priv_uar.index;
+ hr_qp->rq.db_reg_l = hr_dev->reg_base +
+ ROCEE_DB_OTHERS_L_0_REG +
+ DB_REG_OFFSET * hr_dev->priv_uar.index;
+
+ /* Allocate QP buf */
+ if (hns_roce_buf_alloc(hr_dev, hr_qp->buff_size, PAGE_SIZE * 2,
+ &hr_qp->hr_buf)) {
+ dev_err(dev, "hns_roce_buf_alloc error!\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ /* Write MTT */
+ ret = hns_roce_mtt_init(hr_dev, hr_qp->hr_buf.npages,
+ hr_qp->hr_buf.page_shift, &hr_qp->mtt);
+ if (ret) {
+ dev_err(dev, "hns_roce_mtt_init error for kernel create qp\n");
+ goto err_buf;
+ }
+
+ ret = hns_roce_buf_write_mtt(hr_dev, &hr_qp->mtt,
+ &hr_qp->hr_buf);
+ if (ret) {
+ dev_err(dev, "hns_roce_buf_write_mtt error for kernel create qp\n");
+ goto err_mtt;
+ }
+
+ hr_qp->sq.wrid = kmalloc_array(hr_qp->sq.wqe_cnt, sizeof(u64),
+ GFP_KERNEL);
+ hr_qp->rq.wrid = kmalloc_array(hr_qp->rq.wqe_cnt, sizeof(u64),
+ GFP_KERNEL);
+ if (!hr_qp->sq.wrid || !hr_qp->rq.wrid) {
+ ret = -ENOMEM;
+ dev_err(dev, "wrid buf alloc failed!\n");
+ goto err_wrid;
+ }
+ }
+
+ if (sqpn) {
+ qpn = sqpn;
+ } else {
+ /* Get QPN */
+ ret = hns_roce_reserve_range_qp(hr_dev, 1, 1, &qpn);
+ if (ret) {
+ dev_err(dev, "hns_roce_reserve_range_qp alloc qpn error\n");
+ goto err_wrid;
+ }
+ }
+
+ if ((init_attr->qp_type) == IB_QPT_GSI) {
+ ret = hns_roce_gsi_qp_alloc(hr_dev, qpn, hr_qp);
+ if (ret) {
+ dev_err(dev, "hns_roce_qp_alloc failed!\n");
+ goto err_qpn;
+ }
+ } else {
+ ret = hns_roce_qp_alloc(hr_dev, qpn, hr_qp);
+ if (ret) {
+ dev_err(dev, "hns_roce_qp_alloc failed!\n");
+ goto err_qpn;
+ }
+ }
+
+ if (sqpn)
+ hr_qp->doorbell_qpn = 1;
+ else
+ hr_qp->doorbell_qpn = cpu_to_le32(hr_qp->qpn);
+
+ hr_qp->event = hns_roce_ib_qp_event;
+
+ return 0;
+
+err_qpn:
+ if (!sqpn)
+ hns_roce_release_range_qp(hr_dev, qpn, 1);
+
+err_wrid:
+ kfree(hr_qp->sq.wrid);
+ kfree(hr_qp->rq.wrid);
+
+err_mtt:
+ hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt);
+
+err_buf:
+ if (ib_pd->uobject)
+ ib_umem_release(hr_qp->umem);
+ else
+ hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf);
+
+err_out:
+ return ret;
+}
+
+struct ib_qp *hns_roce_create_qp(struct ib_pd *pd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_udata *udata)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_sqp *hr_sqp;
+ struct hns_roce_qp *hr_qp;
+ int ret;
+
+ switch (init_attr->qp_type) {
+ case IB_QPT_RC: {
+ hr_qp = kzalloc(sizeof(*hr_qp), GFP_KERNEL);
+ if (!hr_qp) {
+ dev_err(dev, "hr_qp alloc failed!\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, 0,
+ hr_qp);
+ if (ret) {
+ dev_err(dev, "Create RC QP failed\n");
+ kfree(hr_qp);
+ return ERR_PTR(ret);
+ }
+
+ hr_qp->ibqp.qp_num = hr_qp->qpn;
+
+ break;
+ }
+ case IB_QPT_GSI: {
+ /* Userspace is not allowed to create special QPs: */
+ if (pd->uobject) {
+ dev_err(dev, "not support usr space GSI\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ hr_sqp = kzalloc(sizeof(*hr_sqp), GFP_KERNEL);
+ if (!hr_sqp)
+ return ERR_PTR(-ENOMEM);
+
+ hr_qp = &hr_sqp->hr_qp;
+
+ ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata,
+ hr_dev->caps.sqp_start +
+ hr_dev->caps.num_ports +
+ init_attr->port_num - 1, hr_qp);
+ if (ret) {
+ dev_err(dev, "Create GSI QP failed!\n");
+ kfree(hr_sqp);
+ return ERR_PTR(ret);
+ }
+
+ hr_qp->port = (init_attr->port_num - 1);
+ hr_qp->ibqp.qp_num = hr_dev->caps.sqp_start +
+ hr_dev->caps.num_ports +
+ init_attr->port_num - 1;
+ break;
+ }
+ default:{
+ dev_err(dev, "not support QP type %d\n", init_attr->qp_type);
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
+ return &hr_qp->ibqp;
+}
+
+int to_hr_qp_type(int qp_type)
+{
+ int transport_type;
+
+ if (qp_type == IB_QPT_RC)
+ transport_type = SERV_TYPE_RC;
+ else if (qp_type == IB_QPT_UC)
+ transport_type = SERV_TYPE_UC;
+ else if (qp_type == IB_QPT_UD)
+ transport_type = SERV_TYPE_UD;
+ else if (qp_type == IB_QPT_GSI)
+ transport_type = SERV_TYPE_UD;
+ else
+ transport_type = -1;
+
+ return transport_type;
+}
+
+int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ enum ib_qp_state cur_state, new_state;
+ struct device *dev = &hr_dev->pdev->dev;
+ int ret = -EINVAL;
+ int p;
+
+ mutex_lock(&hr_qp->mutex);
+
+ cur_state = attr_mask & IB_QP_CUR_STATE ?
+ attr->cur_qp_state : (enum ib_qp_state)hr_qp->state;
+ new_state = attr_mask & IB_QP_STATE ?
+ attr->qp_state : cur_state;
+
+ if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type,
+ (enum ib_qp_attr_mask)attr_mask,
+ IB_LINK_LAYER_ETHERNET)) {
+ dev_err(dev, "ib_modify_qp_is_ok failed\n");
+ goto out;
+ }
+
+ if ((attr_mask & IB_QP_PORT) &&
+ (attr->port_num == 0 ||
+ attr->port_num > hr_dev->caps.num_ports)) {
+ dev_err(dev, "attr port_num invalid.attr->port_num=%d\n",
+ attr->port_num);
+ goto out;
+ }
+
+ if (attr_mask & IB_QP_PKEY_INDEX) {
+ p = attr_mask & IB_QP_PORT ? attr->port_num : (hr_qp->port + 1);
+ if (attr->pkey_index >= hr_dev->caps.pkey_table_len[p]) {
+ dev_dbg(dev, "attr pkey_index invalid.attr->pkey_index=%d\n",
+ attr->pkey_index);
+ goto out;
+ }
+ }
+
+ if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
+ attr->max_rd_atomic > hr_dev->caps.max_qp_init_rdma) {
+ dev_dbg(dev, "attr max_rd_atomic invalid.attr->max_rd_atomic=%d\n",
+ attr->max_rd_atomic);
+ goto out;
+ }
+
+ if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
+ attr->max_dest_rd_atomic > hr_dev->caps.max_qp_dest_rdma) {
+ dev_dbg(dev, "attr max_dest_rd_atomic invalid.attr->max_dest_rd_atomic=%d\n",
+ attr->max_dest_rd_atomic);
+ goto out;
+ }
+
+ if (cur_state == new_state && cur_state == IB_QPS_RESET) {
+ ret = -EPERM;
+ dev_dbg(dev, "cur_state=%d new_state=%d\n", cur_state,
+ new_state);
+ goto out;
+ }
+
+ ret = hr_dev->hw->modify_qp(ibqp, attr, attr_mask, cur_state,
+ new_state);
+
+out:
+ mutex_unlock(&hr_qp->mutex);
+
+ return ret;
+}
+
+void hns_roce_lock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq)
+ __acquires(&send_cq->lock) __acquires(&recv_cq->lock)
+{
+ if (send_cq == recv_cq) {
+ spin_lock_irq(&send_cq->lock);
+ __acquire(&recv_cq->lock);
+ } else if (send_cq->cqn < recv_cq->cqn) {
+ spin_lock_irq(&send_cq->lock);
+ spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING);
+ } else {
+ spin_lock_irq(&recv_cq->lock);
+ spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING);
+ }
+}
+
+void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq,
+ struct hns_roce_cq *recv_cq) __releases(&send_cq->lock)
+ __releases(&recv_cq->lock)
+{
+ if (send_cq == recv_cq) {
+ __release(&recv_cq->lock);
+ spin_unlock_irq(&send_cq->lock);
+ } else if (send_cq->cqn < recv_cq->cqn) {
+ spin_unlock(&recv_cq->lock);
+ spin_unlock_irq(&send_cq->lock);
+ } else {
+ spin_unlock(&send_cq->lock);
+ spin_unlock_irq(&recv_cq->lock);
+ }
+}
+
+__be32 send_ieth(struct ib_send_wr *wr)
+{
+ switch (wr->opcode) {
+ case IB_WR_SEND_WITH_IMM:
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ return cpu_to_le32(wr->ex.imm_data);
+ case IB_WR_SEND_WITH_INV:
+ return cpu_to_le32(wr->ex.invalidate_rkey);
+ default:
+ return 0;
+ }
+}
+
+static void *get_wqe(struct hns_roce_qp *hr_qp, int offset)
+{
+
+ return hns_roce_buf_offset(&hr_qp->hr_buf, offset);
+}
+
+void *get_recv_wqe(struct hns_roce_qp *hr_qp, int n)
+{
+ struct ib_qp *ibqp = &hr_qp->ibqp;
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+
+ if ((n < 0) || (n > hr_qp->rq.wqe_cnt)) {
+ dev_err(&hr_dev->pdev->dev, "rq wqe index:%d,rq wqe cnt:%d\r\n",
+ n, hr_qp->rq.wqe_cnt);
+ return NULL;
+ }
+
+ return get_wqe(hr_qp, hr_qp->rq.offset + (n << hr_qp->rq.wqe_shift));
+}
+
+void *get_send_wqe(struct hns_roce_qp *hr_qp, int n)
+{
+ struct ib_qp *ibqp = &hr_qp->ibqp;
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+
+ if ((n < 0) || (n > hr_qp->sq.wqe_cnt)) {
+ dev_err(&hr_dev->pdev->dev, "sq wqe index:%d,sq wqe cnt:%d\r\n",
+ n, hr_qp->sq.wqe_cnt);
+ return NULL;
+ }
+
+ return get_wqe(hr_qp, hr_qp->sq.offset + (n << hr_qp->sq.wqe_shift));
+}
+
+bool hns_roce_wq_overflow(struct hns_roce_wq *hr_wq, int nreq,
+ struct ib_cq *ib_cq)
+{
+ struct hns_roce_cq *hr_cq;
+ u32 cur;
+
+ cur = hr_wq->head - hr_wq->tail;
+ if (likely(cur + nreq < hr_wq->max_post))
+ return 0;
+
+ hr_cq = to_hr_cq(ib_cq);
+ spin_lock(&hr_cq->lock);
+ cur = hr_wq->head - hr_wq->tail;
+ spin_unlock(&hr_cq->lock);
+
+ return cur + nreq >= hr_wq->max_post;
+}
+
+int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev)
+{
+ struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
+ int reserved_from_top = 0;
+ int ret;
+
+ spin_lock_init(&qp_table->lock);
+ INIT_RADIX_TREE(&hr_dev->qp_table_tree, GFP_ATOMIC);
+
+ /* A port include two SQP, six port total 12 */
+ ret = hns_roce_bitmap_init(&qp_table->bitmap, hr_dev->caps.num_qps,
+ hr_dev->caps.num_qps - 1,
+ hr_dev->caps.sqp_start + SQP_NUM,
+ reserved_from_top);
+ if (ret) {
+ dev_err(&hr_dev->pdev->dev, "qp bitmap init failed!error=%d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+void hns_roce_cleanup_qp_table(struct hns_roce_dev *hr_dev)
+{
+ hns_roce_bitmap_cleanup(&hr_dev->qp_table.bitmap);
+}
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_user.h b/drivers/infiniband/hw/hisilicon/hns/hns_roce_user.h
new file mode 100644
index 0000000..0db9a35
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_user.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _HNS_ROCE_USER_H
+#define _HNS_ROCE_USER_H
+
+struct hns_roce_ib_create_cq {
+ __u64 buf_addr;
+ __u64 db_addr;
+};
+
+struct hns_roce_ib_create_qp {
+ __u64 buf_addr;
+ __u64 db_addr;
+ __u8 log_sq_bb_count;
+ __u8 log_sq_stride;
+ __u8 sq_no_prefetch;
+ __u8 reserved[5];
+};
+
+struct hns_roce_ib_alloc_ucontext_resp {
+ __u32 qp_tab_size;
+};
+
+#endif /*_HNS_ROCE_USER_H */
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.c b/drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.c
new file mode 100644
index 0000000..2664dd5
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.c
@@ -0,0 +1,2835 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * Authors: Wei Hu <xavier.huwei-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
+ * Authors: Znlong <zhaonenglong-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
+ * Authors: oulijun <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include "hns_roce_common.h"
+#include "hns_roce_device.h"
+#include "hns_roce_cmd.h"
+#include "hns_roce_icm.h"
+#include "hns_roce_v1_hw.h"
+
+static void set_data_seg(struct hns_roce_wqe_data_seg *dseg, struct ib_sge *sg)
+{
+ dseg->lkey = cpu_to_le32(sg->lkey);
+ dseg->addr = cpu_to_le64(sg->addr);
+ dseg->len = cpu_to_le32(sg->length);
+}
+
+static void set_raddr_seg(struct hns_roce_wqe_raddr_seg *rseg, u64 remote_addr,
+ u32 rkey)
+{
+ rseg->raddr = cpu_to_le64(remote_addr);
+ rseg->rkey = cpu_to_le32(rkey);
+ rseg->len = 0;
+}
+
+int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_ah *ah = to_hr_ah(ud_wr(wr)->ah);
+ struct hns_roce_ud_send_wqe *ud_sq_wqe = NULL;
+ struct hns_roce_wqe_ctrl_seg *ctrl = NULL;
+ struct hns_roce_wqe_data_seg *dseg = NULL;
+ struct hns_roce_qp *qp = to_hr_qp(ibqp);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_sq_db sq_db;
+ int ps_opcode = 0, i = 0;
+ unsigned long flags = 0;
+ void *wqe = NULL;
+ u32 doorbell[2];
+ int nreq = 0;
+ u32 ind = 0;
+ int ret = 0;
+
+ spin_lock_irqsave(&qp->sq.lock, flags);
+
+ ind = qp->sq_next_wqe;
+ for (nreq = 0; wr; ++nreq, wr = wr->next) {
+ if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) {
+ dev_err(dev, "hns_roce_wq_overflow error\n");
+ ret = -ENOMEM;
+ *bad_wr = wr;
+ goto out;
+ }
+
+ if (unlikely(wr->num_sge > qp->sq.max_gs)) {
+ dev_err(dev, "num_sge=%d > qp->sq.max_gs=%d\n",
+ wr->num_sge, qp->sq.max_gs);
+ ret = -EINVAL;
+ *bad_wr = wr;
+ goto out;
+ }
+
+ wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1));
+ qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] =
+ wr->wr_id;
+
+ /* Corresponding to the RC and RD type wqe process separately */
+ if (ibqp->qp_type == IB_QPT_GSI) {
+ ud_sq_wqe = wqe;
+ roce_set_field(ud_sq_wqe->dmac_h,
+ UD_SEND_WQE_U32_4_DMAC_0_M,
+ UD_SEND_WQE_U32_4_DMAC_0_S,
+ ah->av.mac[0]);
+ roce_set_field(ud_sq_wqe->dmac_h,
+ UD_SEND_WQE_U32_4_DMAC_1_M,
+ UD_SEND_WQE_U32_4_DMAC_1_S,
+ ah->av.mac[1]);
+ roce_set_field(ud_sq_wqe->dmac_h,
+ UD_SEND_WQE_U32_4_DMAC_2_M,
+ UD_SEND_WQE_U32_4_DMAC_2_S,
+ ah->av.mac[2]);
+ roce_set_field(ud_sq_wqe->dmac_h,
+ UD_SEND_WQE_U32_4_DMAC_3_M,
+ UD_SEND_WQE_U32_4_DMAC_3_S,
+ ah->av.mac[3]);
+
+ roce_set_field(ud_sq_wqe->u32_8,
+ UD_SEND_WQE_U32_8_DMAC_4_M,
+ UD_SEND_WQE_U32_8_DMAC_4_S,
+ ah->av.mac[4]);
+ roce_set_field(ud_sq_wqe->u32_8,
+ UD_SEND_WQE_U32_8_DMAC_5_M,
+ UD_SEND_WQE_U32_8_DMAC_5_S,
+ ah->av.mac[5]);
+ roce_set_field(ud_sq_wqe->u32_8,
+ UD_SEND_WQE_U32_8_OPERATION_TYPE_M,
+ UD_SEND_WQE_U32_8_OPERATION_TYPE_S,
+ HNS_ROCE_WQE_OPCODE_SEND);
+ roce_set_field(ud_sq_wqe->u32_8,
+ UD_SEND_WQE_U32_8_NUMBER_OF_DATA_SEG_M,
+ UD_SEND_WQE_U32_8_NUMBER_OF_DATA_SEG_S,
+ 2);
+ roce_set_bit(ud_sq_wqe->u32_8,
+ UD_SEND_WQE_U32_8_SEND_GL_ROUTING_HDR_FLAG_S,
+ 1);
+
+ ud_sq_wqe->u32_8 |= (wr->send_flags & IB_SEND_SIGNALED ?
+ cpu_to_le32(HNS_ROCE_WQE_CQ_NOTIFY) : 0) |
+ (wr->send_flags & IB_SEND_SOLICITED ?
+ cpu_to_le32(HNS_ROCE_WQE_SE) : 0) |
+ ((wr->opcode == IB_WR_SEND_WITH_IMM) ?
+ cpu_to_le32(HNS_ROCE_WQE_IMM) : 0);
+
+ roce_set_field(ud_sq_wqe->u32_16,
+ UD_SEND_WQE_U32_16_DEST_QP_M,
+ UD_SEND_WQE_U32_16_DEST_QP_S,
+ ud_wr(wr)->remote_qpn);
+ roce_set_field(ud_sq_wqe->u32_16,
+ UD_SEND_WQE_U32_16_MAX_STATIC_RATE_M,
+ UD_SEND_WQE_U32_16_MAX_STATIC_RATE_S,
+ ah->av.stat_rate);
+
+ roce_set_field(ud_sq_wqe->u32_36,
+ UD_SEND_WQE_U32_36_FLOW_LABEL_M,
+ UD_SEND_WQE_U32_36_FLOW_LABEL_S, 0);
+ roce_set_field(ud_sq_wqe->u32_36,
+ UD_SEND_WQE_U32_36_PRIORITY_M,
+ UD_SEND_WQE_U32_36_PRIORITY_S,
+ ah->av.sl_tclass_flowlabel >>
+ HNS_ROCE_SL_SHIFT);
+ roce_set_field(ud_sq_wqe->u32_36,
+ UD_SEND_WQE_U32_36_SGID_INDEX_M,
+ UD_SEND_WQE_U32_36_SGID_INDEX_S,
+ hns_get_gid_index(hr_dev, qp->port,
+ ah->av.gid_index));
+
+ roce_set_field(ud_sq_wqe->u32_40,
+ UD_SEND_WQE_U32_40_HOP_LIMIT_M,
+ UD_SEND_WQE_U32_40_HOP_LIMIT_S,
+ ah->av.hop_limit);
+ roce_set_field(ud_sq_wqe->u32_40,
+ UD_SEND_WQE_U32_40_TRAFFIC_CLASS_M,
+ UD_SEND_WQE_U32_40_TRAFFIC_CLASS_S, 0);
+
+ memcpy(&ud_sq_wqe->dgid[0], &ah->av.dgid[0], GID_LEN);
+
+ ud_sq_wqe->va0_l = (u32)wr->sg_list[0].addr;
+ ud_sq_wqe->va0_h = (wr->sg_list[0].addr) >>
+ ADDR_SHIFT_32;
+ ud_sq_wqe->l_key0 = wr->sg_list[0].lkey;
+
+ ud_sq_wqe->va1_l = (u32)wr->sg_list[1].addr;
+ ud_sq_wqe->va1_h = (wr->sg_list[1].addr) >>
+ ADDR_SHIFT_32;
+ ud_sq_wqe->l_key1 = wr->sg_list[1].lkey;
+ ind++;
+ } else if (ibqp->qp_type == IB_QPT_RC) {
+ ctrl = wqe;
+ memset(ctrl, 0, sizeof(struct hns_roce_wqe_ctrl_seg));
+ for (i = 0; i < wr->num_sge; i++)
+ ctrl->msg_length += wr->sg_list[i].length;
+
+ ctrl->sgl_pa_h = 0;
+ ctrl->flag = 0;
+ ctrl->imm_data = send_ieth(wr);
+
+ /*Ctrl field, ctrl set type: sig, solic, imm, fence */
+ /* SO wait for conforming application scenarios */
+ ctrl->flag |= (wr->send_flags & IB_SEND_SIGNALED ?
+ cpu_to_le32(HNS_ROCE_WQE_CQ_NOTIFY) : 0) |
+ (wr->send_flags & IB_SEND_SOLICITED ?
+ cpu_to_le32(HNS_ROCE_WQE_SE) : 0) |
+ ((wr->opcode == IB_WR_SEND_WITH_IMM ||
+ wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) ?
+ cpu_to_le32(HNS_ROCE_WQE_IMM) : 0) |
+ (wr->send_flags & IB_SEND_FENCE ?
+ (cpu_to_le32(HNS_ROCE_WQE_FENCE)) : 0);
+
+ wqe += sizeof(struct hns_roce_wqe_ctrl_seg);
+
+ switch (wr->opcode) {
+ case IB_WR_RDMA_READ:
+ ps_opcode = HNS_ROCE_WQE_OPCODE_RDMA_READ;
+ set_raddr_seg(wqe, atomic_wr(wr)->remote_addr,
+ atomic_wr(wr)->rkey);
+ break;
+ case IB_WR_RDMA_WRITE:
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ ps_opcode = HNS_ROCE_WQE_OPCODE_RDMA_WRITE;
+ set_raddr_seg(wqe, atomic_wr(wr)->remote_addr,
+ atomic_wr(wr)->rkey);
+ break;
+ case IB_WR_SEND:
+ case IB_WR_SEND_WITH_INV:
+ case IB_WR_SEND_WITH_IMM:
+ ps_opcode = HNS_ROCE_WQE_OPCODE_SEND;
+ break;
+ case IB_WR_LOCAL_INV:
+ break;
+ case IB_WR_ATOMIC_CMP_AND_SWP:
+ case IB_WR_ATOMIC_FETCH_AND_ADD:
+ case IB_WR_LSO:
+ default:
+ ps_opcode = HNS_ROCE_WQE_OPCODE_MASK;
+ break;
+ }
+ ctrl->flag |= cpu_to_le32(ps_opcode);
+ wqe += sizeof(struct hns_roce_wqe_raddr_seg);
+
+ dseg = wqe;
+ if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) {
+ if (ctrl->msg_length >
+ hr_dev->caps.max_sq_inline) {
+ ret = -EINVAL;
+ *bad_wr = wr;
+ dev_err(dev, "inline len(1-%d)=%d, illegal",
+ ctrl->msg_length,
+ hr_dev->caps.max_sq_inline);
+ goto out;
+ }
+ for (i = 0; i < wr->num_sge; i++) {
+ memcpy(wqe, ((void *) (uintptr_t)
+ wr->sg_list[i].addr),
+ wr->sg_list[i].length);
+ wqe = wqe + wr->sg_list[i].length;
+ }
+ ctrl->flag |= HNS_ROCE_WQE_INLINE;
+ } else {
+ /*sqe num is two */
+ for (i = 0; i < wr->num_sge; i++)
+ set_data_seg(dseg + i, wr->sg_list + i);
+
+ ctrl->flag |= cpu_to_le32(wr->num_sge <<
+ HNS_ROCE_WQE_SGE_NUM_BIT);
+ }
+ ind++;
+ } else {
+ dev_dbg(dev, "unSupported QP type\n");
+ break;
+ }
+ }
+
+out:
+ /* Set DB return */
+ if (likely(nreq)) {
+ qp->sq.head += nreq;
+ /* Memory barrier */
+ wmb();
+
+ sq_db.u32_4 = 0;
+ sq_db.u32_8 = 0;
+ roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_SQ_HEAD_M,
+ SQ_DOORBELL_U32_4_SQ_HEAD_S,
+ (qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1)));
+ roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_PORT_M,
+ SQ_DOORBELL_U32_4_PORT_S, qp->port);
+ roce_set_field(sq_db.u32_8, SQ_DOORBELL_U32_8_QPN_M,
+ SQ_DOORBELL_U32_8_QPN_S, qp->doorbell_qpn);
+ roce_set_bit(sq_db.u32_8, SQ_DOORBELL_HW_SYNC_S, 1);
+
+ doorbell[0] = sq_db.u32_4;
+ doorbell[1] = sq_db.u32_8;
+
+ hns_roce_write64_k(doorbell, qp->sq.db_reg_l);
+ qp->sq_next_wqe = ind;
+ }
+
+ spin_unlock_irqrestore(&qp->sq.lock, flags);
+
+ return ret;
+}
+
+int hns_roce_v1_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr)
+{
+ int ret = 0;
+ int nreq = 0;
+ int ind = 0;
+ int i = 0;
+ u32 reg_val = 0;
+ u32 *addr = NULL;
+ unsigned long flags = 0;
+ struct hns_roce_rq_wqe_ctrl *ctrl = NULL;
+ struct hns_roce_wqe_data_seg *scat = NULL;
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct device *dev = &hr_dev->pdev->dev;
+
+ spin_lock_irqsave(&hr_qp->rq.lock, flags);
+ ind = hr_qp->rq.head & (hr_qp->rq.wqe_cnt - 1);
+
+ for (nreq = 0; wr; ++nreq, wr = wr->next) {
+ if (hns_roce_wq_overflow(&hr_qp->rq, nreq,
+ hr_qp->ibqp.recv_cq)) {
+ dev_err(dev, "hns_roce_wq_overflow error\n");
+ ret = -ENOMEM;
+ *bad_wr = wr;
+ goto out;
+ }
+
+ if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) {
+ dev_err(dev, "rq:num_sge=%d > qp->sq.max_gs=%d\n",
+ wr->num_sge, hr_qp->rq.max_gs);
+ ret = -EINVAL;
+ *bad_wr = wr;
+ goto out;
+ }
+
+ ctrl = get_recv_wqe(hr_qp, ind);
+
+ roce_set_field(ctrl->rwqe_byte_12,
+ RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_M,
+ RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_S,
+ wr->num_sge);
+
+ scat = (struct hns_roce_wqe_data_seg *)(ctrl + 1);
+
+ for (i = 0; i < wr->num_sge; i++)
+ set_data_seg(scat + i, wr->sg_list + i);
+
+ hr_qp->rq.wrid[ind] = wr->wr_id;
+
+ ind = (ind + 1) & (hr_qp->rq.wqe_cnt - 1);
+ }
+
+out:
+ if (likely(nreq)) {
+ hr_qp->rq.head += nreq;
+ /* Memory barrier */
+ wmb();
+
+ if (ibqp->qp_type == IB_QPT_GSI) {
+ /* SW update GSI rq header */
+ addr = (u32 *)(to_hr_dev(ibqp->device)->reg_base +
+ ROCEE_QP1C_CFG3_0_REG +
+ QP1C_CFGN_OFFSET * hr_qp->port);
+ reg_val = roce_readl(addr);
+ roce_set_field(reg_val,
+ ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M,
+ ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S,
+ hr_qp->rq.head);
+ roce_writel(reg_val, addr);
+ } else {
+ uint32_t doorbell[2] = {0};
+ struct hns_roce_rq_db rq_db;
+
+ rq_db.u32_4 = 0;
+ rq_db.u32_8 = 0;
+
+ roce_set_field(rq_db.u32_4, RQ_DOORBELL_U32_4_RQ_HEAD_M,
+ RQ_DOORBELL_U32_4_RQ_HEAD_S,
+ hr_qp->rq.head);
+ roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_QPN_M,
+ RQ_DOORBELL_U32_8_QPN_S, hr_qp->qpn);
+ roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_CMD_M,
+ RQ_DOORBELL_U32_8_CMD_S, 1);
+ roce_set_bit(rq_db.u32_8, RQ_DOORBELL_U32_8_HW_SYNC_S,
+ 1);
+
+ doorbell[0] = rq_db.u32_4;
+ doorbell[1] = rq_db.u32_8;
+
+ hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l);
+ }
+ }
+ spin_unlock_irqrestore(&hr_qp->rq.lock, flags);
+
+ return ret;
+}
+
+void hns_roce_set_db_event_mode(struct hns_roce_dev *hr_dev, int sdb_mode,
+ int odb_mode)
+{
+ u32 val;
+
+ val = roce_readl(hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+ roce_set_bit(val, ROCEE_GLB_CFG_ROCEE_DB_SQ_MODE_S, sdb_mode);
+ roce_set_bit(val, ROCEE_GLB_CFG_ROCEE_DB_OTH_MODE_S, odb_mode);
+ roce_writel(val, hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+}
+
+void hns_roce_set_db_ext_mode(struct hns_roce_dev *hr_dev,
+ u32 sdb_mode, u32 odb_mode)
+{
+ u32 val;
+
+ /* Configure SDB/ODB extend mode */
+ val = roce_readl(hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+ roce_set_bit(val, ROCEE_GLB_CFG_SQ_EXT_DB_MODE_S, sdb_mode);
+ roce_set_bit(val, ROCEE_GLB_CFG_OTH_EXT_DB_MODE_S, odb_mode);
+ roce_writel(val, hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+}
+
+void hns_roce_set_sdb(struct hns_roce_dev *hr_dev, u32 sdb_alept, u32 sdb_alful)
+{
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_db_table *db;
+ u32 val;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ db = &priv->db_table;
+
+ db->sdb_almept = sdb_alept;
+ db->sdb_almful = sdb_alful;
+
+ /* Configure SDB */
+ val = roce_readl(hr_dev->reg_base + ROCEE_DB_SQ_WL_REG);
+ roce_set_field(val, ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_M,
+ ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_S, db->sdb_almful);
+ roce_set_field(val, ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_EMPTY_M,
+ ROCEE_DB_SQ_WL_ROCEE_DB_SQ_WL_EMPTY_S, db->sdb_almept);
+ roce_writel(val, hr_dev->reg_base + ROCEE_DB_SQ_WL_REG);
+}
+
+void hns_roce_set_odb(struct hns_roce_dev *hr_dev, u32 odb_alept, u32 odb_alful)
+{
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_db_table *db;
+ u32 val;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ db = &priv->db_table;
+
+ db->odb_almept = odb_alept;
+ db->odb_almful = odb_alful;
+
+ /* Configure ODB */
+ val = roce_readl(hr_dev->reg_base + ROCEE_DB_OTHERS_WL_REG);
+ roce_set_field(val, ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_M,
+ ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_S, db->odb_almful);
+ roce_set_field(val, ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_EMPTY_M,
+ ROCEE_DB_OTHERS_WL_ROCEE_DB_OTH_WL_EMPTY_S,
+ db->odb_almept);
+ roce_writel(val, hr_dev->reg_base + ROCEE_DB_OTHERS_WL_REG);
+}
+
+void hns_roce_set_sdb_ext(struct hns_roce_dev *hr_dev, u32 ext_sdb_alept,
+ u32 ext_sdb_alful)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_db_table *db;
+ dma_addr_t sdb_dma_addr;
+ u32 val;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ db = &priv->db_table;
+
+ db->ext_db->esdb_almept = ext_sdb_alept;
+ db->ext_db->esdb_alful = ext_sdb_alful;
+
+ /* Configure extend SDB threshold */
+ roce_writel(db->ext_db->esdb_almept,
+ hr_dev->reg_base + ROCEE_EXT_DB_SQ_WL_EMPTY_REG);
+ roce_writel(db->ext_db->esdb_alful,
+ hr_dev->reg_base + ROCEE_EXT_DB_SQ_WL_REG);
+
+ /* Configure extend SDB base addr */
+ sdb_dma_addr = db->ext_db->sdb_buf_list->map;
+ roce_writel((u32)(sdb_dma_addr >> ADDR_SHIFT_12),
+ hr_dev->reg_base + ROCEE_EXT_DB_SQ_REG);
+
+ /* Configure extend SDB depth */
+ val = roce_readl(hr_dev->reg_base + ROCEE_EXT_DB_SQ_H_REG);
+ roce_set_field(val, ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_SHIFT_M,
+ ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_SHIFT_S,
+ db->ext_db->esdb_dep);
+ roce_set_field(val, ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_BA_H_M,
+ ROCEE_EXT_DB_SQ_H_EXT_DB_SQ_BA_H_S,
+ sdb_dma_addr >> ADDR_SHIFT_44);
+ roce_writel(val, hr_dev->reg_base + ROCEE_EXT_DB_SQ_H_REG);
+
+ dev_dbg(dev, "ext SDB depth: 0x%x\n", db->ext_db->esdb_dep);
+ dev_dbg(dev, "ext SDB threshold: epmty: 0x%x, ful: 0x%x\n",
+ db->ext_db->esdb_almept, db->ext_db->esdb_alful);
+}
+
+void hns_roce_set_odb_ext(struct hns_roce_dev *hr_dev, u32 ext_odb_alept,
+ u32 ext_odb_alful)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_db_table *db;
+ dma_addr_t odb_dma_addr;
+ u32 val;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ db = &priv->db_table;
+
+ db->ext_db->eodb_almept = ext_odb_alept;
+ db->ext_db->eodb_alful = ext_odb_alful;
+
+ /* Configure extend ODB threshold */
+ roce_writel(db->ext_db->eodb_almept,
+ hr_dev->reg_base + ROCEE_EXT_DB_OTHERS_WL_EMPTY_REG);
+ roce_writel(db->ext_db->eodb_alful,
+ hr_dev->reg_base + ROCEE_EXT_DB_OTHERS_WL_REG);
+
+ /* Configure extend ODB base addr */
+ odb_dma_addr = db->ext_db->odb_buf_list->map;
+ roce_writel((u32)(odb_dma_addr >> ADDR_SHIFT_12),
+ hr_dev->reg_base + ROCEE_EXT_DB_OTH_REG);
+
+ /* Configure extend ODB depth */
+ val = roce_readl(hr_dev->reg_base + ROCEE_EXT_DB_OTH_H_REG);
+ roce_set_field(val, ROCEE_EXT_DB_OTH_H_EXT_DB_OTH_SHIFT_M,
+ ROCEE_EXT_DB_OTH_H_EXT_DB_OTH_SHIFT_S,
+ db->ext_db->eodb_dep);
+ roce_set_field(val, ROCEE_EXT_DB_SQ_H_EXT_DB_OTH_BA_H_M,
+ ROCEE_EXT_DB_SQ_H_EXT_DB_OTH_BA_H_S,
+ db->ext_db->eodb_dep);
+ roce_writel(val, hr_dev->reg_base + ROCEE_EXT_DB_OTH_H_REG);
+
+ dev_dbg(dev, "ext ODB depth: 0x%x\n", db->ext_db->eodb_dep);
+ dev_dbg(dev, "ext ODB threshold: empty: 0x%x, ful: 0x%x\n",
+ db->ext_db->eodb_almept, db->ext_db->eodb_alful);
+}
+
+int hns_roce_db_ext_init(struct hns_roce_dev *hr_dev, u32 sdb_ext_mod,
+ u32 odb_ext_mod)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_db_table *db;
+ dma_addr_t sdb_dma_addr;
+ dma_addr_t odb_dma_addr;
+ int ret = 0;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ db = &priv->db_table;
+
+ db->ext_db = kmalloc(sizeof(*db->ext_db), GFP_KERNEL);
+ if (!db->ext_db) {
+ ret = -ENOMEM;
+ dev_err(dev, "extend db buf alloc fail\n");
+ return ret;
+ }
+
+ if (sdb_ext_mod) {
+ db->ext_db->sdb_buf_list = kmalloc(
+ sizeof(*db->ext_db->sdb_buf_list), GFP_KERNEL);
+ if (!db->ext_db->sdb_buf_list) {
+ ret = -ENOMEM;
+ dev_err(dev, "sdb buf alloc failed\n");
+ goto ext_sdb_buf_fail_out;
+ }
+
+ db->ext_db->sdb_buf_list->buf = dma_alloc_coherent(dev,
+ HNS_ROCE_V1_EXT_SDB_SIZE,
+ &sdb_dma_addr, GFP_KERNEL);
+ if (!db->ext_db->sdb_buf_list->buf) {
+ ret = -ENOMEM;
+ dev_err(dev, "Send queue db buf alloc fail\n");
+ goto alloc_sq_db_buf_fail;
+ }
+ db->ext_db->sdb_buf_list->map = sdb_dma_addr;
+
+ db->ext_db->esdb_dep = ilog2(HNS_ROCE_V1_EXT_SDB_DEPTH);
+ hns_roce_set_sdb_ext(hr_dev, HNS_ROCE_V1_EXT_SDB_ALEPT,
+ HNS_ROCE_V1_EXT_SDB_ALFUL);
+ } else
+ hns_roce_set_sdb(hr_dev, HNS_ROCE_V1_SDB_ALEPT,
+ HNS_ROCE_V1_SDB_ALFUL);
+
+ if (odb_ext_mod) {
+ db->ext_db->odb_buf_list = kmalloc(
+ sizeof(*db->ext_db->odb_buf_list), GFP_KERNEL);
+ if (!db->ext_db->odb_buf_list) {
+ ret = -ENOMEM;
+ dev_err(dev, "odb buf alloc failed\n");
+ goto ext_odb_buf_fail_out;
+ }
+
+ db->ext_db->odb_buf_list->buf = dma_alloc_coherent(dev,
+ HNS_ROCE_V1_EXT_ODB_SIZE,
+ &odb_dma_addr, GFP_KERNEL);
+ if (!db->ext_db->odb_buf_list->buf) {
+ ret = -ENOMEM;
+ dev_err(dev, "Other queue db buf alloc fail\n");
+ goto alloc_otr_db_buf_fail;
+ }
+ db->ext_db->odb_buf_list->map = odb_dma_addr;
+
+ db->ext_db->eodb_dep = ilog2(HNS_ROCE_V1_EXT_ODB_DEPTH);
+ hns_roce_set_odb_ext(hr_dev, HNS_ROCE_V1_EXT_ODB_ALEPT,
+ HNS_ROCE_V1_EXT_ODB_ALFUL);
+ } else
+ hns_roce_set_odb(hr_dev, HNS_ROCE_V1_ODB_ALEPT,
+ HNS_ROCE_V1_ODB_ALFUL);
+
+ hns_roce_set_db_ext_mode(hr_dev, sdb_ext_mod, odb_ext_mod);
+
+ return 0;
+
+alloc_otr_db_buf_fail:
+ kfree(db->ext_db->odb_buf_list);
+
+ext_odb_buf_fail_out:
+ if (sdb_ext_mod) {
+ dma_free_coherent(dev, HNS_ROCE_V1_EXT_SDB_SIZE,
+ db->ext_db->sdb_buf_list->buf,
+ db->ext_db->sdb_buf_list->map);
+ }
+
+alloc_sq_db_buf_fail:
+ if (sdb_ext_mod)
+ kfree(db->ext_db->sdb_buf_list);
+
+ext_sdb_buf_fail_out:
+ kfree(db->ext_db);
+ return ret;
+}
+
+int hns_roce_db_init(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_db_table *db;
+ u32 sdb_ext_mod;
+ u32 odb_ext_mod;
+ u32 sdb_evt_mod;
+ u32 odb_evt_mod;
+ int ret = 0;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ db = &priv->db_table;
+
+ memset(db, 0, sizeof(*db));
+
+ /* Default DB mode */
+ sdb_ext_mod = HNS_ROCE_SDB_EXTEND_MODE;
+ odb_ext_mod = HNS_ROCE_ODB_EXTEND_MODE;
+ sdb_evt_mod = HNS_ROCE_SDB_NORMAL_MODE;
+ odb_evt_mod = HNS_ROCE_ODB_POLL_MODE;
+
+ db->sdb_ext_mod = sdb_ext_mod;
+ db->odb_ext_mod = odb_ext_mod;
+
+ /* Init extend DB */
+ ret = hns_roce_db_ext_init(hr_dev, sdb_ext_mod, odb_ext_mod);
+ if (ret) {
+ dev_err(dev, "Failed in extend DB configuration.\n");
+ return ret;
+ }
+
+ hns_roce_set_db_event_mode(hr_dev, sdb_evt_mod, odb_evt_mod);
+
+ return 0;
+}
+
+void hns_roce_db_free(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_db_table *db;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ db = &priv->db_table;
+
+ if (db->sdb_ext_mod) {
+ dma_free_coherent(dev, HNS_ROCE_V1_EXT_SDB_SIZE,
+ db->ext_db->sdb_buf_list->buf,
+ db->ext_db->sdb_buf_list->map);
+ kfree(db->ext_db->sdb_buf_list);
+ }
+
+ if (db->odb_ext_mod) {
+ dma_free_coherent(dev, HNS_ROCE_V1_EXT_ODB_SIZE,
+ db->ext_db->odb_buf_list->buf,
+ db->ext_db->odb_buf_list->map);
+ kfree(db->ext_db->odb_buf_list);
+ }
+
+ kfree(db->ext_db);
+}
+
+int hns_roce_raq_init(struct hns_roce_dev *hr_dev)
+{
+ int ret;
+ int raq_shift = 0;
+ dma_addr_t addr;
+ u32 val;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_raq_table *raq;
+ struct device *dev = &hr_dev->pdev->dev;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ raq = &priv->raq_table;
+
+ raq->e_raq_addr = hr_dev->reg_base + ROCEE_EXT_RAQ_REG;
+ raq->e_raq_wl_addr = hr_dev->reg_base + ROCEE_RAQ_WL_REG;
+ raq->e_raq_shift_addr = hr_dev->reg_base + ROCEE_EXT_RAQ_H_REG;
+
+ raq->e_raq_buf = kzalloc(sizeof(*(raq->e_raq_buf)), GFP_KERNEL);
+ if (!raq->e_raq_buf) {
+ ret = -ENOMEM;
+ dev_err(dev, "Failed to alloc raq buf, Aborting.\n");
+ return ret;
+ }
+
+ raq->e_raq_buf->buf = dma_alloc_coherent(dev, HNS_ROCE_V1_RAQ_SIZE,
+ &addr, GFP_KERNEL);
+ if (!raq->e_raq_buf->buf) {
+ ret = -ENOMEM;
+ dev_err(dev, "Failed to dma_alloc ext raq buf.\n");
+ goto _err_dma_alloc_raq;
+ }
+ raq->e_raq_buf->map = addr;
+
+ /* Configure raq extended address. 48bit 4K align*/
+ roce_writel(raq->e_raq_buf->map >> ADDR_SHIFT_12, raq->e_raq_addr);
+
+ /* Configure raq_shift */
+ raq_shift = ilog2(HNS_ROCE_V1_RAQ_SIZE / HNS_ROCE_V1_RAQ_ENTRY);
+ val = roce_readl(raq->e_raq_shift_addr);
+ roce_set_field(val, ROCEE_EXT_RAQ_H_EXT_RAQ_SHIFT_M,
+ ROCEE_EXT_RAQ_H_EXT_RAQ_SHIFT_S,
+ raq_shift);
+ roce_set_field(val, ROCEE_EXT_RAQ_H_EXT_RAQ_BA_H_M,
+ ROCEE_EXT_RAQ_H_EXT_RAQ_BA_H_S,
+ raq->e_raq_buf->map >> ADDR_SHIFT_44);
+ roce_writel(val, raq->e_raq_shift_addr);
+ dev_dbg(dev, "Configure raq_shift 0x%x.\n", val);
+
+ /* Configure raq threshold */
+ val = roce_readl(raq->e_raq_wl_addr);
+ roce_set_field(val, ROCEE_RAQ_WL_ROCEE_RAQ_WL_M,
+ ROCEE_RAQ_WL_ROCEE_RAQ_WL_S,
+ HNS_ROCE_V1_EXT_RAQ_WF);
+ roce_writel(val, raq->e_raq_wl_addr);
+ dev_dbg(dev, "Configure raq_wl 0x%x.\n", val);
+
+ /* Enable extend raq */
+ val = roce_readl(hr_dev->reg_base + ROCEE_WRMS_POL_TIME_INTERVAL_REG);
+ roce_set_field(val,
+ ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_POL_TIME_INTERVAL_M,
+ ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_POL_TIME_INTERVAL_S,
+ POL_TIME_INTERVAL_VAL);
+ roce_set_bit(val, ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_EXT_RAQ_MODE, 1);
+ roce_set_field(val,
+ ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_RAQ_TIMEOUT_CHK_CFG_M,
+ ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_RAQ_TIMEOUT_CHK_CFG_S,
+ 2);
+ roce_set_bit(val,
+ ROCEE_WRMS_POL_TIME_INTERVAL_WRMS_RAQ_TIMEOUT_CHK_EN_S, 1);
+ roce_writel(val, hr_dev->reg_base + ROCEE_WRMS_POL_TIME_INTERVAL_REG);
+ dev_dbg(dev, "Configure WrmsPolTimeInterval 0x%x.\n", val);
+
+ /* Enable raq drop */
+ val = roce_readl(hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+ roce_set_bit(val, ROCEE_GLB_CFG_TRP_RAQ_DROP_EN_S, 1);
+ roce_writel(val, hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+ dev_dbg(dev, "Configure GlbCfg = 0x%x.\n", val);
+
+ return 0;
+
+_err_dma_alloc_raq:
+ kfree(raq->e_raq_buf);
+ return ret;
+}
+
+void hns_roce_raq_free(struct hns_roce_dev *hr_dev)
+{
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_v1_priv *priv;
+ struct hns_roce_raq_table *raq;
+
+ priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+ raq = &priv->raq_table;
+
+ dma_free_coherent(dev, HNS_ROCE_V1_RAQ_SIZE, raq->e_raq_buf->buf,
+ raq->e_raq_buf->map);
+ kfree(raq->e_raq_buf);
+}
+
+void hns_roce_port_enable(struct hns_roce_dev *hr_dev, int enable_flag)
+{
+ u32 val;
+
+ if (enable_flag) {
+ val = roce_readl(hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+ /* Open all ports */
+ roce_set_field(val, ROCEE_GLB_CFG_ROCEE_PORT_ST_M,
+ ROCEE_GLB_CFG_ROCEE_PORT_ST_S,
+ ALL_PORT_VAL_OPEN);
+ roce_writel(val, hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+ } else {
+ val = roce_readl(hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+ /* Close all ports */
+ roce_set_field(val, ROCEE_GLB_CFG_ROCEE_PORT_ST_M,
+ ROCEE_GLB_CFG_ROCEE_PORT_ST_S, 0x0);
+ roce_writel(val, hr_dev->reg_base + ROCEE_GLB_CFG_REG);
+ }
+}
+
+/**
+ * hns_roce_v1_reset - reset roce
+ * @hr_dev: roce device struct pointer
+ * @val: 1 -- drop reset, 0 -- reset
+ * return 0 - success , negative --fail
+ */
+int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, u32 val)
+{
+ struct device_node *dsaf_node;
+ struct device *dev = &hr_dev->pdev->dev;
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ dsaf_node = of_parse_phandle(np, "dsaf-handle", 0);
+
+ if (!val) {
+ ret = hns_dsaf_roce_reset(&dsaf_node->fwnode, 0);
+ } else {
+ ret = hns_dsaf_roce_reset(&dsaf_node->fwnode, 0);
+ if (ret)
+ return ret;
+
+ msleep(SLEEP_TIME_INTERVAL);
+ ret = hns_dsaf_roce_reset(&dsaf_node->fwnode, 1);
+ }
+
+ return ret;
+}
+
+void hns_roce_v1_profile(struct hns_roce_dev *hr_dev)
+{
+ int i = 0;
+ struct hns_roce_caps *caps = &hr_dev->caps;
+
+ hr_dev->vendor_id = le32_to_cpu(roce_readl((hr_dev->reg_base +
+ ROCEE_VENDOR_ID_REG)));
+ hr_dev->vendor_part_id = le32_to_cpu(roce_readl((hr_dev->reg_base +
+ ROCEE_VENDOR_PART_ID_REG)));
+ hr_dev->hw_rev = le32_to_cpu(roce_readl((hr_dev->reg_base +
+ ROCEE_HW_VERSION_REG)));
+ hr_dev->fw_ver = 0;
+
+ hr_dev->sys_image_guid = le32_to_cpu(roce_readl(hr_dev->reg_base +
+ ROCEE_SYS_IMAGE_GUID_L_REG)) |
+ ((u64)le32_to_cpu(roce_readl(hr_dev->reg_base +
+ ROCEE_SYS_IMAGE_GUID_H_REG)) <<
+ ADDR_SHIFT_32);
+
+ caps->fw_ver = hr_dev->hw_rev;
+ caps->num_qps = HNS_ROCE_V1_MAX_QP_NUM;
+ caps->max_wqes = HNS_ROCE_V1_MAX_WQE_NUM;
+ caps->num_cqs = HNS_ROCE_V1_MAX_CQ_NUM;
+ caps->max_cqes = HNS_ROCE_V1_MAX_CQE_NUM;
+ caps->max_sq_sg = HNS_ROCE_V1_SG_NUM;
+ caps->max_rq_sg = HNS_ROCE_V1_SG_NUM;
+ caps->max_sq_inline = HNS_ROCE_V1_INLINE_SIZE;
+ caps->num_uars = HNS_ROCE_V1_UAR_NUM;
+ caps->phy_num_uars = HNS_ROCE_V1_PHY_UAR_NUM;
+ caps->num_aeq_vectors = HNS_ROCE_AEQE_VEC_NUM;
+ caps->num_comp_vectors = HNS_ROCE_COMP_VEC_NUM;
+ caps->num_other_vectors = HNS_ROCE_AEQE_OF_VEC_NUM;
+ caps->num_mtpts = HNS_ROCE_V1_MAX_MTPT_NUM;
+ caps->num_mtt_segs = HNS_ROCE_V1_MAX_MTT_SEGS;
+ caps->num_pds = HNS_ROCE_V1_MAX_PD_NUM;
+ caps->max_qp_init_rdma = HNS_ROCE_V1_MAX_QP_INIT_RDMA;
+ caps->max_qp_dest_rdma = HNS_ROCE_V1_MAX_QP_DEST_RDMA;
+ caps->max_sq_desc_sz = HNS_ROCE_V1_MAX_SQ_DESC_SZ;
+ caps->max_rq_desc_sz = HNS_ROCE_V1_MAX_RQ_DESC_SZ;
+ caps->qpc_entry_sz = HNS_ROCE_V1_QPC_ENTRY_SIZE;
+ caps->irrl_entry_sz = HNS_ROCE_V1_IRRL_ENTRY_SIZE;
+ caps->cqc_entry_sz = HNS_ROCE_V1_CQC_ENTRY_SIZE;
+ caps->mtpt_entry_sz = HNS_ROCE_V1_MTPT_ENTRY_SIZE;
+ caps->mtt_entry_sz = HNS_ROCE_V1_MTT_ENTRY_SIZE;
+ caps->cq_entry_sz = HNS_ROCE_V1_CQE_ENTRY_SIZE;
+ caps->page_size_cap = HNS_ROCE_V1_PAGE_SIZE_SUPPORT;
+ caps->sqp_start = 0;
+ caps->reserved_qps_base = 0;
+ caps->reserved_qps = 0;
+ caps->reserved_qps_cnt = 0;
+ caps->reserved_lkey = 0;
+ caps->reserved_pds = 0;
+ caps->reserved_mrws = 1;
+ caps->reserved_mtts = 0;
+ caps->reserved_uars = 0;
+ caps->reserved_cqs = 0;
+ caps->fmr_reserved_mtts = 0;
+ caps->flags = (u32)IB_DEVICE_PORT_ACTIVE_EVENT |
+ (u32)IB_DEVICE_RC_RNR_NAK_GEN|
+ (u32)IB_DEVICE_LOCAL_DMA_LKEY;
+
+ for (i = 0; i < caps->num_ports; i++)
+ caps->pkey_table_len[i] = 1;
+
+ for (i = 0; i < caps->num_ports; i++) {
+ /* Six ports shared 16 GID in v1 engine */
+ if (i >= (HNS_ROCE_V1_GID_NUM % caps->num_ports))
+ caps->gid_table_len[i] = HNS_ROCE_V1_GID_NUM /
+ caps->num_ports;
+ else
+ caps->gid_table_len[i] = HNS_ROCE_V1_GID_NUM /
+ caps->num_ports + 1;
+ }
+
+ for (i = 0; i < caps->num_comp_vectors; i++)
+ caps->ceqe_depth[i] = HNS_ROCE_V1_NUM_COMP_EQE;
+
+ caps->aeqe_depth = HNS_ROCE_V1_NUM_ASYNC_EQE;
+ caps->local_ca_ack_delay = le32_to_cpu(roce_readl((hr_dev->reg_base +
+ ROCEE_ACK_DELAY_REG)));
+ caps->max_mtu = IB_MTU_2048;
+}
+
+int hns_roce_v1_init(struct hns_roce_dev *hr_dev)
+{
+ int ret;
+ u32 val;
+ struct device *dev = &hr_dev->pdev->dev;
+
+ /* DMAE user config */
+ val = roce_readl(hr_dev->reg_base + ROCEE_DMAE_USER_CFG1_REG);
+ roce_set_field(val, ROCEE_DMAE_USER_CFG1_ROCEE_CACHE_TB_CFG_M,
+ ROCEE_DMAE_USER_CFG1_ROCEE_CACHE_TB_CFG_S, 0xf);
+ roce_set_field(val, ROCEE_DMAE_USER_CFG1_ROCEE_STREAM_ID_TB_CFG_M,
+ ROCEE_DMAE_USER_CFG1_ROCEE_STREAM_ID_TB_CFG_S,
+ 1 << PAGES_SHIFT_16);
+ roce_writel(val, hr_dev->reg_base + ROCEE_DMAE_USER_CFG1_REG);
+
+ val = roce_readl(hr_dev->reg_base + ROCEE_DMAE_USER_CFG2_REG);
+ roce_set_field(val, ROCEE_DMAE_USER_CFG2_ROCEE_CACHE_PKT_CFG_M,
+ ROCEE_DMAE_USER_CFG2_ROCEE_CACHE_PKT_CFG_S, 0xf);
+ roce_set_field(val, ROCEE_DMAE_USER_CFG2_ROCEE_STREAM_ID_PKT_CFG_M,
+ ROCEE_DMAE_USER_CFG2_ROCEE_STREAM_ID_PKT_CFG_S,
+ 1 << PAGES_SHIFT_16);
+
+ ret = hns_roce_db_init(hr_dev);
+ if (ret) {
+ dev_err(dev, "doorbell init failed!\n");
+ return ret;
+ }
+
+ ret = hns_roce_raq_init(hr_dev);
+ if (ret) {
+ dev_err(dev, "raq init failed!\n");
+ goto _error_failed_raq_init;
+ }
+
+ hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_UP);
+
+ return 0;
+
+_error_failed_raq_init:
+ hns_roce_db_free(hr_dev);
+ return ret;
+}
+
+void hns_roce_v1_uninit(struct hns_roce_dev *hr_dev)
+{
+ hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_DOWN);
+ hns_roce_raq_free(hr_dev);
+ hns_roce_db_free(hr_dev);
+}
+
+void hns_roce_v1_set_gid(struct hns_roce_dev *hr_dev, u8 port, int gid_index,
+ union ib_gid *gid)
+{
+ u32 *p = NULL;
+ u8 gid_idx = 0;
+
+ gid_idx = hns_get_gid_index(hr_dev, port, gid_index);
+
+ p = (u32 *)&gid->raw[0];
+ roce_raw_write(*p, hr_dev->reg_base + ROCEE_PORT_GID_L_0_REG +
+ (HNS_ROCE_V1_GID_NUM * gid_idx));
+
+ p = (u32 *)&gid->raw[4];
+ roce_raw_write(*p, hr_dev->reg_base + ROCEE_PORT_GID_ML_0_REG +
+ (HNS_ROCE_V1_GID_NUM * gid_idx));
+
+ p = (u32 *)&gid->raw[8];
+ roce_raw_write(*p, hr_dev->reg_base + ROCEE_PORT_GID_MH_0_REG +
+ (HNS_ROCE_V1_GID_NUM * gid_idx));
+
+ p = (u32 *)&gid->raw[0xc];
+ roce_raw_write(*p, hr_dev->reg_base + ROCEE_PORT_GID_H_0_REG +
+ (HNS_ROCE_V1_GID_NUM * gid_idx));
+}
+
+void hns_roce_v1_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port, u8 *addr)
+{
+ u32 reg_smac_l;
+ u16 reg_smac_h;
+ u16 *p_h;
+ u32 *p;
+ u32 val;
+
+ p = (u32 *)(&addr[0]);
+ reg_smac_l = *p;
+ roce_raw_write(reg_smac_l, hr_dev->reg_base + ROCEE_SMAC_L_0_REG +
+ PHY_PORT_OFFSET * phy_port);
+
+ val = roce_readl(hr_dev->reg_base + ROCEE_SMAC_H_0_REG +
+ phy_port * PHY_PORT_OFFSET);
+ p_h = (u16 *)(&addr[4]);
+ reg_smac_h = *p_h;
+ roce_set_field(val, ROCEE_SMAC_H_ROCEE_SMAC_H_M,
+ ROCEE_SMAC_H_ROCEE_SMAC_H_S, reg_smac_h);
+ roce_writel(val, hr_dev->reg_base + ROCEE_SMAC_H_0_REG +
+ phy_port * PHY_PORT_OFFSET);
+}
+
+void hns_roce_v1_set_mtu(struct hns_roce_dev *hr_dev, u8 phy_port,
+ enum ib_mtu mtu)
+{
+ u32 val;
+
+ val = roce_readl(hr_dev->reg_base + ROCEE_SMAC_H_0_REG +
+ phy_port * PHY_PORT_OFFSET);
+ roce_set_field(val, ROCEE_SMAC_H_ROCEE_PORT_MTU_M,
+ ROCEE_SMAC_H_ROCEE_PORT_MTU_S, mtu);
+ roce_writel(val, hr_dev->reg_base + ROCEE_SMAC_H_0_REG +
+ phy_port * PHY_PORT_OFFSET);
+}
+
+int hns_roce_v1_write_mtpt(void *mb_buf, struct hns_roce_mr *mr, int mtpt_idx)
+{
+ struct hns_roce_v1_mpt_entry *mpt_entry;
+ struct scatterlist *sg;
+ u64 *pages;
+ int entry;
+ int i;
+
+ /* MPT filled into mailbox buf */
+ mpt_entry = (struct hns_roce_v1_mpt_entry *)mb_buf;
+ memset(mpt_entry, 0, sizeof(*mpt_entry));
+
+ roce_set_field(mpt_entry->mpt_byte_4, MPT_BYTE_4_KEY_STATE_M,
+ MPT_BYTE_4_KEY_STATE_S, KEY_VALID);
+ roce_set_field(mpt_entry->mpt_byte_4, MPT_BYTE_4_KEY_M,
+ MPT_BYTE_4_KEY_S, mr->key);
+ roce_set_field(mpt_entry->mpt_byte_4, MPT_BYTE_4_PAGE_SIZE_M,
+ MPT_BYTE_4_PAGE_SIZE_S, MR_SIZE_4K);
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_MW_TYPE_S, 0);
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_MW_BIND_ENABLE_S,
+ (mr->access & IB_ACCESS_MW_BIND ? 1 : 0));
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_OWN_S, 0);
+ roce_set_field(mpt_entry->mpt_byte_4, MPT_BYTE_4_MEMORY_LOCATION_TYPE_M,
+ MPT_BYTE_4_MEMORY_LOCATION_TYPE_S, mr->type);
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_REMOTE_ATOMIC_S, 0);
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_LOCAL_WRITE_S,
+ (mr->access & IB_ACCESS_LOCAL_WRITE ? 1 : 0));
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_REMOTE_WRITE_S,
+ (mr->access & IB_ACCESS_REMOTE_WRITE ? 1 : 0));
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_REMOTE_READ_S,
+ (mr->access & IB_ACCESS_REMOTE_READ ? 1 : 0));
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_REMOTE_INVAL_ENABLE_S,
+ 0);
+ roce_set_bit(mpt_entry->mpt_byte_4, MPT_BYTE_4_ADDRESS_TYPE_S, 0);
+
+ mpt_entry->pbl_addr_l = 0;
+
+ roce_set_field(mpt_entry->mpt_byte_12, MPT_BYTE_12_PBL_ADDR_H_M,
+ MPT_BYTE_12_PBL_ADDR_H_S, 0);
+ roce_set_field(mpt_entry->mpt_byte_12, MPT_BYTE_12_MW_BIND_COUNTER_M,
+ MPT_BYTE_12_MW_BIND_COUNTER_S, 0);
+
+ mpt_entry->virt_addr_l = (u32)mr->iova;
+ mpt_entry->virt_addr_h = (u32)(mr->iova >> ADDR_SHIFT_32);
+ mpt_entry->length = (u32)mr->size;
+
+ roce_set_field(mpt_entry->mpt_byte_28, MPT_BYTE_28_PD_M,
+ MPT_BYTE_28_PD_S, mr->pd);
+ roce_set_field(mpt_entry->mpt_byte_28, MPT_BYTE_28_L_KEY_IDX_L_M,
+ MPT_BYTE_28_L_KEY_IDX_L_S, mtpt_idx);
+ roce_set_field(mpt_entry->mpt_byte_64, MPT_BYTE_64_L_KEY_IDX_H_M,
+ MPT_BYTE_64_L_KEY_IDX_H_S, mtpt_idx >> MTPT_IDX_SHIFT);
+
+ /* DMA momery regsiter */
+ if (mr->type == MR_TYPE_DMA)
+ return 0;
+
+ pages = (u64 *) __get_free_page(GFP_KERNEL);
+ if (!pages)
+ return -ENOMEM;
+
+ i = 0;
+ for_each_sg(
+ mr->umem->sg_head.sgl, sg,
+ mr->umem->nmap, entry) {
+ pages[i] = ((u64)sg_dma_address(sg)) >> ADDR_SHIFT_12;
+
+ /* Directly record to MTPT table firstly 7 entry */
+ if (i >= HNS_ROCE_MAX_INNER_MTPT_NUM)
+ break;
+ i++;
+ }
+
+ /* Register user mr */
+ for (i = 0; i < HNS_ROCE_MAX_INNER_MTPT_NUM; i++) {
+ switch (i) {
+ case 0:
+ mpt_entry->pa0_l = cpu_to_le32((u32)(pages[i]));
+ roce_set_field(mpt_entry->mpt_byte_36,
+ MPT_BYTE_36_PA0_H_M,
+ MPT_BYTE_36_PA0_H_S,
+ cpu_to_le32((u32)(pages[i] >> PAGES_SHIFT_32)));
+ break;
+ case 1:
+ roce_set_field(mpt_entry->mpt_byte_36,
+ MPT_BYTE_36_PA1_L_M,
+ MPT_BYTE_36_PA1_L_S,
+ cpu_to_le32((u32)(pages[i])));
+ roce_set_field(mpt_entry->mpt_byte_40,
+ MPT_BYTE_40_PA1_H_M,
+ MPT_BYTE_40_PA1_H_S,
+ cpu_to_le32((u32)(pages[i] >> PAGES_SHIFT_24)));
+ break;
+ case 2:
+ roce_set_field(mpt_entry->mpt_byte_40,
+ MPT_BYTE_40_PA2_L_M,
+ MPT_BYTE_40_PA2_L_S,
+ cpu_to_le32((u32)(pages[i])));
+ roce_set_field(mpt_entry->mpt_byte_44,
+ MPT_BYTE_44_PA2_H_M,
+ MPT_BYTE_44_PA2_H_S,
+ cpu_to_le32((u32)(pages[i] >> PAGES_SHIFT_16)));
+ break;
+ case 3:
+ roce_set_field(mpt_entry->mpt_byte_44,
+ MPT_BYTE_44_PA3_L_M,
+ MPT_BYTE_44_PA3_L_S,
+ cpu_to_le32((u32)(pages[i])));
+ roce_set_field(mpt_entry->mpt_byte_48,
+ MPT_BYTE_48_PA3_H_M,
+ MPT_BYTE_48_PA3_H_S,
+ cpu_to_le32((u32)(pages[i] >> PAGES_SHIFT_8)));
+ break;
+ case 4:
+ mpt_entry->pa4_l = cpu_to_le32((u32)(pages[i]));
+ roce_set_field(mpt_entry->mpt_byte_56,
+ MPT_BYTE_56_PA4_H_M,
+ MPT_BYTE_56_PA4_H_S,
+ cpu_to_le32((u32)(pages[i] >> PAGES_SHIFT_32)));
+ break;
+ case 5:
+ roce_set_field(mpt_entry->mpt_byte_56,
+ MPT_BYTE_56_PA5_L_M,
+ MPT_BYTE_56_PA5_L_S,
+ cpu_to_le32((u32)(pages[i])));
+ roce_set_field(mpt_entry->mpt_byte_60,
+ MPT_BYTE_60_PA5_H_M,
+ MPT_BYTE_60_PA5_H_S,
+ cpu_to_le32((u32)(pages[i] >> PAGES_SHIFT_24)));
+ break;
+ case 6:
+ roce_set_field(mpt_entry->mpt_byte_60,
+ MPT_BYTE_60_PA6_L_M,
+ MPT_BYTE_60_PA6_L_S,
+ cpu_to_le32((u32)(pages[i])));
+ roce_set_field(mpt_entry->mpt_byte_64,
+ MPT_BYTE_64_PA6_H_M,
+ MPT_BYTE_64_PA6_H_S,
+ cpu_to_le32((u32)(pages[i] >> PAGES_SHIFT_16)));
+ break;
+ default:
+ break;
+ }
+ }
+
+ free_page((unsigned long) pages);
+
+ mpt_entry->pbl_addr_l = (u32)(mr->pbl_dma_addr);
+
+ roce_set_field(mpt_entry->mpt_byte_12, MPT_BYTE_12_PBL_ADDR_H_M,
+ MPT_BYTE_12_PBL_ADDR_H_S,
+ ((u32)(mr->pbl_dma_addr >> ADDR_SHIFT_32)));
+
+ return 0;
+}
+
+static void *get_cqe(struct hns_roce_cq *hr_cq, int n)
+{
+ return hns_roce_buf_offset(&hr_cq->hr_buf.hr_buf,
+ n * HNS_ROCE_V1_CQE_ENTRY_SIZE);
+}
+
+static void *get_sw_cqe(struct hns_roce_cq *hr_cq, int n)
+{
+ struct hns_roce_cqe *hr_cqe = get_cqe(hr_cq, n & hr_cq->ib_cq.cqe);
+
+ /* Get cqe when Owner bit is Conversely with the MSB of cons_idx */
+ return (!!roce_get_bit(hr_cqe->cqe_byte_4, CQE_BYTE_4_OWNER_S) ^
+ !!(n & (hr_cq->ib_cq.cqe + 1))) ? hr_cqe : NULL;
+}
+
+static struct hns_roce_cqe *next_cqe_sw(struct hns_roce_cq *hr_cq)
+{
+ return get_sw_cqe(hr_cq, hr_cq->cons_index);
+}
+
+void hns_roce_v1_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index,
+ spinlock_t *doorbell_lock)
+
+{
+ u32 doorbell[2];
+
+ doorbell[0] = cons_index & ((hr_cq->cq_depth << 1) - 1);
+ roce_set_bit(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S, 1);
+ roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_M,
+ ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_S, 3);
+ roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_MDF_M,
+ ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_MDF_S, 0);
+ roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_INP_H_M,
+ ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_INP_H_S, hr_cq->cqn);
+
+ hns_roce_write64_k(doorbell, hr_cq->cq_db_l);
+}
+
+static void hns_roce_v1_clean_cq(struct hns_roce_cq *hr_cq, u32 qpn,
+ struct hns_roce_srq *srq)
+{
+ struct hns_roce_cqe *cqe, *dest;
+ u32 prod_index;
+ int nfreed = 0;
+ u8 owner_bit;
+
+ for (prod_index = hr_cq->cons_index; get_sw_cqe(hr_cq, prod_index);
+ ++prod_index) {
+ if (prod_index == hr_cq->cons_index + hr_cq->ib_cq.cqe)
+ break;
+ }
+
+ /*
+ * Now backwards through the CQ, removing CQ entries
+ * that match our QP by overwriting them with next entries.
+ */
+ while ((int) --prod_index - (int) hr_cq->cons_index >= 0) {
+ cqe = get_cqe(hr_cq, prod_index & hr_cq->ib_cq.cqe);
+ if ((roce_get_field(cqe->cqe_byte_16, CQE_BYTE_16_LOCAL_QPN_M,
+ CQE_BYTE_16_LOCAL_QPN_S) &
+ HNS_ROCE_CQE_QPN_MASK) == qpn) {
+ /* In v1 engine, not support SRQ */
+ ++nfreed;
+ } else if (nfreed) {
+ dest = get_cqe(hr_cq, (prod_index + nfreed) &
+ hr_cq->ib_cq.cqe);
+ owner_bit = roce_get_bit(dest->cqe_byte_4,
+ CQE_BYTE_4_OWNER_S);
+ memcpy(dest, cqe, sizeof(*cqe));
+ roce_set_bit(dest->cqe_byte_4, CQE_BYTE_4_OWNER_S,
+ owner_bit);
+ }
+ }
+
+ if (nfreed) {
+ hr_cq->cons_index += nfreed;
+ /*
+ * Make sure update of buffer contents is done before
+ * updating consumer index.
+ */
+ wmb();
+
+ hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index,
+ &to_hr_dev(hr_cq->ib_cq.device)->cq_db_lock);
+ }
+}
+
+static void hns_roce_v1_cq_clean(struct hns_roce_cq *hr_cq, u32 qpn,
+ struct hns_roce_srq *srq)
+{
+ spin_lock_irq(&hr_cq->lock);
+ hns_roce_v1_clean_cq(hr_cq, qpn, srq);
+ spin_unlock_irq(&hr_cq->lock);
+}
+
+void hns_roce_v1_write_cqc(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts,
+ dma_addr_t dma_handle, int nent, u32 vector)
+{
+ struct hns_roce_cq_context *cq_context = NULL;
+ void __iomem *tptr_addr;
+
+ cq_context = mb_buf;
+ memset(cq_context, 0, sizeof(*cq_context));
+
+ tptr_addr = 0;
+ hr_dev->priv_addr = tptr_addr;
+ hr_cq->tptr_addr = tptr_addr;
+
+ /* Register cq_context members */
+ roce_set_field(cq_context->cqc_byte_4,
+ CQ_CONTEXT_CQC_BYTE_4_CQC_STATE_M,
+ CQ_CONTEXT_CQC_BYTE_4_CQC_STATE_S, CQ_STATE_VALID);
+ roce_set_field(cq_context->cqc_byte_4, CQ_CONTEXT_CQC_BYTE_4_CQN_M,
+ CQ_CONTEXT_CQC_BYTE_4_CQN_S, hr_cq->cqn);
+ cq_context->cqc_byte_4 = cpu_to_le32(cq_context->cqc_byte_4);
+
+ cq_context->cq_bt_l = (u32)dma_handle;
+ cq_context->cq_bt_l = cpu_to_le32(cq_context->cq_bt_l);
+
+ roce_set_field(cq_context->cqc_byte_12,
+ CQ_CONTEXT_CQC_BYTE_12_CQ_BT_H_M,
+ CQ_CONTEXT_CQC_BYTE_12_CQ_BT_H_S,
+ ((u64)dma_handle >> ADDR_SHIFT_32));
+ roce_set_field(cq_context->cqc_byte_12,
+ CQ_CONTEXT_CQC_BYTE_12_CQ_CQE_SHIFT_M,
+ CQ_CONTEXT_CQC_BYTE_12_CQ_CQE_SHIFT_S,
+ ilog2(nent));
+ roce_set_field(cq_context->cqc_byte_12, CQ_CONTEXT_CQC_BYTE_12_CEQN_M,
+ CQ_CONTEXT_CQC_BYTE_12_CEQN_S, vector);
+ cq_context->cqc_byte_12 = cpu_to_le32(cq_context->cqc_byte_12);
+
+ cq_context->cur_cqe_ba0_l = (u32)(mtts[0]);
+ cq_context->cur_cqe_ba0_l = cpu_to_le32(cq_context->cur_cqe_ba0_l);
+
+ roce_set_field(cq_context->cqc_byte_20,
+ CQ_CONTEXT_CQC_BYTE_20_CUR_CQE_BA0_H_M,
+ CQ_CONTEXT_CQC_BYTE_20_CUR_CQE_BA0_H_S,
+ cpu_to_le32((mtts[0]) >> ADDR_SHIFT_32));
+ /* Dedicated hardware, directly set 0 */
+ roce_set_field(cq_context->cqc_byte_20,
+ CQ_CONTEXT_CQC_BYTE_20_CQ_CUR_INDEX_M,
+ CQ_CONTEXT_CQC_BYTE_20_CQ_CUR_INDEX_S, 0);
+ roce_set_field(cq_context->cqc_byte_20,
+ CQ_CONTEXT_CQC_BYTE_20_CQE_TPTR_ADDR_H_M,
+ CQ_CONTEXT_CQC_BYTE_20_CQE_TPTR_ADDR_H_S,
+ (u64)tptr_addr >> ADDR_SHIFT_44);
+ cq_context->cqc_byte_20 = cpu_to_le32(cq_context->cqc_byte_20);
+
+ cq_context->cqe_tptr_addr_l = (u32)((u64)tptr_addr >> ADDR_SHIFT_12);
+
+ cq_context->cur_cqe_ba1_l = 0;
+
+ roce_set_field(cq_context->cqc_byte_32,
+ CQ_CONTEXT_CQC_BYTE_32_CUR_CQE_BA1_H_M,
+ CQ_CONTEXT_CQC_BYTE_32_CUR_CQE_BA1_H_S, 0);
+ roce_set_bit(cq_context->cqc_byte_32,
+ CQ_CONTEXT_CQC_BYTE_32_SE_FLAG_S, 0);
+ roce_set_bit(cq_context->cqc_byte_32,
+ CQ_CONTEXT_CQC_BYTE_32_CE_FLAG_S, 0);
+ roce_set_bit(cq_context->cqc_byte_32,
+ CQ_CONTEXT_CQC_BYTE_32_NOTIFICATION_FLAG_S, 0);
+ roce_set_bit(cq_context->cqc_byte_32,
+ CQ_CQNTEXT_CQC_BYTE_32_TYPE_OF_COMPLETION_NOTIFICATION_S,
+ 0);
+ /*The initial value of cq's ci is 0 */
+ roce_set_field(cq_context->cqc_byte_32,
+ CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_M,
+ CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_S, 0);
+ cq_context->cqc_byte_32 = cpu_to_le32(cq_context->cqc_byte_32);
+}
+
+int hns_roce_v1_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
+{
+ struct hns_roce_cq *hr_cq = to_hr_cq(ibcq);
+ u32 notification_flag;
+ u32 doorbell[2];
+ int ret = 0;
+
+ notification_flag = ((u32)flags & (u32)IB_CQ_SOLICITED_MASK) ==
+ (u32)IB_CQ_SOLICITED ? CQ_DB_REQ_NOT :
+ CQ_DB_REQ_NOT_SOL;
+ /*
+ * flags = 0; Notification Flag = 1, next
+ * flags = 1; Notification Flag = 0, solocited
+ */
+ doorbell[0] = hr_cq->cons_index & ((hr_cq->cq_depth << 1) - 1);
+ roce_set_bit(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_HW_SYNS_S, 1);
+ roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_M,
+ ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_S, 3);
+ roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_MDF_M,
+ ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_CMD_MDF_S, 1);
+ roce_set_field(doorbell[1], ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_INP_H_M,
+ ROCEE_DB_OTHERS_H_ROCEE_DB_OTH_INP_H_S,
+ hr_cq->cqn | notification_flag);
+
+ hns_roce_write64_k(doorbell, hr_cq->cq_db_l);
+
+ return ret;
+}
+
+static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
+ struct hns_roce_qp **cur_qp, struct ib_wc *wc)
+{
+ int qpn;
+ int is_send;
+ u16 wqe_ctr;
+ u32 status;
+ u32 opcode;
+ struct hns_roce_cqe *cqe;
+ struct hns_roce_qp *hr_qp;
+ struct hns_roce_wq *wq;
+ struct hns_roce_wqe_ctrl_seg *sq_wqe;
+ struct hns_roce_dev *hr_dev = to_hr_dev(hr_cq->ib_cq.device);
+ struct device *dev = &hr_dev->pdev->dev;
+
+ /* Find cqe according consumer index */
+ cqe = next_cqe_sw(hr_cq);
+ if (!cqe)
+ return -EAGAIN;
+
+ ++hr_cq->cons_index;
+ /* Memory barrier */
+ rmb();
+ /* 0->SQ, 1->RQ */
+ is_send = !(roce_get_bit(cqe->cqe_byte_4, CQE_BYTE_4_SQ_RQ_FLAG_S));
+
+ /* Local_qpn in UD cqe is always 1, so it needs to compute new qpn */
+ if (roce_get_field(cqe->cqe_byte_16, CQE_BYTE_16_LOCAL_QPN_M,
+ CQE_BYTE_16_LOCAL_QPN_S) <= 1) {
+ qpn = roce_get_field(cqe->cqe_byte_20, CQE_BYTE_20_PORT_NUM_M,
+ CQE_BYTE_20_PORT_NUM_S) +
+ roce_get_field(cqe->cqe_byte_16, CQE_BYTE_16_LOCAL_QPN_M,
+ CQE_BYTE_16_LOCAL_QPN_S) *
+ HNS_ROCE_MAX_PORTS;
+ } else {
+ qpn = roce_get_field(cqe->cqe_byte_16, CQE_BYTE_16_LOCAL_QPN_M,
+ CQE_BYTE_16_LOCAL_QPN_S);
+ }
+
+ if (!*cur_qp || (qpn & HNS_ROCE_CQE_QPN_MASK) != (*cur_qp)->qpn) {
+ hr_qp = __hns_roce_qp_lookup(hr_dev, qpn);
+ if (unlikely(!hr_qp)) {
+ dev_err(dev, "CQ %06x with entry for unknown QPN %06x\n",
+ hr_cq->cqn, (qpn & HNS_ROCE_CQE_QPN_MASK));
+ return -EINVAL;
+ }
+
+ *cur_qp = hr_qp;
+ }
+
+ wc->qp = &(*cur_qp)->ibqp;
+ wc->vendor_err = 0;
+
+ status = roce_get_field(cqe->cqe_byte_4,
+ CQE_BYTE_4_STATUS_OF_THE_OPERATION_M,
+ CQE_BYTE_4_STATUS_OF_THE_OPERATION_S) &
+ HNS_ROCE_CQE_STATUS_MASK;
+ switch (status) {
+ case HNS_ROCE_CQE_SUCCESS:
+ wc->status = IB_WC_SUCCESS;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_LOCAL_LENGTH_ERR:
+ wc->status = IB_WC_LOC_LEN_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_LOCAL_QP_OP_ERR:
+ wc->status = IB_WC_LOC_QP_OP_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_LOCAL_PROT_ERR:
+ wc->status = IB_WC_LOC_PROT_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_WR_FLUSH_ERR:
+ wc->status = IB_WC_WR_FLUSH_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_MEM_MANAGE_OPERATE_ERR:
+ wc->status = IB_WC_MW_BIND_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_BAD_RESP_ERR:
+ wc->status = IB_WC_BAD_RESP_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_LOCAL_ACCESS_ERR:
+ wc->status = IB_WC_LOC_ACCESS_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_REMOTE_INVAL_REQ_ERR:
+ wc->status = IB_WC_REM_INV_REQ_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_REMOTE_ACCESS_ERR:
+ wc->status = IB_WC_REM_ACCESS_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_REMOTE_OP_ERR:
+ wc->status = IB_WC_REM_OP_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_TRANSPORT_RETRY_EXC_ERR:
+ wc->status = IB_WC_RETRY_EXC_ERR;
+ break;
+ case HNS_ROCE_CQE_SYNDROME_RNR_RETRY_EXC_ERR:
+ wc->status = IB_WC_RNR_RETRY_EXC_ERR;
+ break;
+ default:
+ wc->status = IB_WC_GENERAL_ERR;
+ break;
+ }
+
+ /* CQE status error, directly return */
+ if (wc->status != IB_WC_SUCCESS)
+ return 0;
+
+ if (is_send) {
+ /* SQ conrespond to CQE */
+ sq_wqe = get_send_wqe(*cur_qp, roce_get_field(cqe->cqe_byte_4,
+ CQE_BYTE_4_WQE_INDEX_M,
+ CQE_BYTE_4_WQE_INDEX_S));
+ switch (sq_wqe->flag & HNS_ROCE_WQE_OPCODE_MASK) {
+ case HNS_ROCE_WQE_OPCODE_SEND:
+ wc->opcode = IB_WC_SEND;
+ break;
+ case HNS_ROCE_WQE_OPCODE_RDMA_READ:
+ wc->opcode = IB_WC_RDMA_READ;
+ wc->byte_len = le32_to_cpu(cqe->byte_cnt);
+ break;
+ case HNS_ROCE_WQE_OPCODE_RDMA_WRITE:
+ wc->opcode = IB_WC_RDMA_WRITE;
+ break;
+ case HNS_ROCE_WQE_OPCODE_LOCAL_INV:
+ wc->opcode = IB_WC_LOCAL_INV;
+ break;
+ case HNS_ROCE_WQE_OPCODE_UD_SEND:
+ wc->opcode = IB_WC_SEND;
+ break;
+ default:
+ wc->status = IB_WC_GENERAL_ERR;
+ break;
+ }
+ wc->wc_flags = (sq_wqe->flag & HNS_ROCE_WQE_IMM ?
+ IB_WC_WITH_IMM : 0);
+
+ wq = &(*cur_qp)->sq;
+ if ((*cur_qp)->sq_signal_bits) {
+ /*
+ * If sg_signal_bit is 1,
+ * firstly tail pointer updated to wqe
+ * which current cqe correspond to
+ */
+ wqe_ctr = (u16)roce_get_field(cqe->cqe_byte_4,
+ CQE_BYTE_4_WQE_INDEX_M,
+ CQE_BYTE_4_WQE_INDEX_S);
+ wq->tail += (wqe_ctr - (u16)wq->tail) &
+ (wq->wqe_cnt - 1);
+ }
+ wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
+ ++wq->tail;
+ } else {
+ /* RQ conrespond to CQE */
+ wc->byte_len = le32_to_cpu(cqe->byte_cnt);
+ opcode = roce_get_field(cqe->cqe_byte_4,
+ CQE_BYTE_4_OPERATION_TYPE_M,
+ CQE_BYTE_4_OPERATION_TYPE_S) &
+ HNS_ROCE_CQE_OPCODE_MASK;
+ switch (opcode) {
+ case HNS_ROCE_OPCODE_RDMA_WITH_IMM_RECEIVE:
+ wc->opcode = IB_WC_RECV_RDMA_WITH_IMM;
+ wc->wc_flags = IB_WC_WITH_IMM;
+ wc->ex.imm_data = le32_to_cpu(cqe->immediate_data);
+ break;
+ case HNS_ROCE_OPCODE_SEND_DATA_RECEIVE:
+ if (roce_get_bit(cqe->cqe_byte_4,
+ CQE_BYTE_4_IMM_INDICATOR_S)) {
+ wc->opcode = IB_WC_RECV;
+ wc->wc_flags = IB_WC_WITH_IMM;
+ wc->ex.imm_data = le32_to_cpu(
+ cqe->immediate_data);
+ } else {
+ wc->opcode = IB_WC_RECV;
+ wc->wc_flags = 0;
+ }
+ break;
+ default:
+ wc->status = IB_WC_GENERAL_ERR;
+ break;
+ }
+
+ /* Update tail pointer, record wr_id */
+ wq = &(*cur_qp)->rq;
+ wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
+ ++wq->tail;
+ wc->sl = (u8)roce_get_field(cqe->cqe_byte_20, CQE_BYTE_20_SL_M,
+ CQE_BYTE_20_SL_S);
+ wc->src_qp = (u8)roce_get_field(cqe->cqe_byte_20,
+ CQE_BYTE_20_REMOTE_QPN_M,
+ CQE_BYTE_20_REMOTE_QPN_S);
+ wc->wc_flags |= (roce_get_bit(cqe->cqe_byte_20,
+ CQE_BYTE_20_GRH_PRESENT_S) ?
+ IB_WC_GRH : 0);
+ wc->pkey_index = (u16)roce_get_field(cqe->cqe_byte_28,
+ CQE_BYTE_28_P_KEY_IDX_M,
+ CQE_BYTE_28_P_KEY_IDX_S);
+ }
+
+ return 0;
+}
+
+int hns_roce_v1_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
+{
+ struct hns_roce_cq *hr_cq = to_hr_cq(ibcq);
+ struct hns_roce_qp *cur_qp = NULL;
+ unsigned long flags;
+ int npolled;
+ int ret = 0;
+
+ spin_lock_irqsave(&hr_cq->lock, flags);
+
+ for (npolled = 0; npolled < num_entries; ++npolled) {
+ ret = hns_roce_v1_poll_one(hr_cq, &cur_qp, wc + npolled);
+ if (ret)
+ break;
+ }
+
+ if (npolled) {
+ hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index,
+ &to_hr_dev(ibcq->device)->cq_db_lock);
+ }
+
+ spin_unlock_irqrestore(&hr_cq->lock, flags);
+
+ if (ret == 0 || ret == -EAGAIN)
+ return npolled;
+ else
+ return ret;
+}
+
+static int hns_roce_v1_qp_modify(struct hns_roce_dev *hr_dev,
+ struct hns_roce_mtt *mtt,
+ enum hns_roce_qp_state cur_state,
+ enum hns_roce_qp_state new_state,
+ struct hns_roce_qp_context *context,
+ struct hns_roce_qp *hr_qp)
+{
+ static const u16
+ op[HNS_ROCE_QP_NUM_STATE][HNS_ROCE_QP_NUM_STATE] = {
+ [HNS_ROCE_QP_STATE_RST] = {
+ [HNS_ROCE_QP_STATE_RST] = HNS_ROCE_CMD_2RST_QP,
+ [HNS_ROCE_QP_STATE_ERR] = HNS_ROCE_CMD_2ERR_QP,
+ [HNS_ROCE_QP_STATE_INIT] = HNS_ROCE_CMD_RST2INIT_QP,
+ },
+ [HNS_ROCE_QP_STATE_INIT] = {
+ [HNS_ROCE_QP_STATE_RST] = HNS_ROCE_CMD_2RST_QP,
+ [HNS_ROCE_QP_STATE_ERR] = HNS_ROCE_CMD_2ERR_QP,
+ /* Note: In v1 engine, HW doesn't support RST2INIT.
+ * We use RST2INIT cmd instead of INIT2INIT.
+ */
+ [HNS_ROCE_QP_STATE_INIT] = HNS_ROCE_CMD_RST2INIT_QP,
+ [HNS_ROCE_QP_STATE_RTR] = HNS_ROCE_CMD_INIT2RTR_QP,
+ },
+ [HNS_ROCE_QP_STATE_RTR] = {
+ [HNS_ROCE_QP_STATE_RST] = HNS_ROCE_CMD_2RST_QP,
+ [HNS_ROCE_QP_STATE_ERR] = HNS_ROCE_CMD_2ERR_QP,
+ [HNS_ROCE_QP_STATE_RTS] = HNS_ROCE_CMD_RTR2RTS_QP,
+ },
+ [HNS_ROCE_QP_STATE_RTS] = {
+ [HNS_ROCE_QP_STATE_RST] = HNS_ROCE_CMD_2RST_QP,
+ [HNS_ROCE_QP_STATE_ERR] = HNS_ROCE_CMD_2ERR_QP,
+ [HNS_ROCE_QP_STATE_RTS] = HNS_ROCE_CMD_RTS2RTS_QP,
+ [HNS_ROCE_QP_STATE_SQD] = HNS_ROCE_CMD_RTS2SQD_QP,
+ },
+ [HNS_ROCE_QP_STATE_SQD] = {
+ [HNS_ROCE_QP_STATE_RST] = HNS_ROCE_CMD_2RST_QP,
+ [HNS_ROCE_QP_STATE_ERR] = HNS_ROCE_CMD_2ERR_QP,
+ [HNS_ROCE_QP_STATE_RTS] = HNS_ROCE_CMD_SQD2RTS_QP,
+ [HNS_ROCE_QP_STATE_SQD] = HNS_ROCE_CMD_SQD2SQD_QP,
+ },
+ [HNS_ROCE_QP_STATE_ERR] = {
+ [HNS_ROCE_QP_STATE_RST] = HNS_ROCE_CMD_2RST_QP,
+ [HNS_ROCE_QP_STATE_ERR] = HNS_ROCE_CMD_2ERR_QP,
+ }
+ };
+
+ struct hns_roce_cmd_mailbox *mailbox;
+ struct device *dev = &hr_dev->pdev->dev;
+ int ret = 0;
+
+ if (cur_state >= HNS_ROCE_QP_NUM_STATE ||
+ new_state >= HNS_ROCE_QP_NUM_STATE ||
+ !op[cur_state][new_state]) {
+ dev_err(dev, "[modify_qp]not support state %d to %d\n",
+ cur_state, new_state);
+ return -EINVAL;
+ }
+
+ if (op[cur_state][new_state] == HNS_ROCE_CMD_2RST_QP)
+ return hns_roce_cmd(hr_dev, 0, hr_qp->qpn, 2,
+ HNS_ROCE_CMD_2RST_QP,
+ HNS_ROCE_CMD_TIME_CLASS_A);
+
+ if (op[cur_state][new_state] == HNS_ROCE_CMD_2ERR_QP)
+ return hns_roce_cmd(hr_dev, 0, hr_qp->qpn, 2,
+ HNS_ROCE_CMD_2ERR_QP,
+ HNS_ROCE_CMD_TIME_CLASS_A);
+
+ mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
+ if (IS_ERR(mailbox)) {
+ dev_err(dev, "[modify_qp]mailboc alloc failed!\n");
+ return PTR_ERR(mailbox);
+ }
+
+ memcpy(mailbox->buf, context, sizeof(*context));
+
+ ret = hns_roce_cmd(hr_dev, mailbox->dma, hr_qp->qpn, 0,
+ op[cur_state][new_state], HNS_ROCE_CMD_TIME_CLASS_C);
+
+ hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+ return ret;
+}
+
+static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
+ int attr_mask, enum ib_qp_state cur_state,
+ enum ib_qp_state new_state)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ struct hns_roce_sqp_context *context;
+ struct device *dev = &hr_dev->pdev->dev;
+ dma_addr_t dma_handle = 0;
+ int rq_pa_start;
+ u32 reg_val;
+ u64 *mtts;
+ u32 *addr;
+
+ context = kzalloc(sizeof(*context), GFP_KERNEL);
+ if (!context)
+ return -ENOMEM;
+
+ /* Search QP buf's MTTs */
+ mtts = hns_roce_table_find(&hr_dev->mr_table.mtt_table,
+ hr_qp->mtt.first_seg, &dma_handle);
+ if (!mtts) {
+ dev_err(dev, "qp buf pa find failed\n");
+ goto out;
+ }
+
+ if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+ roce_set_field(context->qp1c_bytes_4,
+ QP1C_BYTES_4_SQ_WQE_SHIFT_M,
+ QP1C_BYTES_4_SQ_WQE_SHIFT_S,
+ ilog2(hr_qp->sq.wqe_cnt));
+ roce_set_field(context->qp1c_bytes_4,
+ QP1C_BYTES_4_RQ_WQE_SHIFT_M,
+ QP1C_BYTES_4_RQ_WQE_SHIFT_S,
+ ilog2(hr_qp->rq.wqe_cnt));
+ roce_set_field(context->qp1c_bytes_4, QP1C_BYTES_4_PD_M,
+ QP1C_BYTES_4_PD_S, to_hr_pd(ibqp->pd)->pdn);
+
+ context->sq_rq_bt_l = (u32)(dma_handle);
+ roce_set_field(context->qp1c_bytes_12,
+ QP1C_BYTES_12_SQ_RQ_BT_H_M,
+ QP1C_BYTES_12_SQ_RQ_BT_H_S,
+ ((u32)(dma_handle >> ADDR_SHIFT_32)));
+
+ roce_set_field(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_HEAD_M,
+ QP1C_BYTES_16_RQ_HEAD_S, hr_qp->rq.head);
+ roce_set_field(context->qp1c_bytes_16, QP1C_BYTES_16_PORT_NUM_M,
+ QP1C_BYTES_16_PORT_NUM_S, hr_qp->port);
+ roce_set_bit(context->qp1c_bytes_16,
+ QP1C_BYTES_16_SIGNALING_TYPE_S,
+ hr_qp->sq_signal_bits);
+ roce_set_bit(context->qp1c_bytes_16,
+ QP1C_BYTES_16_LOCAL_ENABLE_E2E_CREDIT_S,
+ hr_qp->sq_signal_bits);
+ roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_BA_FLG_S,
+ 1);
+ roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SQ_BA_FLG_S,
+ 1);
+ roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_QP1_ERR_S,
+ 0);
+
+ roce_set_field(context->qp1c_bytes_20, QP1C_BYTES_20_SQ_HEAD_M,
+ QP1C_BYTES_20_SQ_HEAD_S, hr_qp->sq.head);
+ roce_set_field(context->qp1c_bytes_20, QP1C_BYTES_20_PKEY_IDX_M,
+ QP1C_BYTES_20_PKEY_IDX_S, attr->pkey_index);
+
+ rq_pa_start = (u32)hr_qp->rq.offset / PAGE_SIZE;
+ context->cur_rq_wqe_ba_l = (u32)(mtts[rq_pa_start]);
+
+ roce_set_field(context->qp1c_bytes_28,
+ QP1C_BYTES_28_CUR_RQ_WQE_BA_H_M,
+ QP1C_BYTES_28_CUR_RQ_WQE_BA_H_S,
+ (mtts[rq_pa_start]) >> ADDR_SHIFT_32);
+ roce_set_field(context->qp1c_bytes_28,
+ QP1C_BYTES_28_RQ_CUR_IDX_M,
+ QP1C_BYTES_28_RQ_CUR_IDX_S, 0);
+
+ roce_set_field(context->qp1c_bytes_32,
+ QP1C_BYTES_32_RX_CQ_NUM_M,
+ QP1C_BYTES_32_RX_CQ_NUM_S,
+ to_hr_cq(ibqp->recv_cq)->cqn);
+ roce_set_field(context->qp1c_bytes_32,
+ QP1C_BYTES_32_TX_CQ_NUM_M,
+ QP1C_BYTES_32_TX_CQ_NUM_S,
+ to_hr_cq(ibqp->send_cq)->cqn);
+
+ context->cur_sq_wqe_ba_l = (u32)mtts[0];
+
+ roce_set_field(context->qp1c_bytes_40,
+ QP1C_BYTES_40_CUR_SQ_WQE_BA_H_M,
+ QP1C_BYTES_40_CUR_SQ_WQE_BA_H_S,
+ (mtts[0]) >> ADDR_SHIFT_32);
+ roce_set_field(context->qp1c_bytes_40,
+ QP1C_BYTES_40_SQ_CUR_IDX_M,
+ QP1C_BYTES_40_SQ_CUR_IDX_S, 0);
+
+ /* Copy context to QP1C register */
+ addr = (u32 *)(hr_dev->reg_base + ROCEE_QP1C_CFG0_0_REG +
+ hr_qp->port * sizeof(*context));
+
+ roce_writel(context->qp1c_bytes_4, addr);
+ roce_writel(context->sq_rq_bt_l, addr + 1);
+ roce_writel(context->qp1c_bytes_12, addr + 2);
+ roce_writel(context->qp1c_bytes_16, addr + 3);
+ roce_writel(context->qp1c_bytes_20, addr + 4);
+ roce_writel(context->cur_rq_wqe_ba_l, addr + 5);
+ roce_writel(context->qp1c_bytes_28, addr + 6);
+ roce_writel(context->qp1c_bytes_32, addr + 7);
+ roce_writel(context->cur_sq_wqe_ba_l, addr + 8);
+ }
+
+ /* Modify QP1C status */
+ addr = (u32 *)(hr_dev->reg_base + ROCEE_QP1C_CFG0_0_REG +
+ hr_qp->port * sizeof(*context));
+ reg_val = roce_readl(addr);
+ roce_set_field(reg_val, ROCEE_QP1C_CFG0_0_ROCEE_QP1C_QP_ST_M,
+ ROCEE_QP1C_CFG0_0_ROCEE_QP1C_QP_ST_S, new_state);
+ roce_writel(reg_val, addr);
+
+ hr_qp->state = new_state;
+ if (new_state == IB_QPS_RESET) {
+ hns_roce_v1_cq_clean(to_hr_cq(ibqp->recv_cq), hr_qp->qpn,
+ ibqp->srq ? to_hr_srq(ibqp->srq) : NULL);
+ if (ibqp->send_cq != ibqp->recv_cq)
+ hns_roce_v1_cq_clean(to_hr_cq(ibqp->send_cq),
+ hr_qp->qpn, NULL);
+
+ hr_qp->rq.head = 0;
+ hr_qp->rq.tail = 0;
+ hr_qp->sq.head = 0;
+ hr_qp->sq.tail = 0;
+ hr_qp->sq_next_wqe = 0;
+ }
+
+ kfree(context);
+ return 0;
+
+out:
+ kfree(context);
+ return -EINVAL;
+}
+
+static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
+ int attr_mask, enum ib_qp_state cur_state,
+ enum ib_qp_state new_state)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_qp_context *context;
+ dma_addr_t dma_handle_2 = 0;
+ dma_addr_t dma_handle = 0;
+ int rq_pa_start = 0;
+ u64 *mtts_2 = NULL;
+ int ret = -EINVAL;
+ u64 *mtts = NULL;
+ int port;
+ u8 *dmac;
+ u8 *smac;
+
+ context = kzalloc(sizeof(*context), GFP_KERNEL);
+ if (!context)
+ return -ENOMEM;
+
+ /* Search qp buf's mtts */
+ mtts = hns_roce_table_find(&hr_dev->mr_table.mtt_table,
+ hr_qp->mtt.first_seg, &dma_handle);
+ if (mtts == NULL) {
+ dev_err(dev, "qp buf pa find failed\n");
+ goto out;
+ }
+
+ /* Search IRRL's mtts */
+ mtts_2 = hns_roce_table_find(&hr_dev->qp_table.irrl_table, hr_qp->qpn,
+ &dma_handle_2);
+ if (mtts_2 == NULL) {
+ dev_err(dev, "qp irrl_table find failed\n");
+ goto out;
+ }
+
+ /*
+ *Reset to init
+ * Mandatory param:
+ * IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_ACCESS_FLAGS
+ * Optional param: NA
+ */
+ if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_M,
+ QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_S,
+ to_hr_qp_type(hr_qp->ibqp.qp_type));
+
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_ENABLE_FPMR_S, 0);
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMA_READ_ENABLE_S,
+ !!(attr->qp_access_flags & IB_ACCESS_REMOTE_READ));
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMA_WRITE_ENABLE_S,
+ !!(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE)
+ );
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_ATOMIC_OPERATION_ENABLE_S,
+ !!(attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC)
+ );
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMAR_USE_S, 1);
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_SQ_WQE_SHIFT_M,
+ QP_CONTEXT_QPC_BYTES_4_SQ_WQE_SHIFT_S,
+ ilog2(hr_qp->sq.wqe_cnt));
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_RQ_WQE_SHIFT_M,
+ QP_CONTEXT_QPC_BYTES_4_RQ_WQE_SHIFT_S,
+ ilog2(hr_qp->rq.wqe_cnt));
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_PD_M,
+ QP_CONTEXT_QPC_BYTES_4_PD_S,
+ to_hr_pd(ibqp->pd)->pdn);
+ hr_qp->access_flags = attr->qp_access_flags;
+ roce_set_field(context->qpc_bytes_8,
+ QP_CONTEXT_QPC_BYTES_8_TX_COMPLETION_M,
+ QP_CONTEXT_QPC_BYTES_8_TX_COMPLETION_S,
+ to_hr_cq(ibqp->send_cq)->cqn);
+ roce_set_field(context->qpc_bytes_8,
+ QP_CONTEXT_QPC_BYTES_8_RX_COMPLETION_M,
+ QP_CONTEXT_QPC_BYTES_8_RX_COMPLETION_S,
+ to_hr_cq(ibqp->recv_cq)->cqn);
+
+ if (ibqp->srq)
+ roce_set_field(context->qpc_bytes_12,
+ QP_CONTEXT_QPC_BYTES_12_SRQ_NUMBER_M,
+ QP_CONTEXT_QPC_BYTES_12_SRQ_NUMBER_S,
+ to_hr_srq(ibqp->srq)->srqn);
+
+ roce_set_field(context->qpc_bytes_12,
+ QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S,
+ attr->pkey_index);
+ hr_qp->pkey_index = attr->pkey_index;
+ roce_set_field(context->qpc_bytes_16,
+ QP_CONTEXT_QPC_BYTES_16_QP_NUM_M,
+ QP_CONTEXT_QPC_BYTES_16_QP_NUM_S, hr_qp->qpn);
+
+ } else if (cur_state == IB_QPS_INIT &&
+ new_state == IB_QPS_INIT) {
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_M,
+ QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_S,
+ to_hr_qp_type(hr_qp->ibqp.qp_type));
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_ENABLE_FPMR_S, 0);
+ if (attr_mask & IB_QP_ACCESS_FLAGS) {
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMA_READ_ENABLE_S,
+ !!(attr->qp_access_flags &
+ IB_ACCESS_REMOTE_READ));
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMA_WRITE_ENABLE_S,
+ !!(attr->qp_access_flags &
+ IB_ACCESS_REMOTE_WRITE));
+ } else {
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMA_READ_ENABLE_S,
+ !!(hr_qp->access_flags &
+ IB_ACCESS_REMOTE_READ));
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMA_WRITE_ENABLE_S,
+ !!(hr_qp->access_flags &
+ IB_ACCESS_REMOTE_WRITE));
+ }
+
+ roce_set_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMAR_USE_S, 1);
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_SQ_WQE_SHIFT_M,
+ QP_CONTEXT_QPC_BYTES_4_SQ_WQE_SHIFT_S,
+ ilog2(hr_qp->sq.wqe_cnt));
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_RQ_WQE_SHIFT_M,
+ QP_CONTEXT_QPC_BYTES_4_RQ_WQE_SHIFT_S,
+ ilog2(hr_qp->rq.wqe_cnt));
+ roce_set_field(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTES_4_PD_M,
+ QP_CONTEXT_QPC_BYTES_4_PD_S,
+ to_hr_pd(ibqp->pd)->pdn);
+
+ roce_set_field(context->qpc_bytes_8,
+ QP_CONTEXT_QPC_BYTES_8_TX_COMPLETION_M,
+ QP_CONTEXT_QPC_BYTES_8_TX_COMPLETION_S,
+ to_hr_cq(ibqp->send_cq)->cqn);
+ roce_set_field(context->qpc_bytes_8,
+ QP_CONTEXT_QPC_BYTES_8_RX_COMPLETION_M,
+ QP_CONTEXT_QPC_BYTES_8_RX_COMPLETION_S,
+ to_hr_cq(ibqp->recv_cq)->cqn);
+
+ if (ibqp->srq)
+ roce_set_field(context->qpc_bytes_12,
+ QP_CONTEXT_QPC_BYTES_12_SRQ_NUMBER_M,
+ QP_CONTEXT_QPC_BYTES_12_SRQ_NUMBER_S,
+ to_hr_srq(ibqp->srq)->srqn);
+ if (attr_mask & IB_QP_PKEY_INDEX)
+ roce_set_field(context->qpc_bytes_12,
+ QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S,
+ attr->pkey_index);
+ else
+ roce_set_field(context->qpc_bytes_12,
+ QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S,
+ hr_qp->pkey_index);
+
+ roce_set_field(context->qpc_bytes_16,
+ QP_CONTEXT_QPC_BYTES_16_QP_NUM_M,
+ QP_CONTEXT_QPC_BYTES_16_QP_NUM_S, hr_qp->qpn);
+ } else if (cur_state == IB_QPS_INIT &&
+ new_state == IB_QPS_RTR) {
+ if ((attr_mask & IB_QP_ALT_PATH) ||
+ (attr_mask & IB_QP_ACCESS_FLAGS) ||
+ (attr_mask & IB_QP_PKEY_INDEX) ||
+ (attr_mask & IB_QP_QKEY)) {
+ dev_err(dev, "INIT2RTR attr_mask error\n");
+ goto out;
+ }
+
+ dmac = (u8 *)attr->ah_attr.dmac;
+
+ context->sq_rq_bt_l = (u32)(dma_handle);
+ roce_set_field(context->qpc_bytes_24,
+ QP_CONTEXT_QPC_BYTES_24_SQ_RQ_BT_H_M,
+ QP_CONTEXT_QPC_BYTES_24_SQ_RQ_BT_H_S,
+ ((u32)(dma_handle >> ADDR_SHIFT_32)));
+ roce_set_bit(context->qpc_bytes_24,
+ QP_CONTEXT_QPC_BYTE_24_REMOTE_ENABLE_E2E_CREDITS_S,
+ 1);
+ roce_set_field(context->qpc_bytes_24,
+ QP_CONTEXT_QPC_BYTES_24_MINIMUM_RNR_NAK_TIMER_M,
+ QP_CONTEXT_QPC_BYTES_24_MINIMUM_RNR_NAK_TIMER_S,
+ attr->min_rnr_timer);
+ context->irrl_ba_l = (u32)(dma_handle_2);
+ roce_set_field(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTES_32_IRRL_BA_H_M,
+ QP_CONTEXT_QPC_BYTES_32_IRRL_BA_H_S,
+ ((u32)(dma_handle_2 >> 32)) &
+ QP_CONTEXT_QPC_BYTES_32_IRRL_BA_H_M);
+ roce_set_field(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTES_32_MIG_STATE_M,
+ QP_CONTEXT_QPC_BYTES_32_MIG_STATE_S, 0);
+ roce_set_bit(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTE_32_LOCAL_ENABLE_E2E_CREDITS_S,
+ 1);
+ roce_set_bit(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTE_32_SIGNALING_TYPE_S,
+ hr_qp->sq_signal_bits);
+
+ for (port = 0; port < hr_dev->caps.num_ports; port++) {
+ smac = (u8 *)hr_dev->dev_addr[port];
+ dev_dbg(dev, "smac: %2x: %2x: %2x: %2x: %2x: %2x\n",
+ smac[0], smac[1], smac[2], smac[3], smac[4],
+ smac[5]);
+ if ((dmac[0] == smac[0]) && (dmac[1] == smac[1]) &&
+ (dmac[2] == smac[2]) && (dmac[3] == smac[3]) &&
+ (dmac[4] == smac[4]) && (dmac[5] == smac[5])) {
+ roce_set_bit(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S,
+ 1);
+ break;
+ }
+ }
+
+ if (hr_dev->loop_idc == 0x1)
+ roce_set_bit(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S, 1);
+
+ roce_set_bit(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTE_32_GLOBAL_HEADER_S,
+ attr->ah_attr.ah_flags);
+ roce_set_field(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTES_32_RESPONDER_RESOURCES_M,
+ QP_CONTEXT_QPC_BYTES_32_RESPONDER_RESOURCES_S,
+ ilog2(attr->max_dest_rd_atomic));
+
+ roce_set_field(context->qpc_bytes_36,
+ QP_CONTEXT_QPC_BYTES_36_DEST_QP_M,
+ QP_CONTEXT_QPC_BYTES_36_DEST_QP_S,
+ attr->dest_qp_num);
+
+ /* Configure GID index */
+ roce_set_field(context->qpc_bytes_36,
+ QP_CONTEXT_QPC_BYTES_36_SGID_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_36_SGID_INDEX_S,
+ hns_get_gid_index(hr_dev,
+ attr->ah_attr.port_num - 1,
+ attr->ah_attr.grh.sgid_index));
+
+ memcpy(&(context->dmac_l), dmac, 4);
+
+ roce_set_field(context->qpc_bytes_44,
+ QP_CONTEXT_QPC_BYTES_44_DMAC_H_M,
+ QP_CONTEXT_QPC_BYTES_44_DMAC_H_S,
+ *((u16 *)(&dmac[4])));
+ roce_set_field(context->qpc_bytes_44,
+ QP_CONTEXT_QPC_BYTES_44_MAXIMUM_STATIC_RATE_M,
+ QP_CONTEXT_QPC_BYTES_44_MAXIMUM_STATIC_RATE_S,
+ attr->ah_attr.static_rate);
+ roce_set_field(context->qpc_bytes_44,
+ QP_CONTEXT_QPC_BYTES_44_HOPLMT_M,
+ QP_CONTEXT_QPC_BYTES_44_HOPLMT_S,
+ attr->ah_attr.grh.hop_limit);
+
+ roce_set_field(context->qpc_bytes_48,
+ QP_CONTEXT_QPC_BYTES_48_FLOWLABEL_M,
+ QP_CONTEXT_QPC_BYTES_48_FLOWLABEL_S,
+ attr->ah_attr.grh.flow_label);
+ roce_set_field(context->qpc_bytes_48,
+ QP_CONTEXT_QPC_BYTES_48_TCLASS_M,
+ QP_CONTEXT_QPC_BYTES_48_TCLASS_S,
+ attr->ah_attr.grh.traffic_class);
+ roce_set_field(context->qpc_bytes_48,
+ QP_CONTEXT_QPC_BYTES_48_MTU_M,
+ QP_CONTEXT_QPC_BYTES_48_MTU_S, attr->path_mtu);
+
+ memcpy(context->dgid, attr->ah_attr.grh.dgid.raw,
+ sizeof(attr->ah_attr.grh.dgid.raw));
+
+ dev_dbg(dev, "dmac:%x :%lx\n", context->dmac_l,
+ roce_get_field(context->qpc_bytes_44,
+ QP_CONTEXT_QPC_BYTES_44_DMAC_H_M,
+ QP_CONTEXT_QPC_BYTES_44_DMAC_H_S));
+
+ roce_set_field(context->qpc_bytes_68,
+ QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_M,
+ QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, 0);
+ roce_set_field(context->qpc_bytes_68,
+ QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_S, 0);
+
+ rq_pa_start = (u32)hr_qp->rq.offset / PAGE_SIZE;
+ context->cur_rq_wqe_ba_l = (u32)(mtts[rq_pa_start]);
+
+ roce_set_field(context->qpc_bytes_76,
+ QP_CONTEXT_QPC_BYTES_76_CUR_RQ_WQE_BA_H_M,
+ QP_CONTEXT_QPC_BYTES_76_CUR_RQ_WQE_BA_H_S,
+ mtts[rq_pa_start] >> ADDR_SHIFT_32);
+ roce_set_field(context->qpc_bytes_76,
+ QP_CONTEXT_QPC_BYTES_76_RX_REQ_MSN_M,
+ QP_CONTEXT_QPC_BYTES_76_RX_REQ_MSN_S, 0);
+
+ context->rx_rnr_time = 0;
+
+ roce_set_field(context->qpc_bytes_84,
+ QP_CONTEXT_QPC_BYTES_84_LAST_ACK_PSN_M,
+ QP_CONTEXT_QPC_BYTES_84_LAST_ACK_PSN_S,
+ attr->rq_psn - 1);
+ roce_set_field(context->qpc_bytes_84,
+ QP_CONTEXT_QPC_BYTES_84_TRRL_HEAD_M,
+ QP_CONTEXT_QPC_BYTES_84_TRRL_HEAD_S, 0);
+
+ roce_set_field(context->qpc_bytes_88,
+ QP_CONTEXT_QPC_BYTES_88_RX_REQ_EPSN_M,
+ QP_CONTEXT_QPC_BYTES_88_RX_REQ_EPSN_S,
+ attr->rq_psn);
+ roce_set_bit(context->qpc_bytes_88,
+ QP_CONTEXT_QPC_BYTES_88_RX_REQ_PSN_ERR_FLAG_S, 0);
+ roce_set_bit(context->qpc_bytes_88,
+ QP_CONTEXT_QPC_BYTES_88_RX_LAST_OPCODE_FLG_S, 0);
+ roce_set_field(context->qpc_bytes_88,
+ QP_CONTEXT_QPC_BYTES_88_RQ_REQ_LAST_OPERATION_TYPE_M,
+ QP_CONTEXT_QPC_BYTES_88_RQ_REQ_LAST_OPERATION_TYPE_S,
+ 0);
+ roce_set_field(context->qpc_bytes_88,
+ QP_CONTEXT_QPC_BYTES_88_RQ_REQ_RDMA_WR_FLAG_M,
+ QP_CONTEXT_QPC_BYTES_88_RQ_REQ_RDMA_WR_FLAG_S,
+ 0);
+
+ context->dma_length = 0;
+ context->r_key = 0;
+ context->va_l = 0;
+ context->va_h = 0;
+
+ roce_set_field(context->qpc_bytes_108,
+ QP_CONTEXT_QPC_BYTES_108_TRRL_SDB_PSN_M,
+ QP_CONTEXT_QPC_BYTES_108_TRRL_SDB_PSN_S, 0);
+ roce_set_bit(context->qpc_bytes_108,
+ QP_CONTEXT_QPC_BYTES_108_TRRL_SDB_PSN_FLG_S, 0);
+ roce_set_bit(context->qpc_bytes_108,
+ QP_CONTEXT_QPC_BYTES_108_TRRL_TDB_PSN_FLG_S, 0);
+
+ roce_set_field(context->qpc_bytes_112,
+ QP_CONTEXT_QPC_BYTES_112_TRRL_TDB_PSN_M,
+ QP_CONTEXT_QPC_BYTES_112_TRRL_TDB_PSN_S, 0);
+ roce_set_field(context->qpc_bytes_112,
+ QP_CONTEXT_QPC_BYTES_112_TRRL_TAIL_M,
+ QP_CONTEXT_QPC_BYTES_112_TRRL_TAIL_S, 0);
+
+ /* For chip resp ack */
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M,
+ QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S,
+ hr_qp->port);
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_SL_M,
+ QP_CONTEXT_QPC_BYTES_156_SL_S, attr->ah_attr.sl);
+ hr_qp->sl = attr->ah_attr.sl;
+ } else if (cur_state == IB_QPS_RTR &&
+ new_state == IB_QPS_RTS) {
+ /* If exist optional param, return error */
+ if ((attr_mask & IB_QP_ALT_PATH) ||
+ (attr_mask & IB_QP_ACCESS_FLAGS) ||
+ (attr_mask & IB_QP_QKEY) ||
+ (attr_mask & IB_QP_PATH_MIG_STATE) ||
+ (attr_mask & IB_QP_CUR_STATE) ||
+ (attr_mask & IB_QP_MIN_RNR_TIMER)) {
+ dev_err(dev, "RTR2RTS attr_mask error\n");
+ goto out;
+ }
+
+ context->rx_cur_sq_wqe_ba_l = (u32)(mtts[0]);
+
+ roce_set_field(context->qpc_bytes_120,
+ QP_CONTEXT_QPC_BYTES_120_RX_CUR_SQ_WQE_BA_H_M,
+ QP_CONTEXT_QPC_BYTES_120_RX_CUR_SQ_WQE_BA_H_S,
+ (mtts[0]) >> ADDR_SHIFT_32);
+
+ roce_set_field(context->qpc_bytes_124,
+ QP_CONTEXT_QPC_BYTES_124_RX_ACK_MSN_M,
+ QP_CONTEXT_QPC_BYTES_124_RX_ACK_MSN_S, 0);
+ roce_set_field(context->qpc_bytes_124,
+ QP_CONTEXT_QPC_BYTES_124_IRRL_MSG_IDX_M,
+ QP_CONTEXT_QPC_BYTES_124_IRRL_MSG_IDX_S, 0);
+
+ roce_set_field(context->qpc_bytes_128,
+ QP_CONTEXT_QPC_BYTES_128_RX_ACK_EPSN_M,
+ QP_CONTEXT_QPC_BYTES_128_RX_ACK_EPSN_S,
+ attr->sq_psn);
+ roce_set_bit(context->qpc_bytes_128,
+ QP_CONTEXT_QPC_BYTES_128_RX_ACK_PSN_ERR_FLG_S, 0);
+ roce_set_field(context->qpc_bytes_128,
+ QP_CONTEXT_QPC_BYTES_128_ACK_LAST_OPERATION_TYPE_M,
+ QP_CONTEXT_QPC_BYTES_128_ACK_LAST_OPERATION_TYPE_S,
+ 0);
+ roce_set_bit(context->qpc_bytes_128,
+ QP_CONTEXT_QPC_BYTES_128_IRRL_PSN_VLD_FLG_S, 0);
+
+ roce_set_field(context->qpc_bytes_132,
+ QP_CONTEXT_QPC_BYTES_132_IRRL_PSN_M,
+ QP_CONTEXT_QPC_BYTES_132_IRRL_PSN_S, 0);
+ roce_set_field(context->qpc_bytes_132,
+ QP_CONTEXT_QPC_BYTES_132_IRRL_TAIL_M,
+ QP_CONTEXT_QPC_BYTES_132_IRRL_TAIL_S, 0);
+
+ roce_set_field(context->qpc_bytes_136,
+ QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_PSN_M,
+ QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_PSN_S,
+ attr->sq_psn);
+ roce_set_field(context->qpc_bytes_136,
+ QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_FPKT_PSN_L_M,
+ QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_FPKT_PSN_L_S,
+ attr->sq_psn);
+
+ roce_set_field(context->qpc_bytes_140,
+ QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_FPKT_PSN_H_M,
+ QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_FPKT_PSN_H_S,
+ (attr->sq_psn >> SQ_PSN_SHIFT));
+ roce_set_field(context->qpc_bytes_140,
+ QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_MSN_M,
+ QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_MSN_S, 0);
+ roce_set_bit(context->qpc_bytes_140,
+ QP_CONTEXT_QPC_BYTES_140_RNR_RETRY_FLG_S, 0);
+
+ roce_set_field(context->qpc_bytes_144,
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_M,
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_S,
+ attr->qp_state);
+
+ roce_set_field(context->qpc_bytes_148,
+ QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_M,
+ QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S, 0);
+ roce_set_field(context->qpc_bytes_148,
+ QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_M,
+ QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S, 0);
+ roce_set_field(context->qpc_bytes_148,
+ QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_M,
+ QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S, 0);
+ roce_set_field(context->qpc_bytes_148,
+ QP_CONTEXT_QPC_BYTES_148_LSN_M,
+ QP_CONTEXT_QPC_BYTES_148_LSN_S, 0x100);
+
+ context->rnr_retry = 0;
+
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_M,
+ QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_S,
+ attr->retry_cnt);
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M,
+ QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S,
+ attr->timeout);
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_M,
+ QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_S,
+ attr->rnr_retry);
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M,
+ QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S,
+ hr_qp->port);
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_SL_M,
+ QP_CONTEXT_QPC_BYTES_156_SL_S, attr->ah_attr.sl);
+ hr_qp->sl = attr->ah_attr.sl;
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_M,
+ QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_S,
+ ilog2(attr->max_rd_atomic));
+ roce_set_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_ACK_REQ_IND_M,
+ QP_CONTEXT_QPC_BYTES_156_ACK_REQ_IND_S, 0);
+ context->pkt_use_len = 0;
+
+ roce_set_field(context->qpc_bytes_164,
+ QP_CONTEXT_QPC_BYTES_164_SQ_PSN_M,
+ QP_CONTEXT_QPC_BYTES_164_SQ_PSN_S, attr->sq_psn);
+ roce_set_field(context->qpc_bytes_164,
+ QP_CONTEXT_QPC_BYTES_164_IRRL_HEAD_M,
+ QP_CONTEXT_QPC_BYTES_164_IRRL_HEAD_S, 0);
+
+ roce_set_field(context->qpc_bytes_168,
+ QP_CONTEXT_QPC_BYTES_168_RETRY_SQ_PSN_M,
+ QP_CONTEXT_QPC_BYTES_168_RETRY_SQ_PSN_S,
+ attr->sq_psn);
+ roce_set_field(context->qpc_bytes_168,
+ QP_CONTEXT_QPC_BYTES_168_SGE_USE_FLA_M,
+ QP_CONTEXT_QPC_BYTES_168_SGE_USE_FLA_S, 0);
+ roce_set_field(context->qpc_bytes_168,
+ QP_CONTEXT_QPC_BYTES_168_DB_TYPE_M,
+ QP_CONTEXT_QPC_BYTES_168_DB_TYPE_S, 0);
+ roce_set_bit(context->qpc_bytes_168,
+ QP_CONTEXT_QPC_BYTES_168_MSG_LP_IND_S, 0);
+ roce_set_bit(context->qpc_bytes_168,
+ QP_CONTEXT_QPC_BYTES_168_CSDB_LP_IND_S, 0);
+ roce_set_bit(context->qpc_bytes_168,
+ QP_CONTEXT_QPC_BYTES_168_QP_ERR_FLG_S, 0);
+ context->sge_use_len = 0;
+
+ roce_set_field(context->qpc_bytes_176,
+ QP_CONTEXT_QPC_BYTES_176_DB_CUR_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_176_DB_CUR_INDEX_S, 0);
+ roce_set_field(context->qpc_bytes_176,
+ QP_CONTEXT_QPC_BYTES_176_RETRY_DB_CUR_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_176_RETRY_DB_CUR_INDEX_S,
+ 0);
+ roce_set_field(context->qpc_bytes_180,
+ QP_CONTEXT_QPC_BYTES_180_SQ_CUR_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_180_SQ_CUR_INDEX_S, 0);
+ roce_set_field(context->qpc_bytes_180,
+ QP_CONTEXT_QPC_BYTES_180_SQ_HEAD_M,
+ QP_CONTEXT_QPC_BYTES_180_SQ_HEAD_S, 0);
+
+ context->tx_cur_sq_wqe_ba_l = (u32)(mtts[0]);
+
+ roce_set_field(context->qpc_bytes_188,
+ QP_CONTEXT_QPC_BYTES_188_TX_CUR_SQ_WQE_BA_H_M,
+ QP_CONTEXT_QPC_BYTES_188_TX_CUR_SQ_WQE_BA_H_S,
+ (mtts[0]) >> ADDR_SHIFT_32);
+ roce_set_bit(context->qpc_bytes_188,
+ QP_CONTEXT_QPC_BYTES_188_PKT_RETRY_FLG_S, 0);
+ roce_set_field(context->qpc_bytes_188,
+ QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_S,
+ 0);
+ } else if ((cur_state == IB_QPS_INIT && new_state == IB_QPS_RESET) ||
+ (cur_state == IB_QPS_INIT && new_state == IB_QPS_ERR) ||
+ (cur_state == IB_QPS_RTR && new_state == IB_QPS_RESET) ||
+ (cur_state == IB_QPS_RTR && new_state == IB_QPS_ERR) ||
+ (cur_state == IB_QPS_RTS && new_state == IB_QPS_RESET) ||
+ (cur_state == IB_QPS_RTS && new_state == IB_QPS_ERR) ||
+ (cur_state == IB_QPS_ERR && new_state == IB_QPS_RESET) ||
+ (cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR)) {
+ roce_set_field(context->qpc_bytes_144,
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_M,
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_S,
+ attr->qp_state);
+
+ } else {
+ dev_err(dev, "not support this modify\n");
+ goto out;
+ }
+
+ /* Every status migrate must change state */
+ roce_set_field(context->qpc_bytes_144,
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_M,
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, attr->qp_state);
+
+ /* SW pass context to HW */
+ ret = hns_roce_v1_qp_modify(hr_dev, &hr_qp->mtt,
+ to_hns_roce_state(cur_state),
+ to_hns_roce_state(new_state), context,
+ hr_qp);
+ if (ret) {
+ dev_err(dev, "hns_roce_qp_modify failed\n");
+ goto out;
+ }
+
+ /*
+ * Use rst2init to instead of init2init with drv,
+ * need to hw to flash RQ HEAD by DB again
+ */
+ if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
+ u32 reg_val = 0;
+ u32 *addr = NULL;
+
+ /* Memory barrier */
+ wmb();
+ if (hr_qp->ibqp.qp_type == IB_QPT_GSI) {
+ /* SW update GSI rq header */
+ addr = (u32 *)(hr_dev->reg_base +
+ ROCEE_QP1C_CFG3_0_REG +
+ QP1C_CFGN_OFFSET * hr_qp->port);
+ reg_val = roce_readl(addr);
+ roce_set_field(reg_val,
+ ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M,
+ ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S,
+ hr_qp->rq.head);
+ roce_writel(reg_val, addr);
+ } else {
+ uint32_t doorbell[2] = {0};
+ struct hns_roce_rq_db rq_db;
+
+ rq_db.u32_4 = 0;
+ rq_db.u32_8 = 0;
+
+ roce_set_field(rq_db.u32_4, RQ_DOORBELL_U32_4_RQ_HEAD_M,
+ RQ_DOORBELL_U32_4_RQ_HEAD_S,
+ hr_qp->rq.head);
+ roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_QPN_M,
+ RQ_DOORBELL_U32_8_QPN_S, hr_qp->qpn);
+ roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_CMD_M,
+ RQ_DOORBELL_U32_8_CMD_S, 1);
+ roce_set_bit(rq_db.u32_8, RQ_DOORBELL_U32_8_HW_SYNC_S,
+ 1);
+
+ doorbell[0] = rq_db.u32_4;
+ doorbell[1] = rq_db.u32_8;
+
+ hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l);
+ }
+ }
+
+ hr_qp->state = new_state;
+
+ if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
+ hr_qp->resp_depth = attr->max_dest_rd_atomic;
+ if (attr_mask & IB_QP_PORT)
+ hr_qp->port = (attr->port_num - 1);
+
+ if (new_state == IB_QPS_RESET && !ibqp->uobject) {
+ hns_roce_v1_cq_clean(to_hr_cq(ibqp->recv_cq), hr_qp->qpn,
+ ibqp->srq ? to_hr_srq(ibqp->srq) : NULL);
+ if (ibqp->send_cq != ibqp->recv_cq)
+ hns_roce_v1_cq_clean(to_hr_cq(ibqp->send_cq),
+ hr_qp->qpn, NULL);
+
+ hr_qp->rq.head = 0;
+ hr_qp->rq.tail = 0;
+ hr_qp->sq.head = 0;
+ hr_qp->sq.tail = 0;
+ hr_qp->sq_next_wqe = 0;
+ }
+out:
+ kfree(context);
+ return ret;
+}
+
+int hns_roce_v1_modify_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
+ int attr_mask, enum ib_qp_state cur_state,
+ enum ib_qp_state new_state)
+{
+
+ if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI)
+ return hns_roce_v1_m_sqp(ibqp, attr, attr_mask, cur_state,
+ new_state);
+ else
+ return hns_roce_v1_m_qp(ibqp, attr, attr_mask, cur_state,
+ new_state);
+}
+
+static enum ib_qp_state to_ib_qp_state(enum hns_roce_qp_state state)
+{
+ switch (state) {
+ case HNS_ROCE_QP_STATE_RST:
+ return IB_QPS_RESET;
+ case HNS_ROCE_QP_STATE_INIT:
+ return IB_QPS_INIT;
+ case HNS_ROCE_QP_STATE_RTR:
+ return IB_QPS_RTR;
+ case HNS_ROCE_QP_STATE_RTS:
+ return IB_QPS_RTS;
+ case HNS_ROCE_QP_STATE_SQD:
+ return IB_QPS_SQD;
+ case HNS_ROCE_QP_STATE_ERR:
+ return IB_QPS_ERR;
+ default:
+ return -1;
+ }
+}
+
+static int hns_roce_v1_query_qpc(struct hns_roce_dev *hr_dev,
+ struct hns_roce_qp *hr_qp,
+ struct hns_roce_qp_context *hr_context)
+{
+ struct hns_roce_cmd_mailbox *mailbox;
+ int ret;
+
+ mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
+ if (IS_ERR(mailbox)) {
+ dev_err(&hr_dev->pdev->dev, "Alloc mailbox failed\n");
+ return PTR_ERR(mailbox);
+ }
+
+ ret = hns_roce_cmd_box(hr_dev, 0, mailbox->dma, hr_qp->qpn, 0,
+ HNS_ROCE_CMD_QUERY_QP,
+ HNS_ROCE_CMD_TIME_CLASS_A);
+ if (!ret)
+ memcpy(hr_context, mailbox->buf, sizeof(*hr_context));
+ else
+ dev_err(&hr_dev->pdev->dev, "QUERY QP cmd process error\n");
+
+ hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+
+ return ret;
+}
+
+int hns_roce_v1_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ struct device *dev = &hr_dev->pdev->dev;
+ struct hns_roce_qp_context *context;
+ int tmp_qp_state = 0;
+ int ret = 0;
+ int state;
+
+ context = kzalloc(sizeof(*context), GFP_KERNEL);
+ if (!context)
+ return -ENOMEM;
+
+ memset(qp_attr, 0, sizeof(*qp_attr));
+ memset(qp_init_attr, 0, sizeof(*qp_init_attr));
+
+ mutex_lock(&hr_qp->mutex);
+
+ if (hr_qp->state == IB_QPS_RESET) {
+ qp_attr->qp_state = IB_QPS_RESET;
+ goto done;
+ }
+
+ ret = hns_roce_v1_query_qpc(hr_dev, hr_qp, context);
+ if (ret) {
+ dev_err(dev, "query qpc error\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ state = roce_get_field(context->qpc_bytes_144,
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_M,
+ QP_CONTEXT_QPC_BYTES_144_QP_STATE_S);
+ tmp_qp_state = (int)to_ib_qp_state((enum hns_roce_qp_state)state);
+ if (tmp_qp_state == -1) {
+ dev_err(dev, "to_ib_qp_state error\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ hr_qp->state = (u8)tmp_qp_state;
+ qp_attr->qp_state = (enum ib_qp_state)hr_qp->state;
+ qp_attr->path_mtu = (enum ib_mtu)roce_get_field(context->qpc_bytes_48,
+ QP_CONTEXT_QPC_BYTES_48_MTU_M,
+ QP_CONTEXT_QPC_BYTES_48_MTU_S);
+ qp_attr->path_mig_state = IB_MIG_ARMED;
+ if (hr_qp->ibqp.qp_type == IB_QPT_UD)
+ qp_attr->qkey = QKEY_VAL;
+ else
+ qp_attr->qkey = 0;
+
+ qp_attr->rq_psn = roce_get_field(context->qpc_bytes_88,
+ QP_CONTEXT_QPC_BYTES_88_RX_REQ_EPSN_M,
+ QP_CONTEXT_QPC_BYTES_88_RX_REQ_EPSN_S);
+ qp_attr->sq_psn = (u32)roce_get_field(context->qpc_bytes_164,
+ QP_CONTEXT_QPC_BYTES_164_SQ_PSN_M,
+ QP_CONTEXT_QPC_BYTES_164_SQ_PSN_S);
+ qp_attr->dest_qp_num = (u8)roce_get_field(context->qpc_bytes_36,
+ QP_CONTEXT_QPC_BYTES_36_DEST_QP_M,
+ QP_CONTEXT_QPC_BYTES_36_DEST_QP_S);
+ qp_attr->qp_access_flags = ((roce_get_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMA_READ_ENABLE_S)) << 2) |
+ ((roce_get_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_RDMA_WRITE_ENABLE_S)) << 1) |
+ ((roce_get_bit(context->qpc_bytes_4,
+ QP_CONTEXT_QPC_BYTE_4_ATOMIC_OPERATION_ENABLE_S)) << 3);
+
+ if (hr_qp->ibqp.qp_type == IB_QPT_RC ||
+ hr_qp->ibqp.qp_type == IB_QPT_UC) {
+ qp_attr->ah_attr.sl = roce_get_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_SL_M,
+ QP_CONTEXT_QPC_BYTES_156_SL_S);
+ qp_attr->ah_attr.grh.flow_label = roce_get_field(
+ context->qpc_bytes_48,
+ QP_CONTEXT_QPC_BYTES_48_FLOWLABEL_M,
+ QP_CONTEXT_QPC_BYTES_48_FLOWLABEL_S);
+ qp_attr->ah_attr.grh.sgid_index = roce_get_field(
+ context->qpc_bytes_36,
+ QP_CONTEXT_QPC_BYTES_36_SGID_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_36_SGID_INDEX_S);
+ qp_attr->ah_attr.grh.hop_limit = roce_get_field(
+ context->qpc_bytes_44,
+ QP_CONTEXT_QPC_BYTES_44_HOPLMT_M,
+ QP_CONTEXT_QPC_BYTES_44_HOPLMT_S);
+ qp_attr->ah_attr.grh.traffic_class = roce_get_field(
+ context->qpc_bytes_48,
+ QP_CONTEXT_QPC_BYTES_48_TCLASS_M,
+ QP_CONTEXT_QPC_BYTES_48_TCLASS_S);
+
+ memcpy(qp_attr->ah_attr.grh.dgid.raw, context->dgid,
+ sizeof(qp_attr->ah_attr.grh.dgid.raw));
+ qp_attr->alt_pkey_index = 0;
+ qp_attr->alt_port_num = 0;
+ }
+
+ qp_attr->pkey_index = roce_get_field(context->qpc_bytes_12,
+ QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_M,
+ QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S);
+ qp_attr->port_num = (u8)roce_get_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M,
+ QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S) + 1;
+ qp_attr->sq_draining = 0;
+ qp_attr->max_rd_atomic = roce_get_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_M,
+ QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_S);
+ qp_attr->max_dest_rd_atomic = roce_get_field(context->qpc_bytes_32,
+ QP_CONTEXT_QPC_BYTES_32_RESPONDER_RESOURCES_M,
+ QP_CONTEXT_QPC_BYTES_32_RESPONDER_RESOURCES_S);
+ qp_attr->min_rnr_timer = (u8)(roce_get_field(context->qpc_bytes_24,
+ QP_CONTEXT_QPC_BYTES_24_MINIMUM_RNR_NAK_TIMER_M,
+ QP_CONTEXT_QPC_BYTES_24_MINIMUM_RNR_NAK_TIMER_S));
+ qp_attr->timeout = (u8)(roce_get_field(context->qpc_bytes_156,
+ QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M,
+ QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S));
+ qp_attr->retry_cnt = roce_get_field(context->qpc_bytes_148,
+ QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_M,
+ QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S);
+ qp_attr->rnr_retry = context->rnr_retry;
+ qp_attr->alt_timeout = 0;
+
+done:
+ qp_attr->cur_qp_state = qp_attr->qp_state;
+ qp_attr->cap.max_recv_wr = hr_qp->rq.wqe_cnt;
+ qp_attr->cap.max_recv_sge = hr_qp->rq.max_gs;
+
+ if (!ibqp->uobject) {
+ qp_attr->cap.max_send_wr = hr_qp->sq.wqe_cnt;
+ qp_attr->cap.max_send_sge = hr_qp->sq.max_gs;
+ } else {
+ qp_attr->cap.max_send_wr = 0;
+ qp_attr->cap.max_send_sge = 0;
+ }
+
+ qp_attr->cap.max_inline_data = 0;
+
+ qp_init_attr->cap = qp_attr->cap;
+ qp_init_attr->create_flags = (enum ib_qp_create_flags)0;
+
+out:
+ mutex_unlock(&hr_qp->mutex);
+ kfree(context);
+ return ret;
+}
+
+static void hns_roce_v1_destroy_qp_common(struct hns_roce_dev *hr_dev,
+ struct hns_roce_qp *hr_qp,
+ int is_user)
+{
+ u32 sdbinvcnt;
+ unsigned long end = 0;
+ u32 sdbinvcnt_val;
+ u32 sdbsendptr_val;
+ u32 sdbisusepr_val;
+ struct hns_roce_cq *send_cq, *recv_cq;
+ struct device *dev = &hr_dev->pdev->dev;
+
+ if (hr_qp->ibqp.qp_type == IB_QPT_RC) {
+ if (hr_qp->state != IB_QPS_RESET) {
+ /*
+ * Set qp to ERR,
+ * waiting for hw complete processing all dbs
+ */
+ if (hns_roce_v1_qp_modify(hr_dev, NULL,
+ to_hns_roce_state(
+ (enum ib_qp_state)hr_qp->state),
+ HNS_ROCE_QP_STATE_ERR, NULL,
+ hr_qp))
+ dev_err(dev, "modify QP %06x to ERR failed.\n",
+ hr_qp->qpn);
+
+ /* Record issued doorbell */
+ sdbisusepr_val = roce_readl(hr_dev->reg_base +
+ ROCEE_SDB_ISSUE_PTR_REG);
+ /*
+ * Query db process status,
+ * until hw process completely
+ */
+ end = msecs_to_jiffies(
+ HNS_ROCE_QP_DESTROY_TIMEOUT_MSECS) + jiffies;
+ do {
+ sdbsendptr_val = roce_readl(hr_dev->reg_base +
+ ROCEE_SDB_SEND_PTR_REG);
+ if (!time_before(jiffies, end)) {
+ dev_err(dev, "destroy qp(0x%x) timeout!!!",
+ hr_qp->qpn);
+ break;
+ }
+ } while ((short)(roce_get_field(sdbsendptr_val,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
+ ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) -
+ roce_get_field(sdbisusepr_val,
+ ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_M,
+ ROCEE_SDB_ISSUE_PTR_SDB_ISSUE_PTR_S)
+ ) < 0);
+
+ /* Get list pointer */
+ sdbinvcnt = roce_readl(hr_dev->reg_base +
+ ROCEE_SDB_INV_CNT_REG);
+
+ /* Query db's list status, until hw reversal */
+ do {
+ sdbinvcnt_val = roce_readl(hr_dev->reg_base +
+ ROCEE_SDB_INV_CNT_REG);
+ if (!time_before(jiffies, end)) {
+ dev_err(dev, "destroy qp(0x%x) timeout!!!",
+ hr_qp->qpn);
+ dev_err(dev, "SdbInvCnt = 0x%x\n",
+ sdbinvcnt_val);
+ break;
+ }
+ } while ((short)(roce_get_field(sdbinvcnt_val,
+ ROCEE_SDB_INV_CNT_SDB_INV_CNT_M,
+ ROCEE_SDB_INV_CNT_SDB_INV_CNT_S) -
+ (sdbinvcnt + SDB_INV_CNT_OFFSET)) < 0);
+
+ /* Modify qp to reset before destroying qp */
+ if (hns_roce_v1_qp_modify(hr_dev, NULL,
+ to_hns_roce_state(
+ (enum ib_qp_state)hr_qp->state),
+ HNS_ROCE_QP_STATE_RST, NULL, hr_qp))
+ dev_err(dev, "modify QP %06x to RESET failed.\n",
+ hr_qp->qpn);
+ }
+ }
+
+ send_cq = to_hr_cq(hr_qp->ibqp.send_cq);
+ recv_cq = to_hr_cq(hr_qp->ibqp.recv_cq);
+
+ hns_roce_lock_cqs(send_cq, recv_cq);
+
+ if (!is_user) {
+ hns_roce_v1_clean_cq(recv_cq, hr_qp->qpn, hr_qp->ibqp.srq ?
+ to_hr_srq(hr_qp->ibqp.srq) : NULL);
+ if (send_cq != recv_cq)
+ hns_roce_v1_clean_cq(send_cq, hr_qp->qpn, NULL);
+ }
+
+ hns_roce_qp_remove(hr_dev, hr_qp);
+
+ hns_roce_unlock_cqs(send_cq, recv_cq);
+
+ hns_roce_qp_free(hr_dev, hr_qp);
+
+ /* Not special_QP, free their QPN */
+ if ((hr_qp->ibqp.qp_type == IB_QPT_RC) ||
+ (hr_qp->ibqp.qp_type == IB_QPT_UC) ||
+ (hr_qp->ibqp.qp_type == IB_QPT_UD))
+ hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
+
+ hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt);
+
+ if (is_user) {
+ if (!hr_qp->ibqp.srq)
+ /* SRQ not support */
+ ;
+ ib_umem_release(hr_qp->umem);
+ } else {
+ kfree(hr_qp->sq.wrid);
+ kfree(hr_qp->rq.wrid);
+ hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf);
+ }
+}
+
+int hns_roce_v1_destroy_qp(struct ib_qp *ibqp)
+{
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+
+ hns_roce_v1_destroy_qp_common(hr_dev, hr_qp, !!ibqp->pd->uobject);
+
+ if (hr_qp->ibqp.qp_type == IB_QPT_GSI)
+ kfree(hr_to_hr_sqp(hr_qp));
+ else
+ kfree(hr_qp);
+
+ return 0;
+}
+
+struct hns_roce_v1_priv hr_v1_priv;
+
+struct hns_roce_hw hns_roce_v1_hw = {
+ .reset = hns_roce_v1_reset,
+ .hw_profile = hns_roce_v1_profile,
+ .hw_init = hns_roce_v1_init,
+ .hw_uninit = hns_roce_v1_uninit,
+ .set_gid = hns_roce_v1_set_gid,
+ .set_mac = hns_roce_v1_set_mac,
+ .set_mtu = hns_roce_v1_set_mtu,
+ .write_mtpt = hns_roce_v1_write_mtpt,
+ .write_cqc = hns_roce_v1_write_cqc,
+ .modify_qp = hns_roce_v1_modify_qp,
+ .query_qp = hns_roce_v1_query_qp,
+ .destroy_qp = hns_roce_v1_destroy_qp,
+ .post_send = hns_roce_v1_post_send,
+ .post_recv = hns_roce_v1_post_recv,
+ .req_notify_cq = hns_roce_v1_req_notify_cq,
+ .poll_cq = hns_roce_v1_poll_cq,
+ .priv = &hr_v1_priv,
+};
diff --git a/drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.h b/drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.h
new file mode 100644
index 0000000..3a03111
--- /dev/null
+++ b/drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.h
@@ -0,0 +1,986 @@
+/*
+ * Copyright (c) 2016 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _HNS_ROCE_V1_HW_H
+#define _HNS_ROCE_V1_HW_H
+
+#define CQ_STATE_INVALID 0
+#define CQ_STATE_RESERV 1
+#define CQ_STATE_VALID 2
+#define CQ_STATE_ERR 3
+
+#define HNS_ROCE_V1_MAX_PD_NUM 0x8000
+#define HNS_ROCE_V1_MAX_CQ_NUM 0x10000
+#define HNS_ROCE_V1_MAX_CQE_NUM 0x8000
+
+#define HNS_ROCE_V1_MAX_QP_NUM 0x40000
+#define HNS_ROCE_V1_MAX_WQE_NUM 0x4000
+
+#define HNS_ROCE_V1_MAX_MTPT_NUM 0x80000
+
+#define HNS_ROCE_V1_MAX_MTT_SEGS 0x100000
+
+#define HNS_ROCE_V1_MAX_QP_INIT_RDMA 128
+#define HNS_ROCE_V1_MAX_QP_DEST_RDMA 128
+
+#define HNS_ROCE_V1_MAX_SQ_DESC_SZ 64
+#define HNS_ROCE_V1_MAX_RQ_DESC_SZ 64
+#define HNS_ROCE_V1_SG_NUM 2
+#define HNS_ROCE_V1_INLINE_SIZE 32
+
+#define HNS_ROCE_V1_UAR_NUM 256
+#define HNS_ROCE_V1_PHY_UAR_NUM 8
+
+#define HNS_ROCE_V1_GID_NUM 16
+
+#define HNS_ROCE_V1_NUM_COMP_EQE 0x8000
+#define HNS_ROCE_V1_NUM_ASYNC_EQE 0x400
+
+#define HNS_ROCE_V1_QPC_ENTRY_SIZE 256
+#define HNS_ROCE_V1_IRRL_ENTRY_SIZE 8
+#define HNS_ROCE_V1_CQC_ENTRY_SIZE 64
+#define HNS_ROCE_V1_MTPT_ENTRY_SIZE 64
+#define HNS_ROCE_V1_MTT_ENTRY_SIZE 64
+#define HNS_ROCE_V1_CEQC_ENTRY_SIZE 16
+#define HNS_ROCE_V1_AEQC_ENTRY_SIZE 16
+
+#define HNS_ROCE_V1_CQE_ENTRY_SIZE 32
+#define HNS_ROCE_V1_WQE_ENTRY_SIZE 64
+#define HNS_ROCE_V1_CEQE_ENTRY_SIZE 4
+#define HNS_ROCE_V1_AEQE_ENTRY_SIZE 16
+
+#define HNS_ROCE_V1_PAGE_SIZE_SUPPORT 0xFFFFF000
+#define HNS_ROCE_V1_DEFAULT_MTU IB_MTU_1024
+#define HNS_ROCE_V1_DEFAULT_SL_WEIGHT 0xf
+
+#define HNS_ROCE_V1_EXT_RAQ_WF 8
+#define HNS_ROCE_V1_RAQ_ENTRY 64
+#define HNS_ROCE_V1_RAQ_DEPTH 32768
+#define HNS_ROCE_V1_RAQ_SIZE (HNS_ROCE_V1_RAQ_ENTRY * HNS_ROCE_V1_RAQ_DEPTH)
+#define HNS_ROCE_V1_POL_TIME 1
+
+#define HNS_ROCE_V1_SDB_DEPTH 0x400
+#define HNS_ROCE_V1_ODB_DEPTH 0x400
+
+#define HNS_ROCE_V1_DB_RSVD 0x80
+
+#define HNS_ROCE_V1_SDB_ALEPT HNS_ROCE_V1_DB_RSVD
+#define HNS_ROCE_V1_SDB_ALFUL (HNS_ROCE_V1_SDB_DEPTH - HNS_ROCE_V1_DB_RSVD)
+#define HNS_ROCE_V1_ODB_ALEPT HNS_ROCE_V1_DB_RSVD
+#define HNS_ROCE_V1_ODB_ALFUL (HNS_ROCE_V1_ODB_DEPTH - HNS_ROCE_V1_DB_RSVD)
+#define HNS_ROCE_V1_SDB_OVFL (HNS_ROCE_V1_SDB_DEPTH - HNS_ROCE_V1_DB_RSVD)
+
+#define HNS_ROCE_V1_EXT_SDB_DEPTH 0x4000
+#define HNS_ROCE_V1_EXT_ODB_DEPTH 0x4000
+#define HNS_ROCE_V1_EXT_SDB_ENTRY 16
+#define HNS_ROCE_V1_EXT_ODB_ENTRY 16
+#define HNS_ROCE_V1_EXT_SDB_SIZE \
+ (HNS_ROCE_V1_EXT_SDB_DEPTH * HNS_ROCE_V1_EXT_SDB_ENTRY)
+#define HNS_ROCE_V1_EXT_ODB_SIZE \
+ (HNS_ROCE_V1_EXT_ODB_DEPTH * HNS_ROCE_V1_EXT_ODB_ENTRY)
+
+#define HNS_ROCE_V1_EXT_SDB_ALEPT HNS_ROCE_V1_DB_RSVD
+#define HNS_ROCE_V1_EXT_SDB_ALFUL \
+ (HNS_ROCE_V1_EXT_SDB_DEPTH - HNS_ROCE_V1_DB_RSVD)
+#define HNS_ROCE_V1_EXT_ODB_ALEPT HNS_ROCE_V1_DB_RSVD
+#define HNS_ROCE_V1_EXT_ODB_ALFUL \
+ (HNS_ROCE_V1_EXT_ODB_DEPTH - HNS_ROCE_V1_DB_RSVD)
+
+#define HNS_ROCE_ODB_POLL_MODE 0
+
+#define HNS_ROCE_SDB_NORMAL_MODE 0
+#define HNS_ROCE_SDB_EXTEND_MODE 1
+
+#define HNS_ROCE_ODB_EXTEND_MODE 1
+
+#define KEY_VALID 0x02
+
+#define HNS_ROCE_CQE_QPN_MASK 0x3ffff
+#define HNS_ROCE_CQE_STATUS_MASK 0x1f
+#define HNS_ROCE_CQE_OPCODE_MASK 0xf
+
+#define HNS_ROCE_CQE_SUCCESS 0x00
+#define HNS_ROCE_CQE_SYNDROME_LOCAL_LENGTH_ERR 0x01
+#define HNS_ROCE_CQE_SYNDROME_LOCAL_QP_OP_ERR 0x02
+#define HNS_ROCE_CQE_SYNDROME_LOCAL_PROT_ERR 0x03
+#define HNS_ROCE_CQE_SYNDROME_WR_FLUSH_ERR 0x04
+#define HNS_ROCE_CQE_SYNDROME_MEM_MANAGE_OPERATE_ERR 0x05
+#define HNS_ROCE_CQE_SYNDROME_BAD_RESP_ERR 0x06
+#define HNS_ROCE_CQE_SYNDROME_LOCAL_ACCESS_ERR 0x07
+#define HNS_ROCE_CQE_SYNDROME_REMOTE_INVAL_REQ_ERR 0x08
+#define HNS_ROCE_CQE_SYNDROME_REMOTE_ACCESS_ERR 0x09
+#define HNS_ROCE_CQE_SYNDROME_REMOTE_OP_ERR 0x0a
+#define HNS_ROCE_CQE_SYNDROME_TRANSPORT_RETRY_EXC_ERR 0x0b
+#define HNS_ROCE_CQE_SYNDROME_RNR_RETRY_EXC_ERR 0x0c
+
+#define QP1C_CFGN_OFFSET 0x28
+#define PHY_PORT_OFFSET 0x8
+#define MTPT_IDX_SHIFT 16
+#define ALL_PORT_VAL_OPEN 0x3f
+#define POL_TIME_INTERVAL_VAL 0x80
+#define SLEEP_TIME_INTERVAL 20
+#define SQ_PSN_SHIFT 8
+#define QKEY_VAL 0x80010000
+#define SDB_INV_CNT_OFFSET 8
+
+struct hns_roce_cq_context {
+ u32 cqc_byte_4;
+ u32 cq_bt_l;
+ u32 cqc_byte_12;
+ u32 cur_cqe_ba0_l;
+ u32 cqc_byte_20;
+ u32 cqe_tptr_addr_l;
+ u32 cur_cqe_ba1_l;
+ u32 cqc_byte_32;
+};
+
+#define CQ_CONTEXT_CQC_BYTE_4_CQC_STATE_S 0
+#define CQ_CONTEXT_CQC_BYTE_4_CQC_STATE_M \
+ (((1UL << 2) - 1) << CQ_CONTEXT_CQC_BYTE_4_CQC_STATE_S)
+
+#define CQ_CONTEXT_CQC_BYTE_4_CQN_S 16
+#define CQ_CONTEXT_CQC_BYTE_4_CQN_M \
+ (((1UL << 16) - 1) << CQ_CONTEXT_CQC_BYTE_4_CQN_S)
+
+#define CQ_CONTEXT_CQC_BYTE_12_CQ_BT_H_S 0
+#define CQ_CONTEXT_CQC_BYTE_12_CQ_BT_H_M \
+ (((1UL << 17) - 1) << CQ_CONTEXT_CQC_BYTE_12_CQ_BT_H_S)
+
+#define CQ_CONTEXT_CQC_BYTE_12_CQ_CQE_SHIFT_S 20
+#define CQ_CONTEXT_CQC_BYTE_12_CQ_CQE_SHIFT_M \
+ (((1UL << 4) - 1) << CQ_CONTEXT_CQC_BYTE_12_CQ_CQE_SHIFT_S)
+
+#define CQ_CONTEXT_CQC_BYTE_12_CEQN_S 24
+#define CQ_CONTEXT_CQC_BYTE_12_CEQN_M \
+ (((1UL << 5) - 1) << CQ_CONTEXT_CQC_BYTE_12_CEQN_S)
+
+#define CQ_CONTEXT_CQC_BYTE_20_CUR_CQE_BA0_H_S 0
+#define CQ_CONTEXT_CQC_BYTE_20_CUR_CQE_BA0_H_M \
+ (((1UL << 5) - 1) << CQ_CONTEXT_CQC_BYTE_20_CUR_CQE_BA0_H_S)
+
+#define CQ_CONTEXT_CQC_BYTE_20_CQ_CUR_INDEX_S 16
+#define CQ_CONTEXT_CQC_BYTE_20_CQ_CUR_INDEX_M \
+ (((1UL << 16) - 1) << CQ_CONTEXT_CQC_BYTE_20_CQ_CUR_INDEX_S)
+
+#define CQ_CONTEXT_CQC_BYTE_20_CQE_TPTR_ADDR_H_S 8
+#define CQ_CONTEXT_CQC_BYTE_20_CQE_TPTR_ADDR_H_M \
+ (((1UL << 5) - 1) << CQ_CONTEXT_CQC_BYTE_20_CQE_TPTR_ADDR_H_S)
+
+#define CQ_CONTEXT_CQC_BYTE_32_CUR_CQE_BA1_H_S 0
+#define CQ_CONTEXT_CQC_BYTE_32_CUR_CQE_BA1_H_M \
+ (((1UL << 5) - 1) << CQ_CONTEXT_CQC_BYTE_32_CUR_CQE_BA1_H_S)
+
+#define CQ_CONTEXT_CQC_BYTE_32_SE_FLAG_S 9
+
+#define CQ_CONTEXT_CQC_BYTE_32_CE_FLAG_S 8
+#define CQ_CONTEXT_CQC_BYTE_32_NOTIFICATION_FLAG_S 14
+#define CQ_CQNTEXT_CQC_BYTE_32_TYPE_OF_COMPLETION_NOTIFICATION_S 15
+
+#define CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_S 16
+#define CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_M \
+ (((1UL << 16) - 1) << CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_S)
+
+struct hns_roce_cqe {
+ u32 cqe_byte_4;
+ union {
+ u32 r_key;
+ u32 immediate_data;
+ };
+ u32 byte_cnt;
+ u32 cqe_byte_16;
+ u32 cqe_byte_20;
+ u32 s_mac_l;
+ u32 cqe_byte_28;
+ u32 reserved;
+};
+
+#define CQE_BYTE_4_OWNER_S 7
+#define CQE_BYTE_4_SQ_RQ_FLAG_S 14
+
+#define CQE_BYTE_4_STATUS_OF_THE_OPERATION_S 8
+#define CQE_BYTE_4_STATUS_OF_THE_OPERATION_M \
+ (((1UL << 5) - 1) << CQE_BYTE_4_STATUS_OF_THE_OPERATION_S)
+
+#define CQE_BYTE_4_WQE_INDEX_S 16
+#define CQE_BYTE_4_WQE_INDEX_M (((1UL << 14) - 1) << CQE_BYTE_4_WQE_INDEX_S)
+
+#define CQE_BYTE_4_OPERATION_TYPE_S 0
+#define CQE_BYTE_4_OPERATION_TYPE_M \
+ (((1UL << 4) - 1) << CQE_BYTE_4_OPERATION_TYPE_S)
+
+#define CQE_BYTE_4_IMM_INDICATOR_S 15
+
+#define CQE_BYTE_16_LOCAL_QPN_S 0
+#define CQE_BYTE_16_LOCAL_QPN_M (((1UL << 24) - 1) << CQE_BYTE_16_LOCAL_QPN_S)
+
+#define CQE_BYTE_20_PORT_NUM_S 26
+#define CQE_BYTE_20_PORT_NUM_M (((1UL << 3) - 1) << CQE_BYTE_20_PORT_NUM_S)
+
+#define CQE_BYTE_20_SL_S 24
+#define CQE_BYTE_20_SL_M (((1UL << 2) - 1) << CQE_BYTE_20_SL_S)
+
+#define CQE_BYTE_20_REMOTE_QPN_S 0
+#define CQE_BYTE_20_REMOTE_QPN_M \
+ (((1UL << 24) - 1) << CQE_BYTE_20_REMOTE_QPN_S)
+
+#define CQE_BYTE_20_GRH_PRESENT_S 29
+
+#define CQE_BYTE_28_P_KEY_IDX_S 16
+#define CQE_BYTE_28_P_KEY_IDX_M (((1UL << 16) - 1) << CQE_BYTE_28_P_KEY_IDX_S)
+
+#define CQ_DB_REQ_NOT_SOL 0
+#define CQ_DB_REQ_NOT (1 << 16)
+
+struct hns_roce_v1_mpt_entry {
+ u32 mpt_byte_4;
+ u32 pbl_addr_l;
+ u32 mpt_byte_12;
+ u32 virt_addr_l;
+ u32 virt_addr_h;
+ u32 length;
+ u32 mpt_byte_28;
+ u32 pa0_l;
+ u32 mpt_byte_36;
+ u32 mpt_byte_40;
+ u32 mpt_byte_44;
+ u32 mpt_byte_48;
+ u32 pa4_l;
+ u32 mpt_byte_56;
+ u32 mpt_byte_60;
+ u32 mpt_byte_64;
+};
+
+#define MPT_BYTE_4_KEY_STATE_S 0
+#define MPT_BYTE_4_KEY_STATE_M (((1UL << 2) - 1) << MPT_BYTE_4_KEY_STATE_S)
+
+#define MPT_BYTE_4_KEY_S 8
+#define MPT_BYTE_4_KEY_M (((1UL << 8) - 1) << MPT_BYTE_4_KEY_S)
+
+#define MPT_BYTE_4_PAGE_SIZE_S 16
+#define MPT_BYTE_4_PAGE_SIZE_M (((1UL << 2) - 1) << MPT_BYTE_4_PAGE_SIZE_S)
+
+#define MPT_BYTE_4_MW_TYPE_S 20
+
+#define MPT_BYTE_4_MW_BIND_ENABLE_S 21
+
+#define MPT_BYTE_4_OWN_S 22
+
+#define MPT_BYTE_4_MEMORY_LOCATION_TYPE_S 24
+#define MPT_BYTE_4_MEMORY_LOCATION_TYPE_M \
+ (((1UL << 2) - 1) << MPT_BYTE_4_MEMORY_LOCATION_TYPE_S)
+
+#define MPT_BYTE_4_REMOTE_ATOMIC_S 26
+#define MPT_BYTE_4_LOCAL_WRITE_S 27
+#define MPT_BYTE_4_REMOTE_WRITE_S 28
+#define MPT_BYTE_4_REMOTE_READ_S 29
+#define MPT_BYTE_4_REMOTE_INVAL_ENABLE_S 30
+#define MPT_BYTE_4_ADDRESS_TYPE_S 31
+
+#define MPT_BYTE_12_PBL_ADDR_H_S 0
+#define MPT_BYTE_12_PBL_ADDR_H_M \
+ (((1UL << 17) - 1) << MPT_BYTE_12_PBL_ADDR_H_S)
+
+#define MPT_BYTE_12_MW_BIND_COUNTER_S 17
+#define MPT_BYTE_12_MW_BIND_COUNTER_M \
+ (((1UL << 15) - 1) << MPT_BYTE_12_MW_BIND_COUNTER_S)
+
+#define MPT_BYTE_28_PD_S 0
+#define MPT_BYTE_28_PD_M (((1UL << 16) - 1) << MPT_BYTE_28_PD_S)
+
+#define MPT_BYTE_28_L_KEY_IDX_L_S 16
+#define MPT_BYTE_28_L_KEY_IDX_L_M \
+ (((1UL << 16) - 1) << MPT_BYTE_28_L_KEY_IDX_L_S)
+
+#define MPT_BYTE_36_PA0_H_S 0
+#define MPT_BYTE_36_PA0_H_M (((1UL << 5) - 1) << MPT_BYTE_36_PA0_H_S)
+
+#define MPT_BYTE_36_PA1_L_S 8
+#define MPT_BYTE_36_PA1_L_M (((1UL << 24) - 1) << MPT_BYTE_36_PA1_L_S)
+
+#define MPT_BYTE_40_PA1_H_S 0
+#define MPT_BYTE_40_PA1_H_M (((1UL << 13) - 1) << MPT_BYTE_40_PA1_H_S)
+
+#define MPT_BYTE_40_PA2_L_S 16
+#define MPT_BYTE_40_PA2_L_M (((1UL << 16) - 1) << MPT_BYTE_40_PA2_L_S)
+
+
+#define MPT_BYTE_44_PA2_H_S 0
+#define MPT_BYTE_44_PA2_H_M (((1UL << 21) - 1) << MPT_BYTE_44_PA2_H_S)
+
+#define MPT_BYTE_44_PA3_L_S 24
+#define MPT_BYTE_44_PA3_L_M (((1UL << 8) - 1) << MPT_BYTE_44_PA3_L_S)
+
+#define MPT_BYTE_48_PA3_H_S 0
+#define MPT_BYTE_48_PA3_H_M (((1UL << 29) - 1) << MPT_BYTE_48_PA3_H_S)
+
+#define MPT_BYTE_56_PA4_H_S 0
+#define MPT_BYTE_56_PA4_H_M (((1UL << 5) - 1) << MPT_BYTE_56_PA4_H_S)
+
+#define MPT_BYTE_56_PA5_L_S 8
+#define MPT_BYTE_56_PA5_L_M (((1UL << 24) - 1) << MPT_BYTE_56_PA5_L_S)
+
+#define MPT_BYTE_60_PA5_H_S 0
+#define MPT_BYTE_60_PA5_H_M (((1UL << 13) - 1) << MPT_BYTE_60_PA5_H_S)
+
+#define MPT_BYTE_60_PA6_L_S 16
+#define MPT_BYTE_60_PA6_L_M (((1UL << 16) - 1) << MPT_BYTE_60_PA6_L_S)
+
+#define MPT_BYTE_64_PA6_H_S 0
+#define MPT_BYTE_64_PA6_H_M (((1UL << 21) - 1) << MPT_BYTE_64_PA6_H_S)
+
+#define MPT_BYTE_64_L_KEY_IDX_H_S 24
+#define MPT_BYTE_64_L_KEY_IDX_H_M \
+ (((1UL << 8) - 1) << MPT_BYTE_64_L_KEY_IDX_H_S)
+
+struct hns_roce_wqe_ctrl_seg {
+ __be32 sgl_pa_h;
+ __be32 flag;
+ __be32 imm_data;
+ __be32 msg_length;
+};
+
+struct hns_roce_wqe_data_seg {
+ __be64 addr;
+ __be32 lkey;
+ __be32 len;
+};
+
+struct hns_roce_wqe_raddr_seg {
+ __be32 rkey;
+ __be32 len;/* reserved */
+ __be64 raddr;
+};
+
+struct hns_roce_rq_wqe_ctrl {
+
+ u32 rwqe_byte_4;
+ u32 rocee_sgl_ba_l;
+ u32 rwqe_byte_12;
+ u32 reserved[5];
+};
+
+#define RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_S 16
+#define RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_M \
+ (((1UL << 6) - 1) << RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_S)
+
+#define HNS_ROCE_QP_DESTROY_TIMEOUT_MSECS 10000
+
+#define GID_LEN 16
+
+struct hns_roce_ud_send_wqe {
+ u32 dmac_h;
+ u32 u32_8;
+ u32 immediate_data;
+
+ u32 u32_16;
+ union {
+ unsigned char dgid[GID_LEN];
+ struct {
+ u32 u32_20;
+ u32 u32_24;
+ u32 u32_28;
+ u32 u32_32;
+ };
+ };
+
+ u32 u32_36;
+ u32 u32_40;
+
+ u32 va0_l;
+ u32 va0_h;
+ u32 l_key0;
+
+ u32 va1_l;
+ u32 va1_h;
+ u32 l_key1;
+};
+
+#define UD_SEND_WQE_U32_4_DMAC_0_S 0
+#define UD_SEND_WQE_U32_4_DMAC_0_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_4_DMAC_0_S)
+
+#define UD_SEND_WQE_U32_4_DMAC_1_S 8
+#define UD_SEND_WQE_U32_4_DMAC_1_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_4_DMAC_1_S)
+
+#define UD_SEND_WQE_U32_4_DMAC_2_S 16
+#define UD_SEND_WQE_U32_4_DMAC_2_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_4_DMAC_2_S)
+
+#define UD_SEND_WQE_U32_4_DMAC_3_S 24
+#define UD_SEND_WQE_U32_4_DMAC_3_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_4_DMAC_3_S)
+
+#define UD_SEND_WQE_U32_8_DMAC_4_S 0
+#define UD_SEND_WQE_U32_8_DMAC_4_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_8_DMAC_4_S)
+
+#define UD_SEND_WQE_U32_8_DMAC_5_S 8
+#define UD_SEND_WQE_U32_8_DMAC_5_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_8_DMAC_5_S)
+
+#define UD_SEND_WQE_U32_8_OPERATION_TYPE_S 16
+#define UD_SEND_WQE_U32_8_OPERATION_TYPE_M \
+ (((1UL << 4) - 1) << UD_SEND_WQE_U32_8_OPERATION_TYPE_S)
+
+#define UD_SEND_WQE_U32_8_NUMBER_OF_DATA_SEG_S 24
+#define UD_SEND_WQE_U32_8_NUMBER_OF_DATA_SEG_M \
+ (((1UL << 6) - 1) << UD_SEND_WQE_U32_8_NUMBER_OF_DATA_SEG_S)
+
+#define UD_SEND_WQE_U32_8_SEND_GL_ROUTING_HDR_FLAG_S 31
+
+#define UD_SEND_WQE_U32_16_DEST_QP_S 0
+#define UD_SEND_WQE_U32_16_DEST_QP_M \
+ (((1UL << 24) - 1) << UD_SEND_WQE_U32_16_DEST_QP_S)
+
+#define UD_SEND_WQE_U32_16_MAX_STATIC_RATE_S 24
+#define UD_SEND_WQE_U32_16_MAX_STATIC_RATE_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_16_MAX_STATIC_RATE_S)
+
+#define UD_SEND_WQE_U32_36_FLOW_LABEL_S 0
+#define UD_SEND_WQE_U32_36_FLOW_LABEL_M \
+ (((1UL << 20) - 1) << UD_SEND_WQE_U32_36_FLOW_LABEL_S)
+
+#define UD_SEND_WQE_U32_36_PRIORITY_S 20
+#define UD_SEND_WQE_U32_36_PRIORITY_M \
+ (((1UL << 4) - 1) << UD_SEND_WQE_U32_36_PRIORITY_S)
+
+#define UD_SEND_WQE_U32_36_SGID_INDEX_S 24
+#define UD_SEND_WQE_U32_36_SGID_INDEX_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_36_SGID_INDEX_S)
+
+#define UD_SEND_WQE_U32_40_HOP_LIMIT_S 0
+#define UD_SEND_WQE_U32_40_HOP_LIMIT_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_40_HOP_LIMIT_S)
+
+#define UD_SEND_WQE_U32_40_TRAFFIC_CLASS_S 8
+#define UD_SEND_WQE_U32_40_TRAFFIC_CLASS_M \
+ (((1UL << 8) - 1) << UD_SEND_WQE_U32_40_TRAFFIC_CLASS_S)
+
+struct hns_roce_sqp_context {
+ u32 qp1c_bytes_4;
+ u32 sq_rq_bt_l;
+ u32 qp1c_bytes_12;
+ u32 qp1c_bytes_16;
+ u32 qp1c_bytes_20;
+ u32 qp1c_bytes_28;
+ u32 cur_rq_wqe_ba_l;
+ u32 qp1c_bytes_32;
+ u32 cur_sq_wqe_ba_l;
+ u32 qp1c_bytes_40;
+};
+
+#define QP1C_BYTES_4_SQ_WQE_SHIFT_S 8
+#define QP1C_BYTES_4_SQ_WQE_SHIFT_M \
+ (((1UL << 4) - 1) << QP1C_BYTES_4_SQ_WQE_SHIFT_S)
+
+#define QP1C_BYTES_4_RQ_WQE_SHIFT_S 12
+#define QP1C_BYTES_4_RQ_WQE_SHIFT_M \
+ (((1UL << 4) - 1) << QP1C_BYTES_4_RQ_WQE_SHIFT_S)
+
+#define QP1C_BYTES_4_PD_S 16
+#define QP1C_BYTES_4_PD_M (((1UL << 16) - 1) << QP1C_BYTES_4_PD_S)
+
+#define QP1C_BYTES_12_SQ_RQ_BT_H_S 0
+#define QP1C_BYTES_12_SQ_RQ_BT_H_M \
+ (((1UL << 17) - 1) << QP1C_BYTES_12_SQ_RQ_BT_H_S)
+
+#define QP1C_BYTES_16_RQ_HEAD_S 0
+#define QP1C_BYTES_16_RQ_HEAD_M (((1UL << 15) - 1) << QP1C_BYTES_16_RQ_HEAD_S)
+
+#define QP1C_BYTES_16_PORT_NUM_S 16
+#define QP1C_BYTES_16_PORT_NUM_M \
+ (((1UL << 3) - 1) << QP1C_BYTES_16_PORT_NUM_S)
+
+#define QP1C_BYTES_16_SIGNALING_TYPE_S 27
+#define QP1C_BYTES_16_LOCAL_ENABLE_E2E_CREDIT_S 28
+#define QP1C_BYTES_16_RQ_BA_FLG_S 29
+#define QP1C_BYTES_16_SQ_BA_FLG_S 30
+#define QP1C_BYTES_16_QP1_ERR_S 31
+
+#define QP1C_BYTES_20_SQ_HEAD_S 0
+#define QP1C_BYTES_20_SQ_HEAD_M (((1UL << 15) - 1) << QP1C_BYTES_20_SQ_HEAD_S)
+
+#define QP1C_BYTES_20_PKEY_IDX_S 16
+#define QP1C_BYTES_20_PKEY_IDX_M \
+ (((1UL << 16) - 1) << QP1C_BYTES_20_PKEY_IDX_S)
+
+#define QP1C_BYTES_28_CUR_RQ_WQE_BA_H_S 0
+#define QP1C_BYTES_28_CUR_RQ_WQE_BA_H_M \
+ (((1UL << 5) - 1) << QP1C_BYTES_28_CUR_RQ_WQE_BA_H_S)
+
+#define QP1C_BYTES_28_RQ_CUR_IDX_S 16
+#define QP1C_BYTES_28_RQ_CUR_IDX_M \
+ (((1UL << 15) - 1) << QP1C_BYTES_28_RQ_CUR_IDX_S)
+
+#define QP1C_BYTES_32_TX_CQ_NUM_S 0
+#define QP1C_BYTES_32_TX_CQ_NUM_M \
+ (((1UL << 16) - 1) << QP1C_BYTES_32_TX_CQ_NUM_S)
+
+#define QP1C_BYTES_32_RX_CQ_NUM_S 16
+#define QP1C_BYTES_32_RX_CQ_NUM_M \
+ (((1UL << 16) - 1) << QP1C_BYTES_32_RX_CQ_NUM_S)
+
+#define QP1C_BYTES_40_CUR_SQ_WQE_BA_H_S 0
+#define QP1C_BYTES_40_CUR_SQ_WQE_BA_H_M \
+ (((1UL << 5) - 1) << QP1C_BYTES_40_CUR_SQ_WQE_BA_H_S)
+
+#define QP1C_BYTES_40_SQ_CUR_IDX_S 16
+#define QP1C_BYTES_40_SQ_CUR_IDX_M \
+ (((1UL << 15) - 1) << QP1C_BYTES_40_SQ_CUR_IDX_S)
+
+#define HNS_ROCE_WQE_INLINE (1UL<<31)
+#define HNS_ROCE_WQE_SE (1UL<<30)
+
+#define HNS_ROCE_WQE_SGE_NUM_BIT 24
+#define HNS_ROCE_WQE_IMM (1UL<<23)
+#define HNS_ROCE_WQE_INV_RKEY (1UL<<22)
+#define HNS_ROCE_WQE_FENCE (1UL<<21)
+#define HNS_ROCE_WQE_CQ_NOTIFY (1UL<<20)
+
+#define HNS_ROCE_WQE_OPCODE_SEND (0<<16)
+#define HNS_ROCE_WQE_OPCODE_RDMA_READ (1<<16)
+#define HNS_ROCE_WQE_OPCODE_RDMA_WRITE (2<<16)
+#define HNS_ROCE_WQE_OPCODE_FAST_REG_MR (3<<16)
+#define HNS_ROCE_WQE_OPCODE_LOCAL_INV (4<<16)
+#define HNS_ROCE_WQE_OPCODE_BIND_MW1 (5<<16)
+#define HNS_ROCE_WQE_OPCODE_BIND_MW2 (6<<16)
+#define HNS_ROCE_WQE_OPCODE_UD_SEND (7<<16)
+#define HNS_ROCE_WQE_OPCODE_MASK (15<<16)
+
+struct hns_roce_qp_context {
+ u32 qpc_bytes_4;
+ u32 qpc_bytes_8;
+ u32 qpc_bytes_12;
+ u32 qpc_bytes_16;
+ u32 sq_rq_bt_l;
+ u32 qpc_bytes_24;
+ u32 irrl_ba_l;
+ u32 qpc_bytes_32;
+ u32 qpc_bytes_36;
+ u32 dmac_l;
+ u32 qpc_bytes_44;
+ u32 qpc_bytes_48;
+ u8 dgid[16];
+ u32 qpc_bytes_68;
+ u32 cur_rq_wqe_ba_l;
+ u32 qpc_bytes_76;
+ u32 rx_rnr_time;
+ u32 qpc_bytes_84;
+ u32 qpc_bytes_88;
+ union {
+ u32 rx_sge_len;
+ u32 dma_length;
+ };
+ union {
+ u32 rx_sge_num;
+ u32 rx_send_pktn;
+ u32 r_key;
+ };
+ u32 va_l;
+ u32 va_h;
+ u32 qpc_bytes_108;
+ u32 qpc_bytes_112;
+ u32 rx_cur_sq_wqe_ba_l;
+ u32 qpc_bytes_120;
+ u32 qpc_bytes_124;
+ u32 qpc_bytes_128;
+ u32 qpc_bytes_132;
+ u32 qpc_bytes_136;
+ u32 qpc_bytes_140;
+ u32 qpc_bytes_144;
+ u32 qpc_bytes_148;
+ union {
+ u32 rnr_retry;
+ u32 ack_time;
+ };
+ u32 qpc_bytes_156;
+ u32 pkt_use_len;
+ u32 qpc_bytes_164;
+ u32 qpc_bytes_168;
+ union {
+ u32 sge_use_len;
+ u32 pa_use_len;
+ };
+ u32 qpc_bytes_176;
+ u32 qpc_bytes_180;
+ u32 tx_cur_sq_wqe_ba_l;
+ u32 qpc_bytes_188;
+ u32 rvd21;
+};
+
+#define QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_S 0
+#define QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_M \
+ (((1UL << 3) - 1) << QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_S)
+
+#define QP_CONTEXT_QPC_BYTE_4_ENABLE_FPMR_S 3
+#define QP_CONTEXT_QPC_BYTE_4_RDMA_READ_ENABLE_S 4
+#define QP_CONTEXT_QPC_BYTE_4_RDMA_WRITE_ENABLE_S 5
+#define QP_CONTEXT_QPC_BYTE_4_ATOMIC_OPERATION_ENABLE_S 6
+#define QP_CONTEXT_QPC_BYTE_4_RDMAR_USE_S 7
+
+#define QP_CONTEXT_QPC_BYTES_4_SQ_WQE_SHIFT_S 8
+#define QP_CONTEXT_QPC_BYTES_4_SQ_WQE_SHIFT_M \
+ (((1UL << 4) - 1) << QP_CONTEXT_QPC_BYTES_4_SQ_WQE_SHIFT_S)
+
+#define QP_CONTEXT_QPC_BYTES_4_RQ_WQE_SHIFT_S 12
+#define QP_CONTEXT_QPC_BYTES_4_RQ_WQE_SHIFT_M \
+ (((1UL << 4) - 1) << QP_CONTEXT_QPC_BYTES_4_RQ_WQE_SHIFT_S)
+
+#define QP_CONTEXT_QPC_BYTES_4_PD_S 16
+#define QP_CONTEXT_QPC_BYTES_4_PD_M \
+ (((1UL << 16) - 1) << QP_CONTEXT_QPC_BYTES_4_PD_S)
+
+#define QP_CONTEXT_QPC_BYTES_8_TX_COMPLETION_S 0
+#define QP_CONTEXT_QPC_BYTES_8_TX_COMPLETION_M \
+ (((1UL << 16) - 1) << QP_CONTEXT_QPC_BYTES_8_TX_COMPLETION_S)
+
+#define QP_CONTEXT_QPC_BYTES_8_RX_COMPLETION_S 16
+#define QP_CONTEXT_QPC_BYTES_8_RX_COMPLETION_M \
+ (((1UL << 16) - 1) << QP_CONTEXT_QPC_BYTES_8_RX_COMPLETION_S)
+
+#define QP_CONTEXT_QPC_BYTES_12_SRQ_NUMBER_S 0
+#define QP_CONTEXT_QPC_BYTES_12_SRQ_NUMBER_M \
+ (((1UL << 16) - 1) << QP_CONTEXT_QPC_BYTES_12_SRQ_NUMBER_S)
+
+#define QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S 16
+#define QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_M \
+ (((1UL << 16) - 1) << QP_CONTEXT_QPC_BYTES_12_P_KEY_INDEX_S)
+
+#define QP_CONTEXT_QPC_BYTES_16_QP_NUM_S 0
+#define QP_CONTEXT_QPC_BYTES_16_QP_NUM_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_16_QP_NUM_S)
+
+#define QP_CONTEXT_QPC_BYTES_24_SQ_RQ_BT_H_S 0
+#define QP_CONTEXT_QPC_BYTES_24_SQ_RQ_BT_H_M \
+ (((1UL << 17) - 1) << QP_CONTEXT_QPC_BYTES_24_SQ_RQ_BT_H_S)
+
+#define QP_CONTEXT_QPC_BYTES_24_MINIMUM_RNR_NAK_TIMER_S 18
+#define QP_CONTEXT_QPC_BYTES_24_MINIMUM_RNR_NAK_TIMER_M \
+ (((1UL << 5) - 1) << QP_CONTEXT_QPC_BYTES_24_MINIMUM_RNR_NAK_TIMER_S)
+
+#define QP_CONTEXT_QPC_BYTE_24_REMOTE_ENABLE_E2E_CREDITS_S 23
+
+#define QP_CONTEXT_QPC_BYTES_32_IRRL_BA_H_S 0
+#define QP_CONTEXT_QPC_BYTES_32_IRRL_BA_H_M \
+ (((1UL << 17) - 1) << QP_CONTEXT_QPC_BYTES_32_IRRL_BA_H_S)
+
+#define QP_CONTEXT_QPC_BYTES_32_MIG_STATE_S 18
+#define QP_CONTEXT_QPC_BYTES_32_MIG_STATE_M \
+ (((1UL << 2) - 1) << QP_CONTEXT_QPC_BYTES_32_MIG_STATE_S)
+
+#define QP_CONTEXT_QPC_BYTE_32_LOCAL_ENABLE_E2E_CREDITS_S 20
+#define QP_CONTEXT_QPC_BYTE_32_SIGNALING_TYPE_S 21
+#define QP_CONTEXT_QPC_BYTE_32_LOOPBACK_INDICATOR_S 22
+#define QP_CONTEXT_QPC_BYTE_32_GLOBAL_HEADER_S 23
+
+#define QP_CONTEXT_QPC_BYTES_32_RESPONDER_RESOURCES_S 24
+#define QP_CONTEXT_QPC_BYTES_32_RESPONDER_RESOURCES_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_32_RESPONDER_RESOURCES_S)
+
+#define QP_CONTEXT_QPC_BYTES_36_DEST_QP_S 0
+#define QP_CONTEXT_QPC_BYTES_36_DEST_QP_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_36_DEST_QP_S)
+
+#define QP_CONTEXT_QPC_BYTES_36_SGID_INDEX_S 24
+#define QP_CONTEXT_QPC_BYTES_36_SGID_INDEX_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_36_SGID_INDEX_S)
+
+#define QP_CONTEXT_QPC_BYTES_44_DMAC_H_S 0
+#define QP_CONTEXT_QPC_BYTES_44_DMAC_H_M \
+ (((1UL << 16) - 1) << QP_CONTEXT_QPC_BYTES_44_DMAC_H_S)
+
+#define QP_CONTEXT_QPC_BYTES_44_MAXIMUM_STATIC_RATE_S 16
+#define QP_CONTEXT_QPC_BYTES_44_MAXIMUM_STATIC_RATE_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_44_MAXIMUM_STATIC_RATE_S)
+
+#define QP_CONTEXT_QPC_BYTES_44_HOPLMT_S 24
+#define QP_CONTEXT_QPC_BYTES_44_HOPLMT_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_44_HOPLMT_S)
+
+#define QP_CONTEXT_QPC_BYTES_48_FLOWLABEL_S 0
+#define QP_CONTEXT_QPC_BYTES_48_FLOWLABEL_M \
+ (((1UL << 20) - 1) << QP_CONTEXT_QPC_BYTES_48_FLOWLABEL_S)
+
+#define QP_CONTEXT_QPC_BYTES_48_TCLASS_S 20
+#define QP_CONTEXT_QPC_BYTES_48_TCLASS_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_48_TCLASS_S)
+
+#define QP_CONTEXT_QPC_BYTES_48_MTU_S 28
+#define QP_CONTEXT_QPC_BYTES_48_MTU_M \
+ (((1UL << 4) - 1) << QP_CONTEXT_QPC_BYTES_48_MTU_S)
+
+#define QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S 0
+#define QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S)
+
+#define QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_S 16
+#define QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_S)
+
+#define QP_CONTEXT_QPC_BYTES_76_CUR_RQ_WQE_BA_H_S 0
+#define QP_CONTEXT_QPC_BYTES_76_CUR_RQ_WQE_BA_H_M \
+ (((1UL << 5) - 1) << QP_CONTEXT_QPC_BYTES_76_CUR_RQ_WQE_BA_H_S)
+
+#define QP_CONTEXT_QPC_BYTES_76_RX_REQ_MSN_S 8
+#define QP_CONTEXT_QPC_BYTES_76_RX_REQ_MSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_76_RX_REQ_MSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_84_LAST_ACK_PSN_S 0
+#define QP_CONTEXT_QPC_BYTES_84_LAST_ACK_PSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_84_LAST_ACK_PSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_84_TRRL_HEAD_S 24
+#define QP_CONTEXT_QPC_BYTES_84_TRRL_HEAD_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_84_TRRL_HEAD_S)
+
+#define QP_CONTEXT_QPC_BYTES_88_RX_REQ_EPSN_S 0
+#define QP_CONTEXT_QPC_BYTES_88_RX_REQ_EPSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_88_RX_REQ_EPSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_88_RX_REQ_PSN_ERR_FLAG_S 24
+#define QP_CONTEXT_QPC_BYTES_88_RX_LAST_OPCODE_FLG_S 25
+
+#define QP_CONTEXT_QPC_BYTES_88_RQ_REQ_LAST_OPERATION_TYPE_S 26
+#define QP_CONTEXT_QPC_BYTES_88_RQ_REQ_LAST_OPERATION_TYPE_M \
+ (((1UL << 2) - 1) << \
+ QP_CONTEXT_QPC_BYTES_88_RQ_REQ_LAST_OPERATION_TYPE_S)
+
+#define QP_CONTEXT_QPC_BYTES_88_RQ_REQ_RDMA_WR_FLAG_S 29
+#define QP_CONTEXT_QPC_BYTES_88_RQ_REQ_RDMA_WR_FLAG_M \
+ (((1UL << 2) - 1) << QP_CONTEXT_QPC_BYTES_88_RQ_REQ_RDMA_WR_FLAG_S)
+
+#define QP_CONTEXT_QPC_BYTES_108_TRRL_SDB_PSN_S 0
+#define QP_CONTEXT_QPC_BYTES_108_TRRL_SDB_PSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_108_TRRL_SDB_PSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_108_TRRL_SDB_PSN_FLG_S 24
+#define QP_CONTEXT_QPC_BYTES_108_TRRL_TDB_PSN_FLG_S 25
+
+#define QP_CONTEXT_QPC_BYTES_112_TRRL_TDB_PSN_S 0
+#define QP_CONTEXT_QPC_BYTES_112_TRRL_TDB_PSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_112_TRRL_TDB_PSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_112_TRRL_TAIL_S 24
+#define QP_CONTEXT_QPC_BYTES_112_TRRL_TAIL_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_112_TRRL_TAIL_S)
+
+#define QP_CONTEXT_QPC_BYTES_120_RX_CUR_SQ_WQE_BA_H_S 0
+#define QP_CONTEXT_QPC_BYTES_120_RX_CUR_SQ_WQE_BA_H_M \
+ (((1UL << 5) - 1) << QP_CONTEXT_QPC_BYTES_120_RX_CUR_SQ_WQE_BA_H_S)
+
+#define QP_CONTEXT_QPC_BYTES_124_RX_ACK_MSN_S 0
+#define QP_CONTEXT_QPC_BYTES_124_RX_ACK_MSN_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_124_RX_ACK_MSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_124_IRRL_MSG_IDX_S 16
+#define QP_CONTEXT_QPC_BYTES_124_IRRL_MSG_IDX_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_124_IRRL_MSG_IDX_S)
+
+#define QP_CONTEXT_QPC_BYTES_128_RX_ACK_EPSN_S 0
+#define QP_CONTEXT_QPC_BYTES_128_RX_ACK_EPSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_128_RX_ACK_EPSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_128_RX_ACK_PSN_ERR_FLG_S 24
+
+#define QP_CONTEXT_QPC_BYTES_128_ACK_LAST_OPERATION_TYPE_S 25
+#define QP_CONTEXT_QPC_BYTES_128_ACK_LAST_OPERATION_TYPE_M \
+ (((1UL << 2) - 1) << QP_CONTEXT_QPC_BYTES_128_ACK_LAST_OPERATION_TYPE_S)
+
+#define QP_CONTEXT_QPC_BYTES_128_IRRL_PSN_VLD_FLG_S 27
+
+#define QP_CONTEXT_QPC_BYTES_132_IRRL_PSN_S 0
+#define QP_CONTEXT_QPC_BYTES_132_IRRL_PSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_132_IRRL_PSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_132_IRRL_TAIL_S 24
+#define QP_CONTEXT_QPC_BYTES_132_IRRL_TAIL_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_132_IRRL_TAIL_S)
+
+#define QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_PSN_S 0
+#define QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_PSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_PSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_FPKT_PSN_L_S 24
+#define QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_FPKT_PSN_L_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_136_RETRY_MSG_FPKT_PSN_L_S)
+
+#define QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_FPKT_PSN_H_S 0
+#define QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_FPKT_PSN_H_M \
+ (((1UL << 16) - 1) << QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_FPKT_PSN_H_S)
+
+#define QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_MSN_S 16
+#define QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_MSN_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_140_RETRY_MSG_MSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_140_RNR_RETRY_FLG_S 31
+
+#define QP_CONTEXT_QPC_BYTES_144_QP_STATE_S 0
+#define QP_CONTEXT_QPC_BYTES_144_QP_STATE_M \
+ (((1UL << 3) - 1) << QP_CONTEXT_QPC_BYTES_144_QP_STATE_S)
+
+#define QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S 0
+#define QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_M \
+ (((1UL << 2) - 1) << QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S)
+
+#define QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S 2
+#define QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_M \
+ (((1UL << 3) - 1) << QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S)
+
+#define QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S 5
+#define QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_M \
+ (((1UL << 3) - 1) << QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S)
+
+#define QP_CONTEXT_QPC_BYTES_148_LSN_S 8
+#define QP_CONTEXT_QPC_BYTES_148_LSN_M \
+ (((1UL << 16) - 1) << QP_CONTEXT_QPC_BYTES_148_LSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_S 0
+#define QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_M \
+ (((1UL << 3) - 1) << QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_S)
+
+#define QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S 3
+#define QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M \
+ (((1UL << 5) - 1) << QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S)
+
+#define QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_S 8
+#define QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_M \
+ (((1UL << 3) - 1) << QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_S)
+
+#define QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S 11
+#define QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M \
+ (((1UL << 3) - 1) << QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S)
+
+#define QP_CONTEXT_QPC_BYTES_156_SL_S 14
+#define QP_CONTEXT_QPC_BYTES_156_SL_M \
+ (((1UL << 2) - 1) << QP_CONTEXT_QPC_BYTES_156_SL_S)
+
+#define QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_S 16
+#define QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_156_INITIATOR_DEPTH_S)
+
+#define QP_CONTEXT_QPC_BYTES_156_ACK_REQ_IND_S 24
+#define QP_CONTEXT_QPC_BYTES_156_ACK_REQ_IND_M \
+ (((1UL << 2) - 1) << QP_CONTEXT_QPC_BYTES_156_ACK_REQ_IND_S)
+
+#define QP_CONTEXT_QPC_BYTES_164_SQ_PSN_S 0
+#define QP_CONTEXT_QPC_BYTES_164_SQ_PSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_164_SQ_PSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_164_IRRL_HEAD_S 24
+#define QP_CONTEXT_QPC_BYTES_164_IRRL_HEAD_M \
+ (((1UL << 8) - 1) << QP_CONTEXT_QPC_BYTES_164_IRRL_HEAD_S)
+
+#define QP_CONTEXT_QPC_BYTES_168_RETRY_SQ_PSN_S 0
+#define QP_CONTEXT_QPC_BYTES_168_RETRY_SQ_PSN_M \
+ (((1UL << 24) - 1) << QP_CONTEXT_QPC_BYTES_168_RETRY_SQ_PSN_S)
+
+#define QP_CONTEXT_QPC_BYTES_168_SGE_USE_FLA_S 24
+#define QP_CONTEXT_QPC_BYTES_168_SGE_USE_FLA_M \
+ (((1UL << 2) - 1) << QP_CONTEXT_QPC_BYTES_168_SGE_USE_FLA_S)
+
+#define QP_CONTEXT_QPC_BYTES_168_DB_TYPE_S 26
+#define QP_CONTEXT_QPC_BYTES_168_DB_TYPE_M \
+ (((1UL << 2) - 1) << QP_CONTEXT_QPC_BYTES_168_DB_TYPE_S)
+
+#define QP_CONTEXT_QPC_BYTES_168_MSG_LP_IND_S 28
+#define QP_CONTEXT_QPC_BYTES_168_CSDB_LP_IND_S 29
+#define QP_CONTEXT_QPC_BYTES_168_QP_ERR_FLG_S 30
+
+#define QP_CONTEXT_QPC_BYTES_176_DB_CUR_INDEX_S 0
+#define QP_CONTEXT_QPC_BYTES_176_DB_CUR_INDEX_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_176_DB_CUR_INDEX_S)
+
+#define QP_CONTEXT_QPC_BYTES_176_RETRY_DB_CUR_INDEX_S 16
+#define QP_CONTEXT_QPC_BYTES_176_RETRY_DB_CUR_INDEX_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_176_RETRY_DB_CUR_INDEX_S)
+
+#define QP_CONTEXT_QPC_BYTES_180_SQ_HEAD_S 0
+#define QP_CONTEXT_QPC_BYTES_180_SQ_HEAD_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_180_SQ_HEAD_S)
+
+#define QP_CONTEXT_QPC_BYTES_180_SQ_CUR_INDEX_S 16
+#define QP_CONTEXT_QPC_BYTES_180_SQ_CUR_INDEX_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_180_SQ_CUR_INDEX_S)
+
+#define QP_CONTEXT_QPC_BYTES_188_TX_CUR_SQ_WQE_BA_H_S 0
+#define QP_CONTEXT_QPC_BYTES_188_TX_CUR_SQ_WQE_BA_H_M \
+ (((1UL << 5) - 1) << QP_CONTEXT_QPC_BYTES_188_TX_CUR_SQ_WQE_BA_H_S)
+
+#define QP_CONTEXT_QPC_BYTES_188_PKT_RETRY_FLG_S 8
+
+#define QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_S 16
+#define QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_M \
+ (((1UL << 15) - 1) << QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_S)
+
+struct hns_roce_rq_db {
+ u32 u32_4;
+ u32 u32_8;
+};
+
+#define RQ_DOORBELL_U32_4_RQ_HEAD_S 0
+#define RQ_DOORBELL_U32_4_RQ_HEAD_M \
+ (((1UL << 15) - 1) << RQ_DOORBELL_U32_4_RQ_HEAD_S)
+
+#define RQ_DOORBELL_U32_8_QPN_S 0
+#define RQ_DOORBELL_U32_8_QPN_M (((1UL << 24) - 1) << RQ_DOORBELL_U32_8_QPN_S)
+
+#define RQ_DOORBELL_U32_8_CMD_S 28
+#define RQ_DOORBELL_U32_8_CMD_M (((1UL << 3) - 1) << RQ_DOORBELL_U32_8_CMD_S)
+
+#define RQ_DOORBELL_U32_8_HW_SYNC_S 31
+
+struct hns_roce_sq_db {
+ u32 u32_4;
+ u32 u32_8;
+};
+
+#define SQ_DOORBELL_U32_4_SQ_HEAD_S 0
+#define SQ_DOORBELL_U32_4_SQ_HEAD_M \
+ (((1UL << 15) - 1) << SQ_DOORBELL_U32_4_SQ_HEAD_S)
+
+#define SQ_DOORBELL_U32_4_PORT_S 18
+#define SQ_DOORBELL_U32_4_PORT_M (((1UL << 3) - 1) << SQ_DOORBELL_U32_4_PORT_S)
+
+#define SQ_DOORBELL_U32_8_QPN_S 0
+#define SQ_DOORBELL_U32_8_QPN_M (((1UL << 24) - 1) << SQ_DOORBELL_U32_8_QPN_S)
+
+#define SQ_DOORBELL_HW_SYNC_S 31
+
+struct hns_roce_ext_db {
+ int esdb_almept;
+ int esdb_alful;
+ int eodb_almept;
+ int eodb_alful;
+ int esdb_dep;
+ int eodb_dep;
+ struct hns_roce_buf_list *sdb_buf_list;
+ struct hns_roce_buf_list *odb_buf_list;
+};
+
+struct hns_roce_db_table {
+ int sdb_ext_mod;
+ int odb_ext_mod;
+ int sdb_almept;
+ int sdb_almful;
+ int odb_almept;
+ int odb_almful;
+ struct hns_roce_ext_db *ext_db;
+};
+
+struct hns_roce_v1_priv {
+ struct hns_roce_db_table db_table;
+ struct hns_roce_raq_table raq_table;
+};
+
+extern int hns_roce_probe(struct platform_device *pdev);
+extern int hns_roce_remove(struct platform_device *pdev);
+extern int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, u32 val);
+
+#endif
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 0/3] IB/hns: Add HiSilicon RoCE driver
From: Lijun Ou @ 2016-03-19 10:50 UTC (permalink / raw)
To: dledford, sean.hefty, hal.rosenstock, davem, jeffrey.t.kirsher,
jiri, ogerlitz
Cc: linux-rdma, linux-kernel, netdev, gongyangming, xiaokun,
tangchaofei, oulijun, haifeng.wei, yisen.zhuang, yankejian,
lisheng011, charles.chenxin, linuxarm
The HiSilicon Network Substem is a long term evolution IP which is
supposed to be used in HiSilicon ICT SoC. RoCE is a feature of hns.
The driver for HiSilicon RoCE engine is a platform driver.
The driver will support mulitple versions of hns. Currently only "v1"
for hip06 SoC is supported.
Changes v2 -> v3:
1. modify the formats of RoCE driver code base v2 by the experts
reviewing. also, it used kmalloc_array instead of kmalloc, used kcalloc
instead of kzalloc, when refer to memory allocation for array
2. remove some functions without use and unconnected macros
3. modify the binding document with RoCE DT base v2 which added interrupt-names
4. redesign the port_map and si_map in hns_dsaf_roce_reset
5. add HiSilicon RoCE driver maintainers introduction in MAINTAINERS document
Changes v1 -> v2:
1. modify the formats of roce driver code by the experts reviewing
2. modify the bindings file with roce dts. add the attribute named
interrput-names.
3. modify the way of defining port mode in hns_dsaf_main.c
4. move the Kconfig file into the hns directory and send it with roce
Lijun Ou (3):
net: hns: Add reset function support for RoCE driver
IB/hns: Add HiSilicon RoCE driver support
IB/hns: Add binding document for HiSilicon RoCE driver
.../bindings/infiniband/hisilicon-hns-roce.txt | 107 +
MAINTAINERS | 8 +
drivers/infiniband/Kconfig | 1 +
drivers/infiniband/hw/Makefile | 1 +
drivers/infiniband/hw/hisilicon/hns/Kconfig | 10 +
drivers/infiniband/hw/hisilicon/hns/Makefile | 9 +
drivers/infiniband/hw/hisilicon/hns/hns_roce_ah.c | 110 +
.../infiniband/hw/hisilicon/hns/hns_roce_alloc.c | 239 ++
drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.c | 338 +++
drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.h | 80 +
.../infiniband/hw/hisilicon/hns/hns_roce_common.h | 308 +++
drivers/infiniband/hw/hisilicon/hns/hns_roce_cq.c | 436 +++
.../infiniband/hw/hisilicon/hns/hns_roce_device.h | 794 ++++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.c | 758 ++++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.h | 133 +
drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.c | 578 ++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.h | 112 +
.../infiniband/hw/hisilicon/hns/hns_roce_main.c | 1097 ++++++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_mr.c | 605 +++++
drivers/infiniband/hw/hisilicon/hns/hns_roce_pd.c | 124 +
drivers/infiniband/hw/hisilicon/hns/hns_roce_qp.c | 841 ++++++
.../infiniband/hw/hisilicon/hns/hns_roce_user.h | 31 +
.../infiniband/hw/hisilicon/hns/hns_roce_v1_hw.c | 2835 ++++++++++++++++++++
.../infiniband/hw/hisilicon/hns/hns_roce_v1_hw.h | 986 +++++++
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 84 +
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h | 30 +
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 62 +-
drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h | 13 +
28 files changed, 10720 insertions(+), 10 deletions(-)
create mode 100644 Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt
create mode 100644 drivers/infiniband/hw/hisilicon/hns/Kconfig
create mode 100644 drivers/infiniband/hw/hisilicon/hns/Makefile
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_ah.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_alloc.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_cmd.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_common.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_cq.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_device.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_eq.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_icm.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_main.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_mr.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_pd.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_qp.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_user.h
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.c
create mode 100644 drivers/infiniband/hw/hisilicon/hns/hns_roce_v1_hw.h
--
1.9.1
^ permalink raw reply
* [PATCH v3 1/3] net: hns: Add reset function support for RoCE driver
From: Lijun Ou @ 2016-03-19 10:50 UTC (permalink / raw)
To: dledford, sean.hefty, hal.rosenstock, davem, jeffrey.t.kirsher,
jiri, ogerlitz
Cc: linux-rdma, linux-kernel, netdev, gongyangming, xiaokun,
tangchaofei, oulijun, haifeng.wei, yisen.zhuang, yankejian,
lisheng011, charles.chenxin, linuxarm
In-Reply-To: <1458384658-16759-1-git-send-email-oulijun@huawei.com>
It added reset function for RoCE driver. RoCE is a feature of hns.
In hip06 SoC, in RoCE reset process, it's needed to configure dsaf
channel reset, port and sl map info. Reset function of RoCE is
located in dsaf module, we only call it in RoCE driver when needed.
Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Wei Hu(Xavier) <xavier.huwei@huawei.com>
Signed-off-by: Lisheng <lisheng011@huawei.com>
---
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 84 ++++++++++++++++++++++
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h | 30 ++++++++
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 62 +++++++++++++---
drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h | 13 ++++
4 files changed, 179 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 38fc5be..9370d46 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -2593,6 +2594,89 @@ static struct platform_driver g_dsaf_driver = {
module_platform_driver(g_dsaf_driver);
+/**
+ * hns_dsaf_roce_reset - reset dsaf and roce
+ * @dsaf_fwnode: Pointer to framework node for the dasf
+ * @val: 0 - request reset , 1 - drop reset
+ * retuen 0 - success , negative -fail
+ */
+int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, u32 val)
+{
+ struct dsaf_device *dsaf_dev;
+ struct platform_device *pdev;
+ unsigned int mp;
+ unsigned int sl;
+ unsigned int credit;
+ int i;
+ const u32 port_map[DSAF_ROCE_CREDIT_CHN][DSAF_ROCE_CHAN_MODE_NUM] = {
+ {DSAF_ROCE_PORT_0, DSAF_ROCE_PORT_0, DSAF_ROCE_PORT_0},
+ {DSAF_ROCE_PORT_1, DSAF_ROCE_PORT_0, DSAF_ROCE_PORT_0},
+ {DSAF_ROCE_PORT_2, DSAF_ROCE_PORT_1, DSAF_ROCE_PORT_0},
+ {DSAF_ROCE_PORT_3, DSAF_ROCE_PORT_1, DSAF_ROCE_PORT_0},
+ {DSAF_ROCE_PORT_4, DSAF_ROCE_PORT_2, DSAF_ROCE_PORT_1},
+ {DSAF_ROCE_PORT_4, DSAF_ROCE_PORT_2, DSAF_ROCE_PORT_1},
+ {DSAF_ROCE_PORT_5, DSAF_ROCE_PORT_3, DSAF_ROCE_PORT_1},
+ {DSAF_ROCE_PORT_5, DSAF_ROCE_PORT_3, DSAF_ROCE_PORT_1},
+ };
+ const u32 sl_map[DSAF_ROCE_CREDIT_CHN][DSAF_ROCE_CHAN_MODE_NUM] = {
+ {DSAF_ROCE_SL_0, DSAF_ROCE_SL_0, DSAF_ROCE_SL_0},
+ {DSAF_ROCE_SL_0, DSAF_ROCE_SL_1, DSAF_ROCE_SL_1},
+ {DSAF_ROCE_SL_0, DSAF_ROCE_SL_0, DSAF_ROCE_SL_2},
+ {DSAF_ROCE_SL_0, DSAF_ROCE_SL_1, DSAF_ROCE_SL_3},
+ {DSAF_ROCE_SL_0, DSAF_ROCE_SL_0, DSAF_ROCE_SL_0},
+ {DSAF_ROCE_SL_1, DSAF_ROCE_SL_1, DSAF_ROCE_SL_1},
+ {DSAF_ROCE_SL_0, DSAF_ROCE_SL_0, DSAF_ROCE_SL_2},
+ {DSAF_ROCE_SL_1, DSAF_ROCE_SL_1, DSAF_ROCE_SL_3},
+ };
+
+ if (!is_of_node(dsaf_fwnode)) {
+ pr_err("Only support DT node!\n");
+ return -EINVAL;
+ }
+ pdev = of_find_device_by_node(to_of_node(dsaf_fwnode));
+ dsaf_dev = dev_get_drvdata(&pdev->dev);
+ if (AE_IS_VER1(dsaf_dev->dsaf_ver)) {
+ dev_err(dsaf_dev->dev, "%s v1 chip do not support roce!\n",
+ dsaf_dev->ae_dev.name);
+ return -ENODEV;
+ }
+
+ if (!val) {
+ /* Reset rocee-channels in dsaf and rocee */
+ hns_dsaf_srst_chns(dsaf_dev, 0x3f000, 0);
+ hns_dsaf_roce_srst(dsaf_dev, 0);
+ } else {
+ /* Configure dsaf tx roce correspond to port map and sl map */
+ mp = dsaf_read_dev(dsaf_dev, DSAF_ROCE_PORT_MAP_REG);
+ for (i = 0; i < DSAF_ROCE_CREDIT_CHN; i++)
+ dsaf_set_field(mp, 7 << i * 3, i * 3,
+ port_map[i][DSAF_ROCE_6PORT_MODE]);
+ dsaf_set_field(mp, 3 << i * 3, i * 3, 0);
+ dsaf_write_dev(dsaf_dev, DSAF_ROCE_PORT_MAP_REG, mp);
+
+ sl = dsaf_read_dev(dsaf_dev, DSAF_ROCE_SL_MAP_REG);
+ for (i = 0; i < DSAF_ROCE_CREDIT_CHN; i++)
+ dsaf_set_field(sl, 3 << i * 2, i * 2,
+ sl_map[i][DSAF_ROCE_6PORT_MODE]);
+ dsaf_write_dev(dsaf_dev, DSAF_ROCE_SL_MAP_REG, sl);
+
+ /* De-reset rocee-channels in dsaf and rocee */
+ hns_dsaf_srst_chns(dsaf_dev, 0x3f000, 1);
+ msleep(20);
+ hns_dsaf_roce_srst(dsaf_dev, 1);
+
+ /* Eanble dsaf channel rocee credit */
+ credit = dsaf_read_dev(dsaf_dev, DSAF_SBM_ROCEE_CFG_REG_REG);
+ dsaf_set_bit(credit, DSAF_SBM_ROCEE_CFG_CRD_EN_B, 0);
+ dsaf_write_dev(dsaf_dev, DSAF_SBM_ROCEE_CFG_REG_REG, credit);
+
+ dsaf_set_bit(credit, DSAF_SBM_ROCEE_CFG_CRD_EN_B, 1);
+ dsaf_write_dev(dsaf_dev, DSAF_SBM_ROCEE_CFG_REG_REG, credit);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(hns_dsaf_roce_reset);
+
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
MODULE_DESCRIPTION("HNS DSAF driver");
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index 5fea226..6108341 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -40,6 +40,32 @@ struct hns_mac_cb;
#define DSAF_DUMP_REGS_NUM 504
#define DSAF_STATIC_NUM 28
+#define DSAF_ROCE_CREDIT_CHN 8
+#define DSAF_ROCE_CHAN_MODE 3
+
+enum dsaf_roce_port_mode {
+ DSAF_ROCE_6PORT_MODE,
+ DSAF_ROCE_4PORT_MODE,
+ DSAF_ROCE_2PORT_MODE,
+ DSAF_ROCE_CHAN_MODE_NUM
+};
+
+enum dsaf_roce_port_num {
+ DSAF_ROCE_PORT_0 = 0,
+ DSAF_ROCE_PORT_1 = 1,
+ DSAF_ROCE_PORT_2 = 2,
+ DSAF_ROCE_PORT_3 = 3,
+ DSAF_ROCE_PORT_4 = 4,
+ DSAF_ROCE_PORT_5 = 5
+};
+
+enum dsaf_roce_qos_sl {
+ DSAF_ROCE_SL_0 = 0,
+ DSAF_ROCE_SL_1 = 1,
+ DSAF_ROCE_SL_2 = 2,
+ DSAF_ROCE_SL_3 = 3
+};
+
#define DSAF_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset))))
enum hal_dsaf_mode {
@@ -400,6 +426,10 @@ void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val);
void hns_dsaf_fix_mac_mode(struct hns_mac_cb *mac_cb);
+void hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, u32 val);
+
+void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, u32 val);
+
int hns_dsaf_ae_init(struct dsaf_device *dsaf_dev);
void hns_dsaf_ae_uninit(struct dsaf_device *dsaf_dev);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
index 607c3be..c0f0e80 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
@@ -87,18 +87,22 @@ void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val)
u32 xbar_reg_addr;
u32 nt_reg_addr;
- if (!val) {
- xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
- nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
+ if (AE_IS_VER1(dsaf_dev->dsaf_ver)) {
+ if (!val) {
+ xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
+ nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
+ } else {
+ xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG;
+ nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG;
+ }
+
+ dsaf_write_reg(dsaf_dev->sc_base, xbar_reg_addr,
+ RESET_REQ_OR_DREQ);
+ dsaf_write_reg(dsaf_dev->sc_base, nt_reg_addr,
+ RESET_REQ_OR_DREQ);
} else {
- xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_DREQ_REG;
- nt_reg_addr = DSAF_SUB_SC_NT_RESET_DREQ_REG;
+ hns_dsaf_srst_chns(dsaf_dev, 0xfffff, val);
}
-
- dsaf_write_reg(dsaf_dev->sc_base, xbar_reg_addr,
- RESET_REQ_OR_DREQ);
- dsaf_write_reg(dsaf_dev->sc_base, nt_reg_addr,
- RESET_REQ_OR_DREQ);
}
void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
@@ -139,6 +143,44 @@ void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
dsaf_write_reg(dsaf_dev->sc_base, reg_addr, reg_val);
}
+/**
+ * hns_dsaf_srst_chns - reset dsaf channels
+ * @dsaf_dev: dsaf device struct pointer
+ * @msk: xbar channels mask value:
+ * bit0-5 for xge0-5
+ * bit6-11 for ppe0-5
+ * bit12-17 for roce0-5
+ * bit18-19 for com/dfx
+ * @val: 0 - request reset , 1 - drop reset
+ */
+void hns_dsaf_srst_chns(struct dsaf_device *dsaf_dev, u32 msk, u32 val)
+{
+ u32 reg_addr;
+
+ if (val == 0)
+ reg_addr = DSAF_SUB_SC_DSAF_RESET_REQ_REG;
+ else
+ reg_addr = DSAF_SUB_SC_DSAF_RESET_DREQ_REG;
+
+ dsaf_write_reg(dsaf_dev->sc_base, reg_addr, msk);
+}
+
+void hns_dsaf_roce_srst(struct dsaf_device *dsaf_dev, u32 val)
+{
+ if (val == 0) {
+ dsaf_write_reg(dsaf_dev->sc_base,
+ DSAF_SUB_SC_ROCEE_RESET_REQ_REG, 1);
+ } else {
+ dsaf_write_reg(dsaf_dev->sc_base,
+ DSAF_SUB_SC_ROCEE_CLK_DIS_REG, 1);
+ dsaf_write_reg(dsaf_dev->sc_base,
+ DSAF_SUB_SC_ROCEE_RESET_DREQ_REG, 1);
+ msleep(20);
+ dsaf_write_reg(dsaf_dev->sc_base,
+ DSAF_SUB_SC_ROCEE_CLK_EN_REG, 1);
+ }
+}
+
void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
{
u32 reg_val_1;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index 60d695d..9aace2e 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -37,6 +37,7 @@
#define DSAFV2_SBM_NUM 8
#define DSAFV2_SBM_XGE_CHN 6
#define DSAFV2_SBM_PPE_CHN 1
+#define DSAFV2_SBM_ROCE_CHN 1
#define DASFV2_ROCEE_CRD_NUM 8
#define DSAF_VOQ_NUM DSAF_NODE_NUM
@@ -82,6 +83,12 @@
#define DSAF_SUB_SC_PPE_RESET_DREQ_REG 0xA4C
#define DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG 0xA88
#define DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG 0xA8C
+#define DSAF_SUB_SC_DSAF_RESET_REQ_REG 0xAA8
+#define DSAF_SUB_SC_ROCEE_RESET_REQ_REG 0xA50
+#define DSAF_SUB_SC_DSAF_RESET_DREQ_REG 0xAAC
+#define DSAF_SUB_SC_ROCEE_CLK_DIS_REG 0x32C
+#define DSAF_SUB_SC_ROCEE_RESET_DREQ_REG 0xA54
+#define DSAF_SUB_SC_ROCEE_CLK_EN_REG 0x328
#define DSAF_SUB_SC_LIGHT_MODULE_DETECT_EN_REG 0x2060
#define DSAF_SUB_SC_TCAM_MBIST_EN_REG 0x2300
#define DSAF_SUB_SC_DSAF_CLK_ST_REG 0x5300
@@ -135,6 +142,9 @@
#define DSAF_PPE_INT_STS_0_REG 0x1E0
#define DSAF_ROCEE_INT_STS_0_REG 0x200
#define DSAFV2_SERDES_LBK_0_REG 0x220
+#define DSAF_PAUSE_CFG_REG 0x240
+#define DSAF_ROCE_PORT_MAP_REG 0x2A0
+#define DSAF_ROCE_SL_MAP_REG 0x2A4
#define DSAF_PPE_QID_CFG_0_REG 0x300
#define DSAF_SW_PORT_TYPE_0_REG 0x320
#define DSAF_STP_PORT_TYPE_0_REG 0x340
@@ -176,6 +186,7 @@
#define DSAF_SBM_BP_CFG_2_XGE_REG_0_REG 0x200C
#define DSAF_SBM_BP_CFG_2_PPE_REG_0_REG 0x230C
#define DSAF_SBM_BP_CFG_2_ROCEE_REG_0_REG 0x260C
+#define DSAF_SBM_ROCEE_CFG_REG_REG 0x2380
#define DSAFV2_SBM_BP_CFG_2_ROCEE_REG_0_REG 0x238C
#define DSAF_SBM_FREE_CNT_0_0_REG 0x2010
#define DSAF_SBM_FREE_CNT_1_0_REG 0x2014
@@ -787,6 +798,8 @@
#define DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S 9
#define DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_M (((1ULL << 9) - 1) << 9)
+#define DSAF_SBM_ROCEE_CFG_CRD_EN_B 2
+
#define DSAF_TBL_TCAM_ADDR_S 0
#define DSAF_TBL_TCAM_ADDR_M ((1ULL << 9) - 1)
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 2/2] isdn: i4l: move active-isdn drivers to staging
From: Tilman Schmidt @ 2016-03-19 10:27 UTC (permalink / raw)
To: Holger Schurig, Arnd Bergmann
Cc: devel, isdn, linux-doc, Greg Kroah-Hartman, Jonathan Corbet,
linux-kernel, netdev, David S. Miller, linux-arm-kernel
In-Reply-To: <87lh5udbcv.fsf@gmail.com>
[-- Attachment #1.1.1: Type: text/plain, Size: 653 bytes --]
Am 07.03.2016 um 07:57 schrieb Holger Schurig:
> I know that in Germany a good amount of land-line telephone line are
> still using ISDN. [...]
> Especially company line are using ISDN still, and there are some Linux
> programs that act on then, e.g. Asterisk and derived PBX software has
> ISDN support which is actively used.
AFAIK none of these uses I4L anymore. Asterisk dropped I4L support with
version 2 if my memory is correct and nowadays uses CAPI, mISDN or its
own DAHDI interface.
--
Tilman Schmidt E-Mail: tilman@imap.cc
Bonn, Germany
Nous, on a des fleurs et des bougies pour nous protéger.
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
[-- Attachment #2: Type: text/plain, Size: 169 bytes --]
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply
* Re: [PATCH] net: phy: at803x: don't depend on GPIOLIB
From: Måns Rullgård @ 2016-03-19 10:01 UTC (permalink / raw)
To: Mason
Cc: Uwe Kleine-Koenig, Sebastian Frias, Daniel Mack, David S. Miller,
netdev, lkml, Florian Fainelli, Fabio Estevam,
Martin Blumenstingl, Linus Walleij
In-Reply-To: <56EC68A5.3050901@free.fr>
Mason <slash.tmp@free.fr> writes:
> On 18/03/2016 21:11, Uwe Kleine-König wrote:
>
>> Hello,
>>
>> On Fri, Mar 18, 2016 at 08:31:20PM +0100, Mason wrote:
>>
>>> On 18/03/2016 20:12, Uwe Kleine-König wrote:
>>>
>>>> On Fri, Mar 18, 2016 at 04:56:21PM +0100, Sebastian Frias wrote:
>>>>
>>>>> What would you think of making at803x_link_change_notify() print a
>>>>> message every time it should do a reset but does not has a way to do it?
>>>>
>>>> Then this question is obsolete because the device doesn't probe.
>>>
>>> I don't understand this statement.
>>>
>>> What does it mean for a question to be obsolete?
>>
>> If the driver doesn't probe because it cannot control the reset line,
>> you don't need to think about how it should behave in
>> at803x_link_change_notify without control of the reset line, because
>> this code isn't reached then.
>
> If I understand correctly, it is possible to soft-reset the PHY
> by writing to a specific register. The GPIO pin is useful only to
> force a hardware-reset when the PHY is wedged by some random event.
Yes, and some variants of this phy are broken and require a hard reset
in certain situations. At least that's what the comment in the code
says.
--
Måns Rullgård
^ permalink raw reply
* SEC Filing
From: zen @ 2016-03-18 15:52 UTC (permalink / raw)
To: netdev
SEC XBRL Filings (www.secxbrlfilings.com) is offering new clients FIRST FILING FREE for a limited period of time and for a limited number of companies.
In addition, will guarantee that we save you at least 20% ongoing versus any competitor in the industry. We have dedicated 24/7 Project management and round the clock production for all our services.
If you are looking to improve the process, get supreme quality EDGAR and XBRL, save time and money then consider SEC XBRL Filings as a solution. It is worth calling to find out more (347) 480-4275.
What's more, we will also update or create your INVESTOR RELATIONS(XBRL Web posting) page for FREE!!!
Regards,
Paul Smith
SEC XBRL Filings
E: info@secxbrlfilings.com
T: (347) 480-4275
www.secxbrlfilings.com
^ permalink raw reply
* Re: [PATCH] rtlwifi: btcoexist: Convert BTC_PRINTK to btc_<foo>_dbg
From: Kalle Valo @ 2016-03-19 9:09 UTC (permalink / raw)
To: Joe Perches
Cc: Larry Finger, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Chaoming Li,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1458272258.9556.46.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org> writes:
> On Thu, 2016-03-17 at 21:54 -0500, Larry Finger wrote:
>> On 03/17/2016 07:00 PM, Joe Perches wrote:
>> > Use a more common logging style.
>
> [ 300K+ quote without comment ]
Yeah, please try to avoid that. For example this makes the patchwork
page for the patch really hard to read:
https://patchwork.kernel.org/patch/8615131/
--
Kalle Valo
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] net: consolidate lock/unlock into unlock_wait
From: Nicholas Mc Guire @ 2016-03-19 7:24 UTC (permalink / raw)
To: Joe Perches; +Cc: David Miller, hofrat, netdev, linux-kernel
In-Reply-To: <1458340518.26915.30.camel@perches.com>
On Fri, Mar 18, 2016 at 03:35:18PM -0700, Joe Perches wrote:
> On Fri, 2016-03-18 at 17:37 -0400, David Miller wrote:
> > From: Nicholas Mc Guire <hofrat@osadl.org>
> > > The spin_lock()/spin_unlock() is synchronizing on the adapter->work_lock
> > > as the comment also suggests, which is equivalent to spin_unlock_wait()
> > > but the later should be more efficient.
> []
> > There really is no justification for this change.
> > This is an optimization in a slow-path of the driver.
> > The device is a rarely used older piece of hardware.
>
> It really might be nice to take some of the ancient
> hardware drivers in drivers/net and move them into
> some separate subdirectory like:
>
> drivers/net/ancient
> or
> drivers/net/antiques
> or
> drivers/net/archaic
> etc...
>
> so there's some clear designation that these crufty
> old drivers don't need to be touched anymore except
> for maybe when kernel wide changes occur.
>
actually thats just the problem - some of those did not
perform such kernel wide changes lock/unlock -> unlock_wait
being one of them. But having a distinction as proposed to
keep people like me from scanning them, sounds like a good idea.
Will add an "age of code" check before submitting API cleanups.
thx!
hofrat
^ permalink raw reply
* [PATCH v3] iwlwifi: dvm: use alloc_ordered_workqueue()
From: Eva Rachel Retuya @ 2016-03-19 5:15 UTC (permalink / raw)
To: outreachy-kernel
Cc: johannes.berg, emmanuel.grumbach, linuxwifi, kvalo,
linux-wireless, netdev, linux-kernel, tj, Eva Rachel Retuya
Use alloc_ordered_workqueue() to allocate the workqueue instead of
create_singlethread_workqueue() since the latter is deprecated and is scheduled
for removal.
There are work items doing related operations that shouldn't be swapped when
queued in a certain order hence preserve the strict execution ordering of a
single threaded (ST) workqueue by switching to alloc_ordered_workqueue().
WQ_MEM_RECLAIM flag is not needed since the worker is not depended
during memory reclaim.
Signed-off-by: Eva Rachel Retuya <eraretuya@gmail.com>
Acked-by: Tejun Heo <tj@kernel.org>
---
Changes in v3:
* revise commit message about WQ_MEM_RECLAIM
* add 'Acked-by:' from previous feedback
Changes in v2:
* switch from alloc_workqueue() to alloc_ordered_workqueue()
* remove unneeded flags: WQ_MEM_RECLAIM and WQ_HIGHPRI
* update commit message to reflect change
drivers/net/wireless/intel/iwlwifi/dvm/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index f62c2d7..14396d8 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1071,7 +1071,7 @@ static void iwl_bg_restart(struct work_struct *data)
static void iwl_setup_deferred_work(struct iwl_priv *priv)
{
- priv->workqueue = create_singlethread_workqueue(DRV_NAME);
+ priv->workqueue = alloc_ordered_workqueue(DRV_NAME, 0);
INIT_WORK(&priv->restart, iwl_bg_restart);
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
--
1.9.1
^ permalink raw reply related
* [GIT] Networking
From: David Miller @ 2016-03-19 4:42 UTC (permalink / raw)
To: torvalds; +Cc: akpm, netdev, linux-kernel
There is a merge conflict against the RDMA tree pull wrt the mlx4 driver,
which I don't know how to resolve.
The device tree file conflicts should be easy to resolve, take the hunks
with the larger number of lines.
Highlights:
1) Support more Realtek wireless chips, from Jes Sorenson.
2) New BPF types for per-cpu hash and arrap maps, from Alexei Starovoitov.
3) Make several TCP sysctls per-namespace, from Nikolay Borisov.
4) Allow the use of SO_REUSEPORT in order to do per-thread processing
of incoming TCP/UDP connections. The muxing can be done using a
BPF program which hashes the incoming packet. From Craig Gallek.
5) Add a multiplexer for TCP streams, to provide a messaged based
interface. BPF programs can be used to determine the message
boundaries. From Tom Herbert.
6) Add 802.1AE MACSEC support, from Sabrina Dubroca.
7) Avoid factorial complexity when taking down an inetdev interface
with lots of configured addresses. We were doing things like
traversing the entire address less for each address removed, and
flushing the entire netfilter conntrack table for every address
as well.
8) Add and use SKB bulk free infrastructure, from Jesper Brouer.
9) Allow offloading u32 classifiers to hardware, and implement for
ixgbe, from John Fastabend.
10) Allow configuring IRQ coalescing parameters on a per-queue basis,
from Kan Liang.
11) Extend ethtool so that larger link mode masks can be supported.
From David Decotigny.
12) Introduce devlink, which can be used to configure port link types
(ethernet vs. Infiniband, etc.), port splitting, and switch device
level attributes as a whole. From Jiri Pirko.
13) Hardware offload support for flower classifiers, from Amir Vadai.
14) Add "Local Checksum Offload". Basically, for a tunneled packet
the checksum of the outer header is 'constant' (because with the
checksum field filled into the inner protocol header, the payload
of the outer frame checksums to 'zero'), and we can take advantage
of that in various ways. From Edward Cree.
Please pull, thanks a lot!
The following changes since commit e2857b8f11a289ed2b61d18d0665e05c1053c446:
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (2016-03-07 15:41:10 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
for you to fetch changes up to fe30937b65354c7fec244caebbdaae68e28ca797:
bonding: fix bond_get_stats() (2016-03-18 23:14:15 -0400)
----------------------------------------------------------------
Aaron Young (4):
ldmvsw: Split sunvnet driver into common code
ldmvsw: Make sunvnet_common compatible with ldmvsw
ldmvsw: Add ldmvsw.c driver code
ldmvsw: Checkpatch sunvnet.c and sunvnet_common.c
Achiad Shochat (3):
net/mlx5: Introduce a new header file for physical port functions
net/mlx5: Introduce physical port PFC access functions
net/mlx5e: Support DCBNL IEEE PFC
Ajit Khaparde (2):
be2net: Request RSS capability of Rx interface depending on number of Rx rings
be2net: Interpret and log new data that's added to the port misconfigure async event
Alexander Aring (12):
MAINTAINERS: update 802.15.4 entries
mac802154: fix mac header length check
at86rf230: fix race on error handling
at86rf230: fix state change handling on error
mrf24j40: add writeable missing reg
6lowpan: iphc: add support for stateful compression
ieee802154: 6lowpan: fix return of netdev notifier
6lowpan: iphc: fix stateful multicast compression
6lowpan: iphc: fix invalid case handling
mac802154: use put and get unaligned functions
6lowpan: debugfs: add missing static
6lowpan: iphc: fix SAM/DAM bit comment
Alexander Duyck (56):
net: Drop unecessary enc_features variable from tunnel segmentation functions
net: Move GSO csum into SKB_GSO_CB
net: Update remote checksum segmentation to support use of GSO checksum
net: Store checksum result for offloaded GSO checksums
net: Move skb_has_shared_frag check out of GRE code and into segmentation
gre: Use GSO flags to determine csum need instead of GRE flags
gre: Use inner_proto to obtain inner header protocol
udp: Clean up the use of flags in UDP segmentation offload
udp: Use uh->len instead of skb->len to compute checksum in segmentation
net: Allow tunnels to use inner checksum offloads with outer checksums needed
igb: clean up code for setting MAC address
igb: Refactor VFTA configuration
igb: Allow asymmetric configuration of MTU versus Rx frame size
igb: Do not factor VLANs into RLPML calculation
igb: Always enable VLAN 0 even if 8021q is not loaded
igb: Merge VLVF configuration into igb_vfta_set
igb: Clean-up configuration of VF port VLANs
igb: Add support for VLAN promiscuous with SR-IOV and NTUPLE
igb: Drop unnecessary checks in transmit path
igb: Enable use of "bridge fdb add" to set unicast table entries
igb: Add workaround for VLAN tag stripping on 82576
i40e/i40evf: Drop outer checksum offload that was not requested
i40e/i40evf: Use u64 values instead of casting them in TSO function
i40e/i40evf: Factor out L4 header and checksum from L3 bits in TSO path
i40e/i40evf: Consolidate all header changes into TSO function
i40e/i40evf: Replace header pointers with unions of pointers in Tx checksum path
i40e/i40evf: Add support for IPv4 encapsulated in IPv6
i40e/i40evf: Handle IPv6 extension headers in checksum offload
i40e/i40evf: Do not write to descriptor unless we complete
i40e/i40evf: Add exception handling for Tx checksum
net: Optimize local checksum offload
i40e/i40evf: Clean-up Rx packet checksum handling
i40e/i40evf: Enable support for SKB_GSO_UDP_TUNNEL_CSUM
i40e: Fix ATR in relation to tunnels
i40e: Do not drop support for IPv6 VXLAN or GENEVE tunnels
i40e: Update feature flags to reflect newly enabled features
i40evf: Update feature flags to reflect newly enabled features
i40e: Add support for ATR w/ IPv6 extension headers
i40e/i40evf: Break up xmit_descriptor_count from maybe_stop_tx
i40e/i40evf: Rewrite logic for 8 descriptor per packet check
i40e/i40evf: Move Tx checksum closer to TSO
GENEVE: Support outer IPv4 Tx checksums by default
VXLAN: Support outer IPv4 Tx checksums by default
flow_dissector: Check for IP fragmentation even if not using IPv4 address
flow_dissector: Fix fragment handling for header length computation
flow_dissector: Correctly handle parsing FCoE
flow_dissector: Use same pointer for IPv4 and IPv6 addresses
eth: Pull header from first fragment via eth_get_headlen
igb: Add support for generic Tx checksums
igbvf: Add support for generic Tx checksums
GSO: Provide software checksum of tunneled UDP fragmentation offload
gro: Defer clearing of flush bit in tunnel paths
csum: Update csum_block_add to use rotate instead of byteswap
ipv4: Update parameters for csum_tcpudp_magic to their original types
ipv6: Pass proto to csum_ipv6_magic as __u8 instead of unsigned short
GSO/UDP: Use skb->len instead of udph->len to determine length of original skb
Alexander Tsoy (1):
ath9k_htc: add device ID for Toshiba WLM-20U2/GN-1080
Alexei Starovoitov (21):
bpf: introduce BPF_MAP_TYPE_PERCPU_HASH map
bpf: introduce BPF_MAP_TYPE_PERCPU_ARRAY map
bpf: add lookup/update support for per-cpu hash and array maps
samples/bpf: update tracex[23] examples to use per-cpu maps
perf: generalize perf_callchain
bpf: introduce BPF_MAP_TYPE_STACK_TRACE
samples/bpf: offwaketime example
bpf: prevent kprobe+bpf deadlocks
bpf: introduce percpu_freelist
bpf: pre-allocate hash map elements
bpf: check for reserved flag bits in array and stack maps
bpf: convert stackmap to pre-allocation
samples/bpf: make map creation more verbose
samples/bpf: move ksym_search() into library
samples/bpf: add map_flags to bpf loader
samples/bpf: test both pre-alloc and normal maps
samples/bpf: add bpf map stress test
samples/bpf: stress test bpf_get_stackid
samples/bpf: add map performance test
bpf: bpf_stackmap_copy depends on CONFIG_PERF_EVENTS
bpf: avoid copying junk bytes in bpf_get_current_comm()
Alexey Khoroshilov (1):
at76c50x-usb: avoid double usb_put_dev() after downloading internal firmware in at76_probe()
Alison Schofield (1):
isdn: divamnt: use y2038-safe ktime_get_ts64() for trace data timestamps
Amir Vadai (11):
net/flower: Introduce hardware offload support
net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public
net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
net/act_skbedit: Utility functions for mark action
net/mlx5_core: Set flow steering dest only for forward rules
net/mlx5e: Relax ndo_setup_tc handle restriction
net/mlx5e: Add a new priority for kernel flow tables
net/mlx5e: Introduce tc offload support
net/mlx5e: Support offload cls_flower with drop action
net/mlx5e: Support offload cls_flower with skbedit mark action
net/flower: Fix pointer cast
Amitkumar Karwar (4):
mwifiex: use SYNC flag for canceling host sleep
mwifiex: increase the priority of firmware dump message
mwifiex: fix corner case association failure
mwifiex: Empty Tx queue during suspend
Amitoj Kaur Chawla (9):
bonding: Return correct error code
net: hamradio: baycom_ser_fdx: Replace timeval with timespec64
dmascc: Return correct error codes
net: tulip: Use setup_timer()
forcedeth: Use setup_timer()
3c59x: Use setup_timer()
netxen: Use kobj_to_dev()
wan: lmc: Switch to using managed resources
mwifiex: Use to_delayed_work()
Andreas Färber (1):
phy: mdio-thunder: Fix some Kconfig typos
Andreas Kemnade (6):
libertas: fix pointer bugs for PS_MODE commands
libertas: check whether bus can do more than polling
libertas: do not confirm sleep if commands are pending
libertas: go back to ps mode without commands pending
libertas: fix ps-mode related removal problems
libertas: add an cfg80211 interface for powersaving
Andrei Otcheretianski (2):
iwlwifi: mvm: allow to disable beacon filtering for AP/GO interface
iwlwifi: add disable_11ac module param
Andrew F. Davis (6):
net: phy: dp83848: Add macro for dp83848 compatible devices
net: phy: dp83848: Add PHY ID for TI version of DP83848C
net: phy: dp83848: Reorganize code for readability and safety
net: phy: dp83848: Add support for TI TLK10x Ethernet PHYs
net: phy: dp83848: Add comments for register definitions
net: phy: dp83848: Fix sysfs naming collision warning
Andrew Lunn (6):
phy: marvell/micrel: Fix Unpossible condition
dsa: Rename mv88e6123_61_65 to mv88e6123 to be consistent
dsa: slave: Don't reference NULL pointer during phy_disconnect
dsa: Destroy fixed link phys after the phy has been disconnected
dsa: dsa: Fix freeing of fixed-phys from user ports.
phy: fixed: Fix removal of phys.
Andrzej Hajda (2):
wlcore: fix error handling in wlcore_event_fw_logger
6lowpan: fix error checking code
Anilkumar Kolli (1):
ath10k: reduce number of peers to support peer stats feature
Anjali Singhai (1):
i40e: Enable Geneve offload for FW API ver > 1.4 for XL710/X710 devices
Anjali Singhai Jain (14):
i40e/i40evf: Fix RSS rx-flow-hash configuration through ethtool
i40e: Cleanup the code with respect to restarting autoneg
i40e: add new device IDs for X722
i40e: Extend ethtool RSS hooks for X722
i40e/i40evf: Fix for UDP/TCP RSS for X722
i40evf: add new write-back mode
i40e: fix write-back-on-itr to work with legacy itr
i40e: add priv flag for automatic rule eviction
i40e: Refactor force_wb and WB_ON_ITR functionality code
i40e: Add a SW workaround for lost interrupts
i40e: Fix PROMISC mode for Multi-function per port (MFP) devices
i40e: Do not disable queues in the Legacy/MSI Interrupt handler
i40e: When in promisc mode apply promisc mode to Tx Traffic as well
i40e: Expose some registers to program parser, FD and RSS logic
Anna-Maria Gleixner (1):
net: mvneta: Add missing hotplug notifier transition
Anthony Wong (1):
rt2x00: add new rt2800usb device Buffalo WLI-UC-G450
Anton Protopopov (2):
Bluetooth: hci_intel: Fix a wrong comparison
ath10k: fix erroneous return value
Antonio Quartulli (12):
batman-adv: fix kerneldoc for DAT functions
batman-adv: fix kerneldoc for TT functions
batman-adv: add kernel doc for AP isolation attributes in bat_priv
batman-adv: remove unused BATADV_BONDING_TQ_THRESHOLD constant
batman-adv: OGMv2 - add basic infrastructure
batman-adv: OGMv2 - implement originators logic
batman-adv: add throughput override attribute to hard_ifaces
batman-adv: keep track of when unicast packets are sent
batman-adv: ELP - compute the metric based on the estimated throughput
batman-adv: ELP - send unicast ELP packets for throughput sampling
batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls
batman-adv: B.A.T.M.A.N. V - implement bat_orig_print API
Arend van Spriel (1):
brcmfmac: change function name for brcmf_cfg80211_wait_vif_event_timeout()
Arnaldo Carvalho de Melo (1):
net: Fix use after free in the recvmmsg exit path
Arnd Bergmann (22):
hostap: avoid uninitialized variable use in hfa384x_get_rid
net: phy: spi_ks8995: include linux/gpio/consumer.h
netfilter: ipvs: avoid unused variable warnings
mac80211: avoid excessive stack usage in sta_info
bnx2x: add a separate GENEVE Kconfig symbol
batman-adv: clarify CFG80211 dependency
ath9k: reduce stack usage in ar9003_aic_cal_post_process
net: mellanox: add DEVLINK dependencies
ipvs: handle ip_vs_fill_iph_skb_off failure
wireless: cw1200: use __maybe_unused to hide pm functions_
kcm: mark helper functions inline
net: mediatek: use dma_addr_t correctly
net: mediatek: remove incorrect dma_mask assignment
net: mediatek: check device_reset return code
mlx4: add missing braces in verify_qp_parameters
farsync: fix off-by-one bug in fst_add_one
ath9k: fix buffer overrun for ar9287
ath9k: fix misleading indentation
net: caif: fix misleading indentation
vmxnet3: fix lock imbalance in vmxnet3_tq_xmit()
smc91x: avoid self-comparison warning
net: mvneta: bm: clarify dependencies
Ashok Raj Nagarajan (2):
ath10k: fix pktlog in QCA99X0
ath10k: add hw_rev to trace events to support pktlog
Avinash Repaka (1):
RDS: IB: Support Fastreg MR (FRMR) memory registration mode
Avri Altman (5):
iwlwifi: mvm: Add P2P client snoozing
iwlwifi: mvm: Remove bf_vif from iwl_power_vifs
iwlwifi: mvm: Remove iwl_mvm_update_beacon_abort
iwlwifi: mvm: forbid U-APSD for P2P Client if the firmware doesn't support it
iwlwifi: mvm: Send power command on BSS_CHANGED_BEACON_INFO if needed
Ayala Beker (1):
iwlwifi: mvm: update GSCAN capabilities
Ben Hutchings (4):
pasemi_mac: Replace LRO with GRO
RDMA/nes: Replace LRO with GRO
ipv4: Remove inet_lro library
ethtool: Set cmd field in ETHTOOL_GLINKSETTINGS response to wrong nwords
Beni Lev (2):
cfg80211: Add global RRM capability
iwlwifi: mvm: Set global RRM capability
Benjamin Poirier (1):
ipv6: Annotate change of locking mechanism for np->opt
Bernhard Walle (2):
net: fec: Add "phy-reset-active-low" property to DT
net: fec: Rename "phy-reset-active-low" property
Bhumika Goyal (1):
Bluetooth: ath3k: Fixed a blank line after declaration issue
Bjorn Andersson (1):
mac80211: Make addr const in SET_IEEE80211_PERM_ADDR()
Bob Copeland (1):
mac80211: mesh: drop constant field mean_chain_len
Bruno Randolf (3):
rtl8xxxu: Enable monitor mode by handling filters
rtl8xxxu: Document REG_RXFLTMAP registers
rtl8xxxu: Enable data frame reception in rtl8xxxu_start
Caesar Wang (4):
net: arc_emac: make the rockchip emac document more compatible
net: arc_emac: add phy reset is optional for device tree
net: arc_emac: support the phy reset for emac driver
net: arc: trivial: cleanup the emac driver
Carolyn Wyborny (3):
i40e: Add functions to blink led on 10GBaseT PHY
i40e: Fix led blink capability for 10GBaseT PHY
i40e: Fix for unexpected messaging
Catherine Sullivan (6):
i40e: Replace X722 mac check in ethtool get_settings
i40e: bump version to 1.4.10
i40e: add 100Mb ethtool reporting
i40e/i40evf: Bump i40e to 1.4.11 and i40evf to 1.4.7
i40evf: Change vf driver string to reflect all products i40evf supports
i40e/i40evf: Bump i40e to 1.4.15 and i40evf to 1.4.11.
Chaya Rachel Ivgi (9):
iwlwifi: mvm: add support for negative temperatures
iwlwifi: mvm: add CT-KILL notification
iwlwifi: mvm: add registration to thermal zone
iwlwifi: mvm: add registration to cooling device
iwlwifi: mvm: update ucode status before stopping device
iwlwifi: mvm: fix unregistration of thermal in some error flows
iwlwifi: mvm: add ctdp operations to debugfs
iwlwifi: mvm: add support for async rx handler without hold the mutex
iwlwifi: mvm: return the cooling state index instead of the budget
Christian Lamparter (1):
carl9170: import 1.9.9 firmware headers
Chun-Hao Lin (1):
r8169:Remove unnecessary phy reset for pcie nic when setting link spped.
Claudiu Manoil (3):
gianfar: Map head TxBD first
gianfar: Use skb_frag_t pointers inside xmit()
gianfar: Remove redundant ops for do_tstamp from xmit()
Clemens Gruber (1):
phy: marvell: Fix 88E1510 initialization
Colin Ian King (3):
net-sysfs: remove unused fmt_long_hex
rtlwifi: pass struct rtl_stats by reference as it is more efficient
mt7601u: do not free dma_buf when ivp allocation fails
Cong Wang (2):
NFC: Use GFP_USER for user-controlled kmalloc
NFC: Close a race condition in llcp_sock_getname()
Corinna Vinschen (1):
igb: Fix VLAN tag stripping on Intel i350
Craig Gallek (8):
sock: struct proto hash function may error
inet: create IPv6-equivalent inet_hash function
tcp: __tcp_hdrlen() helper
inet: refactor inet[6]_lookup functions to take skb
soreuseport: Prep for fast reuseport TCP socket selection
soreuseport: fast reuseport TCP socket selection
soreuseport: BPF selection functional test for TCP
soreuseport: fix merge conflict in tcp bind
Damien Riegel (3):
can: sja1000: of: add per-compatible init hook
can: sja1000: add documentation for Technologic Systems version
can: sja1000: of: add compatibility with Technologic Systems version
Dan Carpenter (8):
mwifiex: fix a reversed condition
rocker: fix rocker_world_port_obj_vlan_add()
mwifiex: fix an indenting mistake
rocker: fix an error code
libertas: fix an error code in probe
mediatek: checking for IS_ERR() instead of NULL
mediatek: unlock on error in mtk_tx_map()
ethernet: micrel: fix some error codes
Daniel Borkmann (23):
net: use skb_postpush_rcsum instead of own implementations
bpf: add new arg_type that allows for 0 sized stack buffer
bpf: add generic bpf_csum_diff helper
bpf: remove artificial bpf_skb_{load, store}_bytes buffer limitation
bpf: try harder on clones when writing into skb
bpf: fix csum update in bpf_l4_csum_replace helper for udp
bpf: don't emit mov A,A on return
bpf: allow bpf_csum_diff to feed bpf_l3_csum_replace as well
bpf: add flags to bpf_skb_store_bytes for clearing hash
bpf: make helper function protos static
bpf: allow to propagate df in bpf_skb_set_tunnel_key
bpf: support for access to tunnel options
bpf, vxlan, geneve, gre: fix usage of dst_cache on xmit
vxlan: allow setting ipv6 traffic class
ip_tunnel, bpf: ip_tunnel_info_opts_{get, set} depends on CONFIG_INET
ip_tunnel: add support for setting flow label via collect metadata
vxlan: support setting IPv6 flow label
geneve: support setting IPv6 flow label
bpf: support flow label for bpf_skb_{set, get}_tunnel_key
cls_bpf: reset class and reuse major in da
bpf: make skb->tc_classid also readable
bpf, dst: add and use dst_tclassid helper
ip_tunnels, bpf: define IP_TUNNEL_OPTS_MAX and use it
David Ahern (6):
net: Add support for fill_slave_info to VRF device
net: Add support for filtering link dump by master device and kind
net: ipv6: Make address flushing on ifdown optional
net: l3mdev: address selection should only consider devices in L3 domain
net: ipv6/l3mdev: Move host route on saved address if necessary
net: ipv6: Fix refcnt on host routes
David Daney (8):
net: thunderx: bgx: Use standard firmware node infrastructure.
net: thunderx: Cleanup PHY probing code.
phy: mdio-octeon: Refactor into two files/modules
phy: mdio-thunder: Add driver for Cavium Thunder SoC MDIO buses.
phy: mdio-cavium: Add missing MODULE_* annotations.
net: cavium: For Kconfig THUNDER_NIC_BGX, select MDIO_THUNDER.
net: thunderx: Don't leak phy device references on -EPROBE_DEFER condition.
netdev: Move octeon/octeon_mgmt driver to cavium directory.
David Decotigny (18):
lib/bitmap.c: conversion routines to/from u32 array
test_bitmap: unit tests for lib/bitmap.c
net: usnic: remove unused call to ethtool_ops::get_settings
net: usnic: use __ethtool_get_settings
net: ethtool: add new ETHTOOL_xLINKSETTINGS API
tx4939: use __ethtool_get_ksettings
net: usnic: use __ethtool_get_ksettings
net: bonding: use __ethtool_get_ksettings
net: ipvlan: use __ethtool_get_ksettings
net: macvlan: use __ethtool_get_ksettings
net: team: use __ethtool_get_ksettings
net: fcoe: use __ethtool_get_ksettings
net: rdma: use __ethtool_get_ksettings
net: 8021q: use __ethtool_get_ksettings
net: bridge: use __ethtool_get_ksettings
net: core: use __ethtool_get_ksettings
net: ethtool: remove unused __ethtool_get_settings
net: mlx4: use new ETHTOOL_G/SSETTINGS API
David Herrmann (1):
net: drop write-only stack variable
David Howells (14):
rxrpc: Fix a case where a call event bit is being used as a flag bit
rxrpc: Convert call flag and event numbers into enums
rxrpc: Rename call events to begin RXRPC_CALL_EV_
rxrpc: Keep the skb private record of the Rx header in host byte order
rxrpc: The protocol family should be set to PF_RXRPC not PF_UNIX
rxrpc: Fix defined range for /proc/sys/net/rxrpc/rx_mtu
rxrpc: Be more selective about the types of received packets we accept
rxrpc: Adjust some whitespace and comments
rxrpc: Use ACCESS_ONCE() when accessing circular buffer pointers
rxrpc: rxkad: The version number in the response should be net byte order
rxrpc: rxkad: Casts are needed when comparing be32 values
rxrpc: Clear the unused part of a sockaddr_rxrpc for memcmp() use
rxrpc: Don't try to map ICMP to error as the lower layer already did that
rxrpc: Replace all unsigned with unsigned int
David Lamparter (1):
net: l3mdev: prefer VRF master for source address selection
David S. Miller (151):
Merge git://git.kernel.org/.../davem/net
Merge git://git.kernel.org/.../davem/net
Merge git://git.kernel.org/.../davem/net
Merge git://git.kernel.org/.../davem/net
Merge branch '40GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch 'rx_nohandler'
Merge branch 'tcp_fast_open_synack_fin'
Merge branch 'bpf-per-cpu-maps'
Merge branch 'tipc-topology-updates'
Merge branch 'vxlan-headers-and-tx-cleanups'
Merge branch 'be2net-non-critical-fixes'
Merge branch 'tcp_cong_ctrl_refactoring'
Merge branch 'sunvnet-tracepoints'
Merge branch 'virtio_net_ethtool_settings'
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Merge branch 'ns-tcp-sysctls'
tcp: Fix syncookies sysctl default.
Merge branch 'bridge-mdb-entry-offload-flag'
Merge branch 'tpacket-gso-csum-offload'
Merge branch 'renesas-bit-twiddling'
Merge branch 'be2net-next'
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Merge branch 'tcp-fast-so_reuseport'
Merge branch 'fec-next'
Merge branch 'cxgb4-tos'
Merge branch 'ethtool-nfc-ipv6'
Merge branch 'gso-checksums'
Merge branch 'igmp-ns'
Merge branch 'thunderx-irq-hints'
Merge branch 'spi_ks8995'
Merge branch 'dp83848-TLK10x'
Merge branch 'virtio_net-ethtool-validation'
Merge branch 'net-mitigate-kmem_free-slowpath'
Merge branch 'tcp_dccp_ports'
Merge branch 'local-checksum-offload'
Merge branch 'bcm7xxx-cleanups'
Merge branch 'ethtool-channels-rxfh-conflict'
Merge branch '1GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch 'bnx2x-next'
Merge branch 'unified-tunnel-dst-caching'
Merge tag 'wireless-drivers-next-for-davem-2016-02-12' of git://git.kernel.org/.../kvalo/wireless-drivers-next
Merge branch 'ip-sysctl-namespaceify'
Merge branch 'tc-hw-offload'
Merge branch '40GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch 'amd-xgbe-next'
Merge branch '40GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch 'renesas-cleanups'
Merge branch 'sctp-cleanups'
Merge branch 'inet_lro-remove'
Merge branch 'xgene-multiq'
Merge branch 'rocker-worlds'
Merge branch '40GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch 'vxlan-cleanups'
Merge branch '40GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch 'netlink-mmap-remove'
Merge branch 'cxgb4-addr-sync'
Merge branch 'iptunnel-pkt-scrub-consolidate'
Merge branch 'qed-vlan-filtering'
Merge branch '40GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch '40GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch 'bridge-mdb-attrs'
Merge branch 'ethtool-perqueue-params'
Merge branch 'bpf-get-stackid'
Merge branch 'lwt-autoload'
Merge branch 'geneve-vxlan-outer-checksum'
Merge branch 'bpf-helper-improvements'
Merge tag 'linux-can-next-for-4.6-20160220' of git://git.kernel.org/.../mkl/linux-can-next
Merge branch 'ipvlan-misc'
Merge branch 'qed-next'
Merge git://git.kernel.org/.../davem/net
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Merge branch 'dsa-pass-bridge-to-drivers'
Merge branch 'mlx5-next'
Merge branch 'flow_dissector-fixes-and-improvements'
Merge branch 'be2net-fixes'
Merge branch 'gianfar-xmit-improvements'
Merge branch 'tc_action-ns'
Merge branch 'vxlan-rx-cleanups'
Merge branch 'dsa-port-vlan-dump'
Merge branch 'gianfar-ls1021a-ptp'
Merge branch 'qed-misc'
Merge branch 'ethtool-ksettings'
Merge branch 'vrf-saddr-selection'
Merge branch '1GbE' of git://git.kernel.org/.../jkirsher/next-queue
Merge branch 'sch-accurate-backlog'
Merge branch 'lan78xx-next'
Merge tag 'linux-can-next-for-4.6-20160226' of git://git.kernel.org/.../mkl/linux-can-next
Merge branch 'bnxt_en-next'
Merge branch 'ndo_set_rx_headroom'
Merge branch 'tc-sw-only'
Merge branch 'devlink'
Merge branch 'mv88e6xxx-vlan-filtering'
Merge branch 'bridge-mcast-tmp-router-port'
Merge tag 'mac80211-next-for-davem-2016-02-26' of git://git.kernel.org/.../jberg/mac80211-next
Merge branch 'ife'
Merge branch 'net-timestamps-y2038'
Merge branch 'mlx5-next'
Merge branch 'qed-next'
sch_mqprio: Fix build with older gcc.
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Merge branch 'qed-next'
Merge branch 'rds-support-FRMR-and-cleanups'
Merge branch 'stmmac-optimizations'
Merge branch 'cxgb4-next'
Merge branch 'for-upstream' of git://git.kernel.org/.../bluetooth/bluetooth-next
Merge branch 'DIV_ROUND_UP-uapi'
Merge tag 'rxrpc-rewrite-20160304' of git://git.kernel.org/.../dhowells/linux-fs
Merge branch 'reset_mac_header'
Merge branch 'qed_hw_gro'
Merge git://git.kernel.org/.../davem/net
Merge branch 'bpf-next'
Merge git://git.kernel.org/.../pablo/nf-next
Merge branch 'bnxt_en-next'
Merge branch 'ipv6-per-netns-gc'
Merge branch 'bpf-map-prealloc'
Merge branch 'kcm'
Merge branch 'variable-length-ll-headers'
Merge tag 'linux-can-next-for-4.6-20160310' of git://git.kernel.org/.../mkl/linux-can-next
Merge branch 'sh_eth-fixes'
Merge branch 'cxgb4-next'
Merge branch 'qlcnic-next'
Merge branch 'mediatek-eth'
Merge branch 'flower-offload'
Merge branch 'bridge_ageing_time'
Merge branch 'bpf-flow-labels'
Merge branch 'qed-mf-updates'
Merge branch 'net-minor-cleanups-and-optimizations'
Merge tag 'wireless-drivers-next-for-davem-2016-03-09' of git://git.kernel.org/.../kvalo/wireless-drivers-next
Merge branch 'xen-netback-fix-multiple-extra-info-handling'
Merge branch 'net-more-bulk-free-users'
Merge branch 'macsec'
Merge tag 'nfc-next-4.6-1' of git://git.kernel.org/.../sameo/nfc-next
ipv4: Don't do expensive useless work during inetdev destroy.
Merge branch 'ipv4-ipv6-csums'
Merge tag 'wireless-drivers-next-for-davem-2016-03-14' of git://git.kernel.org/.../kvalo/wireless-drivers-next
Merge branch 'mvneta-hwbm'
Merge branch 'thunderx-perf'
Merge branch 'net-gcc60-fixes'
Merge branch 'thunderx-phy'
Merge branch 'of_mdio-checks'
Merge branch 'dsa-cleanups'
Merge branch 'for-upstream' of git://git.kernel.org/.../bluetooth/bluetooth-next
Merge branch 'mvneta-fixes'
Merge branch 'dsa-finers-bridging-control'
Merge git://git.kernel.org/.../pablo/nf-next
Merge branch 'arc_emac-next'
Merge branch 'thunderx-mdio-fixes'
Merge branch 'ldmvsw'
Merge branch 'bpf-misc'
Merge branch 'IFF_MULTICAST-dup-sets'
Merge branch 'rds-buffer-tuning'
Deepa Dinamani (3):
net: ipv4: Convert IP network timestamps to be y2038 safe
net: ipv4: tcp_probe: Replace timespec with timespec64
net: sctp: Convert log timestamps to be y2038 safe
Dmitri Epshtein (3):
net: mvneta: enable change MAC address when interface is up
net: mvneta: fix error messages in mvneta_port_down function
net: mvneta: replace magic numbers by existing macros
Dmitry Tunin (4):
Bluetooth: btusb: Add new AR3012 ID 13d3:3395
Bluetooth: Add new AR3012 ID 0489:e095
Bluetooth: btusb: Add a new AR3012 ID 04ca:3014
Bluetooth: btusb: Add a new AR3012 ID 13d3:3472
Edward Cree (10):
ethtool: add IPv6 to the NFC API
sfc: implement IPv6 NFC (and IPV4_USER_FLOW)
net: local checksum offload for encapsulation
net: udp: always set up for CHECKSUM_PARTIAL offload
net: enable LCO for udp_tunnel_handle_offloads() users
net: vxlan: enable local checksum offload
fou: enable LCO in FOU and GUE
net: gre: Implement LCO for GRE over IPv4
net: ip_tunnel: remove 'csum_help' argument to iptunnel_handle_offloads
Documentation/networking: add checksum-offloads.txt to explain LCO
Elad Raz (3):
bridge: mdb: add support for offloaded mdb entries
bridge: mdb: Separate br_mdb_entry->state from net_bridge_port_group->state
bridge: mdb: Passing the port-group pointer to br_mdb module
Eli Cohen (1):
net/mlx4_core: Fix backward compatibility on VFs
Eliad Peller (5):
mac80211: move TKIP TX IVs to public part of key struct
iwlwifi: mvm: move TX PN assignment for TKIP to the driver
mac80211: remove ieee80211_get_key_tx_seq/ieee80211_set_key_tx_seq
wlcore: don't WARN_ON in case of existing ROC
wlcore/wl18xx: add radar_debug_mode handling
Emmanuel Grumbach (22):
iwlwifi: pcie: buffer packets to avoid overflowing Tx queues
iwlwifi: various comments and code cleanups
mac80211: limit the A-MSDU Tx based on peer's capabilities
Merge tag 'mac80211-next-for-davem-2016-02-26' into next2
Merge tag 'iwlwifi-for-kalle-2016-02-15' into HEAD
iwlwifi: mvm: bump firmware API to 21
iwlwifi: pcie: aggregate Flow Handler configuration writes
iwlwifi: pcie: fix identation in trans.c
iwlwifi: mvm: send large SKBs to the transport
iwlwifi: mvm: add Tx A-MSDU inside A-MPDU
iwlwifi: mvm: allow to limit the A-MSDU from debugfs
iwlwifi: mvm: don't enable A-MSDU when the rates are too low
iwlwifi: mvm: don't send an A-MSDU that is larger than the TXF
iwlwifi: pcie: prevent skbs shadowing in iwl_trans_pcie_reclaim
iwlwifi: mvm: remove unused field in iwl_mvm_tid_data
iwlwifi: mvm: various trivial cleanups
iwlwifi: mvm: kill iwl_mvm_enable_agg_txq
Merge branch 'fixes' into next
iwlwifi: mvm: avoid panics with thermal device usage
iwlwifi: mvm: don't let NDPs mess the packet tracking
iwlwifi: mvm: remove RRM advertisement
iwlwifi: mvm: adapt the firmware assert log to new firmware
Eric Dumazet (12):
tcp: fastopen: accept data/FIN present in SYNACK message
tcp: do not enqueue skb with SYN flag
tcp: fastopen: call tcp_fin() if FIN present in SYNACK
tcp/dccp: better use of ephemeral ports in connect()
tcp/dccp: better use of ephemeral ports in bind()
tcp: add tcpi_min_rtt and tcpi_notsent_bytes to tcp_info
net: sched: use pfifo_fast for non real queues
net: diag: add a scheduling point in inet_diag_dump_icsk()
vlan: propagate gso_max_segs
tcp/dccp: remove obsolete WARN_ON() in icmp handlers
net: bcmgenet: fix dma api length mismatch
bonding: fix bond_get_stats()
Eric Engestrom (3):
net/rtnetlink: remove dead code
net/ipv4: remove left over dead code
ethernet/atl1c: remove left over dead code
Eyal Shapira (1):
iwlwifi: mvm: rs: fix a theoretical access to uninitialized array elements
Fabrice Gasnier (3):
stmmac: merge get_rx_owner into rx_status routine.
stmmac: optimize tx clean function
stmmac: fix phy init when attached to a phy
Felix Fietkau (7):
ath9k_hw: add low power tx gain table for AR953x
ath9k: do not limit the number of DFS channel interfaces to 1
mac80211: move A-MSDU skb_linearize call to ieee80211_amsdu_to_8023s
cfg80211: add function for 802.3 conversion with separate output buffer
cfg80211: add support for non-linear skbs in ieee80211_amsdu_to_8023s
cfg80211: fix faulty variable initialization in ieee80211_amsdu_to_8023s
cfg80211: reuse existing page fragments in A-MSDU rx
Florian Fainelli (3):
net: phy: bcm7xxx: Make MII_BCM7XX_64CLK_MDIO naming consistent
net: phy: bcm7xxx: Reduce boilerplate code for 40nm EPHY
Documentation: networking: phy.txt: Add missing functions
Florian Westphal (14):
netlink: remove mmapped netlink support
openvswitch: Revert: "Enable memory mapped Netlink i/o"
Revert "genl: Add genlmsg_new_unicast() for unicast message allocation"
nfnetlink: remove nfnetlink_alloc_skb
nfnetlink: Revert "nfnetlink: add support for memory mapped netlink"
tipc: fix null deref crash in compat config path
netfilter: meta: add PRANDOM support
netfilter: xtables: prepare for on-demand hook register
netfilter: xtables: don't hook tables by default
netfilter: bridge: register hooks only when bridge interface is added
netfilter: don't call hooks unless needed
netfilter: nft_compat: check match/targetinfo attr size
netfilter: x_tables: check for size overflow
bridge: fix potential use-after-free when hook returns QUEUE or STOLEN verdict
Franky Lin (3):
brcmfmac: check for wowl support before enumerating feature flag
brcmfmac: add neighbor discovery offload ip address table configuration
brcmfmac: check return for ARP ip setting iovar
Gal Pressman (2):
net/mlx5e: Don't try to modify CQ moderation if it is not supported
net/mlx5e: Don't modify CQ before it was created
Ganapathi Bhat (1):
mwifiex: add RSSI support for net-detect
Geert Uytterhoeven (1):
ath9k: Drop useless const on chanctx_event_delta() return type
Geliang Tang (1):
cfg80211/mac80211: use to_delayed_work
Giuseppe Cavallaro (14):
stmmac: share reset function between dwmac100 and dwmac1000
stmmac: rework DMA bus setting and introduce new platform AXI structure
stmmac: change descriptor layout
stmmac: review RX/TX ring management
stmmac: add length field to dma data
stmmac: add last_segment field to dma data
stmmac: add is_jumbo field to dma data
stmmac: optimize tx desc management
stmmac: set dirty index out of the loop
stmmac: first frame prep at the end of xmit routine
stmmac: do not poll phy handler when attach a switch
stmmac: do not perform zero-copy for rx frames
stmmac: tune rx copy via threshold.
stmmac: update version to Oct_2015
Golan Ben-Ami (3):
iwlwifi: mvm: add trigger for firmware dump upon TX response status
iwlwifi: mvm: make collecting fw debug data optional
iwlwifi: support ucode with d0 unified image - regular and usniffer
Greg Bowers (1):
i40e: Limit DCB FW version checks to X710/XL710 devices
Gregory CLEMENT (4):
ARM: dts: armada-xp-openblocks-ax3-4: Add BM support
net: add a hardware buffer management helper API
net: mvneta: Use the new hwbm framework
net: mvneta: Fix spinlock usage
Gregory Greenman (2):
iwlwifi: mvm: rs: fix TPC action decision algorithm
iwlwifi: pcie: avoid restocks inside rx loop if not emergency
Grzegorz Bajorski (1):
mac80211: allow drivers to report (non-)monitor frames
Guillaume Nault (2):
ppp: clarify parsing of user supplied data in ppp_set_compress()
ppp: ensure file->private_data can't be overridden
Haim Dreyfuss (1):
iwlwifi: pcie: Add new configuration to enable MSIX
Haiyang Zhang (1):
hv_netvsc: Move subchannel waiting to rndis_filter_device_remove()
Hamad Kadmany (1):
wil6210: TX vring optimization
Hante Meuleman (17):
brcmfmac: Increase nr of supported flowrings.
brcmfmac: Limit memory allocs to <64K
brcmfmac: Configure country code using device specific settings
brcmfmac: Add length checks on firmware events
brcmfmac: use device memsize config from fw if defined
brcmfmac: use bar1 window size as provided by pci subsystem
brcmfmac: add support for the PCIE 4366c0 chip
brcmfmac: remove pcie gen1 support
brcmfmac: increase timeout for tx eapol
brcmfmac: move module init and exit to common
brcmfmac: add wowl gtk rekeying offload support
brcmfmac: move platform data retrieval code to common
brcmfmac: keep ARP and ND offload enabled during WOWL
brcmfmac: switch to new platform data
brcmfmac: merge platform data and module paramaters
brcmfmac: integrate add_keyext in add_key
brcmfmac: add 802.11w management frame protection support
Hariprasad Shenai (14):
iw_cxgb4: make queue allocation code more readable
iw_cxgb4: remove false error log entry
cxgb4/iw_cxgb4: TOS support
cxgb4: Use __dev_uc_sync/__dev_mc_sync to sync MAC address
cxgb4vf: Use __dev_uc_sync/__dev_mc_sync to sync MAC address
cxgb4/cxgb4vf: Use fl capacity to check if fl needs to be replenished
cxgb4/cxgb4vf: For T6 adapter, set FBMIN to 64 bytes
cxgb4vf: Make sge init code more readable
cxgb4vf: Remove redundant adapter ready check during probe
cxgb4vf: Remove dead functions collect_netdev_[um]c_list_addrs
cxgb4vf: Enable interrupts before we register our network devices
cxgb4vf: Configure queue based on resource and interrupt type
cxgb4vf: Add a couple more checks for invalid provisioning configurations
cxgb4vf: Set number of queues in pci probe only
Heikki Krogerus (4):
net: rfkill: add rfkill_find_type function
net: rfkill: gpio: get the name and type from device property
ARM: tegra: use build-in device properties with rfkill_gpio
net: rfkill: gpio: remove rfkill_gpio_platform_data
Heiko Stuebner (1):
clk: rockchip: associate SCLK_MAC_PLL and disable reparenting on rk3036
Heiner Kallweit (2):
Bluetooth: add LED trigger for indicating HCI is powered up
Bluetooth: Use managed version of led_trigger_register in LED trigger
Helmut Buchsbaum (6):
net: phy: spi_ks8995: introduce spi_device_id table
net: phy: spi_ks8995: verify chip and determine revision
net: phy: spi_ks8995: add support for resetting switch using GPIO
net: phy: spi_ks8995: generalize creation of SPI commands
net: phy: spi_ks8995: add support for MICREL KSZ8795CLX
dt-bindings: net: ks8995: add bindings documentation for ks8995
Henning Rogge (3):
mac80211: Remove MPP table entries with MPath
mac80211: let unused MPP table entries timeout
mac80211: Unify mesh and mpp path removal function
Hubert Tarasiuk (1):
iwlwifi: dvm: handle zero brightness for wifi LED
Hui Wang (1):
brcmfmac: Remove waitqueue_active check
Ido Schimmel (7):
bridge: switchdev: Offload VLAN flags to hardware bridge
mlxsw: spectrum: Unmap local port from module during teardown
mlxsw: spectrum: Store local port to module mapping during init
mlxsw: spectrum: Mark unused ports using NULL
mlxsw: spectrum: Introduce port splitting
mlxsw: spectrum: Check requested ageing time is valid
rocker: set FDB cleanup timer according to lowest ageing time
Igal Liberman (1):
fsl/fman: fix dtsec_set_tx_pause_frames
Ilan Peer (1):
mac80211: Recalc min chandef when station is associated
Ivan Vecera (1):
be2net: don't report EVB for older chipsets when SR-IOV is disabled
Iyappan Subramanian (4):
drivers: net: xgene: Add support for Classifier engine
drivers: net: xgene: Add support for RSS
drivers: net: xgene: Add support for multiple queues
dtb: xgene: Add irqs to support multi queue
J.J. Meijer (1):
Bluetooth: hci_bcm: Add new ACPI ID for bcm43241
Jacob Keller (1):
i40e: avoid large memcpy by assigning struct
Jakub Sitnicki (6):
rtl8xxxu: Use REG_EFUSE_TEST register only on multifunctional devices
rtl8xxxu: Don't check for illegal offset when reading from efuse
rtl8xxxu: Skip disabled efuse words early
rtl8xxxu: rtl8723au: Introduce a pointer to efuse
rtl8xxxu: rtl8192cu: Introduce a pointer to efuse
rtl8xxxu: rtl8192eu: Map out EFUSE TX power area
Jamal Hadi Salim (4):
net_sched: Improve readability of filter processing
introduce IFE action
Support to encoding decoding skb mark on IFE action
Support to encoding decoding skb prio on IFE action
Jarno Rajahalme (8):
netfilter: Remove IP_CT_NEW_REPLY definition.
netfilter: Allow calling into nat helper without skb_dst.
openvswitch: Add commentary to conntrack.c
openvswitch: Update the CT state key only after nf_conntrack_in().
openvswitch: Find existing conntrack entry after upcall.
openvswitch: Handle NF_REPEAT in conntrack action.
openvswitch: Delay conntrack helper call for new connections.
openvswitch: Interface with NAT.
Jarod Wilson (4):
net/core: relax BUILD_BUG_ON in netdev_stats_to_stats64
net: add rx_nohandler stat counter
team: track sum of rx_nohandler for all slaves
bond: track sum of rx_nohandler for all slaves
Jean Delvare (1):
NFC: microread: Drop platform data header file
Jean Sacren (1):
sxgbe: remove unused code
Jeffrey Huang (2):
bnxt_en: Improve bnxt_vf_update_mac().
bnxt_en: Send PF driver unload notification to all VFs.
Jes Sorensen (130):
rtl8xxxu: Minor cleanup to rtl8xxxu_download_firmware()
rtl8xxxu: rtl8xxxu_download_firmware(): Cosmetic cleanups
rtl8xxxu: If fw running in RAM, reset the 8051 before trying to download a new one
rtl8xxxu: Add RQPN_[NE]PQ_SHIFT values
rtl8xxxu: Define SYS_CFG_SW_OFFLOAD_EN
rtl8xxxu: Add REG_TX_REPORT_* defines
rtl8xxxu: Add more RCR bits
rtl8xxxu: Implement rtl8xxxu_reset_8051()
rtl8xxxu: Add definitions for antenna selection registers for 8723BU
rtl8xxxu: Add mbox extension register definitions for 8723B
rtl8xxxu: Add REG_OFDM0_RX_D_SYNC_PATH definitions
rtl8xxxu: Remove unused clutter for handling recursive calls to rtl8xxxu_init_device()
rtl8xxxu: Fix cosmetics to quiet down checkpatch police
rtl8xxxu: Remove duplicate USB ID
rtl8xxxu: Fix 80 character per line issue
rtl8xxxu: rtl8xxxu_set_linktype(): Be consistent aboutregister size REG_MSR
rtl8xxxu: Set correct bit to reset MCU IO wrapper
rtl8xxxu: Remove unused mgmt variable from rtl8xxxu_rx_complete()
rtl8xxxu: Remove unused len/cnt variables from rtl8xxxu_rx_complete()
rtl8xxxu: Do not mask RF registers to 6 bits
rtl8xxxu: Make device_init kludge 8723au only
rtl8xxxu: Add missing bit define for REG_APS_FSMCO
rtl8xxxu: Add initial code to parse rtl8192eu efuse
rtl8xxxu: Identify chip vendors correctly
rtl8xxxu: Use 1024 byte block loads for 8192eu firmware
rtl8xxxu: Add rtl8192eu_nic.bin to the MODULE_FIRMWARE list
rtl8xxxu: Implment rtl8192eu_power_on()
rtl8xxxu: Add rtl8xxxu_auto_llt_table()
rtl8xxxu: Init page boundaries before starting the firmware
rtl8xxxu: Init the LLT after we start the firmware
rtl8xxxu: Fix incorrect test for auto LLT failure
rtl8xxxu: Kludge to drop incorrect USB OUT EP for 8192EU
rtl8xxxu: Init REG_HIMR[01] for 8192eu parts
rtl8xxxu: Initial rtl8723bu chip identification
rtl8xxxu: Add rtl8723bu_parse_efuse() and 8723bu efuse definition
rtl8xxxu: Use 1024 byte writes for writing 8723bu firmware
rtl8xxxu: Only setup USB interrupts for parts which support it
rtl8xxxu: Add rtl8723b_phy_1t_init_table
rtl8xxxu: Add rtl8723bu_radioa_1t_init_table
rtl8xxxu: Add rtl8723bu_phy_init_antenna_selection()
rtl8xxxu: Add rtl8723b_mac_init_table
rtl8xxxu: Add 8723by AGC table
rtl8xxxu: Handle 32 bit mailbox extension regs found on 8723bu/8192eu/8812
rtl8xxxu: Add some missing register definitions for 8723bu
rtl8xxxu: Group USB fixups together for all chips
rtl8xxxu: Add definitions for new generation h2c commands
rtl8xxxu: rtl8192eu_parse_efuse(): Use a pointer to the struct rtl8192eu_efuse
rtl8xxxu: rtl8723bu_parse_efuse(): Use a pointer to the struct rtl8723bu_efuse
rtl8xxxu: rtl8xxxu_h2c_cmd(): Add size argument
rtl8xxxu: Do BT_WLAN_CALIBRATION before doing IQK calibration
rtl8xxxu: Do not overwrite rtl8xxxu_debug for untested chips
rtl8xxxu: Use correct formatting type to print sizeof()
rtl8xxxu: Make rtl8xxxu_add_path_on() use device specific init values
rtl8xxxu: Add a couple of new register definitions
rtl8xxxu: First stab at adding IQK calibration for 8723bu parts
rtl8xxxu: Handle S0S1 register in lc_calibrate()
rtl8xxxu: Do LC calibration before IQK calibration
rtl8xxxu: Remove backing up certain registers, which was never used
rtl8xxxu: Initial implementation of rtl8723bu_config_channel()
rtl8xxxu: Initial rtl8723bu_init_bt() code
rtl8xxxu: Remove unused variable
rtl8xxxu: Improve 8723bu init code
rtl8xxxu: Do not ignore wlan activity on 8723bu
rtl8xxxu: Set the right type for ps tdma on 8723bu
rtl8xxxu: Add rtl8723bu (nextgen) rx descriptor definition
rtl8xxxu: Handle 8723bu style rx descriptors
rtl8xxxu: Initial functionality to handle C2H events for 8723bu
rtl8xxxu: Handle BT register writes and MP_OPER events
rtl8xxxu: Issue BT_INFO command
rtl8xxxu: Do not set REG_AFE_XTAL_CTRL on 8723bu
rtl8xxxu: Implement 8723bu power on sequence
rtl8xxxu: Setup LLT before downloading firmware
rtl8xxxu: Additional fixes for 8723bu
rtl8xxxu: Handle XTAL_K value in efuse specific location
rtl8xxxu: Another 8723bu patch for rtl8xxxu_init_phy_bb()
rtl8xxxu: Another 8723bu magic register set during init
rtl8xxxu: Init H2C command register for 8723bu
rtl8xxxu: 80M spur hack is for 8723au only
rtl8xxxu: Do queue init in same order as 8723bu vendor driver
rtl8xxxu: Do not set FPGA0_TX_INFO for 8723bu and use a larger PBP page size
rtl8xxxu: Set RX boundary for 8723bu
rtl8xxxu: Initialize burst parameters for 8723bu
rtl8xxxu: Call device specific _config_channel()
rtl8xxxu: 8723bu lock phy after RF init
rtl8xxxu: Add REG_DWBCN1_CTRL_8723B define
rtl8xxxu: Group chip quirks together
rtl8xxxu: Setup RX aggregation
rtl8xxxu: Add missing blank space in front of bracket
rtl8xxxu: Implement init_statistics for 8723bu
rtl8xxxu: RF_T_METER is different on the newer chips
rtl8xxxu: Set WLAN_ACT_CONTROL per vendor driver setting
rtl8xxxu: 8723bu: REG_BT_COEX_TABLE4 is only 8 bits
rtl8xxxu: Use name for REG_RFE_BUFFER rather than hard coded value
rtl8xxxu: Use REG_RFE_CTRL_ANTA_SRC rather than hard coded value
rtl8xxxu: Setup coex table correctly (hopefully)
rtl8xxxu: Do not use hard-wired RF enable settings for 8723bu
rtl8xxxu: Correct struct rtl8723bu_efuse to list power bases correctly
rtl8xxxu: Introduce set_tx_power() fileop and a new 8723b dummy derivative
rtl8xxxu: Use size of source pointer when copying efuse data
rtl8xxxu: Bump TX power arrays to handle larger channel groups
rtl8xxxu: Parse efuse power indices for 8723bu
rtl8xxxu: Set 8723bu TX power for CCK and OFDM rates
rtl8xxxu: Set 8723bu MCS TX power
rtl8xxxu: Set the correct thermal meter register for 8723bu
rtl8xxxu: Add definition for 8723bu tx descriptor
rtl8xxxu: Handle 40 byte TX descriptors for rtl8723bu
rtl8xxxu: Do not unconditionally print debug info in rtl8723bu_handle_c2h()
rtl8xxxu: Add additional tx descriptor bits for data word 0
rtl8xxxu: Add more 40 byte TX desc bit definitions
rtl8xxxu: Set the correct TX descriptor bits for agg and break on 8723b
rtl8xxxu: Set sequence number correctly for 40 byte TX descriptors
rtl8723au: Update TX descriptor words 4 and 5 definitions
rtl8xxxu: TX RTS rate is word 4 for 8723a
rtl8xxxu: Improve handling of txdesc32 vs txdesc40 handling
rtl8xxxu: Do not parse RX descriptor info for C2H packets
rtl8xxxu: Define 8723b H2C ramask command structure
rtl8xxxu: Implement basic 8723b specific update_rate_mask() function
rtl8xxxu: Report media status using the correct H2C command for 8723bu
rtl8xxxu: Dump contents of unhandled C2H events
rtl8xxxu: Process C2H RA_REPORT events for 8723bu
rtl8xxxu: Pass RX rate to rx_parse_phystats and enable phystats for rtl8723bu
rtl8xxxu: Remove unncessary semicolon
rtl8xxxu: convert rtl8723bu_init_bt() into rtl8723b_enable_rf()
rtl8xxxu: Use define for REG_PWR_DATA bits
rtl8xxxu: Implement 8723bu specific disable_rf() function
rtl8xxxu: Implement device specific power_off function
rtl8xxxu: Flush FIFO before powering down devices
rtl8xxxu: Print a warning if flushing the FIFO fails
rtl8xxxu: Use correct 8051 reset function for 8723b parts
rtl8xxxu: Temporarily disable 8192eu device init
Jesper Dangaard Brouer (6):
net: bulk free infrastructure for NAPI context, use napi_consume_skb
net: bulk free SKBs that were delay free'ed due to IRQ context
ixgbe: bulk free SKBs during TX completion cleanup cycle
net: adjust napi_consume_skb to handle non-NAPI callers
mlx4: use napi_consume_skb API to get bulk free operations
mlx5: use napi_consume_skb API to get bulk free operations
Jesse Brandeburg (22):
i40e: update features with right offload
i40e/i40evf: Use private workqueue
i40e: refactor DCB function
i40e: remove VF device IDs from PF
i40e: trivial: remove unnecessary local var
i40e: trivial: drop duplicate definition
i40e: trivial: fix missing space
i40e: fix bug in dma sync
i40e: allocate memory safer
i40e: fix: do not sleep in netdev_ops
i40e: drop unused function
i40e: count allocation errors
i40e/i40evf: bump version to 1.4.12/1.4.8
i40e: move sync_vsi_filters up in service_task
i40e/i40evf: don't lose interrupts
i40e/i40evf: try again after failure
i40e: dump descriptor indexes in hex
i40e/i40evf: use __GFP_NOWARN
i40e/i40evf: Bump version
i40e: drop unused debugfs file "dump"
i40e: trivial: cleanup use of pf->hw
i40e/i40evf: Bump i40e to 1.4.25 and i40evf to 1.4.15
Jiri Benc (23):
vxlan: cleanup types
vxlan: remove duplicated macros
vxlan: restructure vxlan.h definitions
vxlan: consolidate output route calculation
vxlan: consolidate csum flag handling
vxlan: consolidate vxlan_xmit_skb and vxlan6_xmit_skb
vxlan: introduce vxlan_hdr
vxlan: keep flags and vni in network byte order
vxlan: simplify vxlan_remcsum
vxlan: move GBP header parsing to a separate function
vxlan: clean up extension handling on rx
vxlan: clean up rx error path
vxlan: treat vni in metadata based tunnels consistently
vxlan: tun_id is 64bit, not 32bit
geneve: implement geneve_get_sk_family helper
geneve: move geneve device lookup before iptunnel_pull_header
vxlan: move vxlan device lookup before iptunnel_pull_header
iptunnel: scrub packet in iptunnel_pull_header
vxlan: consolidate GBP handling even more
vxlan: move inner L2 header processing to a separate function
vxlan: move ECN decapsulation to a separate function
vxlan: consolidate rx handling to a single function
vxlan: simplify metadata_dst usage in vxlan_rcv
Jiri Pirko (20):
rocker: remove unused rocker_port param from alloc funcs and shorten their names
rocker: rename rocker.h to rocker_hw.h
rocker: rename rocker.c to rocker_main.c
rocker: push tlv processing into separate files
rocker: implement get settings mode command
rocker: move rocker and rocker_port structs into header
rocker: introduce worlds infrastructure
rocker: pass "learning" value as a parameter to rocker_port_set_learning
rocker: pre-allocate wait structures during cmd ring init
rocker: remove trans parameter to rocker_cmd_exec function
rocker: call rocker_cmd_exec function with "nowait" boolean instead of flags
rocker: move OF-DPA stuff into separate file
rocker: return -EOPNOTSUPP for undefined world ops
Introduce devlink infrastructure
mlx4: Implement devlink interface
mlx4: Implement port type setting via devlink interface
mlxsw: Implement devlink interface
mlxsw: core: Add devlink port splitter callbacks
rocker: move ageing_time from struct rocker to struct ofdpa
mlxsw: pci: Implement reset done check
Joe Perches (1):
cisco: enic: Update logging macros and uses
Joe Stringer (1):
netfilter: nf_defrag_ipv4: Drop redundant ip_send_check()
Johan Hedberg (6):
Bluetooth: Move memset closer to where it's needed
Bluetooth: Fix adding discoverable to adv instance flags
Bluetooth: Add support for limited privacy mode
Bluetooth: Increment management interface revision
Bluetooth: Fix setting correct flags in AD
Bluetooth: Fix potential buffer overflow with Add Advertising
Johannes Berg (18):
cfg80211: remove CFG80211_REG_DEBUG
mac80211: document status.freq restrictions
iwlwifi: mvm: remove shadowing variable
iwlwifi: mvm: fix debugfs signedness warning
iwlwifi: mvm: track low-latency sources separately
iwlwifi: mvm: support setting minimum quota from debugfs
iwlwifi: treat iwl_parse_nvm_data() MAC addr as little endian
ipv4: add option to drop unicast encapsulated in L2 multicast
ipv4: add option to drop gratuitous ARP packets
ipv6: add option to drop unicast encapsulated in L2 multicast
ipv6: add option to drop unsolicited neighbor advertisements
mac80211: refactor HT/VHT to chandef code
mac80211_hwsim: remove shadowing variable
rfkill: disentangle polling pause and suspend
mac80211: add RX_FLAG_MACTIME_PLCP_START
mac80211: always print a message when disconnecting
mac80211: change ieee80211_rx_reorder_ready() arguments
iwlwifi: mvm: don't try to offload AES-CMAC in AP/IBSS modes
John Crispin (4):
net-next: mediatek: document MediaTek SoC ethernet binding
net-next: mediatek: add support for MT7623 ethernet
net-next: mediatek: add Kconfig and Makefile
net-next: mediatek: add an entry to MAINTAINERS
John Fastabend (15):
net: rework ndo tc op to consume additional qdisc handle parameter
net: rework setup_tc ndo op to consume general tc operand
net: sched: add cls_u32 offload hooks for netdevs
net: add tc offload feature flag
net: tc: helper functions to query action types
net: ixgbe: add minimal parser details for ixgbe
net: ixgbe: add support for tc_u32 offload
net: ixgbe: abort with cls u32 divisor groups greater than 1
ixgbe: use u32 instead of __u32 in model header
ixgbe: fix dates on header of ixgbe_model.h
net: pack tc_cls_u32_knode struct slighter better
net: sched: consolidate offload decision in cls_u32
net: cls_u32: move TC offload feature bit into cls_u32 offload logic
net: sched: cls_u32 add bit to specify software only rules
net: relax setup_tc ndo op handle restriction
John Underwood (1):
i40e: add check for null VSI
Jon Maxwell (1):
igbvf: remove "link is Up" message when registering mcast address
Jon Paul Maloy (3):
tipc: eliminate risk of finding to-be-deleted node instance
tipc: fix crash during node removal
tipc: remove pre-allocated message header in link struct
Jouni Malinen (1):
mac80211: Interoperability workaround for 80+80 and 160 MHz channels
Jozsef Kadlecsik (2):
netfilter: ipset: Fix set:list type crash when flush/dump set in parallel
netfilter: ipset: Check IPSET_ATTR_ETHER netlink attribute length
João Paulo Rechi Vita (10):
rfkill: use variable instead of duplicating the expression
rfkill: remove/inline __rfkill_set_hw_state
rfkill: Remove obsolete "claim" sysfs interface
rfkill: Update userspace API documentation
rfkill: Improve documentation language
rfkill: Remove extra blank line
rfkill: Point to the correct deprecated doc location
rfkill: Move "state" sysfs file back to stable
rfkill: Factor rfkill_global_states[].cur assignments
rfkill: Add documentation about LED triggers
Julia Lawall (1):
igb: constify e1000_phy_operations structure
Julian Anastasov (2):
ipvs: drop first packet to redirect conntrack
ipvs: allow rescheduling after RST
Jérôme de Bretagne (1):
Bluetooth: hci_bcm: Add BCM2E55 ACPI ID used in Lenovo ThinkPad Tablet 8
Kalle Valo (6):
ath9k: request NOA update when chanctx active
Merge tag 'iwlwifi-next-for-kalle-2016-01-31_2' of https://git.kernel.org/.../iwlwifi/iwlwifi-next
Merge ath-next from ath.git
Merge 'net-next/master'
Merge tag 'iwlwifi-next-for-kalle-2016-03-02' of https://git.kernel.org/.../iwlwifi/iwlwifi-next
Merge tag 'iwlwifi-next-for-kalle-2016-03-09_2' of https://git.kernel.org/.../iwlwifi/iwlwifi-next
Kan Liang (6):
net/ethtool: introduce a new ioctl for per queue setting
net/ethtool: support get coalesce per queue
net/ethtool: support set coalesce per queue
i40e: queue-specific settings for interrupt moderation
i40e/ethtool: support coalesce getting by queue
i40e/ethtool: support coalesce setting by queue
Keller, Jacob E (3):
ethtool: correctly ensure {GS}CHANNELS doesn't conflict with GS{RXFH}
ethtool: ensure channel counts are within bounds during SCHANNELS
fm10k: don't reinitialize RSS flow table when RXFH configured
Kevin Scott (1):
i40e: Increase timeout when checking GLGEN_RSTAT_DEVSTATE bit
Kim Jones (1):
ethtool: Declare netdev_rss_key as __read_mostly.
Kiran Patil (3):
i40e: Add mac_filter_element at the end of the list instead of HEAD
i40e: APIs to Add/remove port mirroring rules
i40e: Removal of code which relies on BASE VEB SEID
Koen Zandberg (1):
mac802154: Fixes kernel oops when unloading a radio driver
Kyeong Yoo (1):
net_sched: dsmark: use qdisc_dequeue_peeked()
LABBE Corentin (1):
phy: remove documentation of removed members of phy_device structure
Lada Trimasova (1):
net: ezchip: adapt driver to little endian architecture
Larry Finger (7):
rtlwifi: Prepare for reworking 5G channels
rtlwifi: rtl8192de: Convert driver to use common 5G channels
rtlwifi: rtl8192ee: Convert driver to use new 5G channel tables
rtlwifi: rtl8821ae: Convert driver to use common 5G channel table
rtlwifi: rtl8821ae: Silence useless log output
rtlwifi: Change long delays to sleeps
rtlwifi: Fix size of wireless mode variable
Lars-Peter Clausen (2):
b43: Remove unnecessary synchronize_irq() before free_irq()
rtlwifi: Remove unnecessary synchronize_irq() before free_irq()
Lendacky, Thomas (9):
amd-xgbe: Disable VLAN filtering when in promiscuous mode
amd-xgbe: Change from napi_complete to napi_complete_done
amd-xgbe: Use __napi_schedule_irqoff
amd-xgbe: Verify forced speed matches the active speedset
amd-xgbe: Enable/disable PFC per traffic class
amd-xgbe: Fix the mapping of priorities to traffic classes
amd-xgbe: Do traffic class setup when called through dcbnl
amd-xgbe: Check Rx queue fifos before stopping Rx DMA
amd-xgbe: Mask auto-negotiation interrupts in ISR
Liad Kaufman (2):
iwlwifi: mvm: disable DQA support
iwlwifi: mvm: support sw queue start/stop from mvm
Linus Luessing (5):
batman-adv: Add hard_iface specific sysfs wrapper macros for UINT
batman-adv: ELP - adding basic infrastructure
batman-adv: ELP - creating neighbor structures
batman-adv: ELP - adding sysfs parameter for elp interval
batman-adv: B.A.T.M.A.N. V - implement bat_neigh_print API
Lior David (3):
wil6210: fix privacy flag calculation in change_beacon
wil6210: use extra IEs from probe response
cfg80211: basic support for PBSS network type
Loic Poulain (1):
Bluetooth: hci_uart: Add Intel/AG6xx support
Lorenzo Bianconi (2):
mac80211: fix wiphy supported_band access
cfg80211: add radiotap VHT info to rtap_namespace_sizes
Luca Coelho (6):
iwlwifi: pcie: add initial RTPM support for PCI
iwlwifi: mvm: handle pass all scan reporting
iwlwifi: pcie: add pm_prepare and pm_complete ops
iwlwifi: mvm: only release the trans ref if d0i3 is supported in fw
iwlwifi: mvm: take the transport ref back when leaving
iwlwifi: pcie: forbid RTPM on device removal
Luciano Coelho (1):
iwlwifi: pcie: add RTPM support when wifi is enabled
Maciej S. Szmigiero (2):
mISDN: Order IPAC register defines
mISDN: Support DR6 indication in mISDNipac driver
Mahesh Bandewar (4):
ipvlan: inherit MTU from master device
ipvlan: scrub skb before routing in L3 mode.
ipvlan: mode is u16
ipvlan: misc changes
Manish Chopra (4):
qed/qede: Add infrastructure support for hardware GRO
qede: Add slowpath/fastpath support and enable hardware GRO
qede: Fix net-next "make ARCH=x86_64"
qlge: Fix receive packets drop.
Marc Kleine-Budde (2):
can: Kconfig: sort drivers alphabetically
can: ems_usb: fix coding style
Marcel Holtmann (1):
Bluetooth: hci_uart: Add diag and address support for Intel/AG6xx
Marcelo Ricardo Leitner (1):
sctp: allow sctp_transmit_packet and others to use gfp
Marcin Wojtas (7):
misc: sram: add optional ioremap without write combining
ARM: dts: armada-38x: add buffer manager nodes
ARM: dts: armada-38x: enable buffer manager support on Armada 38x boards
ARM: dts: armada-xp: add buffer manager nodes
ARM: dts: armada-xp: enable buffer manager support on Armada XP boards
bus: mvebu-mbus: provide api for obtaining IO and DRAM window information
net: mvneta: bm: add support for hardware buffer management
Marco Angaroni (1):
ipvs: correct initial offset of Call-ID header search in SIP persistence engine
Marek Lindner (1):
batman-adv: kernel doc readability updates
Marek Vasut (9):
can: Kconfig: Sort the Kconfig includes
can: Makefile: Sort the Makefile
of: Add vendor prefix for I/F/I
can: ifi: Add DT bindings for ifi,canfd
can: ifi: Add IFI CANFD IP support
can: ifi: Fix clock generator configuration
can: ifi: Fix TX DLC configuration
can: ifi: Fix RX and TX ID mask
can: ifi: Add obscure bit swap for EFF frame IDs
Martin KaFai Lau (2):
samples/bpf: unit test for BPF_MAP_TYPE_PERCPU_HASH
tcp: Add RFC4898 tcpEStatsPerfDataSegsOut/In
Matthew Finlay (5):
net/mlx5e: Move to checksum complete
net/mlx5e: Protect en header file from redefinitions
net/mlx5e: Add netdev support for VXLAN tunneling
net/mlx5e: Add TX stateless offloads for tunneling
net/mlx5e: Add TX inner packet counters
Matti Gottlieb (3):
iwlwifi: mvm: Do not switch to D3 image on suspend
iwlwifi: mvm: Disable beacon storing in D3 when WOWLAN configured
iwlwifi: mvm: ROC: cleanup time event info on FW failure
Max Stepanov (1):
iwlwifi: mvm: add debug print if scan config is ignored
Maya Erez (5):
wil6210: handle tx completions only if vring tx data is enabled
wil6210: find TX vring only if vring_tx_data is enabled
wil6210: handle multiple connect/disconnect events
wil6210: prevent access to vring_tx_data lock during its init
wil6210: protect synchronous wmi commands handling
Miaoqing Pan (7):
ath9k: avoid ANI restart if no trigger
ath9k: clean up ANI per-channel pointer checking
ath9k: do not reset while BB panic(0x4000409) on ar9561
ath9k: fix inconsistent use of tab and space in indentation
ath9k: fix data bus error on ar9300 and ar9580
ath9k: make NF load complete quickly and reliably
ath9k: clear bb filter calibration power threshold
Michael Chan (14):
bnxt_en: Store irq coalescing timer values in micro seconds.
bnxt_en: Refactor bnxt_hwrm_set_coal().
bnxt_en: Add coalescing support for tx rings.
bnxt_en: Use firmware provided message timeout value.
bnxt_en: Fix dmesg log firmware error messages.
bnxt_en: Refactor _hwrm_send_message().
bnxt_en: Add hwrm_send_message_silent().
bnxt_en: Refactor bnxt_fw_to_ethtool_advertised_spds().
bnxt_en: Add reporting of link partner advertisement.
bnxt_en: Use common function to get ethtool supported flags.
bnxt_en: Extend autoneg to all speeds.
bnxt_en: Add port statistics support.
bnxt_en: Include some hardware port statistics in ndo_get_stats64().
bnxt_en: Include hardware port statistics in ethtool -S.
Michael S. Tsirkin (1):
ethtool: future-proof interface for speed extensions
Michal Kazior (9):
ath10k: prevent txrx running for too long
ath10k: rename some HTT events
ath10k: add new htt definitions
ath10k: add new FW_FEATURE_PEER_FLOW_CONTROL
ath10k: clean up cont frag desc init code
ath10k: implement basic support for new tx path firmware
mac80211: fix txq queue related crashes
mac80211: fix unnecessary frame drops in mesh fwding
mac80211: expose txq queue depth and size to drivers
Michal Kubeček (3):
ipv6: replace global gc_args with local variable
ipv6: per netns fib6 walkers
ipv6: per netns FIB garbage collection
Mika Westerberg (2):
Bluetooth: hci_bcm: Add BCM2E7C ACPI ID
NFC: pn544: Drop two useless checks in ACPI probe path
Mitch Williams (15):
i40evf: allow channel bonding of VFs
i40evf: null out ring pointers on free
igb/igbvf: don't give up
i40e: add counter for arq overflows
i40e: add 20G speed for Tx bandwidth calculations
i40evf: enable bus master after reset
i40e/i40evf: use pages correctly in Rx
i40e/i40evf: use logical operators, not bitwise
i40e: properly show packet split status in debugfs
i40e: get rid of magic number
i40evf: support packet split receive
i40e/i40evf: avoid atomics
i40e: expand comment
i40evf: set adapter state on reset failure
i40e: let go of the past
Mohammed Shafi Shajakhan (10):
ath10k: add support for parsing per STA rx_duration for 10.2.4
ath10k: fix naming Peer stats rssi_changed field in 10.2.4
ath10k: cleanup setting pdev paramaters
ath10k: rename few function names of firmware stats
ath10k: provision to support periodic peer stats update
ath10k: enable periodic peer stats update
ath10k: add debugfs support for Per STA total rx duration
ath10k: fix updating peer stats rx duration
ath10k: fix pointless update of peer stats list
ath10k: fix sanity check on enabling btcoex via debugfs
Moshe Lazer (1):
net/mlx5: Fix global UAR mapping
Nachiket Kukade (1):
mwifiex: fix bandwidth display problem
Neerav Parikh (2):
i40e: Make the DCB firmware checks for X710/XL710 only
i40e: Do not wait for Rx queue disable in DCB reconfig
Neil Armstrong (1):
net: dsa: Fix cleanup resources upon module removal
Nicholas Mc Guire (2):
netfilter: nf_conntrack: consolidate lock/unlock into unlock_wait
sctp: consolidate local_bh_disable/enable + spin_lock/unlock to _bh variant
Nicolas Dichtel (4):
uapi: define DIV_ROUND_UP for userland
cxgb4i: don't redefine DIV_ROUND_UP
drm/vmwgfx: remove userland definition of DIV_ROUND_UP
ethtool.h: define INT_MAX for userland
Nicolas Ferre (1):
net: macb: fix default configuration for GMAC on AT91
Nikolay Aleksandrov (12):
ethtool: add speed/duplex validation functions
virtio_net: add ethtool support for set and get of settings
bonding: 3ad: apply ad_actor settings changes immediately
bonding: 3ad: allow to set ad_actor settings while the bond is up
ethtool: make validate_speed accept all speeds between 0 and INT_MAX
virtio_net: validate ethtool port setting and explain the user validation
bridge: mdb: reduce the indentation level in br_mdb_fill_info
bridge: mdb: add support for more attributes and export timer
bridge: mcast: use names for the different multicast_router types
bridge: mcast: do nothing if port's multicast_router is set to the same val
bridge: mcast: add support for temporary port router
bridge: mcast: add support for more router port information dumping
Nikolay Borisov (19):
ipv4: Namespaceify tcp syn retries sysctl knob
ipv4: Namespaceify tcp synack retries sysctl knob
ipv4: Namespaceify tcp syncookies sysctl knob
ipv4: Namespaceify tcp reordering sysctl knob
ipv4: Namespaceify tcp_retries1 sysctl knob
ipv4: Namespaceify tcp_retries2 sysctl knob
ipv4: Namespaceify tcp_orphan_retries sysctl knob
ipv4: Namespaceify tcp_fin_timeout sysctl knob
ipv4: Namespaceify tcp_notsent_lowat sysctl knob
igmp: Namespaceify igmp_max_memberships sysctl knob
igmp: Namespaceify igmp_max_msf sysctl knob
igmp: Namespaceify igmp_llm_reports sysctl knob
igmp: Namespacify igmp_qrv sysctl knob
ipv4: Namespaceify ip_default_ttl sysctl knob
igmp: net: Move igmp namespace init to correct file
ipv4: Namespacify ip_dynaddr sysctl knob
ipv4: namespacify ip_early_demux sysctl knob
ipv4: namespacify ip fragment max dist sysctl knob
net: Export ip fragment sysctl to unprivileged users
Ola Olsson (2):
cfg80211: add more warnings for inconsistent ops
cfg80211: Fix some linguistics in Kconfig
One Thousand Gnomes (2):
af_llc: fix types on llc_ui_wait_for_conn
rt2x00: unterminated strlen of user data
Or Gerlitz (1):
net/mlx5: Make command timeout way shorter
Pablo Neira Ayuso (4):
Merge tag 'ipvs-for-v4.6' of https://git.kernel.org/.../horms/ipvs-next into HEAD
netfilter: nft_masq: support port range
Merge branch 'master' of git://blackhole.kfki.hu/nf
Merge tag 'ipvs-fixes-for-v4.5' of https://git.kernel.org/.../horms/ipvs
Padmanabh Ratnakar (4):
be2net: Fix Lancer error recovery
be2net: Add retry in case of error recovery failure
be2net: Fix interval calculation in interrupt moderation
be2net: Fix pcie error recovery in case of NIC+RoCE adapters
Pandi Kumar Maharajan (1):
i40e: suspend scheduling during driver unload
Pandi Maharajan (1):
i40e: Store lan_vsi_idx and lan_vsi_id in the right size
Paolo Abeni (12):
net: add dst_cache support
net: replace dst_cache ip6_tunnel implementation with the generic one
ip_tunnel: replace dst_cache with generic implementation
net: use dst_cache for vxlan device
net: add dst_cache to ovs vxlan lwtunnel
geneve: add dst caching support
net/ipv4: add dst cache support for gre lwtunnels
netdev: introduce ndo_set_rx_headroom
bridge: notify enslaved devices of headroom changes
ovs: propagate per dp max headroom to all vports
net/tun: implement ndo_set_rx_headroom
veth: implement ndo_set_rx_headroom
Parthasarathy Bhuvaragan (10):
tipc: remove incorrect check for subscription timeout value
tipc: remove filter and timeout elements from struct tipc_subscription
tipc: remove struct tipc_name_seq from struct tipc_subscription
tipc: introduce tipc_subscrb_subscribe() routine
tipc: fix connection abort during subscription cancellation
tipc: fix connection abort when receiving invalid cancel request
tipc: hold subscriber->lock for tipc_nametbl_subscribe()
tipc: protect tipc_subscrb_get() with subscriber spin lock
tipc: donot create timers if subscription timeout = TIPC_WAIT_FOREVER
tipc: use alloc_ordered_workqueue() instead of WQ_UNBOUND w/ max_active = 1
Paul Durrant (4):
xen-netback: implement dynamic multicast control
xen-netback: re-import canonical netif header
xen-netback: support multiple extra info fragments passed from frontend
xen-netback: reduce log spam
Paul Mcquade (3):
net: wireless: rt2x00: Fixed Spacing issues
net: wireless: rt2x00: Space issue
net: wireless: rt2x00: Space Required
Peter Oh (4):
ath10k: rename Mesh related service names
ath10k: update 10.4 WMI service map
ath10k: use vif->type and vif->p2p for P2P_GO check
ath10k: add abstraction layer for vdev subtype
Petri Gynther (1):
Bluetooth: btbcm: Fix handling of firmware not found
Phil Reid (1):
net: stmmac: Don't search for phys if mdio node is defined.
Phil Turnbull (1):
netfilter: nfnetlink_acct: validate NFACCT_FILTER parameters
Raanan Avargil (5):
e1000e: Increase ULP timer
e1000e: Increase PHY PLL clock gate timing
e1000e: Set HW FIFO minimum pointer gap for non-gig speeds
e1000e: Clear ULP configuration register on ULP exit
e1000e: Initial support for KabeLake
Rafał Miłecki (20):
bgmac: add helper checking for BCM4707 / BCM53018 chip id
bcma: support identifying MX25L25635F serial flash
bcma: identify bus cores (devices) found on BCM47189
bcma: support chipsets with PMU and GCI cores (devices)
bcma: use _PMU_ in all names of PMU registers
bcma: support PMU present as separated bus core
brcmfmac: fix setting primary channel for 80 MHz width
bcma: init serial console directly from ChipCommon code
bcma: add support for BCM47094
bcma: claim only 14e4:4365 PCI Dell card with SoftMAC BCM43142
brcmfmac: analyze descriptors of current component only
brcmfmac: allow storing PMU core without wrapper address
brcmfmac: read extended capabilities of ChipCommon core
brcmfmac: access PMU registers using standalone PMU core if available
brcmfmac: add support for 14e4:4365 PCI ID with BCM4366 chipset
brcmfmac: treat NULL character in NVRAM as separator
bgmac: support Ethernet device on BCM47094 SoC
bcma: drop unneeded fields from bcma_pflash struct
bcma: move parallel flash support to separated file
bcma: move flash detection code to ChipCommon core driver
Raja Mani (15):
dt: bindings: add bindings for ipq4019 wifi block
ath10k: make some of ath10k_pci_* func reusable
ath10k: make ath10k_pci_read32/write32() ops more generic
ath10k: pull reusable code from pci probe and remove for ahb
ath10k: add basic skeleton to support ahb
ath10k: include qca4019 register map table
ath10k: add helper functions in ahb.c for reg rd/wr
ath10k: add clock ctrl related functions in ahb
ath10k: add reset ctrl related functions in ahb
ath10k: add chip and bus halt logic in ahb
ath10k: include irq related functions in ahb
ath10k: add resource init and deinit in ahb
ath10k: expose hif ops for ahb
ath10k: add qca4019 hw params
ath10k: populate qca4019 fw specific wmi init params
Rajesh Borundia (2):
qlcnic: Remove unnecessary usage of atomic_t
qlcnic: Fix mailbox completion handling during spurious interrupt
Rajkumar Manoharan (2):
ath10k: reduce rx_lock contention for htt rx indication
ath10k: process htt rx indication as batch mode
Ram Amrani (1):
qed: Correct BAR sizes for older MFW
Ramesh Shanmugasundaram (1):
can: rcar_can: Add r8a7795 support
Ray Bellis (1):
tools, bpf_asm: simplify parser rule for BPF extensions
Richard Alpe (9):
tipc: fix link attribute propagation bug
tipc: fix link priority propagation
tipc: refactor node xmit and fix memory leaks
tipc: add net device to skb before UDP xmit
tipc: don't check link reset on non existing link
tipc: safely copy UDP netlink data from user
tipc: make sure required IPv6 addresses are scoped
tipc: move netlink policies to netlink.c
tipc: make sure IPv6 header fits in skb headroom
Rob Swindell (1):
bnxt_en: Add installed-package firmware version reporting via Ethtool GDRVINFO
Robert Baldyga (1):
MAINTAINERS: nfc: s3fwrn5: Add second maintainer
Robert Jarzmik (1):
net: smc911x: convert pxa dma to dmaengine
Robert Richter (1):
net: thunderx: bgx: Add log message when setting mac address
Robert Shearman (3):
lwtunnel: autoload of lwt modules
mpls: autoload lwt module
ila: autoload module
Rodrigo Freire (1):
iwlwifi: Document missing module options
Roland Hii (1):
igb: add conditions for I210 to generate periodic clock output
Rosen, Rami (1):
core: remove unneded headers for net cgroup controllers.
Sabrina Dubroca (3):
uapi: add MACsec bits
net: add MACsec netdevice priv_flags and helper
macsec: introduce IEEE 802.1AE driver
Saeed Mahameed (2):
net/mlx5: Introduce physical port TC/prio access functions
net/mlx5e: Support DCBNL IEEE ETS
Samuel Gauthier (1):
ovs: allow nl 'flow set' to use ufid without flow key
Sara Sharon (41):
mac80211: process and save VHT MU-MIMO group frame
mac80211: add flag for duplication check
mac80211: pass RX aggregation window size to driver
mac80211: pass block ack session timeout to to driver
iwlwifi: pcie: add infrastructure for multi-queue rx
iwlwifi: pcie: add 9000 series multi queue rx DMA support
iwlwifi: mvm: support beacon storing
iwlwifi: mvm: change access to ieee80211_hdr
iwlwifi: mvm: change the check for ADD_STA status
iwlwifi: mvm: add tlv for multi queue rx support
iwlwifi: mvm: add new ADD_STA command version
iwlwifi: mvm: support rss queues configuration command
iwlwifi: pcie: enable multi-queue rx path
iwlwifi: pcie: update iwl_mpdu_desc fields
mac80211: support hw managing reorder logic
mac80211: fix ibss scan parameters
mac80211: add API to allow filtering frames in BA sessions
mac80211: fix VHT MU-MIMO frame processing
mac80211: provide interface to driver to set VHT MU-MIMO data
mac80211: move MU_MIMO_OWNER flag to ieee80211_vif
iwlwifi: mvm: set the correct descriptor size for tracing
iwlwifi: mvm: fix RSS key sizing
iwlwifi: mvm: enable VHT MU-MIMO for supported hardware
iwlwifi: mvm: update firmware of VHT MU-MIMO groups status on restart
iwlwifi: support tracing wide commands
iwlwifi: mvm: update rx_status with mactime flag
iwlwifi: mvm: support filtered frames notification
iwlwifi: pcie: configure more RFH settings
iwlwifi: mvm: add duplicate packet detection per rx queue
iwlwifi: mvm: add RSS queues notification infrastructure
iwlwifi: mvm: support VHT MU-MIMO notification
iwlwifi: mvm: take care of padded packets
iwlwifi: pcie: detect and workaround invalid write ptr behavior
iwlwifi: pcie: refactor RXBs reclaiming code
iwlwifi: pcie: set RB chunk size back to 64
iwlwifi: refactor the code that reads the MAC address from the NVM
iwlwifi: mvm: set the correct amsdu enum values
iwlwifi: mvm: extend time event duration
iwlwifi: mvm: turn off AMSDU bit in QoS control for de-aggregated AMSDUs
iwlwifi: pcie: fine tune number of rxbs
iwlwifi: add support for getting HW address from CSR
Sasha Levin (1):
bpf: grab rcu read lock for bpf_percpu_hash_update
Satish Baddipadige (1):
bnxt_en: Enable AER support.
Schemmel Hans-Christoph (1):
qmi_wwan: Added support for Gemalto's Cinterion PHxx WWAN interface
Sergei Shtylyov (12):
ravb: factor out register bit twiddling code
sh_eth: factor out register bit twiddling code
ravb: kill useless *switch* defaults
sh_eth: kill useless *switch* defaults
of_mdio: kill useless variable in of_mdiobus_register()
sh_eth: fix NULL pointer dereference in sh_eth_ring_format()
sh_eth: advance 'rxdesc' later in sh_eth_ring_format()
of_mdio: mdio_device_create() never returns NULL
of_mdio: use IS_ERR_OR_NULL()
of_mdio: use PTR_ERR_OR_ZERO()
sh_eth: kill useless initializers
sh_eth: do not call netif_start_queue() from sh_eth_dev_init()
Sergio Prado (2):
net: macb: add wake-on-lan support via magic packet
net: macb: make magic-packet property generic
Shannon Nelson (22):
i40e: define function capabilities in only one place
i40e: add new proxy-wol bit for X722
i40e: AQ Add Run PHY Activity struct
i40e: AQ Geneve cloud tunnel type
i40e: AQ Add external power class to get link status
i40e: AQ Shared resource flags
i40e: AQ Add set_switch_config
i40e: AQ Add VXLAN-GPE tunnel type
i40e: AQ thermal sensor control struct
i40e: Bump AQ minor version to 1.5 for new FW features
i40e: add a little more to an NVM update debug message
i40e: add netdev info to VSI dump
i40e: do TSO only if CHECKSUM_PARTIAL is set
i40e: negate PHY int mask bits
i40e: set shared bit for multicast filters
i40e: add VEB stat control and remove L2 cloud filter
i40e: use new add_veb calling with VEB stats control
i40e: better error reporting for nvmupdate
i40e: clean event descriptor before use
i40e: add adminq commands for Rx CTL registers
i40e: implement and use Rx CTL helper functions
i40e: Use the new rx ctl register helpers. Don't use AQ calls from clear_hw.
Shengzhen Li (1):
mwifiex: fix power state out of sync problem
Shota Suzuki (2):
igb: Remove unnecessary flag setting in igb_set_flag_queue_pairs()
igb: Unpair the queues when changing the number of queues
Simon Horman (5):
can: rcar: add gen[12] fallback compatibility strings
can: rcar: add device tree support for r8a779[234]
sh_eth, ravb: Use ARCH_RENESAS
nfp: remove Rolf Neugebauer as co-maintainer
openvswitch: allow output of MPLS packets on tunnel vports
Simon Wunderlich (4):
batman-adv: Update/repair bridge loop avoidance kerneldoc
batman-adv: add kerneldoc for batadv_iv_ogm_aggr_packet
batman-adv: add seqno maximum age and protection start flag parameters
batman-adv: Start new development cycle
Siva Reddy Kallam (1):
MAINTAINERS: Update tg3 maintainer
Sjoerd Simons (1):
brcmfmac: sdio: Increase the default timeouts a bit
Somnath Kotur (1):
be2net: Don't run ethtool self-tests for VFs
Sowmini Varadhan (5):
sunvnet: Add support for perf LDC event tracing
sunvnet: perf tracepoint invocations to trace LDC state machine
i40e: use eth_platform_get_mac_address()
RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket
RDS: TCP: Remove unused constant
Sriharsha Basavapatna (2):
be2net: Fix be_vlan_rem_vid() to check vlan id being removed
be2net: SRIOV Queue distribution should factor in EQ-count of VFs
Stafford Horne (1):
3c59x: Ensure to apply the expires time
Stefan Assmann (1):
igb: call ndo_stop() instead of dev_close() when running offline selftest
Stefan Roese (1):
net: phy: Add SGMII support for Marvell 88E1510/1512/1514/1518
Stephen Hemminger (1):
bridge: allow zero ageing time
Sudarsana Reddy Kalluru (2):
qede: Add vlan filtering offload support
qed: Prevent MF link notifications
Sudip Mukherjee (4):
netcp: use pointer to fix build fail
mac80211: fix memory leak
ath10k: remove impossible code
netfilter: xt_osf: remove unused variable
Sunil Goutham (5):
net: thunderx: Use napi_schedule_irqoff()
net: thunderx: Assign affinity hints to vf's interrupts
net: thunderx: Alloc higher order pages when pagesize is small
net: thunderx: Set recevie buffer page usage count in bulk
net: thunderx: Adjust nicvf structure to reduce cache misses
Sunil Shahu (1):
mac80211: mesh_plink: remove redundant sta_info check
Suresh Reddy (2):
be2net: return error status from be_set_phys_id()
be2net: check for INSUFFICIENT_PRIVILEGES error
Sven Eckelmann (51):
batman-adv: Fix kerneldoc parsing of structs/enums
batman-adv: Remove kerneldoc for missing parameters
batman-adv: Fix names in kerneldoc of functions
batman-adv: Drop invalid kerneldoc for variable batadv_vlan_attrs
batman-adv: Fix kerneldoc parsing of return description
batman-adv: Fix kerneldoc of main functions
batman-adv: Fix kerneldoc of network-coding functions
batman-adv: Fix kernel-doc for batadv_claim_free_ref
batman-adv: update copyright years for 2016
batman-adv: Switch to HTTPS version of links
batman-adv: Drop reference to netdevice on last reference
batman-adv: Add lockdep assert for container_list_lock
batman-adv: Convert batadv_hardif_neigh_node to kref
batman-adv: Convert batadv_gw_node to kref
batman-adv: Convert batadv_softif_vlan to kref
batman-adv: Convert batadv_bla_backbone_gw to kref
batman-adv: Convert batadv_bla_claim to kref
batman-adv: Convert batadv_nc_node to kref
batman-adv: Convert batadv_nc_path to kref
batman-adv: Convert batadv_dat_entry to kref
batman-adv: Convert batadv_tvlv_container to kref
batman-adv: Convert batadv_tvlv_handler to kref
batman-adv: Convert batadv_tt_orig_list_entry to kref
batman-adv: Convert batadv_neigh_ifinfo to kref
batman-adv: Convert batadv_orig_ifinfo to kref
batman-adv: Convert batadv_neigh_node to kref
batman-adv: Convert batadv_hard_iface to kref
batman-adv: Convert batadv_orig_node_vlan to kref
batman-adv: Convert batadv_orig_node to kref
batman-adv: Convert batadv_tt_common_entry to kref
batman-adv: Rename batadv_orig_node *_free_ref function to *_put
batman-adv: Rename batadv_hardif *_free_ref function to *_put
batman-adv: Rename batadv_neigh_node *_free_ref function to *_put
batman-adv: Rename batadv_neigh_ifinfo *_free_ref function to *_put
batman-adv: Rename batadv_orig_ifinfo *_free_ref function to *_put
batman-adv: Rename batadv_hardif_neigh *_free_ref function to *_put
batman-adv: Rename batadv_backbone_gw *_free_ref function to *_put
batman-adv: Rename batadv_claim *_free_ref function to *_put
batman-adv: Rename batadv_dat_entry *_free_ref function to *_put
batman-adv: Rename batadv_gw_node *_free_ref function to *_put
batman-adv: Rename batadv_tvlv_handler *_free_ref function to *_put
batman-adv: Rename batadv_tvlv_container *_free_ref function to *_put
batman-adv: Rename batadv_softif_vlan *_free_ref function to *_put
batman-adv: Rename batadv_nc_node *_free_ref function to *_put
batman-adv: Rename batadv_nc_path *_free_ref function to *_put
batman-adv: Rename batadv_orig_node_vlan *_free_ref function to *_put
batman-adv: Rename batadv_tt_local_entry *_free_ref function to *_put
batman-adv: Rename batadv_tt_global_entry *_free_ref function to *_put
batman-adv: Rename batadv_tt_orig_list_entry *_free_ref function to *_put
mac80211: Parse legacy and HT rate in injected frames
MAINTAINERS: Add patchwork URL for BATMAN ADVANCED
Takuma Ueba (1):
igb: When GbE link up, wait for Remote receiver status condition
Tariq Toukan (7):
net/mlx5e: Implement DCBNL IEEE max rate
net/mlx5e: Wake On LAN support
net/mlx5e: Replace async events spinlock with synchronize_irq()
net/mlx5e: Placement changed for carrier state updates
net/mlx5e: Changed naming convention of tx queues in ethtool stats
net/mlx5e: Move common case counters within sq_stats struct
net/mlx5e: Set drop RQ's necessary parameters only
Thanneeru Srinivasulu (1):
net, thunderx: Add TX timeout and RX buffer alloc failure stats.
Tobias Klauser (2):
rtl8xxxu: Fix typo in Kconfig help text
rtl8xxxu: Check return value of kmemdup()
Todd Fujinaka (2):
igb: enable WoL for OEM devices regardless of EEPROM setting
igb: rename igb define to be more generic
Tom Herbert (14):
net: Facility to report route quality of connected sockets
rcu: Add list_next_or_null_rcu
net: Make sock_alloc exportable
net: Allow MSG_EOR in each msghdr of sendmmsg
net: Add MSG_BATCH flag
net: Walk fragments in __skb_splice_bits
tcp: Add tcp_inq to get available receive bytes on socket
kcm: Kernel Connection Multiplexor module
kcm: Add statistics and proc interfaces
kcm: Splice support
kcm: Sendpage support
kcm: Add memory limit for receive message construction
kcm: Add receive message timeout
kcm: Add description in Documentation
Tomer Tayar (1):
qed: Major changes to MB locking
Troy Kisky (8):
net: fec: stop the "rcv is not +last, " error messages
net: fec: fix rx error counts
net: fec: fix fec_enet_get_free_txdesc_num
net: fec: add struct bufdesc_prop
net: fec: add variable reg_desc_active to speed things up
net: fec: don't disable FEC_ENET_TS_TIMER interrupt
net: fec: don't transfer ownership until descriptor write is complete
net: fec: improve error handling
Tycho Andersen (1):
openvswitch: allow management from inside user namespaces
Ujjal Roy (3):
mwifiex: Fixed incorrect indentation issue
mwifiex: Removed extra spaces before commas
mwifiex: Added missing spaces around brackets
Uri Mashiach (2):
wlcore/wl12xx: spi: add power operation function
wlcore/wl12xx: spi: add device tree support
Vivien Didelot (23):
net: bridge: log port STP state on change
net: dsa: mv88e6xxx: add port private structure
net: dsa: pass bridge down to drivers
net: dsa: mv88e6xxx: check hardware VLAN in use
net: dsa: remove dsa_bridge_check_vlan_range
net: dsa: add port_vlan_dump routine
net: dsa: mv88e6xxx: implement port_vlan_dump
net: dsa: drop vlan_getnext
net: dsa: support VLAN filtering switchdev attr
net: dsa: mv88e6xxx: extract single VLAN retrieval
net: dsa: mv88e6xxx: extract single FDB dump
net: dsa: mv88e6xxx: assign dynamic FDB to VLANs
net: dsa: mv88e6xxx: assign default FDB to ports
net: dsa: mv88e6xxx: assign dynamic FDB to bridges
net: dsa: mv88e6xxx: restore VLANTable map control
net: dsa: mv88e6xxx: remove reserved VLANs
net: dsa: mv88e6xxx: support VLAN filtering
net: dsa: mv88e6xxx: rework port state setter
net: dsa: mv88e6xxx: read then write PVID
net: dsa: mv88e6xxx: avoid writing the same mode
net: dsa: rename port_*_bridge routines
net: dsa: make port_bridge_leave return void
net: dsa: refine netdev event notifier
Vladimir Kondratiev (1):
wil6210: wait for disconnect completion
WANG Cong (8):
net_sched: prepare tcf_hashinfo_destroy() for netns support
net_sched: add network namespace support for tc actions
net_sched: introduce qdisc_replace() helper
net_sched: update hierarchical backlog too
sch_htb: update backlog as well
sch_dsmark: update backlog as well
net: remove skb_sender_cpu_clear()
act_ife: fix a typo in kmemdup() parameters
Wei Tang (3):
bpf_dbg: do not initialise statics to 0
netlink: do not initialise statics to 0 or NULL
netlabel: do not initialise statics to NULL
Wei Wang (1):
ipv6: pass up EMSGSIZE msg for UDP socket in Ipv6
Wei-Ning Huang (2):
Bluetooth: hci_core: cancel power off delayed work properly
Bluetooth: btmrvl_sdio: fix firmware activation failure
Willem de Bruijn (8):
packet: move vnet_hdr code to helper functions
packet: vnet_hdr support for tpacket_rcv
packet: parse tpacket header before skb alloc
packet: tpacket_snd gso and checksum offload
net: validate variable length ll headers
ax25: add link layer header validation function
packet: validate variable length ll headers
macvtap: always pass ethernet header in linear
Woojung Huh (2):
lan78xx: handle statistics counter rollover
lan78xx: add ndo_get_stats64
Woojung.Huh@microchip.com (4):
lan78xx: replace devid to chipid & chiprev
lan78xx: remove unnecessary code
lan78xx: add ethtool set & get pause functions
MAINTAINERS: Add LAN78XX entry
Wu Fengguang (3):
stmmac: fix noderef.cocci warnings
net: dst_cache_per_cpu_dst_set() can be static
ovs: internal_set_rx_headroom() can be static
Xin Long (4):
sctp: move rcu_read_lock from __sctp_lookup_association to sctp_lookup_association
sctp: remove rcu_read_lock in sctp_seq_dump_remote_addrs()
sctp: remove the unused sctp_datamsg_free()
sctp: fix the transports round robin issue when init is retransmitted
Xing Zheng (4):
clk: rockchip: add node-id for rk3036 emac hclk
clk: rockchip: associate the rk3036 HCLK_EMAC clock-id
clk: rockchip: add clock-id for rk3036 emac pll source clock
ARM: dts: rockchip: add to support emac for rk3036 SoCs
Xinming Hu (13):
mwifiex: add debugfs file to read chip information
mwifiex: enable pcie MSIx interrupt mode support
mwifiex: add schedule scan support
mwifiex: display right transmit packet delay
mwifiex: process pcie io memory read failure case
mwifiex: skip firmware dump when read_regs() fails
mwifiex: keep original structure in decl header file
mwifiex: use an extensible framework for firmware dump solution
mwifiex: dynamically increase preallocated firmware dump memory size
mwifiex: firmware dump support for w8997 chipset
mwifiex: add delay when tdls confirm frame is queued
mwifiex: add sdio multiport aggregation debug information
mwifiex: do not set multiport flag for tx/rx single packet
Yanbo Li (1):
ath10k: remove the p2p notice of absence info from 10.2.4 FW beacon info
Yangbo Lu (3):
ARM: dts: ls1021a: add 1588 timer node
gianfar_ptp: replace get_of_u32 with of_property_read_u32
gianfar: fix endianness for hardware timestamp
Yannick Brosseau (1):
netfilter: ipvs: Remove noisy debug print from ip_vs_del_service
Yoshihiro Kaneko (1):
ravb: fix result value overwrite
Yuchung Cheng (6):
tcp: retransmit after recovery processing and congestion control
tcp: move cwnd reduction after recovery state procesing
tcp: new delivery accounting
tcp: refactor pkts acked accounting
tcp: make congestion control more robust against reordering
tcp: tcp_cong_control helper
Yuval Mintz (30):
bnx2x: Remove unneccessary EXPORT_SYMBOL
bnx2x: Add Geneve inner-RSS support
bnx2x: Add support for single-port DCBx
bnx2x: extend DCBx support
bnx2x: Warn about grc timeouts in register dump
qed/qede: use 8.7.3.0 FW.
qed: Lay infrastructure for vlan filtering offload
bnx2x: Add missing HSI for big-endian machines
qed: Turn most GFP_ATOMIC into GFP_KERNEL
qed: Handle possible race in SB config
qed: Change metadata needed for SPQ entries
qed: Introduce DMA_REGPAIR_LE
qed,qede: Bump driver versions to 8.7.0.0
qede: Change pci DID for 10g device
qede: Linearize SKBs when needed
qede: Don't report link change needlessly
qed: add MODULE_FIRMWARE()
qed: Prevent probe on previous error
qed, qede: rebrand module description
qed: Semantic refactoring of interrupt code
qed: Add support for HW attentions
qed: Print HW attention reasons
qed: Print additional HW attention info
qed: Support B0 instead of A0
qed: Move statistics to L2 code
qed: Fix error flow on slowpath start
qed: Remove unused NVM vendor ID
qed: Enlrage the drain timeout
bnx2x: don't wait for Tx completion on recovery
bnx2x: Prevent false warning for lack of FC NPIV
Zefir Kurtisi (1):
at803x: fix suspend/resume for SGMII link
Zhang Shengju (16):
bonding: add slave device name for debug
bonding: trivial: style fixes
bonding: use return instead of goto
macvlan: convert to use IFF_NO_QUEUE
vlan: change return type of vlan_proc_rem_dev
vlan: turn on unicast filtering on vlan device
net: pktgen: use reset to set mac header
vxlan: use reset to set header pointers
mac80211_hwsim: use reset to set mac header
mac80211: use reset to set header pointer
wireless: use reset to set mac header
arp: correct return value of arp_rcv
netconf: add macro to represent all attributes
net: fix a comment typo
bonding: remove duplicate set of flag IFF_MULTICAST
team: remove duplicate set of flag IFF_MULTICAST
Zvi Nachmani (1):
qed: Notify of transciever changes
ajit.khaparde@broadcom.com (2):
be2net: Declare some u16 fields as u32 to improve performance
be2net: Fix a UE caused by passing large frames to the ASIC
chunfan chen (5):
mwifiex: firmware download enhancements
mwifiex: fix IBSS data path issue.
mwifiex: add wowlan info messages
mwifiex: add wowlan net-detect support
mwifiex: report wakeup reason to cfg80211
liping.zhang (1):
net: socket: use pr_info_once to tip the obsolete usage of PF_PACKET
santosh.shilimkar@oracle.com (12):
RDS: Drop stale iWARP RDMA transport
RDS: Add support for SO_TIMESTAMP for incoming messages
MAINTAINERS: update RDS entry
RDS: IB: Remove the RDS_IB_SEND_OP dependency
RDS: IB: Re-organise ibmr code
RDS: IB: create struct rds_ib_fmr
RDS: IB: move FMR code to its own file
RDS: IB: add connection info to ibmr
RDS: IB: handle the RDMA CM time wait event
RDS: IB: add mr reused stats
RDS: IB: add Fastreg MR (FRMR) detection support
RDS: IB: allocate extra space on queues for FRMR support
sixiao@microsoft.com (3):
hv_netvsc: cleanup netdev feature flags for netvsc
hv_netvsc: add software transmit timestamp support
hv_netvsc: add ethtool support for set and get of settings
stephen hemminger (3):
rds: duplicate include net/tcp.h
vxlan: udp_tunnel duplicate include net/udp_tunnel.h
vrf: duplicate include of rtnetlink.h
tom.leiming@gmail.com (1):
samples/bpf: unit test for BPF_MAP_TYPE_PERCPU_ARRAY
Documentation/ABI/obsolete/sysfs-class-rfkill | 29 -
Documentation/ABI/removed/sysfs-class-rfkill | 13 +
Documentation/ABI/stable/sysfs-class-rfkill | 27 +-
Documentation/ABI/testing/sysfs-class-net-batman-adv | 17 +-
Documentation/devicetree/bindings/net/arc_emac.txt | 7 +
Documentation/devicetree/bindings/net/can/ifi_canfd.txt | 15 +
Documentation/devicetree/bindings/net/can/rcar_can.txt | 22 +-
Documentation/devicetree/bindings/net/can/sja1000.txt | 3 +-
Documentation/devicetree/bindings/net/cavium-mdio.txt | 61 +-
Documentation/devicetree/bindings/net/emac_rockchip.txt | 8 +-
Documentation/devicetree/bindings/net/fsl-fec.txt | 3 +
Documentation/devicetree/bindings/net/macb.txt | 2 +
Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt | 19 +-
Documentation/devicetree/bindings/net/marvell-neta-bm.txt | 49 +
Documentation/devicetree/bindings/net/mediatek-net.txt | 77 +
Documentation/devicetree/bindings/net/micrel-ks8995.txt | 20 +
Documentation/devicetree/bindings/net/stmmac.txt | 54 +-
Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt | 89 +-
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt | 36 +
Documentation/devicetree/bindings/sram/sram.txt | 5 +
Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
Documentation/networking/00-INDEX | 2 +
Documentation/networking/batman-adv.txt | 2 +-
Documentation/networking/checksum-offloads.txt | 119 +
Documentation/networking/dsa/dsa.txt | 22 +-
Documentation/networking/ip-sysctl.txt | 35 +
Documentation/networking/kcm.txt | 285 ++
Documentation/networking/mac80211-injection.txt | 17 +
Documentation/networking/netlink_mmap.txt | 332 ---
Documentation/networking/phy.txt | 10 +
Documentation/networking/rds.txt | 4 +-
Documentation/rfkill.txt | 2 +
MAINTAINERS | 44 +-
arch/alpha/include/asm/checksum.h | 12 +-
arch/alpha/include/uapi/asm/socket.h | 2 +
arch/alpha/lib/checksum.c | 8 +-
arch/arc/include/asm/checksum.h | 4 +-
arch/arm/boot/dts/armada-385-db-ap.dts | 20 +-
arch/arm/boot/dts/armada-388-clearfog.dts | 6 +
arch/arm/boot/dts/armada-388-db.dts | 17 +-
arch/arm/boot/dts/armada-388-gp.dts | 17 +-
arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi | 15 +-
arch/arm/boot/dts/armada-38x.dtsi | 19 +
arch/arm/boot/dts/armada-xp-db.dts | 19 +-
arch/arm/boot/dts/armada-xp-gp.dts | 19 +-
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 19 +-
arch/arm/boot/dts/armada-xp.dtsi | 19 +
arch/arm/boot/dts/ls1021a.dtsi | 12 +
arch/arm/boot/dts/rk3036-evb.dts | 14 +
arch/arm/boot/dts/rk3036-kylin.dts | 14 +
arch/arm/boot/dts/rk3036.dtsi | 39 +
arch/arm/configs/multi_v5_defconfig | 2 +-
arch/arm/configs/mvebu_v5_defconfig | 2 +-
arch/arm/configs/orion5x_defconfig | 2 +-
arch/arm/include/asm/checksum.h | 14 +-
arch/arm/mach-tegra/board-paz00.c | 17 +-
arch/arm64/boot/dts/apm/apm-shadowcat.dtsi | 8 +-
arch/arm64/boot/dts/apm/apm-storm.dtsi | 8 +-
arch/avr32/include/asm/checksum.h | 10 +-
arch/avr32/include/uapi/asm/socket.h | 2 +
arch/blackfin/include/asm/checksum.h | 4 +-
arch/c6x/include/asm/checksum.h | 4 +-
arch/cris/include/arch-v10/arch/checksum.h | 4 +-
arch/cris/include/arch-v32/arch/checksum.h | 2 +-
arch/cris/include/asm/checksum.h | 5 +-
arch/frv/include/asm/checksum.h | 10 +-
arch/frv/include/uapi/asm/socket.h | 2 +
arch/hexagon/include/asm/checksum.h | 8 +-
arch/hexagon/lib/checksum.c | 10 +-
arch/ia64/include/asm/checksum.h | 16 +-
arch/ia64/include/uapi/asm/socket.h | 2 +
arch/ia64/lib/checksum.c | 8 +-
arch/m32r/include/asm/checksum.h | 10 +-
arch/m32r/include/uapi/asm/socket.h | 2 +
arch/m68k/include/asm/checksum.h | 2 +-
arch/metag/include/asm/checksum.h | 7 +-
arch/microblaze/include/asm/checksum.h | 4 +-
arch/mips/include/asm/checksum.h | 8 +-
arch/mips/include/uapi/asm/socket.h | 2 +
arch/mips/txx9/generic/setup_tx4939.c | 7 +-
arch/mn10300/include/asm/checksum.h | 17 +-
arch/mn10300/include/uapi/asm/socket.h | 2 +
arch/nios2/include/asm/checksum.h | 9 +-
arch/parisc/include/asm/checksum.h | 12 +-
arch/parisc/include/uapi/asm/socket.h | 2 +
arch/powerpc/include/uapi/asm/socket.h | 2 +
arch/s390/include/asm/checksum.h | 6 +-
arch/s390/include/uapi/asm/socket.h | 2 +
arch/score/include/asm/checksum.h | 15 +-
arch/sh/include/asm/checksum_32.h | 9 +-
arch/sparc/configs/sparc64_defconfig | 1 +
arch/sparc/include/asm/checksum_32.h | 13 +-
arch/sparc/include/asm/checksum_64.h | 9 +-
arch/sparc/include/uapi/asm/socket.h | 2 +
arch/tile/configs/tilegx_defconfig | 2 +-
arch/tile/configs/tilepro_defconfig | 2 +-
arch/unicore32/include/asm/checksum.h | 4 +-
arch/x86/include/asm/checksum_32.h | 9 +-
arch/x86/include/asm/checksum_64.h | 10 +-
arch/x86/include/asm/stacktrace.h | 2 +-
arch/x86/kernel/cpu/perf_event.c | 4 +-
arch/x86/kernel/dumpstack.c | 6 +-
arch/x86/kernel/stacktrace.c | 18 +-
arch/x86/lib/csum-wrappers_64.c | 2 +-
arch/x86/oprofile/backtrace.c | 3 +-
arch/x86/um/asm/checksum.h | 9 +-
arch/x86/um/asm/checksum_32.h | 2 +-
arch/xtensa/include/asm/checksum.h | 12 +-
arch/xtensa/include/uapi/asm/socket.h | 2 +
drivers/bcma/Kconfig | 5 +
drivers/bcma/Makefile | 1 +
drivers/bcma/bcma_private.h | 19 +-
drivers/bcma/driver_chipcommon.c | 46 +-
drivers/bcma/driver_chipcommon_pflash.c | 49 +
drivers/bcma/driver_chipcommon_pmu.c | 94 +-
drivers/bcma/driver_chipcommon_sflash.c | 1 +
drivers/bcma/driver_gpio.c | 1 +
drivers/bcma/driver_mips.c | 66 +-
drivers/bcma/host_pci.c | 2 +-
drivers/bcma/main.c | 2 +-
drivers/bcma/scan.c | 5 +
drivers/bluetooth/Kconfig | 11 +
drivers/bluetooth/Makefile | 1 +
drivers/bluetooth/ath3k.c | 9 +
drivers/bluetooth/btbcm.c | 3 +-
drivers/bluetooth/btmrvl_sdio.c | 2 +-
drivers/bluetooth/btusb.c | 4 +
drivers/bluetooth/hci_ag6xx.c | 337 +++
drivers/bluetooth/hci_bcm.c | 3 +
drivers/bluetooth/hci_intel.c | 4 +-
drivers/bluetooth/hci_ldisc.c | 6 +
drivers/bluetooth/hci_uart.h | 8 +-
drivers/bus/mvebu-mbus.c | 52 +
drivers/clk/rockchip/clk-rk3036.c | 4 +-
drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h | 20 +-
drivers/infiniband/hw/cxgb4/cm.c | 54 +-
drivers/infiniband/hw/cxgb4/qp.c | 81 +-
drivers/infiniband/hw/mlx4/Kconfig | 1 +
drivers/infiniband/hw/mlx4/main.c | 7 +
drivers/infiniband/hw/mlx5/main.c | 1 +
drivers/infiniband/hw/nes/Kconfig | 1 -
drivers/infiniband/hw/nes/nes_hw.c | 44 +-
drivers/infiniband/hw/nes/nes_hw.h | 7 -
drivers/infiniband/hw/nes/nes_nic.c | 7 -
drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 10 +-
drivers/isdn/hardware/eicon/debug.c | 4 -
drivers/isdn/hardware/eicon/divamnt.c | 30 +-
drivers/isdn/hardware/mISDN/ipac.h | 41 +-
drivers/isdn/hardware/mISDN/mISDNipac.c | 2 +
drivers/misc/sram.c | 5 +-
drivers/net/Kconfig | 7 +
drivers/net/Makefile | 1 +
drivers/net/bonding/bond_3ad.c | 44 +-
drivers/net/bonding/bond_alb.c | 2 +-
drivers/net/bonding/bond_main.c | 104 +-
drivers/net/bonding/bond_options.c | 7 +-
drivers/net/can/Kconfig | 66 +-
drivers/net/can/Makefile | 17 +-
drivers/net/can/ifi_canfd/Kconfig | 8 +
drivers/net/can/ifi_canfd/Makefile | 5 +
drivers/net/can/ifi_canfd/ifi_canfd.c | 944 +++++++
drivers/net/can/rcar_can.c | 3 +
drivers/net/can/sja1000/sja1000_platform.c | 87 +-
drivers/net/can/usb/ems_usb.c | 8 +-
drivers/net/dsa/Kconfig | 2 +-
drivers/net/dsa/Makefile | 4 +-
drivers/net/dsa/bcm_sf2.c | 18 +-
drivers/net/dsa/bcm_sf2.h | 2 +
drivers/net/dsa/{mv88e6123_61_65.c => mv88e6123.c} | 20 +-
drivers/net/dsa/mv88e6171.c | 8 +-
drivers/net/dsa/mv88e6352.c | 8 +-
drivers/net/dsa/mv88e6xxx.c | 701 +++--
drivers/net/dsa/mv88e6xxx.h | 29 +-
drivers/net/ethernet/3com/3c59x.c | 12 +-
drivers/net/ethernet/Kconfig | 2 +-
drivers/net/ethernet/Makefile | 2 +-
drivers/net/ethernet/amd/xgbe/xgbe-common.h | 10 +-
drivers/net/ethernet/amd/xgbe/xgbe-dcb.c | 39 +-
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 388 ++-
drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 42 +-
drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | 16 +-
drivers/net/ethernet/amd/xgbe/xgbe-main.c | 6 +-
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 53 +-
drivers/net/ethernet/amd/xgbe/xgbe.h | 11 +-
drivers/net/ethernet/apm/xgene/Makefile | 3 +-
drivers/net/ethernet/apm/xgene/xgene_enet_cle.c | 734 +++++
drivers/net/ethernet/apm/xgene/xgene_enet_cle.h | 295 ++
drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 12 +
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 6 +
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 482 ++--
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 35 +-
drivers/net/ethernet/apm/xgene/xgene_enet_ring2.c | 12 +
drivers/net/ethernet/arc/emac.h | 60 +-
drivers/net/ethernet/arc/emac_main.c | 35 +-
drivers/net/ethernet/arc/emac_mdio.c | 39 +-
drivers/net/ethernet/arc/emac_rockchip.c | 41 +-
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 4 -
drivers/net/ethernet/broadcom/Kconfig | 10 +
drivers/net/ethernet/broadcom/bgmac.c | 36 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 19 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 17 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 13 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | 57 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 5 +
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 9 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 185 +-
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 353 ++-
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 52 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 327 ++-
drivers/net/ethernet/broadcom/bnxt/bnxt_nvm_defs.h | 14 +
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 63 +-
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 +-
drivers/net/ethernet/cadence/macb.c | 80 +-
drivers/net/ethernet/cadence/macb.h | 6 +-
drivers/net/ethernet/cavium/Kconfig | 13 +-
drivers/net/ethernet/cavium/Makefile | 1 +
drivers/net/ethernet/{ => cavium}/octeon/Makefile | 0
drivers/net/ethernet/{ => cavium}/octeon/octeon_mgmt.c | 0
drivers/net/ethernet/cavium/thunder/nic.h | 55 +-
drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c | 2 +
drivers/net/ethernet/cavium/thunder/nicvf_main.c | 40 +-
drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 36 +-
drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 81 +-
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 27 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 138 +-
drivers/net/ethernet/chelsio/cxgb4/sge.c | 14 +-
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 92 +-
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 2 +
drivers/net/ethernet/chelsio/cxgb4/t4_values.h | 1 +
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 1 +
drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 8 +
drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 385 +--
drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 55 +-
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 21 +
drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 143 +-
drivers/net/ethernet/cisco/enic/enic.h | 22 +-
drivers/net/ethernet/cisco/enic/vnic_cq.c | 2 +-
drivers/net/ethernet/cisco/enic/vnic_dev.c | 45 +-
drivers/net/ethernet/cisco/enic/vnic_intr.c | 3 +-
drivers/net/ethernet/cisco/enic/vnic_rq.c | 4 +-
drivers/net/ethernet/cisco/enic/vnic_wq.c | 4 +-
drivers/net/ethernet/dec/tulip/tulip_core.c | 14 +-
drivers/net/ethernet/emulex/benet/be.h | 35 +-
drivers/net/ethernet/emulex/benet/be_cmds.c | 133 +-
drivers/net/ethernet/emulex/benet/be_cmds.h | 48 +-
drivers/net/ethernet/emulex/benet/be_ethtool.c | 23 +-
drivers/net/ethernet/emulex/benet/be_main.c | 196 +-
drivers/net/ethernet/ezchip/nps_enet.c | 222 +-
drivers/net/ethernet/ezchip/nps_enet.h | 348 +--
drivers/net/ethernet/freescale/fec.h | 38 +-
drivers/net/ethernet/freescale/fec_main.c | 404 ++-
drivers/net/ethernet/freescale/fman/fman_dtsec.c | 7 +-
drivers/net/ethernet/freescale/gianfar.c | 104 +-
drivers/net/ethernet/freescale/gianfar_ptp.c | 33 +-
drivers/net/ethernet/intel/e1000e/hw.h | 4 +
drivers/net/ethernet/intel/e1000e/ich8lan.c | 30 +-
drivers/net/ethernet/intel/e1000e/ich8lan.h | 7 +
drivers/net/ethernet/intel/e1000e/netdev.c | 4 +
drivers/net/ethernet/intel/fm10k/fm10k_main.c | 10 +-
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 11 +-
drivers/net/ethernet/intel/i40e/i40e.h | 45 +-
drivers/net/ethernet/intel/i40e/i40e_adminq.c | 20 +-
drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 87 +-
drivers/net/ethernet/intel/i40e/i40e_common.c | 776 ++++-
drivers/net/ethernet/intel/i40e/i40e_dcb.c | 27 +-
drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 328 +--
drivers/net/ethernet/intel/i40e/i40e_devids.h | 6 +-
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 296 +-
drivers/net/ethernet/intel/i40e/i40e_fcoe.c | 30 +-
drivers/net/ethernet/intel/i40e/i40e_main.c | 422 ++-
drivers/net/ethernet/intel/i40e/i40e_nvm.c | 5 +-
drivers/net/ethernet/intel/i40e/i40e_prototype.h | 39 +-
drivers/net/ethernet/intel/i40e/i40e_register.h | 48 +
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 873 +++---
drivers/net/ethernet/intel/i40e/i40e_txrx.h | 85 +-
drivers/net/ethernet/intel/i40e/i40e_type.h | 20 +
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 36 +-
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h | 4 +-
drivers/net/ethernet/intel/i40evf/i40e_adminq.c | 5 +-
drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h | 87 +-
drivers/net/ethernet/intel/i40evf/i40e_common.c | 125 +
drivers/net/ethernet/intel/i40evf/i40e_prototype.h | 15 +
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 821 +++---
drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 76 +-
drivers/net/ethernet/intel/i40evf/i40evf.h | 7 +-
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 124 +-
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 121 +-
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c | 6 +
drivers/net/ethernet/intel/igb/e1000_82575.c | 41 +-
drivers/net/ethernet/intel/igb/e1000_82575.h | 4 +-
drivers/net/ethernet/intel/igb/e1000_defines.h | 3 +-
drivers/net/ethernet/intel/igb/e1000_hw.h | 4 +-
drivers/net/ethernet/intel/igb/e1000_mac.c | 213 +-
drivers/net/ethernet/intel/igb/e1000_mac.h | 5 +-
drivers/net/ethernet/intel/igb/e1000_mbx.c | 18 +-
drivers/net/ethernet/intel/igb/igb.h | 4 +-
drivers/net/ethernet/intel/igb/igb_ethtool.c | 4 +-
drivers/net/ethernet/intel/igb/igb_main.c | 957 ++++---
drivers/net/ethernet/intel/igb/igb_ptp.c | 3 +-
drivers/net/ethernet/intel/igbvf/mbx.c | 20 +-
drivers/net/ethernet/intel/igbvf/netdev.c | 143 +-
drivers/net/ethernet/intel/igbvf/vf.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 7 +
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 6 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 275 +-
drivers/net/ethernet/intel/ixgbe/ixgbe_model.h | 112 +
drivers/net/ethernet/marvell/Kconfig | 22 +
drivers/net/ethernet/marvell/Makefile | 1 +
drivers/net/ethernet/marvell/mvneta.c | 532 +++-
drivers/net/ethernet/marvell/mvneta_bm.c | 487 ++++
drivers/net/ethernet/marvell/mvneta_bm.h | 182 ++
drivers/net/ethernet/mediatek/Kconfig | 17 +
drivers/net/ethernet/mediatek/Makefile | 5 +
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1808 ++++++++++++
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 421 +++
drivers/net/ethernet/mellanox/mlx4/Kconfig | 1 +
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 357 +--
drivers/net/ethernet/mellanox/mlx4/en_main.c | 1 +
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 21 +-
drivers/net/ethernet/mellanox/mlx4/en_tx.c | 15 +-
drivers/net/ethernet/mellanox/mlx4/intf.c | 9 +
drivers/net/ethernet/mellanox/mlx4/main.c | 152 +-
drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 +
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 +
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 3 +-
drivers/net/ethernet/mellanox/mlx5/core/Kconfig | 12 +
drivers/net/ethernet/mellanox/mlx5/core/Makefile | 5 +-
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 14 +-
drivers/net/ethernet/mellanox/mlx5/core/en.h | 78 +-
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 302 ++
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 152 +-
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 4 +-
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 316 ++-
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 12 +-
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 429 +++
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h | 51 +
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 46 +-
drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/eq.c | 5 +
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c | 29 +-
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 22 +-
drivers/net/ethernet/mellanox/mlx5/core/main.c | 28 +-
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h | 1 +
drivers/net/ethernet/mellanox/mlx5/core/port.c | 221 ++
drivers/net/ethernet/mellanox/mlx5/core/uar.c | 29 +-
drivers/net/ethernet/mellanox/mlx5/core/vxlan.c | 170 ++
drivers/net/ethernet/mellanox/mlx5/core/vxlan.h | 54 +
drivers/net/ethernet/mellanox/mlxsw/Kconfig | 1 +
drivers/net/ethernet/mellanox/mlxsw/core.c | 55 +-
drivers/net/ethernet/mellanox/mlxsw/core.h | 2 +
drivers/net/ethernet/mellanox/mlxsw/pci.c | 15 +-
drivers/net/ethernet/mellanox/mlxsw/pci.h | 3 +
drivers/net/ethernet/mellanox/mlxsw/port.h | 2 +
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 272 +-
drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 12 +-
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 9 +-
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 20 +
drivers/net/ethernet/micrel/ks8842.c | 10 +-
drivers/net/ethernet/nvidia/forcedeth.c | 8 +-
drivers/net/ethernet/octeon/Kconfig | 14 -
drivers/net/ethernet/pasemi/Kconfig | 5 +-
drivers/net/ethernet/pasemi/pasemi_mac.c | 50 +-
drivers/net/ethernet/pasemi/pasemi_mac.h | 4 -
drivers/net/ethernet/pasemi/pasemi_mac_ethtool.c | 1 -
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 10 +-
drivers/net/ethernet/qlogic/qed/qed.h | 51 +-
drivers/net/ethernet/qlogic/qed/qed_cxt.c | 5 +-
drivers/net/ethernet/qlogic/qed/qed_dev.c | 519 +---
drivers/net/ethernet/qlogic/qed/qed_dev_api.h | 11 +-
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 2715 ++++++++----------
drivers/net/ethernet/qlogic/qed/qed_hw.c | 2 +-
drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c | 22 +-
drivers/net/ethernet/qlogic/qed/qed_init_ops.c | 155 +-
drivers/net/ethernet/qlogic/qed/qed_int.c | 2221 ++++++++++++++-
drivers/net/ethernet/qlogic/qed/qed_int.h | 6 +-
drivers/net/ethernet/qlogic/qed/qed_l2.c | 586 +++-
drivers/net/ethernet/qlogic/qed/qed_main.c | 46 +-
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 334 ++-
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 14 +-
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h | 60 +
drivers/net/ethernet/qlogic/qed/qed_sp.h | 13 +-
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c | 81 +-
drivers/net/ethernet/qlogic/qed/qed_spq.c | 15 +-
drivers/net/ethernet/qlogic/qede/qede.h | 40 +-
drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 6 +-
drivers/net/ethernet/qlogic/qede/qede_main.c | 990 ++++++-
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 3 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 24 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 3 +-
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 11 +
drivers/net/ethernet/realtek/r8169.c | 3 +-
drivers/net/ethernet/renesas/Kconfig | 4 +-
drivers/net/ethernet/renesas/ravb.h | 4 +-
drivers/net/ethernet/renesas/ravb_main.c | 74 +-
drivers/net/ethernet/renesas/ravb_ptp.c | 25 +-
drivers/net/ethernet/renesas/sh_eth.c | 99 +-
drivers/net/ethernet/rocker/Makefile | 1 +
drivers/net/ethernet/rocker/rocker.c | 5495 ------------------------------------
drivers/net/ethernet/rocker/rocker.h | 583 +---
drivers/net/ethernet/rocker/rocker_hw.h | 467 +++
drivers/net/ethernet/rocker/rocker_main.c | 2909 +++++++++++++++++++
drivers/net/ethernet/rocker/rocker_ofdpa.c | 2958 +++++++++++++++++++
drivers/net/ethernet/rocker/rocker_tlv.c | 53 +
drivers/net/ethernet/rocker/rocker_tlv.h | 201 ++
drivers/net/ethernet/samsung/sxgbe/Makefile | 2 +-
drivers/net/ethernet/samsung/sxgbe/sxgbe_xpcs.c | 91 -
drivers/net/ethernet/samsung/sxgbe/sxgbe_xpcs.h | 38 -
drivers/net/ethernet/sfc/efx.h | 3 +-
drivers/net/ethernet/sfc/ethtool.c | 184 ++
drivers/net/ethernet/sfc/tx.c | 10 +-
drivers/net/ethernet/smsc/smc911x.c | 85 +-
drivers/net/ethernet/smsc/smc911x.h | 63 +-
drivers/net/ethernet/smsc/smc91x.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 37 +-
drivers/net/ethernet/stmicro/stmmac/common.h | 39 +-
drivers/net/ethernet/stmicro/stmmac/descs.h | 330 +--
drivers/net/ethernet/stmicro/stmmac/descs_com.h | 77 +-
drivers/net/ethernet/stmicro/stmmac/dwmac100.h | 1 -
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 3 +-
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 111 +-
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c | 22 +-
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 39 +-
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 21 +
drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 226 +-
drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 150 +-
drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 32 +-
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 9 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 41 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 473 ++--
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 4 +
drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 4 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 42 +-
drivers/net/ethernet/sun/Kconfig | 16 +
drivers/net/ethernet/sun/Makefile | 2 +
drivers/net/ethernet/sun/ldmvsw.c | 468 +++
drivers/net/ethernet/sun/sunvnet.c | 1733 +-----------
drivers/net/ethernet/sun/sunvnet.h | 114 -
drivers/net/ethernet/sun/sunvnet_common.c | 1732 ++++++++++++
drivers/net/ethernet/sun/sunvnet_common.h | 145 +
drivers/net/ethernet/ti/netcp_core.c | 14 +-
drivers/net/geneve.c | 197 +-
drivers/net/hamradio/baycom_ser_fdx.c | 12 +-
drivers/net/hamradio/dmascc.c | 13 +-
drivers/net/hyperv/hyperv_net.h | 4 +
drivers/net/hyperv/netvsc_drv.c | 70 +-
drivers/net/hyperv/rndis_filter.c | 19 +-
drivers/net/ieee802154/at86rf230.c | 25 +-
drivers/net/ieee802154/mrf24j40.c | 1 +
drivers/net/ipvlan/ipvlan.h | 10 +-
drivers/net/ipvlan/ipvlan_core.c | 46 +-
drivers/net/ipvlan/ipvlan_main.c | 22 +-
drivers/net/macsec.c | 3297 ++++++++++++++++++++++
drivers/net/macvlan.c | 12 +-
drivers/net/macvtap.c | 9 +-
drivers/net/phy/Kconfig | 22 +-
drivers/net/phy/Makefile | 2 +
drivers/net/phy/at803x.c | 26 +
drivers/net/phy/bcm7xxx.c | 60 +-
drivers/net/phy/dp83848.c | 88 +-
drivers/net/phy/fixed_phy.c | 11 +-
drivers/net/phy/marvell.c | 52 +-
drivers/net/phy/mdio-cavium.c | 153 +
drivers/net/phy/mdio-cavium.h | 119 +
drivers/net/phy/mdio-octeon.c | 280 +-
drivers/net/phy/mdio-thunder.c | 154 +
drivers/net/phy/micrel.c | 9 +-
drivers/net/phy/spi_ks8995.c | 304 +-
drivers/net/ppp/ppp_generic.c | 43 +-
drivers/net/team/team.c | 19 +-
drivers/net/tun.c | 17 +-
drivers/net/usb/lan78xx.c | 406 ++-
drivers/net/usb/lan78xx.h | 1 +
drivers/net/usb/qmi_wwan.c | 3 +
drivers/net/veth.c | 26 +
drivers/net/virtio_net.c | 62 +
drivers/net/vmxnet3/vmxnet3_drv.c | 8 +-
drivers/net/vrf.c | 22 +-
drivers/net/vxlan.c | 689 +++--
drivers/net/wan/farsync.c | 2 +-
drivers/net/wan/lmc/lmc_main.c | 27 +-
drivers/net/wireless/ath/ath10k/Kconfig | 6 +
drivers/net/wireless/ath/ath10k/Makefile | 2 +
drivers/net/wireless/ath/ath10k/ahb.c | 933 ++++++
drivers/net/wireless/ath/ath10k/ahb.h | 87 +
drivers/net/wireless/ath/ath10k/core.c | 48 +-
drivers/net/wireless/ath/ath10k/core.h | 20 +
drivers/net/wireless/ath/ath10k/debug.c | 46 +-
drivers/net/wireless/ath/ath10k/debug.h | 7 +
drivers/net/wireless/ath/ath10k/debugfs_sta.c | 41 +
drivers/net/wireless/ath/ath10k/htt.c | 8 +-
drivers/net/wireless/ath/ath10k/htt.h | 169 +-
drivers/net/wireless/ath/ath10k/htt_rx.c | 54 +-
drivers/net/wireless/ath/ath10k/htt_tx.c | 146 +-
drivers/net/wireless/ath/ath10k/hw.c | 39 +
drivers/net/wireless/ath/ath10k/hw.h | 24 +-
drivers/net/wireless/ath/ath10k/mac.c | 64 +-
drivers/net/wireless/ath/ath10k/pci.c | 171 +-
drivers/net/wireless/ath/ath10k/pci.h | 49 +
drivers/net/wireless/ath/ath10k/targaddrs.h | 3 +
drivers/net/wireless/ath/ath10k/trace.h | 15 +-
drivers/net/wireless/ath/ath10k/wmi-ops.h | 11 +
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 1 +
drivers/net/wireless/ath/ath10k/wmi.c | 162 +-
drivers/net/wireless/ath/ath10k/wmi.h | 92 +-
drivers/net/wireless/ath/ath9k/ani.c | 36 +-
drivers/net/wireless/ath/ath9k/ar9003_aic.c | 79 +-
drivers/net/wireless/ath/ath9k/ar9003_aic.h | 1 -
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 6 +-
drivers/net/wireless/ath/ath9k/ar9003_hw.c | 3 +
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 12 +-
drivers/net/wireless/ath/ath9k/ar9003_phy.h | 3 +
drivers/net/wireless/ath/ath9k/ar953x_initvals.h | 65 +
drivers/net/wireless/ath/ath9k/calib.c | 38 +-
drivers/net/wireless/ath/ath9k/channel.c | 4 +-
drivers/net/wireless/ath/ath9k/eeprom.c | 7 +-
drivers/net/wireless/ath/ath9k/hif_usb.c | 2 +
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 7 +-
drivers/net/wireless/ath/ath9k/hw.c | 10 +
drivers/net/wireless/ath/ath9k/init.c | 29 +-
drivers/net/wireless/ath/ath9k/main.c | 13 +-
drivers/net/wireless/ath/ath9k/reg.h | 4 +-
drivers/net/wireless/ath/carl9170/fwcmd.h | 8 +
drivers/net/wireless/ath/carl9170/fwdesc.h | 6 +
drivers/net/wireless/ath/carl9170/hw.h | 73 +-
drivers/net/wireless/ath/carl9170/main.c | 8 +-
drivers/net/wireless/ath/carl9170/version.h | 6 +-
drivers/net/wireless/ath/wcn36xx/main.c | 8 +-
drivers/net/wireless/ath/wil6210/cfg80211.c | 172 +-
drivers/net/wireless/ath/wil6210/debugfs.c | 6 +-
drivers/net/wireless/ath/wil6210/main.c | 112 +-
drivers/net/wireless/ath/wil6210/netdev.c | 5 +-
drivers/net/wireless/ath/wil6210/txrx.c | 46 +-
drivers/net/wireless/ath/wil6210/wil6210.h | 11 +-
drivers/net/wireless/ath/wil6210/wmi.c | 174 +-
drivers/net/wireless/atmel/at76c50x-usb.c | 2 -
drivers/net/wireless/broadcom/b43/main.c | 14 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 105 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 4 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 640 +++--
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 20 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 45 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h | 3 +
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 152 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h | 43 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 180 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 9 +
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 14 +
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h | 10 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 2 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 38 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h | 20 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 57 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h | 68 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | 29 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 11 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h | 2 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 22 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h | 4 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 26 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 216 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 116 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 2 +-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 16 +-
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c | 8 +-
drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h | 2 +
drivers/net/wireless/intel/iwlegacy/4965-mac.c | 8 +-
drivers/net/wireless/intel/iwlegacy/4965.h | 4 +-
drivers/net/wireless/intel/iwlwifi/Kconfig | 12 +
drivers/net/wireless/intel/iwlwifi/dvm/led.c | 5 +-
drivers/net/wireless/intel/iwlwifi/dvm/lib.c | 20 +-
drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c | 13 +-
drivers/net/wireless/intel/iwlwifi/dvm/main.c | 8 +-
drivers/net/wireless/intel/iwlwifi/iwl-7000.c | 4 +-
drivers/net/wireless/intel/iwlwifi/iwl-8000.c | 5 +-
drivers/net/wireless/intel/iwlwifi/iwl-9000.c | 7 +-
drivers/net/wireless/intel/iwlwifi/iwl-config.h | 6 +
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 59 +
drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h | 31 +-
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 45 +-
drivers/net/wireless/intel/iwlwifi/iwl-fh.h | 84 +
drivers/net/wireless/intel/iwlwifi/iwl-fw-error-dump.h | 3 +
drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h | 42 +
drivers/net/wireless/intel/iwlwifi/iwl-fw.h | 13 +
drivers/net/wireless/intel/iwlwifi/iwl-modparams.h | 4 +
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 148 +-
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h | 5 +-
drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 2 +
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 21 +-
drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 8 +-
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 88 +-
drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 75 +-
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 120 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h | 1 +
drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h | 99 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw-api-sta.h | 69 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 157 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | 6 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 55 +-
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 45 +-
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 109 +-
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 139 +-
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 9 +-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 228 +-
drivers/net/wireless/intel/iwlwifi/mvm/power.c | 131 +-
drivers/net/wireless/intel/iwlwifi/mvm/quota.c | 16 +
drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 28 +-
drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 63 +-
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 171 +-
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 45 +-
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 84 +-
drivers/net/wireless/intel/iwlwifi/mvm/sta.h | 25 +-
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c | 15 +-
drivers/net/wireless/intel/iwlwifi/mvm/time-event.h | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 495 +++-
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 250 +-
drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 34 +-
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 203 +-
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 142 +-
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 858 ++++--
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 428 ++-
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 87 +-
drivers/net/wireless/intersil/hostap/hostap_hw.c | 15 +-
drivers/net/wireless/mac80211_hwsim.c | 16 +-
drivers/net/wireless/marvell/libertas/cfg.c | 38 +
drivers/net/wireless/marvell/libertas/cmd.c | 40 +-
drivers/net/wireless/marvell/libertas/cmdresp.c | 9 +-
drivers/net/wireless/marvell/libertas/dev.h | 1 +
drivers/net/wireless/marvell/libertas/if_sdio.c | 2 +-
drivers/net/wireless/marvell/libertas/if_usb.c | 1 +
drivers/net/wireless/marvell/libertas/main.c | 10 +-
drivers/net/wireless/marvell/mwifiex/11h.c | 6 +-
drivers/net/wireless/marvell/mwifiex/README | 10 +
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 274 +-
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 13 +
drivers/net/wireless/marvell/mwifiex/debugfs.c | 51 +-
drivers/net/wireless/marvell/mwifiex/decl.h | 24 +
drivers/net/wireless/marvell/mwifiex/fw.h | 90 +-
drivers/net/wireless/marvell/mwifiex/init.c | 16 +-
drivers/net/wireless/marvell/mwifiex/ioctl.h | 11 +
drivers/net/wireless/marvell/mwifiex/join.c | 15 +
drivers/net/wireless/marvell/mwifiex/main.c | 14 +
drivers/net/wireless/marvell/mwifiex/main.h | 49 +-
drivers/net/wireless/marvell/mwifiex/pcie.c | 325 ++-
drivers/net/wireless/marvell/mwifiex/pcie.h | 50 +-
drivers/net/wireless/marvell/mwifiex/scan.c | 310 ++
drivers/net/wireless/marvell/mwifiex/sdio.c | 51 +-
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 23 +
drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 6 +
drivers/net/wireless/marvell/mwifiex/sta_event.c | 20 +-
drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 34 +-
drivers/net/wireless/marvell/mwifiex/tdls.c | 7 +
drivers/net/wireless/marvell/mwifiex/uap_cmd.c | 2 +-
drivers/net/wireless/marvell/mwifiex/usb.c | 4 +-
drivers/net/wireless/marvell/mwifiex/util.c | 20 +
drivers/net/wireless/marvell/mwifiex/wmm.c | 7 +-
drivers/net/wireless/marvell/mwl8k.c | 10 +-
drivers/net/wireless/mediatek/mt7601u/main.c | 8 +-
drivers/net/wireless/mediatek/mt7601u/mcu.c | 4 +-
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 7 +-
drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 4 +-
drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 1 +
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 18 +-
drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | 9 +-
drivers/net/wireless/ralink/rt2x00/rt61pci.h | 20 +-
drivers/net/wireless/realtek/rtl8xxxu/Kconfig | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c | 3619 +++++++++++++++++++++---
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 693 ++++-
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h | 152 +-
drivers/net/wireless/realtek/rtlwifi/core.c | 68 +-
drivers/net/wireless/realtek/rtlwifi/pci.c | 3 +-
drivers/net/wireless/realtek/rtlwifi/rc.c | 4 +-
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c | 2 +-
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h | 2 +-
drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c | 23 +-
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c | 12 -
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c | 6 +-
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h | 2 +-
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c | 2 +-
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h | 2 +-
drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c | 4 +-
drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h | 2 +-
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c | 2 +-
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 20 +-
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c | 27 +-
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c | 4 +-
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h | 2 +-
drivers/net/wireless/realtek/rtlwifi/wifi.h | 22 +-
drivers/net/wireless/rsi/rsi_91x_mac80211.c | 19 +-
drivers/net/wireless/st/cw1200/cw1200_spi.c | 9 +-
drivers/net/wireless/st/cw1200/pm.h | 9 +-
drivers/net/wireless/st/cw1200/sta.c | 4 +-
drivers/net/wireless/st/cw1200/sta.h | 4 +-
drivers/net/wireless/ti/wl18xx/debugfs.c | 66 +
drivers/net/wireless/ti/wl18xx/event.c | 3 +-
drivers/net/wireless/ti/wlcore/Kconfig | 2 +-
drivers/net/wireless/ti/wlcore/event.c | 2 +-
drivers/net/wireless/ti/wlcore/init.c | 5 +
drivers/net/wireless/ti/wlcore/main.c | 16 +-
drivers/net/wireless/ti/wlcore/spi.c | 86 +-
drivers/net/wireless/ti/wlcore/wlcore.h | 1 +
drivers/net/xen-netback/common.h | 2 +
drivers/net/xen-netback/netback.c | 65 +-
drivers/net/xen-netback/xenbus.c | 91 +-
drivers/nfc/microread/i2c.c | 8 -
drivers/nfc/pn544/i2c.c | 14 +-
drivers/of/of_mdio.c | 14 +-
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 2 +-
drivers/scsi/fcoe/fcoe_transport.c | 36 +-
drivers/staging/vt6655/rxtx.c | 12 +-
drivers/staging/vt6656/rxtx.c | 12 +-
include/asm-generic/checksum.h | 8 +-
include/dt-bindings/clock/rk3036-cru.h | 2 +
include/linux/bcma/bcma.h | 3 +
include/linux/bcma/bcma_driver_chipcommon.h | 42 +-
include/linux/bitmap.h | 10 +
include/linux/bpf.h | 32 +
include/linux/ethtool.h | 102 +-
include/linux/ieee80211.h | 26 +
include/linux/if_bridge.h | 4 -
include/linux/if_team.h | 1 +
include/linux/igmp.h | 5 -
include/linux/inet_lro.h | 142 -
include/linux/ipv6.h | 3 +
include/linux/kernel.h | 2 +-
include/linux/mbus.h | 3 +
include/linux/mlx4/driver.h | 3 +
include/linux/mlx5/device.h | 17 +
include/linux/mlx5/driver.h | 40 +-
include/linux/mlx5/mlx5_ifc.h | 109 +-
include/linux/mlx5/port.h | 87 +
include/linux/net.h | 1 +
include/linux/netdev_features.h | 3 +
include/linux/netdevice.h | 101 +-
include/linux/netfilter.h | 29 +-
include/linux/netfilter/nfnetlink.h | 2 -
include/linux/netfilter/x_tables.h | 6 +-
include/linux/netfilter_arp/arp_tables.h | 9 +-
include/linux/netfilter_ipv4/ip_tables.h | 9 +-
include/linux/netfilter_ipv6/ip6_tables.h | 9 +-
include/linux/netlink.h | 10 -
include/linux/perf_event.h | 13 +-
include/linux/phy.h | 3 -
include/linux/phy_fixed.h | 5 +-
include/linux/platform_data/brcmfmac-sdio.h | 135 -
include/linux/platform_data/brcmfmac.h | 185 ++
include/linux/platform_data/microread.h | 35 -
include/linux/qed/common_hsi.h | 36 +-
include/linux/qed/eth_common.h | 171 +-
include/linux/qed/qed_chain.h | 4 +
include/linux/qed/qed_eth_if.h | 14 +-
include/linux/qed/qed_if.h | 14 +-
include/linux/rculist.h | 21 +
include/linux/rfkill-gpio.h | 37 -
include/linux/rfkill.h | 18 +-
include/linux/skbuff.h | 69 +-
include/linux/socket.h | 7 +-
include/linux/stmmac.h | 17 +-
include/linux/tcp.h | 14 +-
include/net/6lowpan.h | 32 +
include/net/act_api.h | 84 +-
include/net/addrconf.h | 2 +
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 3 +
include/net/bond_3ad.h | 1 +
include/net/bonding.h | 1 +
include/net/cfg80211.h | 8 +
include/net/checksum.h | 17 +-
include/net/codel.h | 4 +
include/net/devlink.h | 140 +
include/net/dsa.h | 15 +-
include/net/dst.h | 12 +
include/net/dst_cache.h | 97 +
include/net/dst_metadata.h | 6 +-
include/net/flow_dissector.h | 13 +
include/net/genetlink.h | 4 -
include/net/hwbm.h | 28 +
include/net/inet6_hashtables.h | 13 +-
include/net/inet_frag.h | 1 +
include/net/inet_hashtables.h | 25 +-
include/net/ip.h | 8 +-
include/net/ip6_checksum.h | 3 +-
include/net/ip6_tunnel.h | 14 +-
include/net/ip_tunnels.h | 55 +-
include/net/ip_vs.h | 17 +
include/net/ipv6.h | 8 +-
include/net/kcm.h | 226 ++
include/net/l3mdev.h | 4 +-
include/net/lwtunnel.h | 4 +-
include/net/mac80211.h | 198 +-
include/net/mac802154.h | 15 +-
include/net/netfilter/nft_masq.h | 4 +-
include/net/netns/ipv4.h | 19 +
include/net/netns/ipv6.h | 3 +
include/net/phonet/phonet.h | 2 +-
include/net/ping.h | 2 +-
include/net/pkt_cls.h | 65 +
include/net/raw.h | 2 +-
include/net/route.h | 5 +-
include/net/sch_generic.h | 26 +-
include/net/sctp/sm.h | 2 +-
include/net/sctp/structs.h | 11 +-
include/net/sock.h | 6 +-
include/net/tc_act/tc_gact.h | 16 +
include/net/tc_act/tc_ife.h | 61 +
include/net/tc_act/tc_skbedit.h | 16 +
include/net/tcp.h | 53 +-
include/net/udp.h | 3 +-
include/net/udp_tunnel.h | 6 +-
include/net/vxlan.h | 187 +-
include/rdma/ib_addr.h | 14 +-
include/rxrpc/packet.h | 15 +-
include/trace/events/sunvnet.h | 139 +
include/uapi/asm-generic/socket.h | 2 +
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/bpf.h | 52 +
include/uapi/linux/devlink.h | 72 +
include/uapi/linux/ethtool.h | 437 ++-
include/uapi/linux/genetlink.h | 1 +
include/uapi/linux/if.h | 2 +-
include/uapi/linux/if_bridge.h | 37 +-
include/uapi/linux/if_ether.h | 1 +
include/uapi/linux/if_link.h | 43 +
include/uapi/linux/if_macsec.h | 161 ++
include/uapi/linux/ip.h | 2 +
include/uapi/linux/ipv6.h | 3 +
include/uapi/linux/kcm.h | 40 +
include/uapi/linux/kernel.h | 1 +
include/uapi/linux/mroute6.h | 9 +-
include/uapi/linux/netconf.h | 1 +
include/uapi/linux/netfilter/nf_conntrack_common.h | 12 +-
include/uapi/linux/netfilter/nf_tables.h | 6 +
include/uapi/linux/netlink.h | 4 +
include/uapi/linux/netlink_diag.h | 2 +
include/uapi/linux/nl80211.h | 14 +
include/uapi/linux/openvswitch.h | 49 +
include/uapi/linux/pkt_cls.h | 3 +
include/uapi/linux/rfkill.h | 2 +
include/uapi/linux/tc_act/tc_ife.h | 38 +
include/uapi/linux/tcp.h | 5 +
include/xen/interface/io/netif.h | 861 +++++-
kernel/bpf/Makefile | 5 +-
kernel/bpf/arraymap.c | 168 +-
kernel/bpf/hashtab.c | 458 ++-
kernel/bpf/helpers.c | 2 +-
kernel/bpf/percpu_freelist.c | 100 +
kernel/bpf/percpu_freelist.h | 31 +
kernel/bpf/stackmap.c | 290 ++
kernel/bpf/syscall.c | 90 +-
kernel/bpf/verifier.c | 48 +-
kernel/events/callchain.c | 32 +-
kernel/events/internal.h | 2 -
kernel/trace/bpf_trace.c | 4 +-
lib/Kconfig.debug | 8 +
lib/Makefile | 1 +
lib/bitmap.c | 89 +
lib/checksum.c | 4 +-
lib/random32.c | 1 +
lib/test_bitmap.c | 358 +++
net/6lowpan/core.c | 39 +-
net/6lowpan/debugfs.c | 247 ++
net/6lowpan/iphc.c | 413 ++-
net/8021q/vlan.c | 2 +-
net/8021q/vlan_dev.c | 10 +-
net/8021q/vlanproc.c | 3 +-
net/8021q/vlanproc.h | 4 +-
net/Kconfig | 24 +
net/Makefile | 1 +
net/ax25/ax25_ip.c | 15 +
net/batman-adv/Kconfig | 16 +-
net/batman-adv/Makefile | 5 +-
net/batman-adv/bat_algo.h | 30 +-
net/batman-adv/bat_iv_ogm.c | 115 +-
net/batman-adv/bat_v.c | 347 +++
net/batman-adv/bat_v_elp.c | 515 ++++
net/batman-adv/bat_v_elp.h | 33 +
net/batman-adv/bat_v_ogm.c | 833 ++++++
net/batman-adv/bat_v_ogm.h | 36 +
net/batman-adv/bitarray.c | 14 +-
net/batman-adv/bitarray.h | 14 +-
net/batman-adv/bridge_loop_avoidance.c | 329 ++-
net/batman-adv/bridge_loop_avoidance.h | 2 +-
net/batman-adv/debugfs.c | 8 +-
net/batman-adv/debugfs.h | 2 +-
net/batman-adv/distributed-arp-table.c | 100 +-
net/batman-adv/distributed-arp-table.h | 2 +-
net/batman-adv/fragmentation.c | 34 +-
net/batman-adv/fragmentation.h | 4 +-
net/batman-adv/gateway_client.c | 127 +-
net/batman-adv/gateway_client.h | 2 +-
net/batman-adv/gateway_common.c | 8 +-
net/batman-adv/gateway_common.h | 4 +-
net/batman-adv/hard-interface.c | 54 +-
net/batman-adv/hard-interface.h | 18 +-
net/batman-adv/hash.c | 2 +-
net/batman-adv/hash.h | 24 +-
net/batman-adv/icmp_socket.c | 10 +-
net/batman-adv/icmp_socket.h | 2 +-
net/batman-adv/main.c | 112 +-
net/batman-adv/main.h | 39 +-
net/batman-adv/multicast.c | 44 +-
net/batman-adv/multicast.h | 4 +-
net/batman-adv/network-coding.c | 164 +-
net/batman-adv/network-coding.h | 2 +-
net/batman-adv/originator.c | 246 +-
net/batman-adv/originator.h | 18 +-
net/batman-adv/packet.h | 68 +-
net/batman-adv/routing.c | 112 +-
net/batman-adv/routing.h | 5 +-
net/batman-adv/send.c | 98 +-
net/batman-adv/send.h | 16 +-
net/batman-adv/soft-interface.c | 73 +-
net/batman-adv/soft-interface.h | 4 +-
net/batman-adv/sysfs.c | 162 +-
net/batman-adv/sysfs.h | 2 +-
net/batman-adv/translation-table.c | 331 ++-
net/batman-adv/translation-table.h | 2 +-
net/batman-adv/types.h | 160 +-
net/bluetooth/Kconfig | 9 +
net/bluetooth/Makefile | 1 +
net/bluetooth/hci_conn.c | 17 +-
net/bluetooth/hci_core.c | 7 +
net/bluetooth/hci_request.c | 56 +-
net/bluetooth/hci_request.h | 2 +-
net/bluetooth/leds.c | 74 +
net/bluetooth/leds.h | 16 +
net/bluetooth/mgmt.c | 26 +-
net/bridge/br_forward.c | 1 -
net/bridge/br_if.c | 43 +-
net/bridge/br_input.c | 16 +-
net/bridge/br_mdb.c | 124 +-
net/bridge/br_multicast.c | 101 +-
net/bridge/br_netfilter_hooks.c | 68 +-
net/bridge/br_netlink.c | 1 -
net/bridge/br_private.h | 12 +-
net/bridge/br_stp.c | 25 +-
net/bridge/br_stp_if.c | 2 -
net/bridge/br_stp_timer.c | 1 -
net/bridge/br_vlan.c | 11 +
net/bridge/netfilter/nft_reject_bridge.c | 8 +-
net/caif/cfpkt_skbuff.c | 2 +-
net/core/Makefile | 3 +
net/core/dev.c | 34 +-
net/core/devlink.c | 738 +++++
net/core/dst.c | 10 +-
net/core/dst_cache.c | 168 ++
net/core/ethtool.c | 638 ++++-
net/core/filter.c | 254 +-
net/core/flow_dissector.c | 58 +-
net/core/hwbm.c | 87 +
net/core/lwtunnel.c | 37 +
net/core/net-sysfs.c | 18 +-
net/core/netclassid_cgroup.c | 1 -
net/core/netprio_cgroup.c | 1 -
net/core/pktgen.c | 4 +-
net/core/rtnetlink.c | 79 +-
net/core/skbuff.c | 165 +-
net/core/sock.c | 5 +
net/dccp/ipv4.c | 4 +-
net/dccp/ipv6.c | 4 +-
net/dsa/dsa.c | 43 +-
net/dsa/slave.c | 213 +-
net/ethernet/eth.c | 3 +-
net/ieee802154/6lowpan/core.c | 7 +-
net/ieee802154/socket.c | 17 +-
net/ipv4/Kconfig | 9 +-
net/ipv4/Makefile | 1 -
net/ipv4/af_inet.c | 45 +-
net/ipv4/arp.c | 41 +-
net/ipv4/devinet.c | 70 +-
net/ipv4/fib_frontend.c | 4 +
net/ipv4/fou.c | 17 +-
net/ipv4/gre_offload.c | 103 +-
net/ipv4/icmp.c | 5 +-
net/ipv4/igmp.c | 78 +-
net/ipv4/inet_connection_sock.c | 254 +-
net/ipv4/inet_diag.c | 7 +-
net/ipv4/inet_hashtables.c | 237 +-
net/ipv4/inet_lro.c | 374 ---
net/ipv4/ip_forward.c | 1 -
net/ipv4/ip_fragment.c | 29 +-
net/ipv4/ip_gre.c | 36 +-
net/ipv4/ip_input.c | 30 +-
net/ipv4/ip_options.c | 14 +-
net/ipv4/ip_output.c | 3 -
net/ipv4/ip_sockglue.c | 10 +-
net/ipv4/ip_tunnel.c | 78 +-
net/ipv4/ip_tunnel_core.c | 36 +-
net/ipv4/ipip.c | 4 +-
net/ipv4/netfilter/arp_tables.c | 66 +-
net/ipv4/netfilter/arptable_filter.c | 40 +-
net/ipv4/netfilter/ip_tables.c | 63 +-
net/ipv4/netfilter/ipt_SYNPROXY.c | 3 +-
net/ipv4/netfilter/iptable_filter.c | 44 +-
net/ipv4/netfilter/iptable_mangle.c | 41 +-
net/ipv4/netfilter/iptable_nat.c | 41 +-
net/ipv4/netfilter/iptable_raw.c | 38 +-
net/ipv4/netfilter/iptable_security.c | 44 +-
net/ipv4/netfilter/nf_defrag_ipv4.c | 4 +-
net/ipv4/netfilter/nf_nat_l3proto_ipv4.c | 30 +-
net/ipv4/netfilter/nf_nat_masquerade_ipv4.c | 12 +-
net/ipv4/netfilter/nft_masq_ipv4.c | 7 +-
net/ipv4/ping.c | 11 +-
net/ipv4/proc.c | 2 +-
net/ipv4/raw.c | 4 +-
net/ipv4/syncookies.c | 4 +-
net/ipv4/sysctl_net_ipv4.c | 236 +-
net/ipv4/tcp.c | 43 +-
net/ipv4/tcp_fastopen.c | 78 +-
net/ipv4/tcp_input.c | 176 +-
net/ipv4/tcp_ipv4.c | 25 +-
net/ipv4/tcp_metrics.c | 3 +-
net/ipv4/tcp_minisocks.c | 5 +-
net/ipv4/tcp_offload.c | 8 +-
net/ipv4/tcp_output.c | 10 +-
net/ipv4/tcp_probe.c | 8 +-
net/ipv4/tcp_timer.c | 23 +-
net/ipv4/udp.c | 32 +-
net/ipv4/udp_offload.c | 107 +-
net/ipv6/Kconfig | 1 +
net/ipv6/addrconf.c | 206 +-
net/ipv6/af_inet6.c | 6 +-
net/ipv6/ila/ila_common.c | 1 +
net/ipv6/inet6_connection_sock.c | 2 +
net/ipv6/inet6_hashtables.c | 78 +-
net/ipv6/ip6_checksum.c | 26 +-
net/ipv6/ip6_fib.c | 91 +-
net/ipv6/ip6_gre.c | 12 +-
net/ipv6/ip6_input.c | 12 +-
net/ipv6/ip6_output.c | 1 -
net/ipv6/ip6_tunnel.c | 103 +-
net/ipv6/ip6_udp_tunnel.c | 6 +-
net/ipv6/ip6_vti.c | 2 +-
net/ipv6/ndisc.c | 9 +
net/ipv6/netfilter/ip6_tables.c | 65 +-
net/ipv6/netfilter/ip6table_filter.c | 47 +-
net/ipv6/netfilter/ip6table_mangle.c | 46 +-
net/ipv6/netfilter/ip6table_nat.c | 41 +-
net/ipv6/netfilter/ip6table_raw.c | 46 +-
net/ipv6/netfilter/ip6table_security.c | 44 +-
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 30 +-
net/ipv6/netfilter/nft_masq_ipv6.c | 7 +-
net/ipv6/reassembly.c | 6 +-
net/ipv6/sit.c | 23 +-
net/ipv6/syncookies.c | 2 +-
net/ipv6/tcp_ipv6.c | 12 +-
net/ipv6/udp.c | 64 +-
net/ipv6/udp_offload.c | 8 +-
net/kcm/Kconfig | 10 +
net/kcm/Makefile | 3 +
net/kcm/kcmproc.c | 426 +++
net/kcm/kcmsock.c | 2409 ++++++++++++++++
net/l2tp/l2tp_ip6.c | 3 +-
net/l3mdev/l3mdev.c | 11 +-
net/llc/af_llc.c | 4 +-
net/mac80211/agg-rx.c | 50 +-
net/mac80211/agg-tx.c | 53 +-
net/mac80211/cfg.c | 34 +-
net/mac80211/chan.c | 2 +-
net/mac80211/debugfs.c | 1 +
net/mac80211/debugfs_key.c | 5 +-
net/mac80211/driver-ops.c | 10 +-
net/mac80211/driver-ops.h | 4 +-
net/mac80211/ht.c | 5 +
net/mac80211/ibss.c | 32 +-
net/mac80211/ieee80211_i.h | 37 +-
net/mac80211/iface.c | 14 +
net/mac80211/key.c | 86 -
net/mac80211/key.h | 10 +-
net/mac80211/mesh.c | 9 +-
net/mac80211/mesh.h | 3 -
net/mac80211/mesh_hwmp.c | 6 +-
net/mac80211/mesh_pathtbl.c | 111 +-
net/mac80211/mesh_plink.c | 10 +-
net/mac80211/mlme.c | 79 +-
net/mac80211/rx.c | 141 +-
net/mac80211/sta_info.c | 35 +-
net/mac80211/sta_info.h | 24 +-
net/mac80211/status.c | 2 +-
net/mac80211/tkip.c | 36 +-
net/mac80211/tkip.h | 2 -
net/mac80211/trace.h | 43 +-
net/mac80211/tx.c | 100 +-
net/mac80211/util.c | 116 +-
net/mac80211/vht.c | 57 +
net/mac80211/wpa.c | 11 +-
net/mac802154/main.c | 2 +-
net/mpls/mpls_iptunnel.c | 1 +
net/netfilter/ipset/ip_set_bitmap_ipmac.c | 2 +
net/netfilter/ipset/ip_set_core.c | 3 +
net/netfilter/ipset/ip_set_hash_mac.c | 3 +-
net/netfilter/ipset/ip_set_list_set.c | 55 +-
net/netfilter/ipvs/ip_vs_app.c | 8 +-
net/netfilter/ipvs/ip_vs_core.c | 38 +-
net/netfilter/ipvs/ip_vs_ctl.c | 17 +-
net/netfilter/ipvs/ip_vs_pe_sip.c | 6 +-
net/netfilter/ipvs/ip_vs_xmit.c | 12 +-
net/netfilter/nf_conntrack_core.c | 6 +-
net/netfilter/nf_dup_netdev.c | 1 -
net/netfilter/nfnetlink.c | 7 -
net/netfilter/nfnetlink_acct.c | 3 +
net/netfilter/nfnetlink_log.c | 5 +-
net/netfilter/nfnetlink_queue.c | 6 +-
net/netfilter/nft_compat.c | 6 +
net/netfilter/nft_masq.c | 51 +-
net/netfilter/nft_meta.c | 11 +
net/netfilter/x_tables.c | 68 +-
net/netfilter/xt_TPROXY.c | 31 +-
net/netfilter/xt_osf.c | 2 -
net/netfilter/xt_socket.c | 28 +-
net/netlabel/netlabel_domainhash.c | 4 +-
net/netlabel/netlabel_unlabeled.c | 6 +-
net/netlink/Kconfig | 9 -
net/netlink/af_netlink.c | 774 +----
net/netlink/af_netlink.h | 15 -
net/netlink/diag.c | 39 -
net/netlink/genetlink.c | 25 +-
net/nfc/llcp_commands.c | 4 +-
net/nfc/llcp_sock.c | 6 +
net/openvswitch/Kconfig | 4 +-
net/openvswitch/actions.c | 8 +-
net/openvswitch/conntrack.c | 660 ++++-
net/openvswitch/conntrack.h | 3 +-
net/openvswitch/datapath.c | 108 +-
net/openvswitch/datapath.h | 4 +
net/openvswitch/flow.h | 2 +-
net/openvswitch/flow_netlink.c | 9 +-
net/openvswitch/vport-internal_dev.c | 10 +-
net/openvswitch/vport-netdev.c | 2 +-
net/openvswitch/vport.h | 7 -
net/packet/af_packet.c | 472 ++--
net/phonet/socket.c | 6 +-
net/rds/Kconfig | 7 +-
net/rds/Makefile | 4 +-
net/rds/af_rds.c | 26 +
net/rds/ib.c | 47 +-
net/rds/ib.h | 37 +-
net/rds/ib_cm.c | 59 +-
net/rds/ib_fmr.c | 248 ++
net/rds/ib_frmr.c | 376 +++
net/rds/ib_mr.h | 148 +
net/rds/ib_rdma.c | 495 +---
net/rds/ib_send.c | 6 +-
net/rds/ib_stats.c | 2 +
net/rds/iw.c | 312 --
net/rds/iw.h | 398 ---
net/rds/iw_cm.c | 769 -----
net/rds/iw_rdma.c | 837 ------
net/rds/iw_recv.c | 904 ------
net/rds/iw_ring.c | 169 --
net/rds/iw_send.c | 981 -------
net/rds/iw_stats.c | 95 -
net/rds/iw_sysctl.c | 123 -
net/rds/rdma_transport.c | 21 +-
net/rds/rdma_transport.h | 5 -
net/rds/rds.h | 1 +
net/rds/recv.c | 20 +-
net/rds/tcp.c | 146 +-
net/rfkill/Kconfig | 3 +-
net/rfkill/core.c | 172 +-
net/rfkill/rfkill-gpio.c | 24 +-
net/rxrpc/af_rxrpc.c | 39 +-
net/rxrpc/ar-accept.c | 56 +-
net/rxrpc/ar-ack.c | 225 +-
net/rxrpc/ar-call.c | 88 +-
net/rxrpc/ar-connection.c | 85 +-
net/rxrpc/ar-connevent.c | 79 +-
net/rxrpc/ar-error.c | 13 +-
net/rxrpc/ar-input.c | 118 +-
net/rxrpc/ar-internal.h | 218 +-
net/rxrpc/ar-local.c | 29 +-
net/rxrpc/ar-output.c | 75 +-
net/rxrpc/ar-peer.c | 2 +-
net/rxrpc/ar-proc.c | 10 +-
net/rxrpc/ar-recvmsg.c | 20 +-
net/rxrpc/ar-security.c | 6 +-
net/rxrpc/ar-skbuff.c | 7 +-
net/rxrpc/ar-transport.c | 3 +-
net/rxrpc/rxkad.c | 165 +-
net/rxrpc/sysctl.c | 34 +-
net/sched/Kconfig | 22 +
net/sched/Makefile | 3 +
net/sched/act_api.c | 137 +-
net/sched/act_bpf.c | 52 +-
net/sched/act_connmark.c | 54 +-
net/sched/act_csum.c | 67 +-
net/sched/act_gact.c | 55 +-
net/sched/act_ife.c | 870 ++++++
net/sched/act_ipt.c | 127 +-
net/sched/act_meta_mark.c | 79 +
net/sched/act_meta_skbprio.c | 76 +
net/sched/act_mirred.c | 55 +-
net/sched/act_nat.c | 72 +-
net/sched/act_pedit.c | 54 +-
net/sched/act_police.c | 52 +-
net/sched/act_simple.c | 55 +-
net/sched/act_skbedit.c | 54 +-
net/sched/act_vlan.c | 54 +-
net/sched/cls_bpf.c | 13 +-
net/sched/cls_flower.c | 64 +-
net/sched/cls_u32.c | 118 +-
net/sched/sch_api.c | 10 +-
net/sched/sch_cbq.c | 12 +-
net/sched/sch_choke.c | 6 +-
net/sched/sch_codel.c | 10 +-
net/sched/sch_drr.c | 9 +-
net/sched/sch_dsmark.c | 13 +-
net/sched/sch_fq.c | 4 +-
net/sched/sch_fq_codel.c | 17 +-
net/sched/sch_generic.c | 1 +
net/sched/sch_hfsc.c | 9 +-
net/sched/sch_hhf.c | 10 +-
net/sched/sch_htb.c | 24 +-
net/sched/sch_mq.c | 2 +-
net/sched/sch_mqprio.c | 11 +-
net/sched/sch_multiq.c | 16 +-
net/sched/sch_netem.c | 13 +-
net/sched/sch_pie.c | 5 +-
net/sched/sch_prio.c | 15 +-
net/sched/sch_qfq.c | 9 +-
net/sched/sch_red.c | 10 +-
net/sched/sch_sfb.c | 10 +-
net/sched/sch_sfq.c | 16 +-
net/sched/sch_tbf.c | 15 +-
net/sctp/associola.c | 4 +-
net/sctp/chunk.c | 19 +-
net/sctp/input.c | 6 +-
net/sctp/output.c | 6 +-
net/sctp/outqueue.c | 30 +-
net/sctp/probe.c | 10 +-
net/sctp/proc.c | 2 -
net/sctp/sm_make_chunk.c | 80 +-
net/sctp/sm_sideeffect.c | 23 +-
net/sctp/socket.c | 9 +-
net/sctp/transport.c | 2 +-
net/socket.c | 64 +-
net/tipc/bcast.c | 5 -
net/tipc/bcast.h | 1 -
net/tipc/bearer.c | 18 +-
net/tipc/link.c | 167 +-
net/tipc/link.h | 7 +-
net/tipc/name_table.c | 20 +-
net/tipc/net.c | 7 +-
net/tipc/netlink.c | 69 +
net/tipc/netlink.h | 11 +
net/tipc/netlink_compat.c | 2 +-
net/tipc/node.c | 130 +-
net/tipc/server.c | 4 +-
net/tipc/socket.c | 9 +-
net/tipc/subscr.c | 132 +-
net/tipc/subscr.h | 11 +-
net/tipc/udp_media.c | 44 +-
net/unix/af_unix.c | 5 +-
net/wireless/Kconfig | 25 +-
net/wireless/core.c | 10 +
net/wireless/mlme.c | 3 +-
net/wireless/nl80211.c | 29 +-
net/wireless/radiotap.c | 1 +
net/wireless/reg.c | 122 +-
net/wireless/sme.c | 9 +-
net/wireless/util.c | 277 +-
samples/bpf/Makefile | 12 +
samples/bpf/bpf_helpers.h | 3 +
samples/bpf/bpf_load.c | 70 +-
samples/bpf/bpf_load.h | 6 +
samples/bpf/fds_example.c | 2 +-
samples/bpf/libbpf.c | 5 +-
samples/bpf/libbpf.h | 2 +-
samples/bpf/map_perf_test_kern.c | 100 +
samples/bpf/map_perf_test_user.c | 155 +
samples/bpf/offwaketime_kern.c | 131 +
samples/bpf/offwaketime_user.c | 120 +
samples/bpf/sock_example.c | 2 +-
samples/bpf/spintest_kern.c | 68 +
samples/bpf/spintest_user.c | 50 +
samples/bpf/test_maps.c | 211 +-
samples/bpf/test_verifier.c | 4 +-
samples/bpf/tracex2_kern.c | 2 +-
samples/bpf/tracex2_user.c | 7 +-
samples/bpf/tracex3_kern.c | 8 +-
samples/bpf/tracex3_user.c | 21 +-
tools/net/bpf_dbg.c | 10 +-
tools/net/bpf_exp.l | 84 +-
tools/net/bpf_exp.y | 146 +-
tools/testing/selftests/lib/Makefile | 2 +-
tools/testing/selftests/lib/bitmap.sh | 10 +
tools/testing/selftests/net/.gitignore | 1 +
tools/testing/selftests/net/Makefile | 2 +-
tools/testing/selftests/net/reuseport_bpf.c | 117 +-
tools/testing/selftests/net/reuseport_bpf_cpu.c | 258 ++
1289 files changed, 79111 insertions(+), 34126 deletions(-)
delete mode 100644 Documentation/ABI/obsolete/sysfs-class-rfkill
create mode 100644 Documentation/ABI/removed/sysfs-class-rfkill
create mode 100644 Documentation/devicetree/bindings/net/can/ifi_canfd.txt
create mode 100644 Documentation/devicetree/bindings/net/marvell-neta-bm.txt
create mode 100644 Documentation/devicetree/bindings/net/mediatek-net.txt
create mode 100644 Documentation/devicetree/bindings/net/micrel-ks8995.txt
create mode 100644 Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
create mode 100644 Documentation/networking/checksum-offloads.txt
create mode 100644 Documentation/networking/kcm.txt
delete mode 100644 Documentation/networking/netlink_mmap.txt
create mode 100644 drivers/bcma/driver_chipcommon_pflash.c
create mode 100644 drivers/bluetooth/hci_ag6xx.c
create mode 100644 drivers/net/can/ifi_canfd/Kconfig
create mode 100644 drivers/net/can/ifi_canfd/Makefile
create mode 100644 drivers/net/can/ifi_canfd/ifi_canfd.c
rename drivers/net/dsa/{mv88e6123_61_65.c => mv88e6123.c} (84%)
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_cle.c
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_cle.h
rename drivers/net/ethernet/{ => cavium}/octeon/Makefile (100%)
rename drivers/net/ethernet/{ => cavium}/octeon/octeon_mgmt.c (100%)
create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_model.h
create mode 100644 drivers/net/ethernet/marvell/mvneta_bm.c
create mode 100644 drivers/net/ethernet/marvell/mvneta_bm.h
create mode 100644 drivers/net/ethernet/mediatek/Kconfig
create mode 100644 drivers/net/ethernet/mediatek/Makefile
create mode 100644 drivers/net/ethernet/mediatek/mtk_eth_soc.c
create mode 100644 drivers/net/ethernet/mediatek/mtk_eth_soc.h
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
delete mode 100644 drivers/net/ethernet/octeon/Kconfig
delete mode 100644 drivers/net/ethernet/rocker/rocker.c
create mode 100644 drivers/net/ethernet/rocker/rocker_hw.h
create mode 100644 drivers/net/ethernet/rocker/rocker_main.c
create mode 100644 drivers/net/ethernet/rocker/rocker_ofdpa.c
create mode 100644 drivers/net/ethernet/rocker/rocker_tlv.c
create mode 100644 drivers/net/ethernet/rocker/rocker_tlv.h
delete mode 100644 drivers/net/ethernet/samsung/sxgbe/sxgbe_xpcs.c
delete mode 100644 drivers/net/ethernet/samsung/sxgbe/sxgbe_xpcs.h
create mode 100644 drivers/net/ethernet/sun/ldmvsw.c
delete mode 100644 drivers/net/ethernet/sun/sunvnet.h
create mode 100644 drivers/net/ethernet/sun/sunvnet_common.c
create mode 100644 drivers/net/ethernet/sun/sunvnet_common.h
create mode 100644 drivers/net/macsec.c
create mode 100644 drivers/net/phy/mdio-cavium.c
create mode 100644 drivers/net/phy/mdio-cavium.h
create mode 100644 drivers/net/phy/mdio-thunder.c
create mode 100644 drivers/net/wireless/ath/ath10k/ahb.c
create mode 100644 drivers/net/wireless/ath/ath10k/ahb.h
delete mode 100644 include/linux/inet_lro.h
create mode 100644 include/linux/mlx5/port.h
delete mode 100644 include/linux/platform_data/brcmfmac-sdio.h
create mode 100644 include/linux/platform_data/brcmfmac.h
delete mode 100644 include/linux/platform_data/microread.h
delete mode 100644 include/linux/rfkill-gpio.h
create mode 100644 include/net/devlink.h
create mode 100644 include/net/dst_cache.h
create mode 100644 include/net/hwbm.h
create mode 100644 include/net/kcm.h
create mode 100644 include/net/tc_act/tc_ife.h
create mode 100644 include/trace/events/sunvnet.h
create mode 100644 include/uapi/linux/devlink.h
create mode 100644 include/uapi/linux/if_macsec.h
create mode 100644 include/uapi/linux/kcm.h
create mode 100644 include/uapi/linux/tc_act/tc_ife.h
create mode 100644 kernel/bpf/percpu_freelist.c
create mode 100644 kernel/bpf/percpu_freelist.h
create mode 100644 kernel/bpf/stackmap.c
create mode 100644 lib/test_bitmap.c
create mode 100644 net/batman-adv/bat_v.c
create mode 100644 net/batman-adv/bat_v_elp.c
create mode 100644 net/batman-adv/bat_v_elp.h
create mode 100644 net/batman-adv/bat_v_ogm.c
create mode 100644 net/batman-adv/bat_v_ogm.h
create mode 100644 net/bluetooth/leds.c
create mode 100644 net/bluetooth/leds.h
create mode 100644 net/core/devlink.c
create mode 100644 net/core/dst_cache.c
create mode 100644 net/core/hwbm.c
delete mode 100644 net/ipv4/inet_lro.c
create mode 100644 net/kcm/Kconfig
create mode 100644 net/kcm/Makefile
create mode 100644 net/kcm/kcmproc.c
create mode 100644 net/kcm/kcmsock.c
create mode 100644 net/rds/ib_fmr.c
create mode 100644 net/rds/ib_frmr.c
create mode 100644 net/rds/ib_mr.h
delete mode 100644 net/rds/iw.c
delete mode 100644 net/rds/iw.h
delete mode 100644 net/rds/iw_cm.c
delete mode 100644 net/rds/iw_rdma.c
delete mode 100644 net/rds/iw_recv.c
delete mode 100644 net/rds/iw_ring.c
delete mode 100644 net/rds/iw_send.c
delete mode 100644 net/rds/iw_stats.c
delete mode 100644 net/rds/iw_sysctl.c
create mode 100644 net/sched/act_ife.c
create mode 100644 net/sched/act_meta_mark.c
create mode 100644 net/sched/act_meta_skbprio.c
create mode 100644 samples/bpf/map_perf_test_kern.c
create mode 100644 samples/bpf/map_perf_test_user.c
create mode 100644 samples/bpf/offwaketime_kern.c
create mode 100644 samples/bpf/offwaketime_user.c
create mode 100644 samples/bpf/spintest_kern.c
create mode 100644 samples/bpf/spintest_user.c
create mode 100755 tools/testing/selftests/lib/bitmap.sh
create mode 100644 tools/testing/selftests/net/reuseport_bpf_cpu.c
^ permalink raw reply
* Re: [RFC net-next 0/2] Create ancient subdirectories for old hardware
From: David Miller @ 2016-03-19 3:16 UTC (permalink / raw)
To: joe; +Cc: netdev, linux-kernel
In-Reply-To: <1458354482.26915.35.camel@perches.com>
From: Joe Perches <joe@perches.com>
Date: Fri, 18 Mar 2016 19:28:02 -0700
> On Fri, 2016-03-18 at 22:11 -0400, David Miller wrote:
>> From: Joe Perches <joe@perches.com>
>> Date: Fri, 18 Mar 2016 17:33:29 -0700
>>
>> > Maybe something like this:
>> >
>> > Old, rare, and unsupported hardware should be exposed as ancient.
>> >
>> > The drivers for these ancient hardwares are generally untested with
>> > current kernels.
>>
>> Moving drivers has a long term maintainence cost.
>>
>> If they've moved into drivers/net proper, we have to maintain
>> them there forever.
>
> I don't doubt that.
>
> All files are still in drivers/net, just possibly in
> separate subdirectories for easier visibility to
> determine if changes like what were proposed for cxgb
> should actually be done or not.
You don't understand my concern, backporting patches to -stable
releases is more painful if you move the driver anywhere other
than where it has been for years.
I'm not entertaining this idea, sorry Joe.
^ permalink raw reply
* Re: [PATCH net] bonding: fix bond_get_stats()
From: David Miller @ 2016-03-19 3:15 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, gospo, j.vosburgh, vfalico
In-Reply-To: <1458260616.31963.14.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 17 Mar 2016 17:23:36 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> bond_get_stats() can be called from rtnetlink (with RTNL held)
> or from /proc/net/dev seq handler (with RCU held)
>
> The logic added in commit 5f0c5f73e5ef ("bonding: make global bonding
> stats more reliable") kind of assumed only one cpu could run there.
>
> If multiple threads are reading /proc/net/dev, stats can be really
> messed up after a while.
>
> A second problem is that some fields are 32bit, so we need to properly
> handle the wrap around problem.
>
> Given that RTNL is not always held, we need to use
> bond_for_each_slave_rcu().
>
> Fixes: 5f0c5f73e5ef ("bonding: make global bonding stats more reliable")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied and queued up for -stable, thanks Eric.
^ permalink raw reply
* Re: [PATCH net] net: bcmgenet: fix dma api length mismatch
From: David Miller @ 2016-03-19 3:13 UTC (permalink / raw)
To: eric.dumazet; +Cc: f.fainelli, netdev, opendmb
In-Reply-To: <1458241026.7353.62.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 17 Mar 2016 11:57:06 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> When un-mapping skb->data in __bcmgenet_tx_reclaim(),
> we must use the length that was used in original dma_map_single(),
> instead of skb->len that might be bigger (includes the frags)
>
> We simply can store skb_len into tx_cb_ptr->dma_len and use it
> at unmap time.
>
> Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH net 1/3] ipip: Properly mark ipip GRO packets as encapsulated.
From: David Miller @ 2016-03-19 3:12 UTC (permalink / raw)
To: jesse; +Cc: netdev, boutilpj
In-Reply-To: <1458239136-37814-1-git-send-email-jesse@kernel.org>
Jesse, can you repost this series with a patch introductory "PATCH
0/3" email explaining things at a high level about what this series is
doing?
Thanks.
^ permalink raw reply
* Re: [PATCH net-next] net/mlx4_core: Fix backward compatibility on VFs
From: David Miller @ 2016-03-19 3:11 UTC (permalink / raw)
To: eli-VPRAkNaXOzVWk0Htik3J/w
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
aik-sLpHqDYs0B2HXe+LvDLADg
In-Reply-To: <1458233382-12871-1-git-send-email-eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
From: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Date: Thu, 17 Mar 2016 18:49:42 +0200
> Commit 85743f1eb345 ("net/mlx4_core: Set UAR page size to 4KB regardless
> of system page size") introduced dependency where old VF drivers without
> this fix fail to load if the PF driver runs with this commit.
>
> To resolve this add a module parameter which disables that functionality
> by default. If both the PF and VFs are running with a driver with that
> commit the administrator may set the module param to true.
>
> The module parameter is called enable_4k_uar.
>
> Fixes: 85743f1eb345 ('net/mlx4_core: Set UAR page size to 4KB ...')
> Signed-off-by: Eli Cohen <eli-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Applied.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] phy: mdio-thunder: Fix some Kconfig typos
From: David Miller @ 2016-03-19 3:05 UTC (permalink / raw)
To: afaerber; +Cc: netdev, linux-arm-kernel, david.daney, f.fainelli, linux-kernel
In-Reply-To: <1458170617-31784-1-git-send-email-afaerber@suse.de>
From: Andreas Färber <afaerber@suse.de>
Date: Thu, 17 Mar 2016 00:23:37 +0100
> Drop two extra occurrences of "on" in option title and help text.
>
> Fixes: 379d7ac7ca31 ("phy: mdio-thunder: Add driver for Cavium Thunder SoC MDIO buses.")
> Cc: David Daney <david.daney@cavium.com>
> Signed-off-by: Andreas Färber <afaerber@suse.de>
Applied.
^ permalink raw reply
* Re: [RFC PATCH 6/9] ethtool: Add support for toggling any of the GSO offloads
From: Alexander Duyck @ 2016-03-19 2:43 UTC (permalink / raw)
To: Jesse Gross
Cc: Ben Hutchings, Alexander Duyck, Edward Cree, Netdev, David Miller,
Tom Herbert
In-Reply-To: <CAEh+42ihKJ30O_i9f7H0KzQBjNrBfQFXN=S3-ZsdYKssBkTSXg@mail.gmail.com>
On Fri, Mar 18, 2016 at 7:01 PM, Jesse Gross <jesse@kernel.org> wrote:
> On Fri, Mar 18, 2016 at 6:42 PM, Ben Hutchings <ben@decadent.org.uk> wrote:
>> On Fri, 2016-03-18 at 17:30 -0700, Alexander Duyck wrote:
>>> On Fri, Mar 18, 2016 at 5:18 PM, Ben Hutchings <ben@decadent.org.uk> wrote:
>>> > On Fri, 2016-03-18 at 16:25 -0700, Alexander Duyck wrote:
>>> > > [NETIF_F_GSO_IPIP_BIT] = "tx-ipip-segmentation",
>>> > > [NETIF_F_GSO_SIT_BIT] = "tx-sit-segmentation",
>>> > > [NETIF_F_GSO_UDP_TUNNEL_BIT] = "tx-udp_tnl-segmentation",
>>> > > + [NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT] = "tx-udp_tnl-csum-segmentation",
>>> > > + [NETIF_F_GSO_TUNNEL_REMCSUM_BIT] = "tx-remcsum-segmentation",
>>> > I think this should be "tx-tunnel-remote-checksum-segmentation", though
>>> > that is getting quite unwieldy.
>>> Right. As it is I think we might be coming up on the 32 character
>>> limit for the strings. Replacing csum with checksum would probably
>>> push us over.
>>
>> Right, I wasn't even thinking about the static limit! That does weigh
>> rather heavily in favour of abbreviation here.
>>
>> Please do at least hyphenate "remcsum" though.
>
> I think that remote checksum offload is just a purely internal feature
> - that is no device will ever expose support for it, since it is
> explicitly to work around lack of hardware support. As a result, I
> don't know if it makes sense to show it through ethtool at all.
That's true. I can probably drop that. The two I cared about where
the GRE and UDP bits anyway.
- Alex
^ permalink raw reply
* Re: [RFC PATCH 9/9] ixgbe/ixgbevf: Add support for GSO partial
From: Alexander Duyck @ 2016-03-19 2:42 UTC (permalink / raw)
To: Jesse Gross
Cc: Alexander Duyck, Edward Cree, Linux Kernel Network Developers,
David Miller, Tom Herbert
In-Reply-To: <CAEh+42hwfx6EEbE9pf6RFdL9xkcc60CbguSFm+c+QDa63UMymA@mail.gmail.com>
On Fri, Mar 18, 2016 at 7:05 PM, Jesse Gross <jesse@kernel.org> wrote:
> On Fri, Mar 18, 2016 at 4:25 PM, Alexander Duyck <aduyck@mirantis.com> wrote:
>> This patch adds support for partial GSO segmentation in the case of GRE or
>> UDP encapsulated frames.
>>
>> The one bit in this patch that is a bit controversial is the fact that we
>> are leaving the inner IPv4 IP ID as a static value in the case of
>> segmentation. As per RFC6864 this should be acceptable as TCP frames set
>> the DF bit so the IP ID should be ignored. However this is not always the
>> case as header compression schemes for PPP and SLIP can end up taking a
>> performance hit as they have to record the fact that the ID didn't change
>> as expected.
>>
>> In addition GRO was examining the IP ID field as well. As such on older
>> GRO implementations TSO frames from this driver may end up blocking GRO on
>> the other end which will likely hurt performance instead of helping it.
>>
>> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
>
> I wasn't able to apply this patch, it seems like it might be based on
> some Intel driver patches that haven't been merged into net-next yet?
Yeah, I based it off of Jeff's Kirshers dev-queue branch of his
next-queue git repo. Odds are it isn't working because net-next still
doesn't have the HW_CSUM patches I submitted a couple months ago. I
ended up doing that as I needed to pull in that and a couple of other
fixes for i40e in order to apply the patches for those two drivers.
- Alex
^ permalink raw reply
* Re: [PATCH v2 net-next 0/2] lan78xx: patch series
From: David Miller @ 2016-03-19 2:28 UTC (permalink / raw)
To: Woojung.Huh; +Cc: netdev, UNGLinuxDriver
In-Reply-To: <9235D6609DB808459E95D78E17F2E43D404C94B1@CHN-SV-EXMX02.mchp-main.com>
Series applied, thanks.
^ permalink raw reply
* Re: [RFC net-next 0/2] Create ancient subdirectories for old hardware
From: Joe Perches @ 2016-03-19 2:28 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20160318.221153.997255526626920777.davem@davemloft.net>
On Fri, 2016-03-18 at 22:11 -0400, David Miller wrote:
> From: Joe Perches <joe@perches.com>
> Date: Fri, 18 Mar 2016 17:33:29 -0700
>
> > Maybe something like this:
> >
> > Old, rare, and unsupported hardware should be exposed as ancient.
> >
> > The drivers for these ancient hardwares are generally untested with
> > current kernels.
>
> Moving drivers has a long term maintainence cost.
>
> If they've moved into drivers/net proper, we have to maintain
> them there forever.
I don't doubt that.
All files are still in drivers/net, just possibly in
separate subdirectories for easier visibility to
determine if changes like what were proposed for cxgb
should actually be done or not.
^ permalink raw reply
* Re: [PATCH net-next v4 0/2] RDS: TCP: tunable socket buffer parameters
From: David Miller @ 2016-03-19 2:26 UTC (permalink / raw)
To: sowmini.varadhan; +Cc: netdev, santosh.shilimkar, hannes, eric.dumazet
In-Reply-To: <cover.1458152608.git.sowmini.varadhan@oracle.com>
From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Date: Wed, 16 Mar 2016 11:38:11 -0700
> Patch 1 uses sysctl to create tunable socket buffer size parameters.
>
> Patch 2 removes an unuused constant.
>
> v2: use sysctl
> v3: review comments from Santosh Shilimkar, Eric Dumazet
> v4: review comments from Hannes Sowa
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH v2] net: smc911x: convert pxa dma to dmaengine
From: David Miller @ 2016-03-19 2:25 UTC (permalink / raw)
To: robert.jarzmik; +Cc: netdev, linux-kernel, fabio.estevam
In-Reply-To: <1458149162-11469-1-git-send-email-robert.jarzmik@free.fr>
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Wed, 16 Mar 2016 18:26:02 +0100
> Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
> slave driver. This makes this driver a bit more PXA agnostic.
>
> The driver was only compile tested. The risk is quite small as no
> current PXA platform I'm aware of is using smc911x driver.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
> Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
> ---
> Since v1: added Fabio's Tested-by
Applied, thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox