[patch v2 net-next 12/13] net: hns: implement the miscellaneous operation by asl

2016-05-29 Thread Kejian Yan
The miscellaneous operation is implemented in BIOS, the kernel can call
_DSM method help to call the implementation in ACPI case. Here is a patch
to do that.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
change log:
 v2: use a serial function to implement the reset sequence

 v1: first submit
  link: https://lkml.org/lkml/2016/5/13/94
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 167 +
 1 file changed, 167 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
index f21177b..96cb628 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
@@ -12,6 +12,27 @@
 #include "hns_dsaf_ppe.h"
 #include "hns_dsaf_reg.h"
 
+enum _dsm_op_index {
+   HNS_OP_RESET_FUNC   = 0x1,
+   HNS_OP_SERDES_LP_FUNC   = 0x2,
+   HNS_OP_LED_SET_FUNC = 0x3,
+   HNS_OP_GET_PORT_TYPE_FUNC   = 0x4,
+   HNS_OP_GET_SFP_STAT_FUNC= 0x5,
+};
+
+enum _dsm_rst_type {
+   HNS_DSAF_RESET_FUNC = 0x1,
+   HNS_PPE_RESET_FUNC  = 0x2,
+   HNS_XGE_CORE_RESET_FUNC = 0x3,
+   HNS_XGE_RESET_FUNC  = 0x4,
+   HNS_GE_RESET_FUNC   = 0x5,
+};
+
+const u8 hns_dsaf_acpi_dsm_uuid[] = {
+   0x1A, 0xAA, 0x85, 0x1A, 0x93, 0xE2, 0x5E, 0x41,
+   0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A
+};
+
 static void dsaf_write_sub(struct dsaf_device *dsaf_dev, u32 reg, u32 val)
 {
if (dsaf_dev->sub_ctrl)
@@ -109,6 +130,34 @@ static int cpld_set_led_id(struct hns_mac_cb *mac_cb,
 
 #define RESET_REQ_OR_DREQ 1
 
+static void hns_dsaf_acpi_srst_by_port(struct dsaf_device *dsaf_dev, u8 
op_type,
+  u32 port_type, u32 port, u32 val)
+{
+   union acpi_object *obj;
+   union acpi_object obj_args[3], argv4;
+
+   obj_args[0].integer.type = ACPI_TYPE_INTEGER;
+   obj_args[0].integer.value = port_type;
+   obj_args[1].integer.type = ACPI_TYPE_INTEGER;
+   obj_args[1].integer.value = port;
+   obj_args[2].integer.type = ACPI_TYPE_INTEGER;
+   obj_args[2].integer.value = val;
+
+   argv4.type = ACPI_TYPE_PACKAGE;
+   argv4.package.count = 3;
+   argv4.package.elements = obj_args;
+
+   obj = acpi_evaluate_dsm(ACPI_HANDLE(dsaf_dev->dev),
+   hns_dsaf_acpi_dsm_uuid, 0, op_type, );
+   if (!obj) {
+   dev_warn(dsaf_dev->dev, "reset port_type%d port%d fail!",
+port_type, port);
+   return;
+   }
+
+   ACPI_FREE(obj);
+}
+
 static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, bool dereset)
 {
u32 xbar_reg_addr;
@@ -126,6 +175,13 @@ static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, 
bool dereset)
dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ);
 }
 
+static void hns_dsaf_rst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
+{
+   hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
+  HNS_DSAF_RESET_FUNC,
+  0, dereset);
+}
+
 static void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
  bool dereset)
 {
@@ -146,6 +202,13 @@ static void hns_dsaf_xge_srst_by_port(struct dsaf_device 
*dsaf_dev, u32 port,
dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
 }
 
+static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
+  u32 port, bool dereset)
+{
+   hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
+  HNS_XGE_RESET_FUNC, port, dereset);
+}
+
 static void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
   u32 port, bool dereset)
 {
@@ -166,6 +229,14 @@ static void hns_dsaf_xge_core_srst_by_port(struct 
dsaf_device *dsaf_dev,
dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
 }
 
+static void
+hns_dsaf_xge_core_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
+   u32 port, bool dereset)
+{
+   hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
+  HNS_XGE_CORE_RESET_FUNC, port, dereset);
+}
+
 static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
 bool dereset)
 {
@@ -218,6 +289,13 @@ static void hns_dsaf_ge_srst_by_port(struct dsaf_device 
*dsaf_dev, u32 port,
}
 }
 
+static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
+ u32 port, bool dereset)
+{
+   hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
+  HNS_GE_RESET_FUNC, port, dereset);
+}
+
 static void hns_ppe_

[patch v2 net-next 04/13] net: hisilicon: add support of acpi for hns-mdio

2016-05-29 Thread Kejian Yan
hns-mdio needs to register itself to mii-bus. The info of the device can
be read by both DT and ACPI.
HNS tries to call Linux PHY driver to help access PHY-devices, the HNS
hardware topology is as below. The MDIO controller may control several
PHY-devices, and each PHY-device connects to a MAC device. The MDIO will
be registered to mdiobus, then PHY-devices will register when each mac
find PHY device.
   cpu
|
|
 ---
|   |   |
|   |   |
|  dsaf |
   MDIO |  MDIO
|  ---  |
| | | |   | |
| | | |   | |
|MAC   MAC   MAC MAC|
| | | |   | |
  | | |   | 
 ||||||   ||
 PHY   PHY   PHY PHY

And the driver can handle reset sequence by _RST method in DSDT in ACPI
case.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
change log:
 v2:
1. use dev_of_node instead of IS_ENABLED macro
2. Add ACPI bits
 v1: first submit
Link: https://lkml.org/lkml/2016/5/13/93
---
 drivers/net/ethernet/hisilicon/hns_mdio.c | 107 +++---
 1 file changed, 69 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c 
b/drivers/net/ethernet/hisilicon/hns_mdio.c
index 381cf0a..f78286c 100644
--- a/drivers/net/ethernet/hisilicon/hns_mdio.c
+++ b/drivers/net/ethernet/hisilicon/hns_mdio.c
@@ -7,6 +7,7 @@
  * (at your option) any later version.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -354,48 +355,60 @@ static int hns_mdio_reset(struct mii_bus *bus)
struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
int ret;
 
-   if (!dev_of_node(bus->parent))
-   return -ENOTSUPP;
+   if (dev_of_node(bus->parent)) {
+   if (!mdio_dev->subctrl_vbase) {
+   dev_err(>dev, "mdio sys ctl reg has not maped\n");
+   return -ENODEV;
+   }
 
-   if (!mdio_dev->subctrl_vbase) {
-   dev_err(>dev, "mdio sys ctl reg has not maped\n");
-   return -ENODEV;
-   }
+   /* 1. reset req, and read reset st check */
+   ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_REQ, 0x1,
+   MDIO_SC_RESET_ST, 0x1,
+   MDIO_CHECK_SET_ST);
+   if (ret) {
+   dev_err(>dev, "MDIO reset fail\n");
+   return ret;
+   }
 
-   /*1. reset req, and read reset st check*/
-   ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_REQ, 0x1,
-   MDIO_SC_RESET_ST, 0x1,
-   MDIO_CHECK_SET_ST);
-   if (ret) {
-   dev_err(>dev, "MDIO reset fail\n");
-   return ret;
-   }
+   /* 2. dis clk, and read clk st check */
+   ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_DIS,
+   0x1, MDIO_SC_CLK_ST, 0x1,
+   MDIO_CHECK_CLR_ST);
+   if (ret) {
+   dev_err(>dev, "MDIO dis clk fail\n");
+   return ret;
+   }
 
-   /*2. dis clk, and read clk st check*/
-   ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_DIS,
-   0x1, MDIO_SC_CLK_ST, 0x1,
-   MDIO_CHECK_CLR_ST);
-   if (ret) {
-   dev_err(>dev, "MDIO dis clk fail\n");
-   return ret;
-   }
+   /* 3. reset dreq, and read reset st check */
+   ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_DREQ, 0x1,
+   MDIO_SC_RESET_ST, 0x1,
+   MDIO_CHECK_CLR_ST);
+   if (ret) {
+   dev_err(>dev, "MDIO dis clk fail\n");
+   return ret;
+   }
 
-   /*3. reset dreq, and read reset st check*/
-   ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_DREQ, 0x1,
-   MDIO_SC_RESET_ST, 0x1,
-   MDIO_CHECK_CLR_ST);
-   if (ret) {
-   dev_err(>dev, "MDIO dis clk fail\n");
-   return ret;
+   /* 4. en clk, and read clk st check */
+  

[patch v2 net-next 02/13] ACPI: bus: add stub acpi_evaluate_dsm() to linux/acpi.h

2016-05-29 Thread Kejian Yan
acpi_evaluate_dsm() will be used to handle the _DSM method in ACPI case.
It will be compiled in non-ACPI case, but the function is in acpi_bus.h
and acpi_bus.h can only be used in ACPI case, so this patch add the stub
function to linux/acpi.h to make compiled successfully in non-ACPI cases.

Cc: Rafael J. Wysocki <r...@rjwysocki.net>
Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
 include/linux/acpi.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 3025d19..4d4bb49 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -659,6 +659,14 @@ static inline bool acpi_driver_match_device(struct device 
*dev,
return false;
 }
 
+static inline union acpi_object *acpi_evaluate_dsm(acpi_handle handle,
+  const u8 *uuid,
+  int rev, int func,
+  union acpi_object *argv4)
+{
+   return NULL;
+}
+
 static inline int acpi_device_uevent_modalias(struct device *dev,
struct kobj_uevent_env *env)
 {
-- 
1.9.1



[patch v2 net-next 09/13] net: hns: add dsaf misc operation method

2016-05-29 Thread Kejian Yan
The misc operation for different hw platform may be different, if using
current implementation, it will add a new branch on each function for
every new hw platform, so we add a method for this operation.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  |  4 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |  6 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  | 14 ++--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |  2 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 11 ++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h | 33 ++---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 79 +++---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h |  7 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c  | 15 ++--
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c| 10 +--
 10 files changed, 111 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 8e009f4..d37b778 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -637,13 +637,15 @@ static int hns_ae_config_loopback(struct hnae_handle 
*handle,
int ret;
struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle);
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
+   struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
 
switch (loop) {
case MAC_INTERNALLOOP_PHY:
ret = 0;
break;
case MAC_INTERNALLOOP_SERDES:
-   ret = hns_mac_config_sds_loopback(vf_cb->mac_cb, en);
+   ret = dsaf_dev->misc_op->cfg_serdes_loopback(vf_cb->mac_cb,
+!!en);
break;
case MAC_INTERNALLOOP_MAC:
ret = hns_mac_config_mac_loopback(vf_cb->mac_cb, loop, en);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 44abb08..1235c7f 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -110,7 +110,7 @@ static void hns_gmac_free(void *mac_drv)
 
u32 mac_id = drv->mac_id;
 
-   hns_dsaf_ge_srst_by_port(dsaf_dev, mac_id, 0);
+   dsaf_dev->misc_op->ge_srst(dsaf_dev, mac_id, 0);
 }
 
 static void hns_gmac_set_tx_auto_pause_frames(void *mac_drv, u16 newval)
@@ -317,9 +317,9 @@ static void hns_gmac_init(void *mac_drv)
 
port = drv->mac_id;
 
-   hns_dsaf_ge_srst_by_port(dsaf_dev, port, 0);
+   dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 0);
mdelay(10);
-   hns_dsaf_ge_srst_by_port(dsaf_dev, port, 1);
+   dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 1);
mdelay(10);
hns_gmac_disable(mac_drv, MAC_COMM_MODE_RX_AND_TX);
hns_gmac_tx_loop_pkt_dis(mac_drv);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 527b49d..2ebf14a 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -95,7 +95,7 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 
*link_status)
else
*link_status = 0;
 
-   ret = hns_mac_get_sfp_prsnt(mac_cb, _prsnt);
+   ret = mac_cb->dsaf_dev->misc_op->get_sfp_prsnt(mac_cb, _prsnt);
if (!ret)
*link_status = *link_status && sfp_prsnt;
 
@@ -512,7 +512,7 @@ void hns_mac_stop(struct hns_mac_cb *mac_cb)
 
mac_ctrl_drv->mac_en_flg = 0;
mac_cb->link = 0;
-   cpld_led_reset(mac_cb);
+   mac_cb->dsaf_dev->misc_op->cpld_reset_led(mac_cb);
 }
 
 /**
@@ -804,7 +804,7 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct 
hns_mac_cb *mac_cb)
else
mac_cb->mac_type = HNAE_PORT_DEBUG;
 
-   mac_cb->phy_if = hns_mac_get_phy_if(mac_cb);
+   mac_cb->phy_if = dsaf_dev->misc_op->get_phy_if(mac_cb);
 
ret = hns_mac_get_mode(mac_cb->phy_if);
if (ret < 0) {
@@ -819,7 +819,7 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct 
hns_mac_cb *mac_cb)
if (ret)
return ret;
 
-   cpld_led_reset(mac_cb);
+   mac_cb->dsaf_dev->misc_op->cpld_reset_led(mac_cb);
mac_cb->vaddr = hns_mac_get_vaddr(dsaf_dev, mac_cb, mac_mode_idx);
 
return 0;
@@ -906,7 +906,7 @@ void hns_mac_uninit(struct dsaf_device *dsaf_dev)
int max_port_num = hns_mac_get_max_port_num(dsaf_dev);
 
for (i = 0; i < max_port_num; i++) {
-   cpld_led_reset(dsaf_dev->mac_cb[i]);
+   dsaf_dev->misc_op->cpld_reset_led(dsaf_dev->m

[patch v2 net-next 13/13] net: hns: net: hns: enet adds support of acpi

2016-05-29 Thread Kejian Yan
Enet needs to get configration parameter by acpi. This patch
adds support of ACPI for enet. The configuration parameter will
be configed in BIOS.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
change log:
 v2:
 1. use acpi_dev_found() instead of acpi_match_device_ids()
 2. use is_acpi_node() to check if it works by ACPI case
 3. use dev_of_node() to check if it works by DT case

 v1: first submit
  link: https://lkml.org/lkml/2016/5/13/99
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 56 +--
 1 file changed, 44 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 3ec3c27..ad742a6 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -132,6 +132,13 @@ static void fill_v2_desc(struct hnae_ring *ring, void 
*priv,
ring_ptr_move_fw(ring, next_to_use);
 }
 
+static const struct acpi_device_id hns_enet_acpi_match[] = {
+   { "HISI00C1", 0 },
+   { "HISI00C2", 0 },
+   { },
+};
+MODULE_DEVICE_TABLE(acpi, hns_enet_acpi_match);
+
 static void fill_desc(struct hnae_ring *ring, void *priv,
  int size, dma_addr_t dma, int frag_end,
  int buf_num, enum hns_desc_type type, int mtu)
@@ -1870,7 +1877,6 @@ static int hns_nic_dev_probe(struct platform_device *pdev)
struct device *dev = >dev;
struct net_device *ndev;
struct hns_nic_priv *priv;
-   struct device_node *ae_node;
u32 port_id;
int ret;
 
@@ -1884,20 +1890,45 @@ static int hns_nic_dev_probe(struct platform_device 
*pdev)
priv->dev = dev;
priv->netdev = ndev;
 
-   if (of_device_is_compatible(dev->of_node, "hisilicon,hns-nic-v1"))
-   priv->enet_ver = AE_VERSION_1;
-   else
-   priv->enet_ver = AE_VERSION_2;
+   if (dev_of_node(dev)) {
+   struct device_node *ae_node;
 
-   ae_node = of_parse_phandle(dev->of_node, "ae-handle", 0);
-   if (IS_ERR_OR_NULL(ae_node)) {
-   ret = PTR_ERR(ae_node);
-   dev_err(dev, "not find ae-handle\n");
-   goto out_read_prop_fail;
+   if (of_device_is_compatible(dev->of_node,
+   "hisilicon,hns-nic-v1"))
+   priv->enet_ver = AE_VERSION_1;
+   else
+   priv->enet_ver = AE_VERSION_2;
+
+   ae_node = of_parse_phandle(dev->of_node, "ae-handle", 0);
+   if (IS_ERR_OR_NULL(ae_node)) {
+   ret = PTR_ERR(ae_node);
+   dev_err(dev, "not find ae-handle\n");
+   goto out_read_prop_fail;
+   }
+   priv->fwnode = _node->fwnode;
+   } else if (is_acpi_node(dev->fwnode)) {
+   struct acpi_reference_args args;
+
+   if (acpi_dev_found(hns_enet_acpi_match[0].id))
+   priv->enet_ver = AE_VERSION_1;
+   else if (acpi_dev_found(hns_enet_acpi_match[1].id))
+   priv->enet_ver = AE_VERSION_2;
+   else
+   return -ENXIO;
+
+   /* try to find port-idx-in-ae first */
+   ret = acpi_node_get_property_reference(dev->fwnode,
+  "ae-handle", 0, );
+   if (ret) {
+   dev_err(dev, "not find ae-handle\n");
+   goto out_read_prop_fail;
+   }
+   priv->fwnode = acpi_fwnode_handle(args.adev);
+   } else {
+   dev_err(dev, "cannot read cfg data from OF or acpi\n");
+   return -ENXIO;
}
-   priv->fwnode = _node->fwnode;
 
-   /* try to find port-idx-in-ae first */
ret = device_property_read_u32(dev, "port-idx-in-ae", _id);
if (ret) {
/* only for old code compatible */
@@ -2014,6 +2045,7 @@ static struct platform_driver hns_nic_dev_driver = {
.driver = {
.name = "hns-nic",
.of_match_table = hns_enet_of_match,
+   .acpi_match_table = ACPI_PTR(hns_enet_acpi_match),
},
.probe = hns_nic_dev_probe,
.remove = hns_nic_dev_remove,
-- 
1.9.1



[patch v2 net-next 00/13] net: hns: add support of ACPI

2016-05-29 Thread Kejian Yan
This series adds HNS support of acpi. The routine will call some ACPI
helper functions, like acpi_dev_found() and acpi_evaluate_dsm(), which
are not included in other cases. In order to make system compile
successfully in other cases except ACPI, it needs to add relative stub
functions to linux/acpi.h. And we use device property functions instead
of serial helper functions to suport both DT and ACPI cases. And then
add the supports of ACPI for HNS.

change log:
 v1 -> v2:
 1. use acpi_dev_found() instead of acpi_match_device_ids() to check if
it is a acpi node.
 2. use is_of_node() instead of IS_ENABLED() to check if it is a DT node.
 3. split the patch("add support of acpi for hns-mdio") into two patches:
3.1 Move to use fwnode_handle
3.2 Add ACPI
 4. add the patch which subject is dsaf misc operation method
 5. fix the comments by Andy Shevchenko

Kejian Yan (13):
  ACPI: bus: add stub acpi_dev_found() to linux/acpi.h
  ACPI: bus: add stub acpi_evaluate_dsm() to linux/acpi.h
  net: hisilicon: cleanup to prepare for other cases
  net: hisilicon: add support of acpi for hns-mdio
  net: hns: use device_* APIs instead of of_* APIs
  net: hns: use platform_get_irq instead of irq_of_parse_and_map
  net: hns: enet specify a reference to dsaf by fwnode_handle
  net: hns: add uniform interface for phy connection
  net: hns: add dsaf misc operation method
  net: hns: dsaf adds support of acpi
  net: hns: register phy device in each mac initial sequence
  net: hns: implement the miscellaneous operation by asl
  net: hns: net: hns: enet adds support of acpi

 drivers/net/ethernet/hisilicon/hns/hnae.c  |  18 +-
 drivers/net/ethernet/hisilicon/hns/hnae.h  |   5 +-
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  |   6 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |   6 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  | 247 +++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |   4 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 105 ++---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  33 ++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 250 ++---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h |   7 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c  |  15 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c  |   5 +-
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c|  10 +-
 drivers/net/ethernet/hisilicon/hns/hns_enet.c  |  90 +---
 drivers/net/ethernet/hisilicon/hns/hns_enet.h  |   2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |   2 +-
 drivers/net/ethernet/hisilicon/hns_mdio.c  | 147 +++-
 include/linux/acpi.h   |  13 ++
 18 files changed, 710 insertions(+), 255 deletions(-)

-- 
1.9.1



[patch v2 net-next 03/13] net: hisilicon: cleanup to prepare for other cases

2016-05-29 Thread Kejian Yan
Hns-mdio only supports DT case now. do some cleanup to prepare
for introducing other cases later, no functional change.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns_mdio.c | 46 +++
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c 
b/drivers/net/ethernet/hisilicon/hns_mdio.c
index 765ddb3..381cf0a 100644
--- a/drivers/net/ethernet/hisilicon/hns_mdio.c
+++ b/drivers/net/ethernet/hisilicon/hns_mdio.c
@@ -354,6 +354,9 @@ static int hns_mdio_reset(struct mii_bus *bus)
struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
int ret;
 
+   if (!dev_of_node(bus->parent))
+   return -ENOTSUPP;
+
if (!mdio_dev->subctrl_vbase) {
dev_err(>dev, "mdio sys ctl reg has not maped\n");
return -ENODEV;
@@ -399,19 +402,12 @@ static int hns_mdio_reset(struct mii_bus *bus)
 /**
  * hns_mdio_bus_name - get mdio bus name
  * @name: mdio bus name
- * @np: mdio device node pointer
+ * @addr: mdio physical address
  */
-static void hns_mdio_bus_name(char *name, struct device_node *np)
+static void hns_mdio_bus_name(char *name, phys_addr_t addr)
 {
-   const u32 *addr;
-   u64 taddr = OF_BAD_ADDR;
-
-   addr = of_get_address(np, 0, NULL, NULL);
-   if (addr)
-   taddr = of_translate_address(np, addr);
-
-   snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name,
-(unsigned long long)taddr);
+   snprintf(name, MII_BUS_ID_SIZE,
+"hns-mdio@%llx", (unsigned long long)addr);
 }
 
 /**
@@ -422,17 +418,16 @@ static void hns_mdio_bus_name(char *name, struct 
device_node *np)
  */
 static int hns_mdio_probe(struct platform_device *pdev)
 {
-   struct device_node *np;
struct hns_mdio_device *mdio_dev;
struct mii_bus *new_bus;
struct resource *res;
-   int ret;
+   int ret = -ENODEV;
 
if (!pdev) {
dev_err(NULL, "pdev is NULL!\r\n");
return -ENODEV;
}
-   np = pdev->dev.of_node;
+
mdio_dev = devm_kzalloc(>dev, sizeof(*mdio_dev), GFP_KERNEL);
if (!mdio_dev)
return -ENOMEM;
@@ -448,7 +443,7 @@ static int hns_mdio_probe(struct platform_device *pdev)
new_bus->write = hns_mdio_write;
new_bus->reset = hns_mdio_reset;
new_bus->priv = mdio_dev;
-   hns_mdio_bus_name(new_bus->id, np);
+   new_bus->parent = >dev;
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mdio_dev->vbase = devm_ioremap_resource(>dev, res);
@@ -457,18 +452,23 @@ static int hns_mdio_probe(struct platform_device *pdev)
return ret;
}
 
-   mdio_dev->subctrl_vbase =
-   syscon_node_to_regmap(of_parse_phandle(np, "subctrl-vbase", 0));
-   if (IS_ERR(mdio_dev->subctrl_vbase)) {
-   dev_warn(>dev, "no syscon hisilicon,peri-c-subctrl\n");
-   mdio_dev->subctrl_vbase = NULL;
-   }
-   new_bus->parent = >dev;
platform_set_drvdata(pdev, new_bus);
 
-   ret = of_mdiobus_register(new_bus, np);
+   hns_mdio_bus_name(new_bus->id, res->start);
+   if (dev_of_node(>dev)) {
+   mdio_dev->subctrl_vbase = syscon_node_to_regmap(
+   of_parse_phandle(pdev->dev.of_node,
+"subctrl-vbase", 0));
+   if (IS_ERR(mdio_dev->subctrl_vbase)) {
+   dev_warn(>dev, "no syscon 
hisilicon,peri-c-subctrl\n");
+   mdio_dev->subctrl_vbase = NULL;
+   }
+   ret = of_mdiobus_register(new_bus, pdev->dev.of_node);
+   }
+
if (ret) {
dev_err(>dev, "Cannot register as MDIO bus!\n");
+
platform_set_drvdata(pdev, NULL);
return ret;
}
-- 
1.9.1



[patch v2 net-next 11/13] net: hns: register phy device in each mac initial sequence

2016-05-29 Thread Kejian Yan
In ACPI case, there is no interface to register phy device to mdio-bus.
Phy device has to be registered itself to mdio-bus, and then enet can
get the phy device's info so that it can config the phy-device to help
to trasmit and receive data.
HNS hardware topology is as below. The MDIO controller may control several
PHY-devices, and each PHY-device connects to a MAC device. PHY-devices
will register when each mac find PHY device in initial sequence.

   cpu
|
|
 ---
|   |   |
|   |   |
|  dsaf |
   MDIO |  MDIO
|  ---  |
| | | |   | |
| | | |   | |
|MAC   MAC   MAC MAC|
| | | |   | |
  | | |   | 
 ||||||   ||
 PHY   PHY   PHY PHY

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
change log:
 v2: fix the build error by kbuild test robot

 v1: first submit
  link: https://lkml.org/lkml/2016/5/13/97
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 133 --
 1 file changed, 126 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 3ef0c9b..c526558 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -7,6 +7,7 @@
  * (at your option) any later version.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -638,6 +639,115 @@ free_mac_drv:
return ret;
 }
 
+static int
+hns_mac_phy_parse_addr(struct device *dev, struct fwnode_handle *fwnode)
+{
+   u32 addr;
+   int ret;
+
+   ret = fwnode_property_read_u32(fwnode, "phy-addr", );
+   if (ret) {
+   dev_err(dev, "has invalid PHY address ret:%d\n", ret);
+   return ret;
+   }
+
+   if (addr >= PHY_MAX_ADDR) {
+   dev_err(dev, "PHY address %i is too large\n", addr);
+   return -EINVAL;
+   }
+
+   return addr;
+}
+
+static int hns_mac_phydev_match(struct device *dev, void *fwnode)
+{
+   return dev->fwnode == fwnode;
+}
+
+static struct
+platform_device *hns_mac_find_platform_device(struct fwnode_handle *fwnode)
+{
+   struct device *dev;
+
+   dev = bus_find_device(_bus_type, NULL,
+ fwnode, hns_mac_phydev_match);
+   return dev ? to_platform_device(dev) : NULL;
+}
+
+static int
+hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb,
+   u32 addr)
+{
+   struct phy_device *phy;
+   const char *phy_type;
+   bool is_c45;
+   int rc;
+
+   rc = fwnode_property_read_string(mac_cb->fw_port,
+"phy-mode", _type);
+   if (rc < 0)
+   return rc;
+
+   if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_XGMII)))
+   is_c45 = 1;
+   else if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_SGMII)))
+   is_c45 = 0;
+   else
+   return -ENODATA;
+
+   phy = get_phy_device(mdio, addr, is_c45);
+   if (!phy || IS_ERR(phy))
+   return -EIO;
+
+   if (mdio->irq)
+   phy->irq = mdio->irq[addr];
+
+   /* All data is now stored in the phy struct;
+* register it
+*/
+   rc = phy_device_register(phy);
+   if (rc) {
+   phy_device_free(phy);
+   return -ENODEV;
+   }
+
+   mac_cb->phy_dev = phy;
+
+   dev_dbg(>dev, "registered phy at address %i\n", addr);
+
+   return 0;
+}
+
+static void hns_mac_register_phy(struct hns_mac_cb *mac_cb)
+{
+   struct acpi_reference_args args;
+   struct platform_device *pdev;
+   struct mii_bus *mii_bus;
+   int rc;
+   int addr;
+
+   /* Loop over the child nodes and register a phy_device for each one */
+   if (!to_acpi_device_node(mac_cb->fw_port))
+   return;
+
+   rc = acpi_node_get_property_reference(
+   mac_cb->fw_port, "mdio-node", 0, );
+   if (rc)
+   return;
+
+   addr = hns_mac_phy_parse_addr(mac_cb->dev, mac_cb->fw_port);
+   if (addr < 0)
+   return;
+
+   /* dev address in adev */
+   pdev = hns_mac_find_platform_device(acpi_fwnode_handle(args.adev));
+   mii_bus = platform_get_drvdata(pdev);
+   rc = hns_mac_register_phydev(mii_bus, mac_cb, addr);
+   if

[patch v2 net-next 05/13] net: hns: use device_* APIs instead of of_* APIs

2016-05-29 Thread Kejian Yan
OF series functions can be used only for DT case. Use unified
device property function instead to support both DT and ACPI.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c |  9 +
 drivers/net/ethernet/hisilicon/hns/hns_enet.c  | 11 +++
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 1c2ddb2..9afc5e6 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -50,7 +50,7 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
else
dsaf_dev->dsaf_ver = AE_VERSION_2;
 
-   ret = of_property_read_string(np, "mode", _str);
+   ret = device_property_read_string(dsaf_dev->dev, "mode", _str);
if (ret) {
dev_err(dsaf_dev->dev, "get dsaf mode fail, ret=%d!\n", ret);
return ret;
@@ -142,7 +142,7 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
}
}
 
-   ret = of_property_read_u32(np, "desc-num", _num);
+   ret = device_property_read_u32(dsaf_dev->dev, "desc-num", _num);
if (ret < 0 || desc_num < HNS_DSAF_MIN_DESC_CNT ||
desc_num > HNS_DSAF_MAX_DESC_CNT) {
dev_err(dsaf_dev->dev, "get desc-num(%d) fail, ret=%d!\n",
@@ -151,14 +151,15 @@ 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", _offset);
+   ret = device_property_read_u32(dsaf_dev->dev, "reset-field-offset",
+  _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", _size);
+   ret = device_property_read_u32(dsaf_dev->dev, "buf-size", _size);
if (ret < 0) {
dev_err(dsaf_dev->dev,
"get buf-size fail, ret=%d!\r\n", ret);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index e621636..8851420 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -1067,13 +1067,8 @@ void hns_nic_update_stats(struct net_device *netdev)
 static void hns_init_mac_addr(struct net_device *ndev)
 {
struct hns_nic_priv *priv = netdev_priv(ndev);
-   struct device_node *node = priv->dev->of_node;
-   const void *mac_addr_temp;
 
-   mac_addr_temp = of_get_mac_address(node);
-   if (mac_addr_temp && is_valid_ether_addr(mac_addr_temp)) {
-   memcpy(ndev->dev_addr, mac_addr_temp, ndev->addr_len);
-   } else {
+   if (!device_get_mac_address(priv->dev, ndev->dev_addr, ETH_ALEN)) {
eth_hw_addr_random(ndev);
dev_warn(priv->dev, "No valid mac, use random mac %pM",
 ndev->dev_addr);
@@ -1898,10 +1893,10 @@ static int hns_nic_dev_probe(struct platform_device 
*pdev)
goto out_read_prop_fail;
}
/* try to find port-idx-in-ae first */
-   ret = of_property_read_u32(node, "port-idx-in-ae", _id);
+   ret = device_property_read_u32(dev, "port-idx-in-ae", _id);
if (ret) {
/* only for old code compatible */
-   ret = of_property_read_u32(node, "port-id", _id);
+   ret = device_property_read_u32(dev, "port-id", _id);
if (ret)
goto out_read_prop_fail;
/* for old dts, we need to caculate the port offset */
-- 
1.9.1



[patch v2 net-next 10/13] net: hns: dsaf adds support of acpi

2016-05-29 Thread Kejian Yan
Dsaf needs to get configuration parameter by ACPI, so this patch add
support of ACPI.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
change log:
 v2:
  1. use dev_of_node() instead of IS_ENABLED() to check if it is in
DT case,
  2. split a new patch to implement misc operation method,
  3. use acpi_dev_found() instead of acpi_match_device_ids() to
check which hw version it is,
  4. use is_acpi_node instead of ACPI_COMPANION to check if it is
work in ACPI case.

 v1: first submit
  link: https://lkml.org/lkml/2016/5/13/108
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  | 80 ++--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 85 +++---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 32 
 3 files changed, 114 insertions(+), 83 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 2ebf14a..3ef0c9b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -689,9 +689,7 @@ static int  hns_mac_get_info(struct hns_mac_cb *mac_cb)
return 0;
}
 
-   if (!is_of_node(mac_cb->fw_port))
-   return -EINVAL;
-
+   if (is_of_node(mac_cb->fw_port)) {
/* parse property from port subnode in dsaf */
np = of_parse_phandle(to_of_node(mac_cb->fw_port), "phy-handle", 0);
mac_cb->phy_dev = of_phy_find_device(np);
@@ -701,47 +699,49 @@ static int  hns_mac_get_info(struct hns_mac_cb *mac_cb)
mac_cb->mac_id, np->name);
}
 
-   syscon = syscon_node_to_regmap(
-   of_parse_phandle(to_of_node(mac_cb->fw_port),
-"serdes-syscon", 0));
-   if (IS_ERR_OR_NULL(syscon)) {
-   dev_err(mac_cb->dev, "serdes-syscon is needed!\n");
-   return -EINVAL;
-   }
-   mac_cb->serdes_ctrl = syscon;
-
-   ret = fwnode_property_read_u32(mac_cb->fw_port,
-  "port-rst-offset",
-  _cb->port_rst_off);
-   if (ret) {
-   dev_dbg(mac_cb->dev,
-   "mac%d port-rst-offset not found, use default value.\n",
-   mac_cb->mac_id);
-   }
+   syscon = syscon_node_to_regmap(
+   of_parse_phandle(to_of_node(mac_cb->fw_port),
+"serdes-syscon", 0));
+   if (IS_ERR_OR_NULL(syscon)) {
+   dev_err(mac_cb->dev, "serdes-syscon is needed!\n");
+   return -EINVAL;
+   }
+   mac_cb->serdes_ctrl = syscon;
 
-   ret = fwnode_property_read_u32(mac_cb->fw_port,
-  "port-mode-offset",
-  _cb->port_mode_off);
-   if (ret) {
-   dev_dbg(mac_cb->dev,
-   "mac%d port-mode-offset not found, use default 
value.\n",
-   mac_cb->mac_id);
-   }
+   ret = fwnode_property_read_u32(mac_cb->fw_port,
+  "port-rst-offset",
+  _cb->port_rst_off);
+   if (ret) {
+   dev_dbg(mac_cb->dev,
+   "mac%d port-rst-offset not found, use default 
value.\n",
+   mac_cb->mac_id);
+   }
 
-   ret = of_parse_phandle_with_fixed_args(to_of_node(mac_cb->fw_port),
-  "cpld-syscon", 1, 0, _args);
-   if (ret) {
-   dev_dbg(mac_cb->dev, "mac%d no cpld-syscon found.\n",
-   mac_cb->mac_id);
-   mac_cb->cpld_ctrl = NULL;
-   } else {
-   syscon = syscon_node_to_regmap(cpld_args.np);
-   if (IS_ERR_OR_NULL(syscon)) {
-   dev_dbg(mac_cb->dev, "no cpld-syscon found!\n");
+   ret = fwnode_property_read_u32(mac_cb->fw_port,
+  "port-mode-offset",
+  _cb->port_mode_off);
+   if (ret) {
+   dev_dbg(mac_cb->dev,
+   "mac%d port-mode-offset not found, use default 
value.\n",
+   mac_cb->mac_id);
+   }
+
+   ret = of_parse_phandle_with_fixed_args(
+   to_of_node(mac_cb->fw_port), "

[patch v2 net-next 08/13] net: hns: add uniform interface for phy connection

2016-05-29 Thread Kejian Yan
As device_node is only used by DT case, HNS needs to treat the other
cases including ACPI. It needs to use uniform ways to handle both of
DT and ACPI. This patch chooses phy_device, and of_phy_connect and
of_phy_attach are only used by DT case. It needs to use uniform interface
to handle that sequence by both DT and ACPI.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
change log:
 v2:
  1. remove the redundant functions, and
  2. adds fwnode match method beside DT and ACPI.

 v1: first submit
  link: https://lkml.org/lkml/2016/5/13/100
---
 drivers/net/ethernet/hisilicon/hns/hnae.c  |  8 -
 drivers/net/ethernet/hisilicon/hns/hnae.h  |  3 +-
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  | 34 +++---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_enet.c  | 21 +++--
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |  2 +-
 8 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index d630acd..5d3047c 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -96,7 +96,13 @@ static int __ae_match(struct device *dev, const void *data)
 {
struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
 
-   return (data == >dev->of_node->fwnode);
+   if (dev_of_node(hdev->dev))
+   return (data == >dev->of_node->fwnode);
+   else if (is_acpi_node(hdev->dev->fwnode))
+   return (data == hdev->dev->fwnode);
+
+   dev_err(dev, "__ae_match cannot read cfg data from OF or acpi\n");
+   return 0;
 }
 
 static struct hnae_ae_dev *find_ae(const struct fwnode_handle *fwnode)
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index f5f8140..529cb13 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -27,6 +27,7 @@
  * "cb" means control block
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -512,7 +513,7 @@ struct hnae_ae_dev {
 struct hnae_handle {
struct device *owner_dev; /* the device which make use of this handle */
struct hnae_ae_dev *dev;  /* the device who provides this handle */
-   struct device_node *phy_node;
+   struct phy_device *phy_dev;
phy_interface_t phy_if;
u32 if_support;
int q_num;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 7a757e8..8e009f4 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -131,7 +131,7 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev 
*dev,
vf_cb->mac_cb = dsaf_dev->mac_cb[port_id];
 
ae_handle->phy_if = vf_cb->mac_cb->phy_if;
-   ae_handle->phy_node = vf_cb->mac_cb->phy_node;
+   ae_handle->phy_dev = vf_cb->mac_cb->phy_dev;
ae_handle->if_support = vf_cb->mac_cb->if_support;
ae_handle->port_type = vf_cb->mac_cb->mac_type;
ae_handle->dport_id = port_id;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 611581f..527b49d 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -15,7 +15,8 @@
 #include 
 #include 
 #include 
-#include 
+#include 
+#include 
 #include 
 
 #include "hns_dsaf_main.h"
@@ -645,7 +646,7 @@ free_mac_drv:
  */
 static int  hns_mac_get_info(struct hns_mac_cb *mac_cb)
 {
-   struct device_node *np = mac_cb->dev->of_node;
+   struct device_node *np;
struct regmap *syscon;
struct of_phandle_args cpld_args;
u32 ret;
@@ -672,21 +673,34 @@ static int  hns_mac_get_info(struct hns_mac_cb *mac_cb)
 * from dsaf node
 */
if (!mac_cb->fw_port) {
-   mac_cb->phy_node = of_parse_phandle(np, "phy-handle",
-   mac_cb->mac_id);
-   if (mac_cb->phy_node)
+   np = of_parse_phandle(mac_cb->dev->of_node, "phy-handle",
+ mac_cb->mac_id);
+   mac_cb->phy_dev = of_phy_find_device(np);
+   if (mac_cb->phy_dev) {
+   /* refcount is held by of_phy_find_device()
+* if the phy_dev is found
+*/
+   put_device(_cb->phy_dev->mdio.dev);
+
  

[patch v2 net-next 01/13] ACPI: bus: add stub acpi_dev_found() to linux/acpi.h

2016-05-29 Thread Kejian Yan
acpi_dev_found() will be used to detect if a given ACPI device is in the
system. It will be compiled in non-ACPI case, but the function is in
acpi_bus.h and acpi_bus.h can only be used in ACPI case, so this patch add
the stub function to linux/acpi.h to make compiled successfully in
non-ACPI cases.

Cc: Rafael J. Wysocki <r...@rjwysocki.net>
Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
 include/linux/acpi.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5..3025d19 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -543,6 +543,11 @@ struct platform_device *acpi_create_platform_device(struct 
acpi_device *);
 
 struct fwnode_handle;
 
+static inline bool acpi_dev_found(const char *hid)
+{
+   return false;
+}
+
 static inline bool is_acpi_node(struct fwnode_handle *fwnode)
 {
return false;
-- 
1.9.1



[patch v2 net-next 07/13] net: hns: enet specify a reference to dsaf by fwnode_handle

2016-05-29 Thread Kejian Yan
As device_node is only used by DT case, it is expected to find uniform
ways. So fwnode_handle is the suitable method.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
change log:
 v2: remove the redundant line

 v1: first submit
 link: https://lkml.org/lkml/2016/5/13/98
---
 drivers/net/ethernet/hisilicon/hns/hnae.c | 12 ++--
 drivers/net/ethernet/hisilicon/hns/hnae.h |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 14 --
 drivers/net/ethernet/hisilicon/hns/hns_enet.h |  2 +-
 4 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index 3bfe36f..d630acd 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -96,16 +96,16 @@ static int __ae_match(struct device *dev, const void *data)
 {
struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
 
-   return hdev->dev->of_node == data;
+   return (data == >dev->of_node->fwnode);
 }
 
-static struct hnae_ae_dev *find_ae(const struct device_node *ae_node)
+static struct hnae_ae_dev *find_ae(const struct fwnode_handle *fwnode)
 {
struct device *dev;
 
-   WARN_ON(!ae_node);
+   WARN_ON(!fwnode);
 
-   dev = class_find_device(hnae_class, NULL, ae_node, __ae_match);
+   dev = class_find_device(hnae_class, NULL, fwnode, __ae_match);
 
return dev ? cls_to_ae_dev(dev) : NULL;
 }
@@ -312,7 +312,7 @@ EXPORT_SYMBOL(hnae_reinit_handle);
  * return handle ptr or ERR_PTR
  */
 struct hnae_handle *hnae_get_handle(struct device *owner_dev,
-   const struct device_node *ae_node,
+   const struct fwnode_handle  *fwnode,
u32 port_id,
struct hnae_buf_ops *bops)
 {
@@ -321,7 +321,7 @@ struct hnae_handle *hnae_get_handle(struct device 
*owner_dev,
int i, j;
int ret;
 
-   dev = find_ae(ae_node);
+   dev = find_ae(fwnode);
if (!dev)
return ERR_PTR(-ENODEV);
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index e8d36aa..f5f8140 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -528,7 +528,7 @@ struct hnae_handle {
 #define ring_to_dev(ring) ((ring)->q->dev->dev)
 
 struct hnae_handle *hnae_get_handle(struct device *owner_dev,
-   const struct device_node *ae_node,
+   const struct fwnode_handle  *fwnode,
u32 port_id,
struct hnae_buf_ops *bops);
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 8851420..93f6ccb 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -1807,7 +1807,7 @@ static int hns_nic_try_get_ae(struct net_device *ndev)
int ret;
 
h = hnae_get_handle(>netdev->dev,
-   priv->ae_node, priv->port_id, NULL);
+   priv->fwnode, priv->port_id, NULL);
if (IS_ERR_OR_NULL(h)) {
ret = -ENODEV;
dev_dbg(priv->dev, "has not handle, register notifier!\n");
@@ -1867,7 +1867,7 @@ static int hns_nic_dev_probe(struct platform_device *pdev)
struct device *dev = >dev;
struct net_device *ndev;
struct hns_nic_priv *priv;
-   struct device_node *node = dev->of_node;
+   struct device_node *ae_node;
u32 port_id;
int ret;
 
@@ -1881,17 +1881,19 @@ static int hns_nic_dev_probe(struct platform_device 
*pdev)
priv->dev = dev;
priv->netdev = ndev;
 
-   if (of_device_is_compatible(node, "hisilicon,hns-nic-v1"))
+   if (of_device_is_compatible(dev->of_node, "hisilicon,hns-nic-v1"))
priv->enet_ver = AE_VERSION_1;
else
priv->enet_ver = AE_VERSION_2;
 
-   priv->ae_node = (void *)of_parse_phandle(node, "ae-handle", 0);
-   if (IS_ERR_OR_NULL(priv->ae_node)) {
-   ret = PTR_ERR(priv->ae_node);
+   ae_node = of_parse_phandle(dev->of_node, "ae-handle", 0);
+   if (IS_ERR_OR_NULL(ae_node)) {
+   ret = PTR_ERR(ae_node);
dev_err(dev, "not find ae-handle\n");
goto out_read_prop_fail;
}
+   priv->fwnode = _node->fwnode;
+
/* try to find port-idx-in-ae first */
ret = device_property_read_u32(dev, "port-idx-in-ae", _id);
if (ret) {
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h 
b/drivers/net/e

[patch v2 net-next 06/13] net: hns: use platform_get_irq instead of irq_of_parse_and_map

2016-05-29 Thread Kejian Yan
As irq_of_parse_and_map is only used by DT case, it is excepted to use
a uniform interface. So it is used platform_get_irq() instead.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
Signed-off-by: Yisen Zhuang <yisen.zhu...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
index 4ef6d23..3ce2409 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
@@ -458,7 +458,6 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common)
u32 i;
u32 ring_num = rcb_common->ring_num;
int base_irq_idx = hns_rcb_get_base_irq_idx(rcb_common);
-   struct device_node *np = rcb_common->dsaf_dev->dev->of_node;
struct platform_device *pdev =
to_platform_device(rcb_common->dsaf_dev->dev);
bool is_ver1 = AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver);
@@ -473,10 +472,10 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common)
ring_pair_cb->port_id_in_comm =
hns_rcb_get_port_in_comm(rcb_common, i);
ring_pair_cb->virq[HNS_RCB_IRQ_IDX_TX] =
-   is_ver1 ? irq_of_parse_and_map(np, base_irq_idx + i * 2) :
+   is_ver1 ? platform_get_irq(pdev, base_irq_idx + i * 2) :
  platform_get_irq(pdev, base_irq_idx + i * 3 + 1);
ring_pair_cb->virq[HNS_RCB_IRQ_IDX_RX] =
-   is_ver1 ? irq_of_parse_and_map(np, base_irq_idx + i * 2 + 1) :
+   is_ver1 ? platform_get_irq(pdev, base_irq_idx + i * 2 + 1) :
  platform_get_irq(pdev, base_irq_idx + i * 3);
ring_pair_cb->q.phy_base =
RCB_COMM_BASE_TO_RING_BASE(rcb_common->phy_base, i);
-- 
1.9.1



[PATCH v3 net-next 1/2] net: hns: fix return value of the function about rss

2016-03-10 Thread Kejian Yan
Both .get_rxfh and .get_rxfh are always return 0, it should return result
from hardware when getting or setting rss. And the rss function should
return the correct data type.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
change log:
PATCH v3:
 - This patch removes unused variable 'ret' to fix the build warning

PATCH v2:
 - This patch fixes the comments provided by Andy Shevchenko 

 Link: https://lkml.org/lkml/2016/3/10/266

PATCH v1:
 - first submit

 Link: https://lkml.org/lkml/2016/3/9/978
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 14 --
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index d4f92ed..d07db1f 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -799,7 +799,7 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const 
u32 *indir,
 
/* set the RSS Hash Key if specififed by the user */
if (key)
-   hns_ppe_set_rss_key(ppe_cb, (int *)key);
+   hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
 
/* update the shadow RSS table with user specified qids */
memcpy(ppe_cb->rss_indir_table, indir, HNS_PPEV2_RSS_IND_TBL_SIZE);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
index f302ef9..811ef35 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
@@ -27,7 +27,7 @@ void hns_ppe_set_tso_enable(struct hns_ppe_cb *ppe_cb, u32 
value)
 void hns_ppe_set_rss_key(struct hns_ppe_cb *ppe_cb,
 const u32 rss_key[HNS_PPEV2_RSS_KEY_NUM])
 {
-   int key_item = 0;
+   u32 key_item = 0;
 
for (key_item = 0; key_item < HNS_PPEV2_RSS_KEY_NUM; key_item++)
dsaf_write_dev(ppe_cb, PPEV2_RSS_KEY_REG + key_item * 0x4,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3c4a3bc..01b65eb 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1178,7 +1178,7 @@ hns_get_rss_key_size(struct net_device *netdev)
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
   "RSS feature is not supported on this hardware\n");
-   return -EOPNOTSUPP;
+   return (u32)-EOPNOTSUPP;
}
 
ops = priv->ae_handle->dev->ops;
@@ -1197,7 +1197,7 @@ hns_get_rss_indir_size(struct net_device *netdev)
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
   "RSS feature is not supported on this hardware\n");
-   return -EOPNOTSUPP;
+   return (u32)-EOPNOTSUPP;
}
 
ops = priv->ae_handle->dev->ops;
@@ -1211,7 +1211,6 @@ hns_get_rss(struct net_device *netdev, u32 *indir, u8 
*key, u8 *hfunc)
 {
struct hns_nic_priv *priv = netdev_priv(netdev);
struct hnae_ae_ops *ops;
-   int ret;
 
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
@@ -1224,9 +1223,7 @@ hns_get_rss(struct net_device *netdev, u32 *indir, u8 
*key, u8 *hfunc)
if (!indir)
return 0;
 
-   ret = ops->get_rss(priv->ae_handle, indir, key, hfunc);
-
-   return 0;
+   return ops->get_rss(priv->ae_handle, indir, key, hfunc);
 }
 
 static int
@@ -1235,7 +1232,6 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, 
const u8 *key,
 {
struct hns_nic_priv *priv = netdev_priv(netdev);
struct hnae_ae_ops *ops;
-   int ret;
 
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
@@ -1252,9 +1248,7 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, 
const u8 *key,
if (!indir)
return 0;
 
-   ret = ops->set_rss(priv->ae_handle, indir, key, hfunc);
-
-   return 0;
+   return ops->set_rss(priv->ae_handle, indir, key, hfunc);
 }
 
 static struct ethtool_ops hns_ethtool_ops = {
-- 
1.9.1



[PATCH v3 net-next 0/2] net: hns: get and set RSS indirection table by using ethtool

2016-03-10 Thread Kejian Yan
When we use ethtool to retrieves or configure the receive flow hash 
indirection table, ethtool needs to call .get_rxnfc to get the ring number
so this patchset implements the .get_rxnfc and fixes the bug that we can
not get the tatal table each time.

---
change log:
PATCH v3:
 - This patchset fixes the building warning and error

PATCH v2:
 - This patchset fixes the comments provided by Andy Shevchenko 

PATCH v1:
 - first submit

Kejian Yan (2):
  net: hns: fix return value of the function about rss
  net: hns: fixes a bug of RSS

 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  8 ---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 28 ---
 3 files changed, 26 insertions(+), 12 deletions(-)

-- 
1.9.1



[PATCH v3 net-next 2/2] net: hns: fixes a bug of RSS

2016-03-10 Thread Kejian Yan
If trying to get receive flow hash indirection table by ethtool, it needs
to call .get_rxnfc to get ring number first. So this patch implements the
.get_rxnfc of ethtool. And the data type of rss_indir_table is u32, it has
to be multiply by the width of data type when using memcpy.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
change log:
PATCH v3:
 - This patch modifies the return value of .get_rxnfc to fix building error

PATCH v2:
 - This patch fixes the comments provided by Andy Shevchenko 

 Link: https://lkml.org/lkml/2016/3/10/267

PATCH v1:
 - first submit

 Link: https://lkml.org/lkml/2016/3/9/981
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  6 --
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 18 ++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index d07db1f..7b06e9b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -787,7 +787,8 @@ static int hns_ae_get_rss(struct hnae_handle *handle, u32 
*indir, u8 *key,
memcpy(key, ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE);
 
/* update the current hash->queue mappings from the shadow RSS table */
-   memcpy(indir, ppe_cb->rss_indir_table, HNS_PPEV2_RSS_IND_TBL_SIZE);
+   memcpy(indir, ppe_cb->rss_indir_table,
+  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
 
return 0;
 }
@@ -802,7 +803,8 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const 
u32 *indir,
hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
 
/* update the shadow RSS table with user specified qids */
-   memcpy(ppe_cb->rss_indir_table, indir, HNS_PPEV2_RSS_IND_TBL_SIZE);
+   memcpy(ppe_cb->rss_indir_table, indir,
+  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
 
/* now update the hardware */
hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 01b65eb..46379ce 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1251,6 +1251,23 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, 
const u8 *key,
return ops->set_rss(priv->ae_handle, indir, key, hfunc);
 }
 
+static int hns_get_rxnfc(struct net_device *netdev,
+struct ethtool_rxnfc *cmd,
+u32 *rule_locs)
+{
+   struct hns_nic_priv *priv = netdev_priv(netdev);
+
+   switch (cmd->cmd) {
+   case ETHTOOL_GRXRINGS:
+   cmd->data = priv->ae_handle->q_num;
+   break;
+   default:
+   return -EOPNOTSUPP;
+   }
+
+   return 0;
+}
+
 static struct ethtool_ops hns_ethtool_ops = {
.get_drvinfo = hns_nic_get_drvinfo,
.get_link  = hns_nic_get_link,
@@ -1274,6 +1291,7 @@ static struct ethtool_ops hns_ethtool_ops = {
.get_rxfh_indir_size = hns_get_rss_indir_size,
.get_rxfh = hns_get_rss,
.set_rxfh = hns_set_rss,
+   .get_rxnfc = hns_get_rxnfc,
 };
 
 void hns_ethtool_set_ops(struct net_device *ndev)
-- 
1.9.1



[PATCH v2 net-next 0/2] net: hns: get and set RSS indirection table by using ethtool

2016-03-10 Thread Kejian Yan
When we use ethtool to retrieves or configure the receive flow hash 
indirection table, ethtool needs to call .get_rxnfc to get the ring number
so this patchset implements the .get_rxnfc and fixes the bug that we can
not get the tatal table each time.

---
change log:
PATCH v2:
 - This patch fixes the comments provided by Andy Shevchenko 

PATCH v1:
 - first submit

Kejian Yan (2):
  net: hns: fix return value of the function about rss
  net: hns: fixes a bug of RSS

 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  8 ---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 26 +--
 3 files changed, 26 insertions(+), 10 deletions(-)

-- 
1.9.1



[PATCH v2 net-next 2/2] net: hns: fixes a bug of RSS

2016-03-10 Thread Kejian Yan
If trying to get receive flow hash indirection table by ethtool, it needs
to call .get_rxnfc to get ring number first. So this patch implements the
.get_rxnfc of ethtool. And the data type of rss_indir_table is u32, it has
to be multiply by the width of data type when using memcpy.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
change log:
PATCH v2:
 - This patch fixes the comments provided by Andy Shevchenko 

PATCH v1:
 - first submit

 Link: https://lkml.org/lkml/2016/3/9/981
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  6 --
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 18 ++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index d07db1f..7b06e9b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -787,7 +787,8 @@ static int hns_ae_get_rss(struct hnae_handle *handle, u32 
*indir, u8 *key,
memcpy(key, ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE);
 
/* update the current hash->queue mappings from the shadow RSS table */
-   memcpy(indir, ppe_cb->rss_indir_table, HNS_PPEV2_RSS_IND_TBL_SIZE);
+   memcpy(indir, ppe_cb->rss_indir_table,
+  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
 
return 0;
 }
@@ -802,7 +803,8 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const 
u32 *indir,
hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
 
/* update the shadow RSS table with user specified qids */
-   memcpy(ppe_cb->rss_indir_table, indir, HNS_PPEV2_RSS_IND_TBL_SIZE);
+   memcpy(ppe_cb->rss_indir_table, indir,
+  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
 
/* now update the hardware */
hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3b914ac..24b2b5f 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1253,6 +1253,23 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, 
const u8 *key,
return ops->set_rss(priv->ae_handle, indir, key, hfunc);
 }
 
+static int hns_get_rxnfc(struct net_device *netdev,
+struct ethtool_rxnfc *cmd,
+u32 *rule_locs)
+{
+   struct hns_nic_priv *priv = netdev_priv(netdev);
+
+   switch (cmd->cmd) {
+   case ETHTOOL_GRXRINGS:
+   cmd->data = priv->ae_handle->q_num;
+   break;
+   default:
+   return -ERRNO;
+   }
+
+   return 0;
+}
+
 static struct ethtool_ops hns_ethtool_ops = {
.get_drvinfo = hns_nic_get_drvinfo,
.get_link  = hns_nic_get_link,
@@ -1276,6 +1293,7 @@ static struct ethtool_ops hns_ethtool_ops = {
.get_rxfh_indir_size = hns_get_rss_indir_size,
.get_rxfh = hns_get_rss,
.set_rxfh = hns_set_rss,
+   .get_rxnfc = hns_get_rxnfc,
 };
 
 void hns_ethtool_set_ops(struct net_device *ndev)
-- 
1.9.1



[PATCH v2 net-next 1/2] net: hns: fix return value of the function about rss

2016-03-10 Thread Kejian Yan
Both .get_rxfh and .get_rxfh are always return 0, it should return result
from hardware when getting or setting rss. And the rss function should
return the correct data type.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
change log:
PATCH v2:
 - This patch fixes the comments provided by Andy Shevchenko 

PATCH v1:
 - first submit

 Link: https://lkml.org/lkml/2016/3/9/978
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 12 
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index d4f92ed..d07db1f 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -799,7 +799,7 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const 
u32 *indir,
 
/* set the RSS Hash Key if specififed by the user */
if (key)
-   hns_ppe_set_rss_key(ppe_cb, (int *)key);
+   hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
 
/* update the shadow RSS table with user specified qids */
memcpy(ppe_cb->rss_indir_table, indir, HNS_PPEV2_RSS_IND_TBL_SIZE);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
index f302ef9..811ef35 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
@@ -27,7 +27,7 @@ void hns_ppe_set_tso_enable(struct hns_ppe_cb *ppe_cb, u32 
value)
 void hns_ppe_set_rss_key(struct hns_ppe_cb *ppe_cb,
 const u32 rss_key[HNS_PPEV2_RSS_KEY_NUM])
 {
-   int key_item = 0;
+   u32 key_item = 0;
 
for (key_item = 0; key_item < HNS_PPEV2_RSS_KEY_NUM; key_item++)
dsaf_write_dev(ppe_cb, PPEV2_RSS_KEY_REG + key_item * 0x4,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3c4a3bc..3b914ac 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1178,7 +1178,7 @@ hns_get_rss_key_size(struct net_device *netdev)
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
   "RSS feature is not supported on this hardware\n");
-   return -EOPNOTSUPP;
+   return (u32)-EOPNOTSUPP;
}
 
ops = priv->ae_handle->dev->ops;
@@ -1197,7 +1197,7 @@ hns_get_rss_indir_size(struct net_device *netdev)
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
   "RSS feature is not supported on this hardware\n");
-   return -EOPNOTSUPP;
+   return (u32)-EOPNOTSUPP;
}
 
ops = priv->ae_handle->dev->ops;
@@ -1224,9 +1224,7 @@ hns_get_rss(struct net_device *netdev, u32 *indir, u8 
*key, u8 *hfunc)
if (!indir)
return 0;
 
-   ret = ops->get_rss(priv->ae_handle, indir, key, hfunc);
-
-   return 0;
+   return ops->get_rss(priv->ae_handle, indir, key, hfunc);
 }
 
 static int
@@ -1252,9 +1250,7 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, 
const u8 *key,
if (!indir)
return 0;
 
-   ret = ops->set_rss(priv->ae_handle, indir, key, hfunc);
-
-   return 0;
+   return ops->set_rss(priv->ae_handle, indir, key, hfunc);
 }
 
 static struct ethtool_ops hns_ethtool_ops = {
-- 
1.9.1



[PATCH net] net: hns: bug fix about ping6

2016-03-09 Thread Kejian Yan
The current upstreaming code fails to ping other IPv6 net device, because
the enet receives the multicast packets with the src mac addr whick is the
same as its mac addr. These packets need to be dropped.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 3f77ff7..9ad5da4 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -564,6 +564,7 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data 
*ring_data,
struct sk_buff *skb;
struct hnae_desc *desc;
struct hnae_desc_cb *desc_cb;
+   struct ethhdr *eh;
unsigned char *va;
int bnum, length, i;
int pull_len;
@@ -670,6 +671,14 @@ out_bnum_err:
return -EFAULT;
}
 
+   /* filter out multicast pkt with the same src mac as this port */
+   eh = (struct ethhdr *)skb->data;
+   if (unlikely(is_multicast_ether_addr(eh->h_dest) &&
+ether_addr_equal(ndev->dev_addr, eh->h_source))) {
+   dev_kfree_skb_any(skb);
+   return -EFAULT;
+   }
+
ring->stats.rx_pkts++;
ring->stats.rx_bytes += skb->len;
 
-- 
1.9.1



[patch net 2/2] net: hns: fixes a bug of RSS

2016-03-09 Thread Kejian Yan
If trying to get receive flow hash indirection table by ethtool, it needs
to call .get_rxnfc to get ring number first. So this patch implements the
.get_rxnfc of ethtool. And the data type of rss_indir_table is u32, it has
to be multiply by the width of data type when using memcpy.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  6 --
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 20 
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 3b8f301..c733a5a 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -779,7 +779,8 @@ static int hns_ae_get_rss(struct hnae_handle *handle, u32 
*indir, u8 *key,
memcpy(key, ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE);
 
/* update the current hash->queue mappings from the shadow RSS table */
-   memcpy(indir, ppe_cb->rss_indir_table, HNS_PPEV2_RSS_IND_TBL_SIZE);
+   memcpy(indir, ppe_cb->rss_indir_table,
+  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
 
return 0;
 }
@@ -794,7 +795,8 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const 
u32 *indir,
hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
 
/* update the shadow RSS table with user specified qids */
-   memcpy(ppe_cb->rss_indir_table, indir, HNS_PPEV2_RSS_IND_TBL_SIZE);
+   memcpy(ppe_cb->rss_indir_table, indir,
+  HNS_PPEV2_RSS_IND_TBL_SIZE * sizeof(*indir));
 
/* now update the hardware */
hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index ada8e04..a070392 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1244,6 +1244,25 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, 
const u8 *key,
return ret;
 }
 
+static int hns_get_rxnfc(struct net_device *netdev,
+struct ethtool_rxnfc *cmd,
+u32 *rule_locs)
+{
+   struct hns_nic_priv *priv = netdev_priv(netdev);
+   int ret = 0;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_GRXRINGS:
+   cmd->data = priv->ae_handle->q_num;
+   break;
+   default:
+   ret = -EOPNOTSUPP;
+   break;
+   }
+
+   return ret;
+}
+
 static struct ethtool_ops hns_ethtool_ops = {
.get_drvinfo = hns_nic_get_drvinfo,
.get_link  = hns_nic_get_link,
@@ -1267,6 +1286,7 @@ static struct ethtool_ops hns_ethtool_ops = {
.get_rxfh_indir_size = hns_get_rss_indir_size,
.get_rxfh = hns_get_rss,
.set_rxfh = hns_set_rss,
+   .get_rxnfc = hns_get_rxnfc,
 };
 
 void hns_ethtool_set_ops(struct net_device *ndev)
-- 
1.9.1



[patch net 0/2] net: hns: get and set RSS indirection table by using ethtool

2016-03-09 Thread Kejian Yan
When we use ethtool to retrieves or configure the receive flow hash 
indirection table, ethtool needs to call .get_rxnfc to get the ring number
so this patchset implements the .get_rxnfc and fixes the bug that we can
not get the tatal table each time.

Kejian Yan (2):
  net: hns: fix return value of the function about rss
  net: hns: fixes a bug of RSS

 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  8 ---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 28 +++
 3 files changed, 30 insertions(+), 8 deletions(-)

-- 
1.9.1



[patch net 1/2] net: hns: fix return value of the function about rss

2016-03-09 Thread Kejian Yan
Both .get_rxfh and .get_rxfh are always return 0, it should return result
from hardware when getting or setting rss. And the rss function should
return the correct data type.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c | 2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c  | 8 
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index a0070d0..3b8f301 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -791,7 +791,7 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const 
u32 *indir,
 
/* set the RSS Hash Key if specififed by the user */
if (key)
-   hns_ppe_set_rss_key(ppe_cb, (int *)key);
+   hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
 
/* update the shadow RSS table with user specified qids */
memcpy(ppe_cb->rss_indir_table, indir, HNS_PPEV2_RSS_IND_TBL_SIZE);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
index f302ef9..811ef35 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
@@ -27,7 +27,7 @@ void hns_ppe_set_tso_enable(struct hns_ppe_cb *ppe_cb, u32 
value)
 void hns_ppe_set_rss_key(struct hns_ppe_cb *ppe_cb,
 const u32 rss_key[HNS_PPEV2_RSS_KEY_NUM])
 {
-   int key_item = 0;
+   u32 key_item = 0;
 
for (key_item = 0; key_item < HNS_PPEV2_RSS_KEY_NUM; key_item++)
dsaf_write_dev(ppe_cb, PPEV2_RSS_KEY_REG + key_item * 0x4,
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 3df2284..ada8e04 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1165,7 +1165,7 @@ hns_get_rss_key_size(struct net_device *netdev)
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
   "RSS feature is not supported on this hardware\n");
-   return -EOPNOTSUPP;
+   return (u32)-EOPNOTSUPP;
}
 
ops = priv->ae_handle->dev->ops;
@@ -1184,7 +1184,7 @@ hns_get_rss_indir_size(struct net_device *netdev)
if (AE_IS_VER1(priv->enet_ver)) {
netdev_err(netdev,
   "RSS feature is not supported on this hardware\n");
-   return -EOPNOTSUPP;
+   return (u32)-EOPNOTSUPP;
}
 
ops = priv->ae_handle->dev->ops;
@@ -1213,7 +1213,7 @@ hns_get_rss(struct net_device *netdev, u32 *indir, u8 
*key, u8 *hfunc)
 
ret = ops->get_rss(priv->ae_handle, indir, key, hfunc);
 
-   return 0;
+   return ret;
 }
 
 static int
@@ -1241,7 +1241,7 @@ hns_set_rss(struct net_device *netdev, const u32 *indir, 
const u8 *key,
 
ret = ops->set_rss(priv->ae_handle, indir, key, hfunc);
 
-   return 0;
+   return ret;
 }
 
 static struct ethtool_ops hns_ethtool_ops = {
-- 
1.9.1



[patch RESEND net] net: hns: fix the bug about mtu setting

2016-03-09 Thread Kejian Yan
In chip V1, the maximum mtu value is 9600 for service ports and 1514 for
debug ports. And in chip V2, it is 9728 for service ports and 1514 for
debug ports. But it is always configurates as 9600 before this patch. This
patch will configurate the right mtu value.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 7 ++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h | 2 ++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 3 +++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h | 2 ++
 4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 5ef0e96..65b8d91 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -467,8 +467,13 @@ int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu)
struct mac_driver *drv = hns_mac_get_drv(mac_cb);
u32 buf_size = mac_cb->dsaf_dev->buf_size;
u32 new_frm = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+   u32 max_frm = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver) ?
+   MAC_MAX_MTU : MAC_MAX_MTU_V2;
 
-   if ((new_mtu < MAC_MIN_MTU) || (new_frm > MAC_MAX_MTU) ||
+   if (mac_cb->mac_type == HNAE_PORT_DEBUG)
+   max_frm = MAC_MAX_MTU_DBG;
+
+   if ((new_mtu < MAC_MIN_MTU) || (new_frm > max_frm) ||
(new_frm > HNS_RCB_RING_MAX_BD_PER_PKT * buf_size))
return -EINVAL;
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index 0b05219..fc51e3d 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -26,7 +26,9 @@ struct dsaf_device;
 
 #define MAC_DEFAULT_MTU(ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN + 
ETH_DATA_LEN)
 #define MAC_MAX_MTU9600
+#define MAC_MAX_MTU_V2 9728
 #define MAC_MIN_MTU68
+#define MAC_MAX_MTU_DBG MAC_DEFAULT_MTU
 
 #define MAC_DEFAULT_PAUSE_TIME 0xff
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
index f302ef9..7a61c57 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
@@ -343,6 +343,9 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb)
if (!AE_IS_VER1(dsaf_dev->dsaf_ver)) {
hns_ppe_set_vlan_strip(ppe_cb, 0);
 
+   dsaf_write_dev(ppe_cb, PPE_CFG_MAX_FRAME_LEN_REG,
+  HNS_PPEV2_MAX_FRAME_LEN);
+
/* set default RSS key in h/w */
hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key);
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h
index 0f5cb69..e9c0ec2 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h
@@ -30,6 +30,8 @@
 #define HNS_PPEV2_RSS_KEY_SIZE 40 /* in bytes or 320 bits */
 #define HNS_PPEV2_RSS_KEY_NUM (HNS_PPEV2_RSS_KEY_SIZE / sizeof(u32))
 
+#define HNS_PPEV2_MAX_FRAME_LEN 0X980
+
 enum ppe_qid_mode {
PPE_QID_MODE0 = 0, /* fixed queue id mode */
PPE_QID_MODE1, /* switch:128VM non switch:6Port/4VM/4TC */
-- 
1.9.1



[PATCH v2 net] net: hns: fix the bug about loopback

2016-03-04 Thread Kejian Yan
It will always be passed if the soc is tested the loopback cases. This
patch will fix this bug.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
change log:
PATCH v2:
 - This patch fixes the comments provided by Andy Shevchenko 

PATCH v1:
 - first submit

 Link: https://lkml.org/lkml/2016/3/3/266
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  |  8 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 37 ++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  1 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |  5 +++
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   | 15 -
 5 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index a0070d0..d4f92ed 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -675,8 +675,12 @@ static int hns_ae_config_loopback(struct hnae_handle 
*handle,
 {
int ret;
struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle);
+   struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
 
switch (loop) {
+   case MAC_INTERNALLOOP_PHY:
+   ret = 0;
+   break;
case MAC_INTERNALLOOP_SERDES:
ret = hns_mac_config_sds_loopback(vf_cb->mac_cb, en);
break;
@@ -686,6 +690,10 @@ static int hns_ae_config_loopback(struct hnae_handle 
*handle,
default:
ret = -EINVAL;
}
+
+   if (!ret)
+   hns_dsaf_set_inner_lb(mac_cb->dsaf_dev, mac_cb->mac_id, en);
+
return ret;
 }
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 9439f04..38fc5be 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -230,6 +230,30 @@ static void hns_dsaf_mix_def_qid_cfg(struct dsaf_device 
*dsaf_dev)
}
 }
 
+static void hns_dsaf_inner_qid_cfg(struct dsaf_device *dsaf_dev)
+{
+   u16 max_q_per_vf, max_vfn;
+   u32 q_id, q_num_per_port;
+   u32 mac_id;
+
+   if (AE_IS_VER1(dsaf_dev->dsaf_ver))
+   return;
+
+   hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode,
+  HNS_DSAF_COMM_SERVICE_NW_IDX,
+  _vfn, _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++) {
+   dsaf_set_dev_field(dsaf_dev,
+  DSAFV2_SERDES_LBK_0_REG + 4 * mac_id,
+  DSAFV2_SERDES_LBK_QID_M,
+  DSAFV2_SERDES_LBK_QID_S,
+  q_id);
+   q_id += q_num_per_port;
+   }
+}
+
 /**
  * hns_dsaf_sw_port_type_cfg - cfg sw type
  * @dsaf_id: dsa fabric id
@@ -691,6 +715,16 @@ 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);
 }
 
+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)
+   return;
+
+   dsaf_set_dev_bit(dsaf_dev, DSAFV2_SERDES_LBK_0_REG + 4 * mac_id,
+DSAFV2_SERDES_LBK_EN_B, !!en);
+}
+
 /**
  * hns_dsaf_tbl_stat_en - tbl
  * @dsaf_id: dsa fabric id
@@ -1022,6 +1056,9 @@ static void hns_dsaf_comm_init(struct dsaf_device 
*dsaf_dev)
/* set promisc def queue id */
hns_dsaf_mix_def_qid_cfg(dsaf_dev);
 
+   /* set inner loopback queue id */
+   hns_dsaf_inner_qid_cfg(dsaf_dev);
+
/* in non switch mode, set all port to access mode */
hns_dsaf_sw_port_type_cfg(dsaf_dev, DSAF_SW_PORT_TYPE_NON_VLAN);
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index 40205b9..5fea226 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -417,5 +417,6 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int 
port);
 void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data);
 int hns_dsaf_get_regs_count(void);
 void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en);
+void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en);
 
 #endif /* __HNS_DSAF_MAIN_H__ */
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index f0c4f9b..60d695d 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -134,6 +134,7 @@
 #define DSAF_XGE_INT_STS_0_REG 0x1C0
 #define DSAF_PPE_INT_ST

[PATCH net] net: hns: fix the fault about mtu setting

2016-03-03 Thread Kejian Yan
As the User Manual describes, maximum value are 9728 for service ports and
1500 for debug ports, not always 9600. So it needs to be configured to
right value for the different port. The max frame len of ppe needs to be
set to the right as well.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 7 ++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h | 2 ++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 3 +++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h | 2 ++
 4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 5ef0e96..65b8d91 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -467,8 +467,13 @@ int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu)
struct mac_driver *drv = hns_mac_get_drv(mac_cb);
u32 buf_size = mac_cb->dsaf_dev->buf_size;
u32 new_frm = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+   u32 max_frm = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver) ?
+   MAC_MAX_MTU : MAC_MAX_MTU_V2;
 
-   if ((new_mtu < MAC_MIN_MTU) || (new_frm > MAC_MAX_MTU) ||
+   if (mac_cb->mac_type == HNAE_PORT_DEBUG)
+   max_frm = MAC_MAX_MTU_DBG;
+
+   if ((new_mtu < MAC_MIN_MTU) || (new_frm > max_frm) ||
(new_frm > HNS_RCB_RING_MAX_BD_PER_PKT * buf_size))
return -EINVAL;
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index 0b05219..fc51e3d 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -26,7 +26,9 @@ struct dsaf_device;
 
 #define MAC_DEFAULT_MTU(ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN + 
ETH_DATA_LEN)
 #define MAC_MAX_MTU9600
+#define MAC_MAX_MTU_V2 9728
 #define MAC_MIN_MTU68
+#define MAC_MAX_MTU_DBG MAC_DEFAULT_MTU
 
 #define MAC_DEFAULT_PAUSE_TIME 0xff
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
index f302ef9..7a61c57 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
@@ -343,6 +343,9 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb)
if (!AE_IS_VER1(dsaf_dev->dsaf_ver)) {
hns_ppe_set_vlan_strip(ppe_cb, 0);
 
+   dsaf_write_dev(ppe_cb, PPE_CFG_MAX_FRAME_LEN_REG,
+  HNS_PPEV2_MAX_FRAME_LEN);
+
/* set default RSS key in h/w */
hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key);
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h
index 0f5cb69..e9c0ec2 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h
@@ -30,6 +30,8 @@
 #define HNS_PPEV2_RSS_KEY_SIZE 40 /* in bytes or 320 bits */
 #define HNS_PPEV2_RSS_KEY_NUM (HNS_PPEV2_RSS_KEY_SIZE / sizeof(u32))
 
+#define HNS_PPEV2_MAX_FRAME_LEN 0X980
+
 enum ppe_qid_mode {
PPE_QID_MODE0 = 0, /* fixed queue id mode */
PPE_QID_MODE1, /* switch:128VM non switch:6Port/4VM/4TC */
-- 
1.9.1



[PATCH net] net: hns: fix the bug about loopback

2016-03-03 Thread Kejian Yan
It will always be passed if the soc is tested the loopback cases. This
patch will fix this bug.

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  |  8 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 37 
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  1 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |  6 
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   | 40 ++
 5 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index a0070d0..d4f92ed 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -675,8 +675,12 @@ static int hns_ae_config_loopback(struct hnae_handle 
*handle,
 {
int ret;
struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle);
+   struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
 
switch (loop) {
+   case MAC_INTERNALLOOP_PHY:
+   ret = 0;
+   break;
case MAC_INTERNALLOOP_SERDES:
ret = hns_mac_config_sds_loopback(vf_cb->mac_cb, en);
break;
@@ -686,6 +690,10 @@ static int hns_ae_config_loopback(struct hnae_handle 
*handle,
default:
ret = -EINVAL;
}
+
+   if (!ret)
+   hns_dsaf_set_inner_lb(mac_cb->dsaf_dev, mac_cb->mac_id, en);
+
return ret;
 }
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 9439f04..dcf4e8a 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -230,6 +230,30 @@ static void hns_dsaf_mix_def_qid_cfg(struct dsaf_device 
*dsaf_dev)
}
 }
 
+static void hns_dsaf_inner_qid_cfg(struct dsaf_device *dsaf_dev)
+{
+   u16 max_q_per_vf, max_vfn;
+   u32 q_id = 0, q_num_per_port;
+   u32 mac_id;
+
+   if (AE_IS_VER1(dsaf_dev->dsaf_ver))
+   return;
+
+   hns_rcb_get_queue_mode(dsaf_dev->dsaf_mode,
+  HNS_DSAF_COMM_SERVICE_NW_IDX,
+  _vfn, _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++) {
+   dsaf_set_dev_field(dsaf_dev,
+  DSAFV2_SERDES_LBK_0_REG + 0x4 * mac_id,
+  DSAFV2_SERDES_LBK_QID_M,
+  DSAFV2_SERDES_LBK_QID_S,
+  q_id);
+   q_id += q_num_per_port;
+   }
+}
+
 /**
  * hns_dsaf_sw_port_type_cfg - cfg sw type
  * @dsaf_id: dsa fabric id
@@ -691,6 +715,16 @@ 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);
 }
 
+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)
+   return;
+
+   dsaf_set_dev_bit(dsaf_dev, DSAFV2_SERDES_LBK_0_REG + 0x4 * mac_id,
+DSAFV2_SERDES_LBK_EN_B, !!en);
+}
+
 /**
  * hns_dsaf_tbl_stat_en - tbl
  * @dsaf_id: dsa fabric id
@@ -1022,6 +1056,9 @@ static void hns_dsaf_comm_init(struct dsaf_device 
*dsaf_dev)
/* set promisc def queue id */
hns_dsaf_mix_def_qid_cfg(dsaf_dev);
 
+   /* set inner loopback queue id */
+   hns_dsaf_inner_qid_cfg(dsaf_dev);
+
/* in non switch mode, set all port to access mode */
hns_dsaf_sw_port_type_cfg(dsaf_dev, DSAF_SW_PORT_TYPE_NON_VLAN);
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index 40205b9..5fea226 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -417,5 +417,6 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int 
port);
 void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data);
 int hns_dsaf_get_regs_count(void);
 void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en);
+void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en);
 
 #endif /* __HNS_DSAF_MAIN_H__ */
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h 
b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index f0c4f9b..3bb044b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -134,6 +134,7 @@
 #define DSAF_XGE_INT_STS_0_REG 0x1C0
 #define DSAF_PPE_INT_STS_0_REG 0x1E0
 #define DSAF_ROCEE_INT_STS_0_REG   0x200
+#define DSAFV2_SERDES_LBK_0_REG 0x220
 #define DSAF_PPE_QID_CF

[PATCH v2 net-next] net: hns: optimize XGE capability by reducing cpu usage

2015-12-07 Thread Kejian Yan
here is the patch raising the performance of XGE by:
1)changes the way page management method for enet momery, and
2)reduces the count of rmb, and
3)adds Memory prefetching

Signed-off-by: Kejian Yan <yankej...@huawei.com>
---
change log:
v2:
 fixes the review comments by Devid and joe:
 - makes indented properly
 - removes useless variable initialization

v1:
 Intial driver Version

v1 patch reference: https://lkml.org/lkml/2015/12/5/20
---
 drivers/net/ethernet/hisilicon/hns/hnae.h |  5 +-
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  1 -
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 79 +++
 3 files changed, 55 insertions(+), 30 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h 
b/drivers/net/ethernet/hisilicon/hns/hnae.h
index d1f3316..6ca94dc 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.h
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -341,7 +341,8 @@ struct hnae_queue {
void __iomem *io_base;
phys_addr_t phy_base;
struct hnae_ae_dev *dev;/* the device who use this queue */
-   struct hnae_ring rx_ring, tx_ring;
+   struct hnae_ring rx_ring cacheline_internodealigned_in_smp;
+   struct hnae_ring tx_ring cacheline_internodealigned_in_smp;
struct hnae_handle *handle;
 };
 
@@ -597,11 +598,9 @@ static inline void hnae_replace_buffer(struct hnae_ring 
*ring, int i,
   struct hnae_desc_cb *res_cb)
 {
struct hnae_buf_ops *bops = ring->q->handle->bops;
-   struct hnae_desc_cb tmp_cb = ring->desc_cb[i];
 
bops->unmap_buffer(ring, >desc_cb[i]);
ring->desc_cb[i] = *res_cb;
-   *res_cb = tmp_cb;
ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c 
b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 77c6edb..522b264 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -341,7 +341,6 @@ void hns_ae_toggle_ring_irq(struct hnae_ring *ring, u32 
mask)
else
flag = RCB_INT_FLAG_RX;
 
-   hns_rcb_int_clr_hw(ring->q, flag);
hns_rcb_int_ctrl_hw(ring->q, flag, mask);
 }
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index cad2663..5a81daf 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -33,6 +33,7 @@
 
 #define RCB_IRQ_NOT_INITED 0
 #define RCB_IRQ_INITED 1
+#define HNS_BUFFER_SIZE_2048 2048
 
 #define BD_MAX_SEND_SIZE 8191
 #define SKB_TMP_LEN(SKB) \
@@ -491,13 +492,51 @@ static unsigned int hns_nic_get_headlen(unsigned char 
*data, u32 flag,
return max_size;
 }
 
-static void
-hns_nic_reuse_page(struct hnae_desc_cb *desc_cb, int tsize, int last_offset)
+static void hns_nic_reuse_page(struct sk_buff *skb, int i,
+  struct hnae_ring *ring, int pull_len,
+  struct hnae_desc_cb *desc_cb)
 {
+   struct hnae_desc *desc;
+   int truesize, size;
+   int last_offset;
+
+   desc = >desc[ring->next_to_clean];
+   size = le16_to_cpu(desc->rx.size);
+
+#if (PAGE_SIZE < 8192)
+   if (hnae_buf_size(ring) == HNS_BUFFER_SIZE_2048) {
+   truesize = hnae_buf_size(ring);
+   } else {
+   truesize = ALIGN(size, L1_CACHE_BYTES);
+   last_offset = hnae_page_size(ring) - hnae_buf_size(ring);
+   }
+
+#else
+   truesize = ALIGN(size, L1_CACHE_BYTES);
+   last_offset = hnae_page_size(ring) - hnae_buf_size(ring);
+#endif
+
+   skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len,
+   size - pull_len, truesize - pull_len);
+
 /* avoid re-using remote pages,flag default unreuse */
if (likely(page_to_nid(desc_cb->priv) == numa_node_id())) {
+#if (PAGE_SIZE < 8192)
+   if (hnae_buf_size(ring) == HNS_BUFFER_SIZE_2048) {
+   /* if we are only owner of page we can reuse it */
+   if (likely(page_count(desc_cb->priv) == 1)) {
+   /* flip page offset to other buffer */
+   desc_cb->page_offset ^= truesize;
+
+   desc_cb->reuse_flag = 1;
+   /* bump ref count on page before it is given*/
+   get_page(desc_cb->priv);
+   }
+   return;
+   }
+#endif
/* move offset up to the next cache line */
-   desc_cb->page_offset += tsize;
+   desc_cb->page_offset += truesize;
 
if (desc_cb->page_offset <= last_offset) {