From: Chengchang Tang <tangchengchang@huawei.com> Support setting GSI QP SL by sysfs. Signed-off-by: Chengchang Tang <tangchengchang@huawei.com> --- drivers/infiniband/hw/hns/hns_roce_device.h | 1 + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 5 +- drivers/infiniband/hw/hns/hns_roce_sysfs.c | 63 +++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 245fe626a267..7368ef1e9e3a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1142,6 +1142,7 @@ struct hns_roce_dev { void *dca_safe_buf; dma_addr_t dca_safe_page; siphash_key_t dca_safe_hash_key; + u8 gsi_sl; }; enum hns_roce_trace_type { diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 312aeccfed1f..feaa03ab3a43 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -516,8 +516,9 @@ static int fill_ud_av(struct hns_roce_qp *qp, hr_reg_write(ud_sq_wqe, UD_SEND_WQE_HOPLIMIT, ah->av.hop_limit); hr_reg_write(ud_sq_wqe, UD_SEND_WQE_TCLASS, ah->av.tclass); hr_reg_write(ud_sq_wqe, UD_SEND_WQE_FLOW_LABEL, ah->av.flowlabel); - if (!qp->ud_sl_set) { - qp->sl = ah->av.sl; + if (!qp->ud_sl_set || qp->ibqp.qp_type == IB_QPT_GSI) { + qp->sl = qp->ibqp.qp_type == IB_QPT_GSI ? + hr_dev->gsi_sl : ah->av.sl; qp->ud_sl_set = true; } diff --git a/drivers/infiniband/hw/hns/hns_roce_sysfs.c b/drivers/infiniband/hw/hns/hns_roce_sysfs.c index cd498c5ea417..054e08df0187 100644 --- a/drivers/infiniband/hw/hns/hns_roce_sysfs.c +++ b/drivers/infiniband/hw/hns/hns_roce_sysfs.c @@ -348,10 +348,73 @@ static const struct attribute_group dip_cc_param_group = { .is_visible = scc_attr_is_visible, }; +static umode_t gsi_sl_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int i) +{ + return 0600; +} + +static ssize_t gsi_sl_attr_show(struct ib_device *ibdev, u32 port_num, + struct ib_port_attribute *attr, char *buf) +{ + struct hns_roce_dev *hr_dev = to_hr_dev(ibdev); + + return sysfs_emit(buf, "%u\n", hr_dev->gsi_sl); +} + +static ssize_t gsi_sl_attr_store(struct ib_device *ibdev, u32 port_num, + struct ib_port_attribute *attr, + const char *buf, size_t count) +{ + struct hns_roce_dev *hr_dev = to_hr_dev(ibdev); + struct net_device *netdev; + u32 val; + int ret; + + netdev = ib_device_get_netdev(ibdev, port_num); + if (!netdev) + return -ENODEV; + + if (ib_get_curr_port_state(netdev) == IB_PORT_ACTIVE) { + ret = -EOPNOTSUPP; + goto out; + } + + ret = kstrtou32(buf, 0, &val); + if (ret) + goto out; + + if (val > MAX_SERVICE_LEVEL) { + ret = -EINVAL; + goto out; + } + + hr_dev->gsi_sl = val; + +out: + dev_put(netdev); + return ret ? : count; +} + +static struct ib_port_attribute hns_roce_port_attr_gsi_sl = + __ATTR(sl, 0600, gsi_sl_attr_show, gsi_sl_attr_store); + +static struct attribute *gsi_sl_param_attrs[] = { + &hns_roce_port_attr_gsi_sl.attr, + NULL, +}; + +static const struct attribute_group gsi_sl_param_group = { + .name = "gsi_sl", + .attrs = gsi_sl_param_attrs, + .is_visible = gsi_sl_attr_is_visible, +}; + const struct attribute_group *hns_attr_port_groups[] = { &dcqcn_cc_param_group, &ldcp_cc_param_group, &hc3_cc_param_group, &dip_cc_param_group, + &gsi_sl_param_group, NULL, }; -- 2.33.0