net: hns: separate debug dsaf device from service dsaf device
[deliverable/linux.git] / drivers / net / ethernet / hisilicon / hns / hns_dsaf_main.c
index 5978a5c8ef35e139bb4af766954e8d8f39f8b1ba..33cdb215a547a60007656c5d63e7eeee03089ace 100644 (file)
@@ -7,27 +7,29 @@
  * (at your option) any later version.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
-#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/vmalloc.h>
 
+#include "hns_dsaf_mac.h"
 #include "hns_dsaf_main.h"
-#include "hns_dsaf_rcb.h"
 #include "hns_dsaf_ppe.h"
-#include "hns_dsaf_mac.h"
+#include "hns_dsaf_rcb.h"
 
 const char *g_dsaf_mode_match[DSAF_MODE_MAX] = {
        [DSAF_MODE_DISABLE_2PORT_64VM] = "2port-64vf",
        [DSAF_MODE_DISABLE_6PORT_0VM] = "6port-16rss",
        [DSAF_MODE_DISABLE_6PORT_16VM] = "6port-16vf",
+       [DSAF_MODE_DISABLE_SP] = "single-port",
 };
 
 int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
@@ -35,8 +37,13 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
        int ret, i;
        u32 desc_num;
        u32 buf_size;
+       u32 reset_offset = 0;
+       u32 res_idx = 0;
        const char *mode_str;
+       struct regmap *syscon;
+       struct resource *res;
        struct device_node *np = dsaf_dev->dev->of_node;
+       struct platform_device *pdev = to_platform_device(dsaf_dev->dev);
 
        if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1"))
                dsaf_dev->dsaf_ver = AE_VERSION_1;
@@ -73,42 +80,68 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
        else
                dsaf_dev->dsaf_tc_mode = HRD_DSAF_4TC_MODE;
 
-       dsaf_dev->sc_base = of_iomap(np, 0);
-       if (!dsaf_dev->sc_base) {
-               dev_err(dsaf_dev->dev,
-                       "%s of_iomap 0 fail!\n", dsaf_dev->ae_dev.name);
-               ret = -ENOMEM;
-               goto unmap_base_addr;
-       }
+       syscon = syscon_node_to_regmap(
+                       of_parse_phandle(np, "subctrl-syscon", 0));
+       if (IS_ERR_OR_NULL(syscon)) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++);
+               if (!res) {
+                       dev_err(dsaf_dev->dev, "subctrl info is needed!\n");
+                       return -ENOMEM;
+               }
+               dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev, res);
+               if (!dsaf_dev->sc_base) {
+                       dev_err(dsaf_dev->dev, "subctrl can not map!\n");
+                       return -ENOMEM;
+               }
 
-       dsaf_dev->sds_base = of_iomap(np, 1);
-       if (!dsaf_dev->sds_base) {
-               dev_err(dsaf_dev->dev,
-                       "%s of_iomap 1 fail!\n", dsaf_dev->ae_dev.name);
-               ret = -ENOMEM;
-               goto unmap_base_addr;
+               res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++);
+               if (!res) {
+                       dev_err(dsaf_dev->dev, "serdes-ctrl info is needed!\n");
+                       return -ENOMEM;
+               }
+               dsaf_dev->sds_base = devm_ioremap_resource(&pdev->dev, res);
+               if (!dsaf_dev->sds_base) {
+                       dev_err(dsaf_dev->dev, "serdes-ctrl can not map!\n");
+                       return -ENOMEM;
+               }
+       } else {
+               dsaf_dev->sub_ctrl = syscon;
        }
 
-       dsaf_dev->ppe_base = of_iomap(np, 2);
-       if (!dsaf_dev->ppe_base) {
-               dev_err(dsaf_dev->dev,
-                       "%s of_iomap 2 fail!\n", dsaf_dev->ae_dev.name);
-               ret = -ENOMEM;
-               goto unmap_base_addr;
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe-base");
+       if (!res) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++);
+               if (!res) {
+                       dev_err(dsaf_dev->dev, "ppe-base info is needed!\n");
+                       return -ENOMEM;
+               }
        }
-
-       dsaf_dev->io_base = of_iomap(np, 3);
-       if (!dsaf_dev->io_base) {
-               dev_err(dsaf_dev->dev,
-                       "%s of_iomap 3 fail!\n", dsaf_dev->ae_dev.name);
-               ret = -ENOMEM;
-               goto unmap_base_addr;
+       dsaf_dev->ppe_base = devm_ioremap_resource(&pdev->dev, res);
+       if (!dsaf_dev->ppe_base) {
+               dev_err(dsaf_dev->dev, "ppe-base resource can not map!\n");
+               return -ENOMEM;
+       }
+       dsaf_dev->ppe_paddr = res->start;
+
+       if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
+               res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                  "dsaf-base");
+               if (!res) {
+                       res = platform_get_resource(pdev, IORESOURCE_MEM,
+                                                   res_idx);
+                       if (!res) {
+                               dev_err(dsaf_dev->dev,
+                                       "dsaf-base info is needed!\n");
+                               return -ENOMEM;
+                       }
+               }
+               dsaf_dev->io_base = devm_ioremap_resource(&pdev->dev, res);
+               if (!dsaf_dev->io_base) {
+                       dev_err(dsaf_dev->dev, "dsaf-base resource can not map!\n");
+                       return -ENOMEM;
+               }
        }
 
-       dsaf_dev->cpld_base = of_iomap(np, 4);
-       if (!dsaf_dev->cpld_base)
-               dev_dbg(dsaf_dev->dev, "NO CPLD ADDR");
-
        ret = of_property_read_u32(np, "desc-num", &desc_num);
        if (ret < 0 || desc_num < HNS_DSAF_MIN_DESC_CNT ||
            desc_num > HNS_DSAF_MAX_DESC_CNT) {
@@ -118,6 +151,13 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
        }
        dsaf_dev->desc_num = desc_num;
 
+       ret = of_property_read_u32(np, "reset-field-offset", &reset_offset);
+       if (ret < 0) {
+               dev_dbg(dsaf_dev->dev,
+                       "get reset-field-offset fail, ret=%d!\r\n", ret);
+       }
+       dsaf_dev->reset_offset = reset_offset;
+
        ret = of_property_read_u32(np, "buf-size", &buf_size);
        if (ret < 0) {
                dev_err(dsaf_dev->dev,
@@ -217,9 +257,7 @@ static void hns_dsaf_mix_def_qid_cfg(struct dsaf_device *dsaf_dev)
        u32 q_id, q_num_per_port;
        u32 i;
 
-       hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode,
-                              HNS_DSAF_COMM_SERVICE_NW_IDX,
-                              &max_vfn, &max_q_per_vf);
+       hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode, &max_vfn, &max_q_per_vf);
        q_num_per_port = max_vfn * max_q_per_vf;
 
        for (i = 0, q_id = 0; i < DSAF_SERVICE_NW_NUM; i++) {
@@ -239,9 +277,7 @@ static void hns_dsaf_inner_qid_cfg(struct dsaf_device *dsaf_dev)
        if (AE_IS_VER1(dsaf_dev->dsaf_ver))
                return;
 
-       hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode,
-                              HNS_DSAF_COMM_SERVICE_NW_IDX,
-                              &max_vfn, &max_q_per_vf);
+       hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode, &max_vfn, &max_q_per_vf);
        q_num_per_port = max_vfn * max_q_per_vf;
 
        for (mac_id = 0, q_id = 0; mac_id < DSAF_SERVICE_NW_NUM; mac_id++) {
@@ -712,13 +748,15 @@ static void hns_dsaf_tbl_tcam_data_ucast_pul(
 
 void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en)
 {
-       dsaf_set_dev_bit(dsaf_dev, DSAF_CFG_0_REG, DSAF_CFG_MIX_MODE_S, !!en);
+       if (!HNS_DSAF_IS_DEBUG(dsaf_dev))
+               dsaf_set_dev_bit(dsaf_dev, DSAF_CFG_0_REG,
+                                DSAF_CFG_MIX_MODE_S, !!en);
 }
 
 void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en)
 {
        if (AE_IS_VER1(dsaf_dev->dsaf_ver) ||
-           dsaf_dev->mac_cb[mac_id].mac_type == HNAE_PORT_DEBUG)
+           dsaf_dev->mac_cb[mac_id]->mac_type == HNAE_PORT_DEBUG)
                return;
 
        dsaf_set_dev_bit(dsaf_dev, DSAFV2_SERDES_LBK_0_REG + 4 * mac_id,
@@ -1022,12 +1060,52 @@ static void hns_dsaf_tbl_tcam_init(struct dsaf_device *dsaf_dev)
  * @mac_cb: mac contrl block
  */
 static void hns_dsaf_pfc_en_cfg(struct dsaf_device *dsaf_dev,
-                               int mac_id, int en)
+                               int mac_id, int tc_en)
+{
+       dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, tc_en);
+}
+
+static void hns_dsaf_set_pfc_pause(struct dsaf_device *dsaf_dev,
+                                  int mac_id, int tx_en, int rx_en)
+{
+       if (AE_IS_VER1(dsaf_dev->dsaf_ver)) {
+               if (!tx_en || !rx_en)
+                       dev_err(dsaf_dev->dev, "dsaf v1 can not close pfc!\n");
+
+               return;
+       }
+
+       dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4,
+                        DSAF_PFC_PAUSE_RX_EN_B, !!rx_en);
+       dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4,
+                        DSAF_PFC_PAUSE_TX_EN_B, !!tx_en);
+}
+
+int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
+                                u32 en)
 {
-       if (!en)
-               dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, 0);
+       if (AE_IS_VER1(dsaf_dev->dsaf_ver)) {
+               if (!en)
+                       dev_err(dsaf_dev->dev, "dsafv1 can't close rx_pause!\n");
+
+               return -EINVAL;
+       }
+
+       dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4,
+                        DSAF_MAC_PAUSE_RX_EN_B, !!en);
+
+       return 0;
+}
+
+void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
+                                 u32 *en)
+{
+       if (AE_IS_VER1(dsaf_dev->dsaf_ver))
+               *en = 1;
        else
-               dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, 0xff);
+               *en = dsaf_get_dev_bit(dsaf_dev,
+                                      DSAF_PAUSE_CFG_REG + mac_id * 4,
+                                      DSAF_MAC_PAUSE_RX_EN_B);
 }
 
 /**
@@ -1039,6 +1117,7 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev)
 {
        u32 i;
        u32 o_dsaf_cfg;
+       bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver);
 
        o_dsaf_cfg = dsaf_read_dev(dsaf_dev, DSAF_CFG_0_REG);
        dsaf_set_bit(o_dsaf_cfg, DSAF_CFG_EN_S, dsaf_dev->dsaf_en);
@@ -1064,8 +1143,10 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev)
        hns_dsaf_sw_port_type_cfg(dsaf_dev, DSAF_SW_PORT_TYPE_NON_VLAN);
 
        /*set dsaf pfc  to 0 for parseing rx pause*/
-       for (i = 0; i < DSAF_COMM_CHN; i++)
+       for (i = 0; i < DSAF_COMM_CHN; i++) {
                hns_dsaf_pfc_en_cfg(dsaf_dev, i, 0);
+               hns_dsaf_set_pfc_pause(dsaf_dev, i, is_ver1, is_ver1);
+       }
 
        /*msk and  clr exception irqs */
        for (i = 0; i < DSAF_COMM_CHN; i++) {
@@ -1264,6 +1345,9 @@ static int hns_dsaf_init(struct dsaf_device *dsaf_dev)
        u32 i;
        int ret;
 
+       if (HNS_DSAF_IS_DEBUG(dsaf_dev))
+               return 0;
+
        ret = hns_dsaf_init_hw(dsaf_dev);
        if (ret)
                return ret;
@@ -2013,6 +2097,8 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num)
 {
        struct dsaf_hw_stats *hw_stats
                = &dsaf_dev->hw_stats[node_num];
+       bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver);
+       u32 reg_tmp;
 
        hw_stats->pad_drop += dsaf_read_dev(dsaf_dev,
                DSAF_INODE_PAD_DISCARD_NUM_0_REG + 0x80 * (u64)node_num);
@@ -2022,8 +2108,12 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num)
                DSAF_INODE_FINAL_IN_PKT_NUM_0_REG + 0x80 * (u64)node_num);
        hw_stats->rx_pkt_id += dsaf_read_dev(dsaf_dev,
                DSAF_INODE_SBM_PID_NUM_0_REG + 0x80 * (u64)node_num);
-       hw_stats->rx_pause_frame += dsaf_read_dev(dsaf_dev,
-               DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG + 0x80 * (u64)node_num);
+
+       reg_tmp = is_ver1 ? DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG :
+                           DSAFV2_INODE_FINAL_IN_PAUSE_NUM_0_REG;
+       hw_stats->rx_pause_frame +=
+               dsaf_read_dev(dsaf_dev, reg_tmp + 0x80 * (u64)node_num);
+
        hw_stats->release_buf_num += dsaf_read_dev(dsaf_dev,
                DSAF_INODE_SBM_RELS_NUM_0_REG + 0x80 * (u64)node_num);
        hw_stats->sbm_drop += dsaf_read_dev(dsaf_dev,
@@ -2056,6 +2146,8 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data)
        u32 i = 0;
        u32 j;
        u32 *p = data;
+       u32 reg_tmp;
+       bool is_ver1 = AE_IS_VER1(ddev->dsaf_ver);
 
        /* dsaf common registers */
        p[0] = dsaf_read_dev(ddev, DSAF_SRAM_INIT_OVER_0_REG);
@@ -2120,8 +2212,9 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data)
                                DSAF_INODE_FINAL_IN_PKT_NUM_0_REG + j * 0x80);
                p[190 + i] = dsaf_read_dev(ddev,
                                DSAF_INODE_SBM_PID_NUM_0_REG + j * 0x80);
-               p[193 + i] = dsaf_read_dev(ddev,
-                               DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG + j * 0x80);
+               reg_tmp = is_ver1 ? DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG :
+                                   DSAFV2_INODE_FINAL_IN_PAUSE_NUM_0_REG;
+               p[193 + i] = dsaf_read_dev(ddev, reg_tmp + j * 0x80);
                p[196 + i] = dsaf_read_dev(ddev,
                                DSAF_INODE_SBM_RELS_NUM_0_REG + j * 0x80);
                p[199 + i] = dsaf_read_dev(ddev,
@@ -2368,8 +2461,11 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data)
        p[496] = dsaf_read_dev(ddev, DSAF_NETPORT_CTRL_SIG_0_REG + port * 0x4);
        p[497] = dsaf_read_dev(ddev, DSAF_XGE_CTRL_SIG_CFG_0_REG + port * 0x4);
 
+       if (!is_ver1)
+               p[498] = dsaf_read_dev(ddev, DSAF_PAUSE_CFG_REG + port * 0x4);
+
        /* mark end of dsaf regs */
-       for (i = 498; i < 504; i++)
+       for (i = 499; i < 504; i++)
                p[i] = 0xdddddddd;
 }
 
This page took 0.028573 seconds and 5 git commands to generate.