]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/hns: Add bonding cmds
authorJunxian Huang <huangjunxian6@hisilicon.com>
Wed, 12 Nov 2025 09:35:06 +0000 (17:35 +0800)
committerLeon Romanovsky <leon@kernel.org>
Mon, 24 Nov 2025 07:58:29 +0000 (02:58 -0500)
Add three bonding cmds to configure bonding settings to HW.

Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
Link: https://patch.msgid.link/20251112093510.3696363-5-huangjunxian6@hisilicon.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/hns/hns_roce_bond.h
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.h

index a11de04c42e9f2c2f139843567ce50905fecc598..84c94cbc397d158ed8e2bc59160a4c2bb671b76a 100644 (file)
 
 #define BOND_ID(id) BIT(id)
 
+enum {
+       BOND_MODE_1,
+       BOND_MODE_2_4,
+};
+
+enum hns_roce_bond_hashtype {
+       BOND_HASH_L2,
+       BOND_HASH_L34,
+       BOND_HASH_L23,
+};
+
 enum bond_support_type {
        BOND_NOT_SUPPORT,
        /*
@@ -32,6 +43,12 @@ enum hns_roce_bond_state {
        HNS_ROCE_BOND_SLAVE_CHANGESTATE,
 };
 
+enum hns_roce_bond_cmd_type {
+       HNS_ROCE_SET_BOND,
+       HNS_ROCE_CHANGE_BOND,
+       HNS_ROCE_CLEAR_BOND,
+};
+
 struct hns_roce_func_info {
        struct net_device *net_dev;
        struct hnae3_handle *handle;
@@ -40,6 +57,9 @@ struct hns_roce_func_info {
 struct hns_roce_bond_group {
        struct net_device *upper_dev;
        struct hns_roce_dev *main_hr_dev;
+       u8 active_slave_num;
+       u32 slave_map;
+       u32 active_slave_map;
        u8 bond_id;
        u8 bus_num;
        struct hns_roce_func_info bond_func_info[ROCE_BOND_FUNC_MAX];
index 6750bad9bb53b94974ca691c8427fcbf214a4637..2952684011a92c77ff7ca26314c3deedc0918b25 100644 (file)
@@ -1431,6 +1431,79 @@ static int hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
        return ret;
 }
 
+static enum hns_roce_opcode_type
+       get_bond_opcode(enum hns_roce_bond_cmd_type bond_type)
+{
+       switch (bond_type) {
+       case HNS_ROCE_SET_BOND:
+               return HNS_ROCE_OPC_SET_BOND_INFO;
+       case HNS_ROCE_CHANGE_BOND:
+               return HNS_ROCE_OPC_CHANGE_ACTIVE_PORT;
+       case HNS_ROCE_CLEAR_BOND:
+               return HNS_ROCE_OPC_CLEAR_BOND_INFO;
+       default:
+               WARN(true, "Invalid bond type %d!\n", bond_type);
+               return HNS_ROCE_OPC_SET_BOND_INFO;
+       }
+}
+
+static enum hns_roce_bond_hashtype
+       get_bond_hashtype(enum netdev_lag_hash netdev_hashtype)
+{
+       switch (netdev_hashtype) {
+       case NETDEV_LAG_HASH_L2:
+               return BOND_HASH_L2;
+       case NETDEV_LAG_HASH_L34:
+               return BOND_HASH_L34;
+       case NETDEV_LAG_HASH_L23:
+               return BOND_HASH_L23;
+       default:
+               WARN(true, "Invalid hash type %d!\n", netdev_hashtype);
+               return BOND_HASH_L2;
+       }
+}
+
+int hns_roce_cmd_bond(struct hns_roce_bond_group *bond_grp,
+                     enum hns_roce_bond_cmd_type bond_type)
+{
+       enum hns_roce_opcode_type opcode = get_bond_opcode(bond_type);
+       struct hns_roce_bond_info *slave_info;
+       struct hns_roce_cmq_desc desc = {};
+       int ret;
+
+       slave_info = (struct hns_roce_bond_info *)desc.data;
+       hns_roce_cmq_setup_basic_desc(&desc, opcode, false);
+
+       slave_info->bond_id = cpu_to_le32(bond_grp->bond_id);
+       if (bond_type == HNS_ROCE_CLEAR_BOND)
+               goto out;
+
+       if (bond_grp->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
+               slave_info->bond_mode = cpu_to_le32(BOND_MODE_1);
+               if (bond_grp->active_slave_num != 1)
+                       ibdev_warn(&bond_grp->main_hr_dev->ib_dev,
+                                  "active slave cnt(%u) in Mode 1 is invalid.\n",
+                                  bond_grp->active_slave_num);
+       } else {
+               slave_info->bond_mode = cpu_to_le32(BOND_MODE_2_4);
+               slave_info->hash_policy =
+                       cpu_to_le32(get_bond_hashtype(bond_grp->hash_type));
+       }
+
+       slave_info->active_slave_cnt = cpu_to_le32(bond_grp->active_slave_num);
+       slave_info->active_slave_mask = cpu_to_le32(bond_grp->active_slave_map);
+       slave_info->slave_mask = cpu_to_le32(bond_grp->slave_map);
+
+out:
+       ret = hns_roce_cmq_send(bond_grp->main_hr_dev, &desc, 1);
+       if (ret)
+               ibdev_err(&bond_grp->main_hr_dev->ib_dev,
+                         "cmq bond type(%d) failed, ret = %d.\n",
+                         bond_type, ret);
+
+       return ret;
+}
+
 static int config_hem_ba_to_hw(struct hns_roce_dev *hr_dev,
                               dma_addr_t base_addr, u8 cmd, unsigned long tag)
 {
index e64a04d6f85b7d48a50481f3befa8d45cda3af82..82cec4b38c924806a3478afeb98f9a647c124456 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/bitops.h>
 #include "hnae3.h"
+#include "hns_roce_bond.h"
 
 #define HNS_ROCE_V2_MAX_RC_INL_INN_SZ          32
 #define HNS_ROCE_V2_MTT_ENTRY_SZ               64
@@ -228,6 +229,9 @@ enum hns_roce_opcode_type {
        HNS_ROCE_OPC_CFG_GMV_BT                         = 0x8510,
        HNS_ROCE_QUERY_RAM_ECC                          = 0x8513,
        HNS_SWITCH_PARAMETER_CFG                        = 0x1033,
+       HNS_ROCE_OPC_SET_BOND_INFO                      = 0x8601,
+       HNS_ROCE_OPC_CLEAR_BOND_INFO                    = 0x8602,
+       HNS_ROCE_OPC_CHANGE_ACTIVE_PORT                 = 0x8603,
 };
 
 #define HNS_ROCE_OPC_POST_MB_TIMEOUT 35000
@@ -1465,7 +1469,18 @@ struct hns_roce_sccc_clr_done {
        __le32 rsv[5];
 };
 
+struct hns_roce_bond_info {
+       __le32 bond_id;
+       __le32 bond_mode;
+       __le32 active_slave_cnt;
+       __le32 active_slave_mask;
+       __le32 slave_mask;
+       __le32 hash_policy;
+};
+
 int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
+int hns_roce_cmd_bond(struct hns_roce_bond_group *bond_grp,
+                     enum hns_roce_bond_cmd_type bond_type);
 
 static inline void hns_roce_write64(struct hns_roce_dev *hr_dev, __le32 val[2],
                                    void __iomem *dest)