The hardware vendors need to generate RoCEv1 or RoCEv2
packet according to the sgid type configured.

Besides, update the gid table size for hip08 RoCE
device.

Signed-off-by: Lijun Ou <ouli...@huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.hu...@huawei.com>
Signed-off-by: Shaobo Xu <xushao...@huawei.com>
Signed-off-by: Yixian Liu <liuyix...@huawei.com>
---
 drivers/infiniband/hw/hns/hns_roce_device.h |  4 ++--
 drivers/infiniband/hw/hns/hns_roce_hw_v1.c  |  7 +++++--
 drivers/infiniband/hw/hns/hns_roce_hw_v2.c  | 25 +++++++++++++++++++++----
 drivers/infiniband/hw/hns/hns_roce_hw_v2.h  |  7 +++++++
 drivers/infiniband/hw/hns/hns_roce_main.c   | 11 +++++++----
 5 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h 
b/drivers/infiniband/hw/hns/hns_roce_device.h
index ba3bb36..c4a28a0 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -586,8 +586,8 @@ struct hns_roce_hw {
                         u64 out_param, u32 in_modifier, u8 op_modifier, u16 op,
                         u16 token, int event);
        int (*chk_mbox)(struct hns_roce_dev *hr_dev, unsigned long timeout);
-       void (*set_gid)(struct hns_roce_dev *hr_dev, u8 port, int gid_index,
-                       union ib_gid *gid);
+       int (*set_gid)(struct hns_roce_dev *hr_dev, u8 port, int gid_index,
+                      union ib_gid *gid, const struct ib_gid_attr *attr);
        int (*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);
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 00cbfc9..af27168 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -1703,8 +1703,9 @@ static int hns_roce_v1_chk_mbox(struct hns_roce_dev 
*hr_dev,
        return 0;
 }
 
-static void hns_roce_v1_set_gid(struct hns_roce_dev *hr_dev, u8 port,
-                               int gid_index, union ib_gid *gid)
+static int hns_roce_v1_set_gid(struct hns_roce_dev *hr_dev, u8 port,
+                              int gid_index, union ib_gid *gid,
+                              const struct ib_gid_attr *attr)
 {
        u32 *p = NULL;
        u8 gid_idx = 0;
@@ -1726,6 +1727,8 @@ static void hns_roce_v1_set_gid(struct hns_roce_dev 
*hr_dev, u8 port,
        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));
+
+       return 0;
 }
 
 static int hns_roce_v1_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port,
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c 
b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 2e17dc1..3b0cf55 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -948,7 +948,7 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
        caps->flags             = HNS_ROCE_CAP_FLAG_REREG_MR |
                                  HNS_ROCE_CAP_FLAG_ROCE_V1_V2;
        caps->pkey_table_len[0] = 1;
-       caps->gid_table_len[0] = 2;
+       caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM;
        caps->local_ca_ack_delay = 0;
        caps->max_mtu = IB_MTU_4096;
 
@@ -1043,12 +1043,27 @@ static int hns_roce_v2_chk_mbox(struct hns_roce_dev 
*hr_dev,
        return 0;
 }
 
-static void hns_roce_v2_set_gid(struct hns_roce_dev *hr_dev, u8 port,
-                               int gid_index, union ib_gid *gid)
+static int hns_roce_v2_set_gid(struct hns_roce_dev *hr_dev, u8 port,
+                              int gid_index, union ib_gid *gid,
+                              const struct ib_gid_attr *attr)
 {
+       enum hns_roce_sgid_type sgid_type = GID_TYPE_FLAG_ROCE_V1;
        u32 *p;
        u32 val;
 
+       if (!gid || !attr)
+               return -EINVAL;
+
+       if (attr->gid_type == IB_GID_TYPE_ROCE)
+               sgid_type = GID_TYPE_FLAG_ROCE_V1;
+
+       if (attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
+               if (ipv6_addr_v4mapped((void *)gid))
+                       sgid_type = GID_TYPE_FLAG_ROCE_V2_IPV4;
+               else
+                       sgid_type = GID_TYPE_FLAG_ROCE_V2_IPV6;
+       }
+
        p = (u32 *)&gid->raw[0];
        roce_raw_write(*p, hr_dev->reg_base + ROCEE_VF_SGID_CFG0_REG +
                       0x20 * gid_index);
@@ -1067,9 +1082,11 @@ static void hns_roce_v2_set_gid(struct hns_roce_dev 
*hr_dev, u8 port,
 
        val = roce_read(hr_dev, ROCEE_VF_SGID_CFG4_REG + 0x20 * gid_index);
        roce_set_field(val, ROCEE_VF_SGID_CFG4_SGID_TYPE_M,
-                      ROCEE_VF_SGID_CFG4_SGID_TYPE_S, 0);
+                      ROCEE_VF_SGID_CFG4_SGID_TYPE_S, sgid_type);
 
        roce_write(hr_dev, ROCEE_VF_SGID_CFG4_REG + 0x20 * gid_index, val);
+
+       return 0;
 }
 
 static int hns_roce_v2_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port,
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h 
b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
index 6106ad1..864fcd1 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -77,6 +77,7 @@
 #define HNS_ROCE_MTT_HOP_NUM                   1
 #define HNS_ROCE_CQE_HOP_NUM                   1
 #define HNS_ROCE_PBL_HOP_NUM                   2
+#define HNS_ROCE_V2_GID_INDEX_NUM              256
 
 #define HNS_ROCE_V2_TABLE_CHUNK_SIZE           (1 << 18)
 
@@ -203,6 +204,12 @@ enum hns_roce_cmd_return_status {
        CMD_QUEUE_FULL          = 3,
 };
 
+enum hns_roce_sgid_type {
+       GID_TYPE_FLAG_ROCE_V1 = 0,
+       GID_TYPE_FLAG_ROCE_V2_IPV4,
+       GID_TYPE_FLAG_ROCE_V2_IPV6,
+};
+
 struct hns_roce_v2_cq_context {
        u32     byte_4_pg_ceqn;
        u32     byte_8_cqn;
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c 
b/drivers/infiniband/hw/hns/hns_roce_main.c
index 8bb75ea..5bc8cc2 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -81,17 +81,19 @@ static int hns_roce_add_gid(struct ib_device *device, u8 
port_num,
        struct hns_roce_dev *hr_dev = to_hr_dev(device);
        u8 port = port_num - 1;
        unsigned long flags;
+       int ret;
 
        if (port >= hr_dev->caps.num_ports)
                return -EINVAL;
 
        spin_lock_irqsave(&hr_dev->iboe.lock, flags);
 
-       hr_dev->hw->set_gid(hr_dev, port, index, (union ib_gid *)gid);
+       ret = hr_dev->hw->set_gid(hr_dev, port, index, (union ib_gid *)gid,
+                                  attr);
 
        spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
 
-       return 0;
+       return ret;
 }
 
 static int hns_roce_del_gid(struct ib_device *device, u8 port_num,
@@ -101,17 +103,18 @@ static int hns_roce_del_gid(struct ib_device *device, u8 
port_num,
        union ib_gid zgid = { {0} };
        u8 port = port_num - 1;
        unsigned long flags;
+       int ret;
 
        if (port >= hr_dev->caps.num_ports)
                return -EINVAL;
 
        spin_lock_irqsave(&hr_dev->iboe.lock, flags);
 
-       hr_dev->hw->set_gid(hr_dev, port, index, &zgid);
+       ret = hr_dev->hw->set_gid(hr_dev, port, index, &zgid, NULL);
 
        spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
 
-       return 0;
+       return ret;
 }
 
 static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
-- 
1.9.1

Reply via email to