diff options
author | Salil <salil.mehta@huawei.com> | 2016-08-24 04:44:49 +0800 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-08-25 10:05:10 -0400 |
commit | d605916b76593417340397fe281acd2e8a953706 (patch) | |
tree | 2f8b179281043aa8874ad1a85d0be33f6cbba3be /drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | |
parent | 204f69ba64122b1ee6732bab8cfd71fe2d68c188 (diff) |
net: hns: Add support of ACPI to HNS driver RoCE Reset function
In the Hip06 SoC, the RoCE Engine is part of the Hisilicon Network
Subsystem and is dependent upon DSAF module. Therefore, certain
functions like RESET are exposed through the common registers of
HNS DSAF module which are memory-mapped by the HNS driver and
currently can only be accessed through DT/syscon interface.
This patch adds the support of ACPI to the existing RoCE reset
function in the HNS driver(please refer NOTE 2). Hisilicon RoCE
driver (please refer NOTE 1) shall call this reset function during
probe time to reset the RoCE Engine.
The HNS Reset function indirectly ends up in calling the _DSM()
function part of the DSDT ACPI Table. Actual reset functionality
for ACPI is implemented within the ACPI DSDT Table which also has
been enhanced to support this change.
Support of ACPI in the HNS RoCE driver shall be pushed through a
different accompanying below patch:
"IB/hns: Add support of ACPI to the Hisilicon RoCE Driver"
NOTE 1: HNS RoCE driver has already been accepted by its maintainer
Doug Ledford<dledford@redhat.com>. Please refer below link:
https://www.spinics.net/lists/linux-rdma/msg38850.html
NOTE 2: RoCE reset function patch has been accepted and now is
part of the net-next:
https://www.mail-archive.com/netdev@vger.kernel.org/msg123867.html
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c')
-rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index 05bd19f9ebc5..9283bc60bb24 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -2788,7 +2788,7 @@ module_platform_driver(g_dsaf_driver); * @enable: false - request reset , true - drop reset * retuen 0 - success , negative -fail */ -int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool enable) +int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool dereset) { struct dsaf_device *dsaf_dev; struct platform_device *pdev; @@ -2817,24 +2817,44 @@ int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool enable) {DSAF_ROCE_SL_1, DSAF_ROCE_SL_1, DSAF_ROCE_SL_3}, }; - if (!is_of_node(dsaf_fwnode)) { - pr_err("hisi_dsaf: Only support DT node!\n"); + /* find the platform device corresponding to fwnode */ + if (is_of_node(dsaf_fwnode)) { + pdev = of_find_device_by_node(to_of_node(dsaf_fwnode)); + } else if (is_acpi_device_node(dsaf_fwnode)) { + pdev = hns_dsaf_find_platform_device(dsaf_fwnode); + } else { + pr_err("fwnode is neither OF or ACPI type\n"); return -EINVAL; } - pdev = of_find_device_by_node(to_of_node(dsaf_fwnode)); + + /* check if we were a success in fetching pdev */ + if (!pdev) { + pr_err("couldn't find platform device for node\n"); + return -ENODEV; + } + + /* retrieve the dsaf_device from the driver data */ dsaf_dev = dev_get_drvdata(&pdev->dev); + if (!dsaf_dev) { + dev_err(&pdev->dev, "dsaf_dev is NULL\n"); + return -ENODEV; + } + + /* now, make sure we are running on compatible SoC */ if (AE_IS_VER1(dsaf_dev->dsaf_ver)) { dev_err(dsaf_dev->dev, "%s v1 chip doesn't support RoCE!\n", dsaf_dev->ae_dev.name); return -ENODEV; } - if (!enable) { - /* Reset rocee-channels in dsaf and rocee */ - hns_dsaf_srst_chns(dsaf_dev, DSAF_CHNS_MASK, false); - hns_dsaf_roce_srst(dsaf_dev, false); + /* do reset or de-reset according to the flag */ + if (!dereset) { + /* reset rocee-channels in dsaf and rocee */ + dsaf_dev->misc_op->hns_dsaf_srst_chns(dsaf_dev, DSAF_CHNS_MASK, + false); + dsaf_dev->misc_op->hns_dsaf_roce_srst(dsaf_dev, false); } else { - /* Configure dsaf tx roce correspond to port map and sl map */ + /* 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, @@ -2848,12 +2868,13 @@ int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool enable) 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, DSAF_CHNS_MASK, true); + /* de-reset rocee-channels in dsaf and rocee */ + dsaf_dev->misc_op->hns_dsaf_srst_chns(dsaf_dev, DSAF_CHNS_MASK, + true); msleep(SRST_TIME_INTERVAL); - hns_dsaf_roce_srst(dsaf_dev, true); + dsaf_dev->misc_op->hns_dsaf_roce_srst(dsaf_dev, true); - /* Eanble dsaf channel rocee credit */ + /* enable 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); |