aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
diff options
context:
space:
mode:
authoroulijun <oulijun@huawei.com>2016-08-18 08:32:52 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-19 19:58:33 -0400
commite018068812e54c407da599513bf8ad2d99fd0eaf (patch)
treebb018db88fca35dff805193c83dac495f3276fd8 /drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
parenta68d53988bc7f54aa383ecb308e7684c787af67c (diff)
net: hns: Add reset function support for RoCE driver
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. This patch is used to fix the conflict, please refer to this link: https://www.spinics.net/lists/linux-rdma/msg39114.html Signed-off-by: Wei Hu <xavier.huwei@huawei.com> Signed-off-by: Nenglong Zhao <zhaonenglong@hisilicon.com> Signed-off-by: Lijun Ou <oulijun@huawei.com> Signed-off-by: Sheng Li <lisheng011@huawei.com> Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c')
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index afb5daa3721d..05bd19f9ebc5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -18,6 +18,7 @@
18#include <linux/of.h> 18#include <linux/of.h>
19#include <linux/of_address.h> 19#include <linux/of_address.h>
20#include <linux/of_irq.h> 20#include <linux/of_irq.h>
21#include <linux/of_platform.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/vmalloc.h> 23#include <linux/vmalloc.h>
23 24
@@ -2781,6 +2782,89 @@ static struct platform_driver g_dsaf_driver = {
2781 2782
2782module_platform_driver(g_dsaf_driver); 2783module_platform_driver(g_dsaf_driver);
2783 2784
2785/**
2786 * hns_dsaf_roce_reset - reset dsaf and roce
2787 * @dsaf_fwnode: Pointer to framework node for the dasf
2788 * @enable: false - request reset , true - drop reset
2789 * retuen 0 - success , negative -fail
2790 */
2791int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool enable)
2792{
2793 struct dsaf_device *dsaf_dev;
2794 struct platform_device *pdev;
2795 u32 mp;
2796 u32 sl;
2797 u32 credit;
2798 int i;
2799 const u32 port_map[DSAF_ROCE_CREDIT_CHN][DSAF_ROCE_CHAN_MODE_NUM] = {
2800 {DSAF_ROCE_PORT_0, DSAF_ROCE_PORT_0, DSAF_ROCE_PORT_0},
2801 {DSAF_ROCE_PORT_1, DSAF_ROCE_PORT_0, DSAF_ROCE_PORT_0},
2802 {DSAF_ROCE_PORT_2, DSAF_ROCE_PORT_1, DSAF_ROCE_PORT_0},
2803 {DSAF_ROCE_PORT_3, DSAF_ROCE_PORT_1, DSAF_ROCE_PORT_0},
2804 {DSAF_ROCE_PORT_4, DSAF_ROCE_PORT_2, DSAF_ROCE_PORT_1},
2805 {DSAF_ROCE_PORT_4, DSAF_ROCE_PORT_2, DSAF_ROCE_PORT_1},
2806 {DSAF_ROCE_PORT_5, DSAF_ROCE_PORT_3, DSAF_ROCE_PORT_1},
2807 {DSAF_ROCE_PORT_5, DSAF_ROCE_PORT_3, DSAF_ROCE_PORT_1},
2808 };
2809 const u32 sl_map[DSAF_ROCE_CREDIT_CHN][DSAF_ROCE_CHAN_MODE_NUM] = {
2810 {DSAF_ROCE_SL_0, DSAF_ROCE_SL_0, DSAF_ROCE_SL_0},
2811 {DSAF_ROCE_SL_0, DSAF_ROCE_SL_1, DSAF_ROCE_SL_1},
2812 {DSAF_ROCE_SL_0, DSAF_ROCE_SL_0, DSAF_ROCE_SL_2},
2813 {DSAF_ROCE_SL_0, DSAF_ROCE_SL_1, DSAF_ROCE_SL_3},
2814 {DSAF_ROCE_SL_0, DSAF_ROCE_SL_0, DSAF_ROCE_SL_0},
2815 {DSAF_ROCE_SL_1, DSAF_ROCE_SL_1, DSAF_ROCE_SL_1},
2816 {DSAF_ROCE_SL_0, DSAF_ROCE_SL_0, DSAF_ROCE_SL_2},
2817 {DSAF_ROCE_SL_1, DSAF_ROCE_SL_1, DSAF_ROCE_SL_3},
2818 };
2819
2820 if (!is_of_node(dsaf_fwnode)) {
2821 pr_err("hisi_dsaf: Only support DT node!\n");
2822 return -EINVAL;
2823 }
2824 pdev = of_find_device_by_node(to_of_node(dsaf_fwnode));
2825 dsaf_dev = dev_get_drvdata(&pdev->dev);
2826 if (AE_IS_VER1(dsaf_dev->dsaf_ver)) {
2827 dev_err(dsaf_dev->dev, "%s v1 chip doesn't support RoCE!\n",
2828 dsaf_dev->ae_dev.name);
2829 return -ENODEV;
2830 }
2831
2832 if (!enable) {
2833 /* Reset rocee-channels in dsaf and rocee */
2834 hns_dsaf_srst_chns(dsaf_dev, DSAF_CHNS_MASK, false);
2835 hns_dsaf_roce_srst(dsaf_dev, false);
2836 } else {
2837 /* Configure dsaf tx roce correspond to port map and sl map */
2838 mp = dsaf_read_dev(dsaf_dev, DSAF_ROCE_PORT_MAP_REG);
2839 for (i = 0; i < DSAF_ROCE_CREDIT_CHN; i++)
2840 dsaf_set_field(mp, 7 << i * 3, i * 3,
2841 port_map[i][DSAF_ROCE_6PORT_MODE]);
2842 dsaf_set_field(mp, 3 << i * 3, i * 3, 0);
2843 dsaf_write_dev(dsaf_dev, DSAF_ROCE_PORT_MAP_REG, mp);
2844
2845 sl = dsaf_read_dev(dsaf_dev, DSAF_ROCE_SL_MAP_REG);
2846 for (i = 0; i < DSAF_ROCE_CREDIT_CHN; i++)
2847 dsaf_set_field(sl, 3 << i * 2, i * 2,
2848 sl_map[i][DSAF_ROCE_6PORT_MODE]);
2849 dsaf_write_dev(dsaf_dev, DSAF_ROCE_SL_MAP_REG, sl);
2850
2851 /* De-reset rocee-channels in dsaf and rocee */
2852 hns_dsaf_srst_chns(dsaf_dev, DSAF_CHNS_MASK, true);
2853 msleep(SRST_TIME_INTERVAL);
2854 hns_dsaf_roce_srst(dsaf_dev, true);
2855
2856 /* Eanble dsaf channel rocee credit */
2857 credit = dsaf_read_dev(dsaf_dev, DSAF_SBM_ROCEE_CFG_REG_REG);
2858 dsaf_set_bit(credit, DSAF_SBM_ROCEE_CFG_CRD_EN_B, 0);
2859 dsaf_write_dev(dsaf_dev, DSAF_SBM_ROCEE_CFG_REG_REG, credit);
2860
2861 dsaf_set_bit(credit, DSAF_SBM_ROCEE_CFG_CRD_EN_B, 1);
2862 dsaf_write_dev(dsaf_dev, DSAF_SBM_ROCEE_CFG_REG_REG, credit);
2863 }
2864 return 0;
2865}
2866EXPORT_SYMBOL(hns_dsaf_roce_reset);
2867
2784MODULE_LICENSE("GPL"); 2868MODULE_LICENSE("GPL");
2785MODULE_AUTHOR("Huawei Tech. Co., Ltd."); 2869MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
2786MODULE_DESCRIPTION("HNS DSAF driver"); 2870MODULE_DESCRIPTION("HNS DSAF driver");