Commit b1c6a3a4 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns-acpi'

Kejian Yan says:

====================
net: hns: add support of ACPI

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:
 v3->v4:
  mii-id gets from dev-name instead of address

 v2->v3:
 1. add Review-by: Andy Shevchenko
 2. fix the potential memory leak

 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
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 169fbdc6 63434888
...@@ -96,16 +96,22 @@ static int __ae_match(struct device *dev, const void *data) ...@@ -96,16 +96,22 @@ static int __ae_match(struct device *dev, const void *data)
{ {
struct hnae_ae_dev *hdev = cls_to_ae_dev(dev); struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
return hdev->dev->of_node == data; if (dev_of_node(hdev->dev))
return (data == &hdev->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 device_node *ae_node) static struct hnae_ae_dev *find_ae(const struct fwnode_handle *fwnode)
{ {
struct device *dev; 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; return dev ? cls_to_ae_dev(dev) : NULL;
} }
...@@ -312,7 +318,7 @@ EXPORT_SYMBOL(hnae_reinit_handle); ...@@ -312,7 +318,7 @@ EXPORT_SYMBOL(hnae_reinit_handle);
* return handle ptr or ERR_PTR * return handle ptr or ERR_PTR
*/ */
struct hnae_handle *hnae_get_handle(struct device *owner_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, u32 port_id,
struct hnae_buf_ops *bops) struct hnae_buf_ops *bops)
{ {
...@@ -321,7 +327,7 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev, ...@@ -321,7 +327,7 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev,
int i, j; int i, j;
int ret; int ret;
dev = find_ae(ae_node); dev = find_ae(fwnode);
if (!dev) if (!dev)
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
* "cb" means control block * "cb" means control block
*/ */
#include <linux/acpi.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -512,7 +513,7 @@ struct hnae_ae_dev { ...@@ -512,7 +513,7 @@ struct hnae_ae_dev {
struct hnae_handle { struct hnae_handle {
struct device *owner_dev; /* the device which make use of this 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 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; phy_interface_t phy_if;
u32 if_support; u32 if_support;
int q_num; int q_num;
...@@ -528,7 +529,7 @@ struct hnae_handle { ...@@ -528,7 +529,7 @@ struct hnae_handle {
#define ring_to_dev(ring) ((ring)->q->dev->dev) #define ring_to_dev(ring) ((ring)->q->dev->dev)
struct hnae_handle *hnae_get_handle(struct device *owner_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, u32 port_id,
struct hnae_buf_ops *bops); struct hnae_buf_ops *bops);
......
...@@ -131,7 +131,7 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev, ...@@ -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]; vf_cb->mac_cb = dsaf_dev->mac_cb[port_id];
ae_handle->phy_if = vf_cb->mac_cb->phy_if; 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->if_support = vf_cb->mac_cb->if_support;
ae_handle->port_type = vf_cb->mac_cb->mac_type; ae_handle->port_type = vf_cb->mac_cb->mac_type;
ae_handle->dport_id = port_id; ae_handle->dport_id = port_id;
...@@ -637,13 +637,15 @@ static int hns_ae_config_loopback(struct hnae_handle *handle, ...@@ -637,13 +637,15 @@ static int hns_ae_config_loopback(struct hnae_handle *handle,
int ret; int ret;
struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle); struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle);
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle); struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
switch (loop) { switch (loop) {
case MAC_INTERNALLOOP_PHY: case MAC_INTERNALLOOP_PHY:
ret = 0; ret = 0;
break; break;
case MAC_INTERNALLOOP_SERDES: 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; break;
case MAC_INTERNALLOOP_MAC: case MAC_INTERNALLOOP_MAC:
ret = hns_mac_config_mac_loopback(vf_cb->mac_cb, loop, en); ret = hns_mac_config_mac_loopback(vf_cb->mac_cb, loop, en);
......
...@@ -110,7 +110,7 @@ static void hns_gmac_free(void *mac_drv) ...@@ -110,7 +110,7 @@ static void hns_gmac_free(void *mac_drv)
u32 mac_id = drv->mac_id; 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) 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) ...@@ -317,9 +317,9 @@ static void hns_gmac_init(void *mac_drv)
port = drv->mac_id; 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); mdelay(10);
hns_dsaf_ge_srst_by_port(dsaf_dev, port, 1); dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 1);
mdelay(10); mdelay(10);
hns_gmac_disable(mac_drv, MAC_COMM_MODE_RX_AND_TX); hns_gmac_disable(mac_drv, MAC_COMM_MODE_RX_AND_TX);
hns_gmac_tx_loop_pkt_dis(mac_drv); hns_gmac_tx_loop_pkt_dis(mac_drv);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#include <linux/acpi.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -15,7 +16,8 @@ ...@@ -15,7 +16,8 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/phy_fixed.h> #include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include "hns_dsaf_main.h" #include "hns_dsaf_main.h"
...@@ -94,7 +96,7 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) ...@@ -94,7 +96,7 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
else else
*link_status = 0; *link_status = 0;
ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt); ret = mac_cb->dsaf_dev->misc_op->get_sfp_prsnt(mac_cb, &sfp_prsnt);
if (!ret) if (!ret)
*link_status = *link_status && sfp_prsnt; *link_status = *link_status && sfp_prsnt;
...@@ -511,7 +513,7 @@ void hns_mac_stop(struct hns_mac_cb *mac_cb) ...@@ -511,7 +513,7 @@ void hns_mac_stop(struct hns_mac_cb *mac_cb)
mac_ctrl_drv->mac_en_flg = 0; mac_ctrl_drv->mac_en_flg = 0;
mac_cb->link = 0; mac_cb->link = 0;
cpld_led_reset(mac_cb); mac_cb->dsaf_dev->misc_op->cpld_reset_led(mac_cb);
} }
/** /**
...@@ -637,6 +639,115 @@ static int hns_mac_init_ex(struct hns_mac_cb *mac_cb) ...@@ -637,6 +639,115 @@ static int hns_mac_init_ex(struct hns_mac_cb *mac_cb)
return ret; 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", &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(&platform_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", &phy_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(&mdio->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, &args);
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 (!rc)
dev_dbg(mac_cb->dev, "mac%d register phy addr:%d\n",
mac_cb->mac_id, addr);
}
/** /**
*hns_mac_get_info - get mac information from device node *hns_mac_get_info - get mac information from device node
*@mac_cb: mac device *@mac_cb: mac device
...@@ -645,7 +756,7 @@ static int hns_mac_init_ex(struct hns_mac_cb *mac_cb) ...@@ -645,7 +756,7 @@ static int hns_mac_init_ex(struct hns_mac_cb *mac_cb)
*/ */
static int hns_mac_get_info(struct hns_mac_cb *mac_cb) 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 regmap *syscon;
struct of_phandle_args cpld_args; struct of_phandle_args cpld_args;
u32 ret; u32 ret;
...@@ -672,63 +783,85 @@ static int hns_mac_get_info(struct hns_mac_cb *mac_cb) ...@@ -672,63 +783,85 @@ static int hns_mac_get_info(struct hns_mac_cb *mac_cb)
* from dsaf node * from dsaf node
*/ */
if (!mac_cb->fw_port) { if (!mac_cb->fw_port) {
mac_cb->phy_node = of_parse_phandle(np, "phy-handle", np = of_parse_phandle(mac_cb->dev->of_node, "phy-handle",
mac_cb->mac_id); mac_cb->mac_id);
if (mac_cb->phy_node) 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(&mac_cb->phy_dev->mdio.dev);
dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n", dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n",
mac_cb->mac_id, mac_cb->phy_node->name); mac_cb->mac_id, np->name);
return 0; }
}
if (!is_of_node(mac_cb->fw_port))
return -EINVAL;
/* parse property from port subnode in dsaf */
mac_cb->phy_node = of_parse_phandle(to_of_node(mac_cb->fw_port),
"phy-handle", 0);
if (mac_cb->phy_node)
dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n",
mac_cb->mac_id, mac_cb->phy_node->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, return 0;
"port-rst-offset",
&mac_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 = fwnode_property_read_u32(mac_cb->fw_port, if (is_of_node(mac_cb->fw_port)) {
"port-mode-offset", /* parse property from port subnode in dsaf */
&mac_cb->port_mode_off); np = of_parse_phandle(to_of_node(mac_cb->fw_port),
if (ret) { "phy-handle", 0);
dev_dbg(mac_cb->dev, mac_cb->phy_dev = of_phy_find_device(np);
"mac%d port-mode-offset not found, use default value.\n", if (mac_cb->phy_dev) {
mac_cb->mac_id); /* refcount is held by of_phy_find_device()
} * if the phy_dev is found
*/
put_device(&mac_cb->phy_dev->mdio.dev);
dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n",
mac_cb->mac_id, np->name);
}
ret = of_parse_phandle_with_fixed_args(to_of_node(mac_cb->fw_port), syscon = syscon_node_to_regmap(
"cpld-syscon", 1, 0, &cpld_args); of_parse_phandle(to_of_node(mac_cb->fw_port),
if (ret) { "serdes-syscon", 0));
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)) { if (IS_ERR_OR_NULL(syscon)) {
dev_dbg(mac_cb->dev, "no cpld-syscon found!\n"); 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",
&mac_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 = fwnode_property_read_u32(mac_cb->fw_port,
"port-mode-offset",
&mac_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), "cpld-syscon", 1, 0,
&cpld_args);
if (ret) {
dev_dbg(mac_cb->dev, "mac%d no cpld-syscon found.\n",
mac_cb->mac_id);
mac_cb->cpld_ctrl = NULL; mac_cb->cpld_ctrl = NULL;
} else { } else {
mac_cb->cpld_ctrl = syscon; syscon = syscon_node_to_regmap(cpld_args.np);
mac_cb->cpld_ctrl_reg = cpld_args.args[0]; if (IS_ERR_OR_NULL(syscon)) {
dev_dbg(mac_cb->dev, "no cpld-syscon found!\n");
mac_cb->cpld_ctrl = NULL;
} else {
mac_cb->cpld_ctrl = syscon;
mac_cb->cpld_ctrl_reg = cpld_args.args[0];
}
} }
} else if (is_acpi_node(mac_cb->fw_port)) {
hns_mac_register_phy(mac_cb);
} else {
dev_err(mac_cb->dev, "mac%d cannot find phy node\n",
mac_cb->mac_id);
} }
return 0; return 0;
...@@ -790,7 +923,7 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct hns_mac_cb *mac_cb) ...@@ -790,7 +923,7 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct hns_mac_cb *mac_cb)
else else
mac_cb->mac_type = HNAE_PORT_DEBUG; 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); ret = hns_mac_get_mode(mac_cb->phy_if);
if (ret < 0) { if (ret < 0) {
...@@ -805,7 +938,7 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct hns_mac_cb *mac_cb) ...@@ -805,7 +938,7 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct hns_mac_cb *mac_cb)
if (ret) if (ret)
return 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); mac_cb->vaddr = hns_mac_get_vaddr(dsaf_dev, mac_cb, mac_mode_idx);
return 0; return 0;
...@@ -892,7 +1025,7 @@ void hns_mac_uninit(struct dsaf_device *dsaf_dev) ...@@ -892,7 +1025,7 @@ void hns_mac_uninit(struct dsaf_device *dsaf_dev)
int max_port_num = hns_mac_get_max_port_num(dsaf_dev); int max_port_num = hns_mac_get_max_port_num(dsaf_dev);
for (i = 0; i < max_port_num; i++) { 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->mac_cb[i]);
dsaf_dev->mac_cb[i] = NULL; dsaf_dev->mac_cb[i] = NULL;
} }
} }
...@@ -975,7 +1108,7 @@ void hns_set_led_opt(struct hns_mac_cb *mac_cb) ...@@ -975,7 +1108,7 @@ void hns_set_led_opt(struct hns_mac_cb *mac_cb)
nic_data = 0; nic_data = 0;
mac_cb->txpkt_for_led = mac_cb->hw_stats.tx_good_pkts; mac_cb->txpkt_for_led = mac_cb->hw_stats.tx_good_pkts;
mac_cb->rxpkt_for_led = mac_cb->hw_stats.rx_good_pkts; mac_cb->rxpkt_for_led = mac_cb->hw_stats.rx_good_pkts;
hns_cpld_set_led(mac_cb, (int)mac_cb->link, mac_cb->dsaf_dev->misc_op->cpld_set_led(mac_cb, (int)mac_cb->link,
mac_cb->speed, nic_data); mac_cb->speed, nic_data);
} }
...@@ -985,5 +1118,5 @@ int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb, ...@@ -985,5 +1118,5 @@ int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb,
if (!mac_cb || !mac_cb->cpld_ctrl) if (!mac_cb || !mac_cb->cpld_ctrl)
return 0; return 0;
return cpld_set_led_id(mac_cb, status); return mac_cb->dsaf_dev->misc_op->cpld_set_led_id(mac_cb, status);
} }
...@@ -338,7 +338,7 @@ struct hns_mac_cb { ...@@ -338,7 +338,7 @@ struct hns_mac_cb {
phy_interface_t phy_if; phy_interface_t phy_if;
enum hnae_loop loop_mode; enum hnae_loop loop_mode;
struct device_node *phy_node; struct phy_device *phy_dev;
struct mac_hw_stats hw_stats; struct mac_hw_stats hw_stats;
}; };
...@@ -448,8 +448,6 @@ int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en); ...@@ -448,8 +448,6 @@ int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en);
int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu); int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu);
int hns_mac_get_port_info(struct hns_mac_cb *mac_cb, int hns_mac_get_port_info(struct hns_mac_cb *mac_cb,
u8 *auto_neg, u16 *speed, u8 *duplex); u8 *auto_neg, u16 *speed, u8 *duplex);
phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb);
int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en);
int hns_mac_config_mac_loopback(struct hns_mac_cb *mac_cb, int hns_mac_config_mac_loopback(struct hns_mac_cb *mac_cb,
enum hnae_loop loop, int en); enum hnae_loop loop, int en);
void hns_mac_update_stats(struct hns_mac_cb *mac_cb); void hns_mac_update_stats(struct hns_mac_cb *mac_cb);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#include <linux/acpi.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
#include "hns_dsaf_main.h" #include "hns_dsaf_main.h"
#include "hns_dsaf_ppe.h" #include "hns_dsaf_ppe.h"
#include "hns_dsaf_rcb.h" #include "hns_dsaf_rcb.h"
#include "hns_dsaf_misc.h"
const char *g_dsaf_mode_match[DSAF_MODE_MAX] = { const char *g_dsaf_mode_match[DSAF_MODE_MAX] = {
[DSAF_MODE_DISABLE_2PORT_64VM] = "2port-64vf", [DSAF_MODE_DISABLE_2PORT_64VM] = "2port-64vf",
...@@ -32,6 +34,13 @@ const char *g_dsaf_mode_match[DSAF_MODE_MAX] = { ...@@ -32,6 +34,13 @@ const char *g_dsaf_mode_match[DSAF_MODE_MAX] = {
[DSAF_MODE_DISABLE_SP] = "single-port", [DSAF_MODE_DISABLE_SP] = "single-port",
}; };
static const struct acpi_device_id hns_dsaf_acpi_match[] = {
{ "HISI00B1", 0 },
{ "HISI00B2", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, hns_dsaf_acpi_match);
int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
{ {
int ret, i; int ret, i;
...@@ -45,12 +54,24 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) ...@@ -45,12 +54,24 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
struct device_node *np = dsaf_dev->dev->of_node; struct device_node *np = dsaf_dev->dev->of_node;
struct platform_device *pdev = to_platform_device(dsaf_dev->dev); struct platform_device *pdev = to_platform_device(dsaf_dev->dev);
if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1")) if (dev_of_node(dsaf_dev->dev)) {
dsaf_dev->dsaf_ver = AE_VERSION_1; if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1"))
else dsaf_dev->dsaf_ver = AE_VERSION_1;
dsaf_dev->dsaf_ver = AE_VERSION_2; else
dsaf_dev->dsaf_ver = AE_VERSION_2;
} else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
if (acpi_dev_found(hns_dsaf_acpi_match[0].id))
dsaf_dev->dsaf_ver = AE_VERSION_1;
else if (acpi_dev_found(hns_dsaf_acpi_match[1].id))
dsaf_dev->dsaf_ver = AE_VERSION_2;
else
return -ENXIO;
} else {
dev_err(dsaf_dev->dev, "cannot get cfg data from of or acpi\n");
return -ENXIO;
}
ret = of_property_read_string(np, "mode", &mode_str); ret = device_property_read_string(dsaf_dev->dev, "mode", &mode_str);
if (ret) { if (ret) {
dev_err(dsaf_dev->dev, "get dsaf mode fail, ret=%d!\n", ret); dev_err(dsaf_dev->dev, "get dsaf mode fail, ret=%d!\n", ret);
return ret; return ret;
...@@ -80,32 +101,40 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) ...@@ -80,32 +101,40 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
else else
dsaf_dev->dsaf_tc_mode = HRD_DSAF_4TC_MODE; dsaf_dev->dsaf_tc_mode = HRD_DSAF_4TC_MODE;
syscon = syscon_node_to_regmap( if (dev_of_node(dsaf_dev->dev)) {
of_parse_phandle(np, "subctrl-syscon", 0)); syscon = syscon_node_to_regmap(
if (IS_ERR_OR_NULL(syscon)) { of_parse_phandle(np, "subctrl-syscon", 0));
res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++); if (IS_ERR_OR_NULL(syscon)) {
if (!res) { res = platform_get_resource(pdev, IORESOURCE_MEM,
dev_err(dsaf_dev->dev, "subctrl info is needed!\n"); res_idx++);
return -ENOMEM; if (!res) {
} dev_err(dsaf_dev->dev, "subctrl info is needed!\n");
dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev, res); return -ENOMEM;
if (!dsaf_dev->sc_base) { }
dev_err(dsaf_dev->dev, "subctrl can not map!\n");
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++); dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev,
if (!res) { res);
dev_err(dsaf_dev->dev, "serdes-ctrl info is needed!\n"); if (!dsaf_dev->sc_base) {
return -ENOMEM; dev_err(dsaf_dev->dev, "subctrl can not map!\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"); res = platform_get_resource(pdev, IORESOURCE_MEM,
return -ENOMEM; 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;
} }
} else {
dsaf_dev->sub_ctrl = syscon;
} }
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe-base"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe-base");
...@@ -142,7 +171,7 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) ...@@ -142,7 +171,7 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
} }
} }
ret = of_property_read_u32(np, "desc-num", &desc_num); ret = device_property_read_u32(dsaf_dev->dev, "desc-num", &desc_num);
if (ret < 0 || desc_num < HNS_DSAF_MIN_DESC_CNT || if (ret < 0 || desc_num < HNS_DSAF_MIN_DESC_CNT ||
desc_num > HNS_DSAF_MAX_DESC_CNT) { desc_num > HNS_DSAF_MAX_DESC_CNT) {
dev_err(dsaf_dev->dev, "get desc-num(%d) fail, ret=%d!\n", dev_err(dsaf_dev->dev, "get desc-num(%d) fail, ret=%d!\n",
...@@ -151,14 +180,15 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) ...@@ -151,14 +180,15 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
} }
dsaf_dev->desc_num = desc_num; dsaf_dev->desc_num = desc_num;
ret = of_property_read_u32(np, "reset-field-offset", &reset_offset); ret = device_property_read_u32(dsaf_dev->dev, "reset-field-offset",
&reset_offset);
if (ret < 0) { if (ret < 0) {
dev_dbg(dsaf_dev->dev, dev_dbg(dsaf_dev->dev,
"get reset-field-offset fail, ret=%d!\r\n", ret); "get reset-field-offset fail, ret=%d!\r\n", ret);
} }
dsaf_dev->reset_offset = reset_offset; dsaf_dev->reset_offset = reset_offset;
ret = of_property_read_u32(np, "buf-size", &buf_size); ret = device_property_read_u32(dsaf_dev->dev, "buf-size", &buf_size);
if (ret < 0) { if (ret < 0) {
dev_err(dsaf_dev->dev, dev_err(dsaf_dev->dev,
"get buf-size fail, ret=%d!\r\n", ret); "get buf-size fail, ret=%d!\r\n", ret);
...@@ -173,6 +203,10 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) ...@@ -173,6 +203,10 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
goto unmap_base_addr; goto unmap_base_addr;
} }
dsaf_dev->misc_op = hns_misc_op_get(dsaf_dev);
if (!dsaf_dev->misc_op)
return -ENOMEM;
if (!dma_set_mask_and_coherent(dsaf_dev->dev, DMA_BIT_MASK(64ULL))) if (!dma_set_mask_and_coherent(dsaf_dev->dev, DMA_BIT_MASK(64ULL)))
dev_dbg(dsaf_dev->dev, "set mask to 64bit\n"); dev_dbg(dsaf_dev->dev, "set mask to 64bit\n");
else else
...@@ -1295,9 +1329,9 @@ static int hns_dsaf_init_hw(struct dsaf_device *dsaf_dev) ...@@ -1295,9 +1329,9 @@ static int hns_dsaf_init_hw(struct dsaf_device *dsaf_dev)
dev_dbg(dsaf_dev->dev, dev_dbg(dsaf_dev->dev,
"hns_dsaf_init_hw begin %s !\n", dsaf_dev->ae_dev.name); "hns_dsaf_init_hw begin %s !\n", dsaf_dev->ae_dev.name);
hns_dsaf_rst(dsaf_dev, 0); dsaf_dev->misc_op->dsaf_reset(dsaf_dev, 0);
mdelay(10); mdelay(10);
hns_dsaf_rst(dsaf_dev, 1); dsaf_dev->misc_op->dsaf_reset(dsaf_dev, 1);
hns_dsaf_comm_init(dsaf_dev); hns_dsaf_comm_init(dsaf_dev);
...@@ -1325,7 +1359,7 @@ static int hns_dsaf_init_hw(struct dsaf_device *dsaf_dev) ...@@ -1325,7 +1359,7 @@ static int hns_dsaf_init_hw(struct dsaf_device *dsaf_dev)
static void hns_dsaf_remove_hw(struct dsaf_device *dsaf_dev) static void hns_dsaf_remove_hw(struct dsaf_device *dsaf_dev)
{ {
/*reset*/ /*reset*/
hns_dsaf_rst(dsaf_dev, 0); dsaf_dev->misc_op->dsaf_reset(dsaf_dev, 0);
} }
/** /**
...@@ -2680,6 +2714,7 @@ static struct platform_driver g_dsaf_driver = { ...@@ -2680,6 +2714,7 @@ static struct platform_driver g_dsaf_driver = {
.driver = { .driver = {
.name = DSAF_DRV_NAME, .name = DSAF_DRV_NAME,
.of_match_table = g_dsaf_match, .of_match_table = g_dsaf_match,
.acpi_match_table = hns_dsaf_acpi_match,
}, },
}; };
......
...@@ -268,6 +268,27 @@ struct dsaf_int_stat { ...@@ -268,6 +268,27 @@ struct dsaf_int_stat {
}; };
struct dsaf_misc_op {
void (*cpld_set_led)(struct hns_mac_cb *mac_cb, int link_status,
u16 speed, int data);
void (*cpld_reset_led)(struct hns_mac_cb *mac_cb);
int (*cpld_set_led_id)(struct hns_mac_cb *mac_cb,
enum hnae_led_state status);
/* reset seris function, it will be reset if the dereseet is 0 */
void (*dsaf_reset)(struct dsaf_device *dsaf_dev, bool dereset);
void (*xge_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
void (*xge_core_srst)(struct dsaf_device *dsaf_dev, u32 port,
bool dereset);
void (*ge_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
void (*ppe_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
void (*ppe_comm_srst)(struct dsaf_device *dsaf_dev, bool dereset);
phy_interface_t (*get_phy_if)(struct hns_mac_cb *mac_cb);
int (*get_sfp_prsnt)(struct hns_mac_cb *mac_cb, int *sfp_prsnt);
int (*cfg_serdes_loopback)(struct hns_mac_cb *mac_cb, bool en);
};
/* Dsaf device struct define ,and mac -> dsaf */ /* Dsaf device struct define ,and mac -> dsaf */
struct dsaf_device { struct dsaf_device {
struct device *dev; struct device *dev;
...@@ -292,6 +313,7 @@ struct dsaf_device { ...@@ -292,6 +313,7 @@ struct dsaf_device {
struct ppe_common_cb *ppe_common[DSAF_COMM_DEV_NUM]; struct ppe_common_cb *ppe_common[DSAF_COMM_DEV_NUM];
struct rcb_common_cb *rcb_common[DSAF_COMM_DEV_NUM]; struct rcb_common_cb *rcb_common[DSAF_COMM_DEV_NUM];
struct hns_mac_cb *mac_cb[DSAF_MAX_PORT_NUM]; struct hns_mac_cb *mac_cb[DSAF_MAX_PORT_NUM];
struct dsaf_misc_op *misc_op;
struct dsaf_hw_stats hw_stats[DSAF_NODE_NUM]; struct dsaf_hw_stats hw_stats[DSAF_NODE_NUM];
struct dsaf_int_stat int_stat; struct dsaf_int_stat int_stat;
...@@ -388,22 +410,11 @@ int hns_dsaf_get_mac_entry_by_index( ...@@ -388,22 +410,11 @@ int hns_dsaf_get_mac_entry_by_index(
u16 entry_index, u16 entry_index,
struct dsaf_drv_mac_multi_dest_entry *mac_entry); struct dsaf_drv_mac_multi_dest_entry *mac_entry);
void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val);
void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val);
void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val);
void hns_dsaf_fix_mac_mode(struct hns_mac_cb *mac_cb); void hns_dsaf_fix_mac_mode(struct hns_mac_cb *mac_cb);
int hns_dsaf_ae_init(struct dsaf_device *dsaf_dev); int hns_dsaf_ae_init(struct dsaf_device *dsaf_dev);
void hns_dsaf_ae_uninit(struct dsaf_device *dsaf_dev); void hns_dsaf_ae_uninit(struct dsaf_device *dsaf_dev);
void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val);
void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val);
void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
u32 port, u32 val);
void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 inode_num); void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 inode_num);
int hns_dsaf_get_sset_count(int stringset); int hns_dsaf_get_sset_count(int stringset);
......
...@@ -33,11 +33,6 @@ ...@@ -33,11 +33,6 @@
#define DSAF_LED_DATA_B 4 #define DSAF_LED_DATA_B 4
#define DSAF_LED_ANCHOR_B 5 #define DSAF_LED_ANCHOR_B 5
void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev);
u16 speed, int data);
void cpld_led_reset(struct hns_mac_cb *mac_cb);
int cpld_set_led_id(struct hns_mac_cb *mac_cb,
enum hnae_led_state status);
int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt);
#endif #endif
...@@ -112,7 +112,6 @@ void hns_ppe_common_free_cfg(struct dsaf_device *dsaf_dev, u32 comm_index) ...@@ -112,7 +112,6 @@ void hns_ppe_common_free_cfg(struct dsaf_device *dsaf_dev, u32 comm_index)
static void __iomem *hns_ppe_get_iobase(struct ppe_common_cb *ppe_common, static void __iomem *hns_ppe_get_iobase(struct ppe_common_cb *ppe_common,
int ppe_idx) int ppe_idx)
{ {
return ppe_common->dsaf_dev->ppe_base + ppe_idx * PPE_REG_OFFSET; return ppe_common->dsaf_dev->ppe_base + ppe_idx * PPE_REG_OFFSET;
} }
...@@ -200,11 +199,12 @@ static void hns_ppe_set_port_mode(struct hns_ppe_cb *ppe_cb, ...@@ -200,11 +199,12 @@ static void hns_ppe_set_port_mode(struct hns_ppe_cb *ppe_cb,
static int hns_ppe_common_init_hw(struct ppe_common_cb *ppe_common) static int hns_ppe_common_init_hw(struct ppe_common_cb *ppe_common)
{ {
enum ppe_qid_mode qid_mode; enum ppe_qid_mode qid_mode;
enum dsaf_mode dsaf_mode = ppe_common->dsaf_dev->dsaf_mode; struct dsaf_device *dsaf_dev = ppe_common->dsaf_dev;
enum dsaf_mode dsaf_mode = dsaf_dev->dsaf_mode;
hns_ppe_com_srst(ppe_common, 0); dsaf_dev->misc_op->ppe_comm_srst(dsaf_dev, 0);
mdelay(100); mdelay(100);
hns_ppe_com_srst(ppe_common, 1); dsaf_dev->misc_op->ppe_comm_srst(dsaf_dev, 1);
mdelay(100); mdelay(100);
if (ppe_common->ppe_mode == PPE_COMMON_MODE_SERVICE) { if (ppe_common->ppe_mode == PPE_COMMON_MODE_SERVICE) {
...@@ -288,9 +288,9 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) ...@@ -288,9 +288,9 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb)
/* get default RSS key */ /* get default RSS key */
netdev_rss_key_fill(ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE); netdev_rss_key_fill(ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE);
hns_ppe_srst_by_port(dsaf_dev, port, 0); dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 0);
mdelay(10); mdelay(10);
hns_ppe_srst_by_port(dsaf_dev, port, 1); dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 1);
/* clr and msk except irq*/ /* clr and msk except irq*/
hns_ppe_exc_irq_en(ppe_cb, 0); hns_ppe_exc_irq_en(ppe_cb, 0);
...@@ -328,10 +328,11 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) ...@@ -328,10 +328,11 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb)
static void hns_ppe_uninit_hw(struct hns_ppe_cb *ppe_cb) static void hns_ppe_uninit_hw(struct hns_ppe_cb *ppe_cb)
{ {
u32 port; u32 port;
struct dsaf_device *dsaf_dev = ppe_cb->ppe_common_cb->dsaf_dev;
if (ppe_cb->ppe_common_cb) { if (ppe_cb->ppe_common_cb) {
port = ppe_cb->index; port = ppe_cb->index;
hns_ppe_srst_by_port(ppe_cb->ppe_common_cb->dsaf_dev, port, 0); dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 0);
} }
} }
......
...@@ -458,7 +458,6 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common) ...@@ -458,7 +458,6 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common)
u32 i; u32 i;
u32 ring_num = rcb_common->ring_num; u32 ring_num = rcb_common->ring_num;
int base_irq_idx = hns_rcb_get_base_irq_idx(rcb_common); 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 = struct platform_device *pdev =
to_platform_device(rcb_common->dsaf_dev->dev); to_platform_device(rcb_common->dsaf_dev->dev);
bool is_ver1 = AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver); 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) ...@@ -473,10 +472,10 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common)
ring_pair_cb->port_id_in_comm = ring_pair_cb->port_id_in_comm =
hns_rcb_get_port_in_comm(rcb_common, i); hns_rcb_get_port_in_comm(rcb_common, i);
ring_pair_cb->virq[HNS_RCB_IRQ_IDX_TX] = 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); platform_get_irq(pdev, base_irq_idx + i * 3 + 1);
ring_pair_cb->virq[HNS_RCB_IRQ_IDX_RX] = 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); platform_get_irq(pdev, base_irq_idx + i * 3);
ring_pair_cb->q.phy_base = ring_pair_cb->q.phy_base =
RCB_COMM_BASE_TO_RING_BASE(rcb_common->phy_base, i); RCB_COMM_BASE_TO_RING_BASE(rcb_common->phy_base, i);
......
...@@ -119,7 +119,7 @@ static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode) ...@@ -119,7 +119,7 @@ static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode)
= (struct dsaf_device *)dev_get_drvdata(drv->dev); = (struct dsaf_device *)dev_get_drvdata(drv->dev);
u32 port = drv->mac_id; u32 port = drv->mac_id;
hns_dsaf_xge_core_srst_by_port(dsaf_dev, port, 1); dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 1);
mdelay(10); mdelay(10);
/*enable XGE rX/tX */ /*enable XGE rX/tX */
...@@ -157,7 +157,7 @@ static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode) ...@@ -157,7 +157,7 @@ static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode)
} }
mdelay(10); mdelay(10);
hns_dsaf_xge_core_srst_by_port(dsaf_dev, port, 0); dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 0);
} }
/** /**
...@@ -198,9 +198,9 @@ static void hns_xgmac_init(void *mac_drv) ...@@ -198,9 +198,9 @@ static void hns_xgmac_init(void *mac_drv)
= (struct dsaf_device *)dev_get_drvdata(drv->dev); = (struct dsaf_device *)dev_get_drvdata(drv->dev);
u32 port = drv->mac_id; u32 port = drv->mac_id;
hns_dsaf_xge_srst_by_port(dsaf_dev, port, 0); dsaf_dev->misc_op->xge_srst(dsaf_dev, port, 0);
mdelay(100); mdelay(100);
hns_dsaf_xge_srst_by_port(dsaf_dev, port, 1); dsaf_dev->misc_op->xge_srst(dsaf_dev, port, 1);
mdelay(100); mdelay(100);
hns_xgmac_exc_irq_en(drv, 0); hns_xgmac_exc_irq_en(drv, 0);
...@@ -425,7 +425,7 @@ static void hns_xgmac_free(void *mac_drv) ...@@ -425,7 +425,7 @@ static void hns_xgmac_free(void *mac_drv)
u32 mac_id = drv->mac_id; u32 mac_id = drv->mac_id;
hns_dsaf_xge_srst_by_port(dsaf_dev, mac_id, 0); dsaf_dev->misc_op->xge_srst(dsaf_dev, mac_id, 0);
} }
/** /**
......
...@@ -132,6 +132,13 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv, ...@@ -132,6 +132,13 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv,
ring_ptr_move_fw(ring, next_to_use); 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, static void fill_desc(struct hnae_ring *ring, void *priv,
int size, dma_addr_t dma, int frag_end, int size, dma_addr_t dma, int frag_end,
int buf_num, enum hns_desc_type type, int mtu) int buf_num, enum hns_desc_type type, int mtu)
...@@ -996,19 +1003,22 @@ static void hns_nic_adjust_link(struct net_device *ndev) ...@@ -996,19 +1003,22 @@ static void hns_nic_adjust_link(struct net_device *ndev)
int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h) int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)
{ {
struct hns_nic_priv *priv = netdev_priv(ndev); struct hns_nic_priv *priv = netdev_priv(ndev);
struct phy_device *phy_dev = NULL; struct phy_device *phy_dev = h->phy_dev;
int ret;
if (!h->phy_node) if (!h->phy_dev)
return 0; return 0;
if (h->phy_if != PHY_INTERFACE_MODE_XGMII) if (h->phy_if != PHY_INTERFACE_MODE_XGMII) {
phy_dev = of_phy_connect(ndev, h->phy_node, phy_dev->dev_flags = 0;
hns_nic_adjust_link, 0, h->phy_if);
else
phy_dev = of_phy_attach(ndev, h->phy_node, 0, h->phy_if);
if (unlikely(!phy_dev) || IS_ERR(phy_dev)) ret = phy_connect_direct(ndev, phy_dev, hns_nic_adjust_link,
return !phy_dev ? -ENODEV : PTR_ERR(phy_dev); h->phy_if);
} else {
ret = phy_attach_direct(ndev, phy_dev, 0, h->phy_if);
}
if (unlikely(ret))
return -ENODEV;
phy_dev->supported &= h->if_support; phy_dev->supported &= h->if_support;
phy_dev->advertising = phy_dev->supported; phy_dev->advertising = phy_dev->supported;
...@@ -1067,13 +1077,8 @@ void hns_nic_update_stats(struct net_device *netdev) ...@@ -1067,13 +1077,8 @@ void hns_nic_update_stats(struct net_device *netdev)
static void hns_init_mac_addr(struct net_device *ndev) static void hns_init_mac_addr(struct net_device *ndev)
{ {
struct hns_nic_priv *priv = netdev_priv(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 (!device_get_mac_address(priv->dev, ndev->dev_addr, ETH_ALEN)) {
if (mac_addr_temp && is_valid_ether_addr(mac_addr_temp)) {
memcpy(ndev->dev_addr, mac_addr_temp, ndev->addr_len);
} else {
eth_hw_addr_random(ndev); eth_hw_addr_random(ndev);
dev_warn(priv->dev, "No valid mac, use random mac %pM", dev_warn(priv->dev, "No valid mac, use random mac %pM",
ndev->dev_addr); ndev->dev_addr);
...@@ -1812,7 +1817,7 @@ static int hns_nic_try_get_ae(struct net_device *ndev) ...@@ -1812,7 +1817,7 @@ static int hns_nic_try_get_ae(struct net_device *ndev)
int ret; int ret;
h = hnae_get_handle(&priv->netdev->dev, h = hnae_get_handle(&priv->netdev->dev,
priv->ae_node, priv->port_id, NULL); priv->fwnode, priv->port_id, NULL);
if (IS_ERR_OR_NULL(h)) { if (IS_ERR_OR_NULL(h)) {
ret = -ENODEV; ret = -ENODEV;
dev_dbg(priv->dev, "has not handle, register notifier!\n"); dev_dbg(priv->dev, "has not handle, register notifier!\n");
...@@ -1872,7 +1877,6 @@ static int hns_nic_dev_probe(struct platform_device *pdev) ...@@ -1872,7 +1877,6 @@ static int hns_nic_dev_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct net_device *ndev; struct net_device *ndev;
struct hns_nic_priv *priv; struct hns_nic_priv *priv;
struct device_node *node = dev->of_node;
u32 port_id; u32 port_id;
int ret; int ret;
...@@ -1886,22 +1890,49 @@ static int hns_nic_dev_probe(struct platform_device *pdev) ...@@ -1886,22 +1890,49 @@ static int hns_nic_dev_probe(struct platform_device *pdev)
priv->dev = dev; priv->dev = dev;
priv->netdev = ndev; priv->netdev = ndev;
if (of_device_is_compatible(node, "hisilicon,hns-nic-v1")) if (dev_of_node(dev)) {
priv->enet_ver = AE_VERSION_1; struct device_node *ae_node;
else
priv->enet_ver = AE_VERSION_2; 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); ae_node = of_parse_phandle(dev->of_node, "ae-handle", 0);
if (IS_ERR_OR_NULL(priv->ae_node)) { if (IS_ERR_OR_NULL(ae_node)) {
ret = PTR_ERR(priv->ae_node); ret = PTR_ERR(ae_node);
dev_err(dev, "not find ae-handle\n"); dev_err(dev, "not find ae-handle\n");
goto out_read_prop_fail; goto out_read_prop_fail;
}
priv->fwnode = &ae_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, &args);
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;
} }
/* try to find port-idx-in-ae first */
ret = of_property_read_u32(node, "port-idx-in-ae", &port_id); ret = device_property_read_u32(dev, "port-idx-in-ae", &port_id);
if (ret) { if (ret) {
/* only for old code compatible */ /* only for old code compatible */
ret = of_property_read_u32(node, "port-id", &port_id); ret = device_property_read_u32(dev, "port-id", &port_id);
if (ret) if (ret)
goto out_read_prop_fail; goto out_read_prop_fail;
/* for old dts, we need to caculate the port offset */ /* for old dts, we need to caculate the port offset */
...@@ -2014,6 +2045,7 @@ static struct platform_driver hns_nic_dev_driver = { ...@@ -2014,6 +2045,7 @@ static struct platform_driver hns_nic_dev_driver = {
.driver = { .driver = {
.name = "hns-nic", .name = "hns-nic",
.of_match_table = hns_enet_of_match, .of_match_table = hns_enet_of_match,
.acpi_match_table = ACPI_PTR(hns_enet_acpi_match),
}, },
.probe = hns_nic_dev_probe, .probe = hns_nic_dev_probe,
.remove = hns_nic_dev_remove, .remove = hns_nic_dev_remove,
......
...@@ -54,7 +54,7 @@ struct hns_nic_ops { ...@@ -54,7 +54,7 @@ struct hns_nic_ops {
}; };
struct hns_nic_priv { struct hns_nic_priv {
const struct device_node *ae_node; const struct fwnode_handle *fwnode;
u32 enet_ver; u32 enet_ver;
u32 port_id; u32 port_id;
int phy_mode; int phy_mode;
......
...@@ -596,7 +596,7 @@ static void hns_nic_self_test(struct net_device *ndev, ...@@ -596,7 +596,7 @@ static void hns_nic_self_test(struct net_device *ndev,
st_param[1][0] = MAC_INTERNALLOOP_SERDES; st_param[1][0] = MAC_INTERNALLOOP_SERDES;
st_param[1][1] = 1; /*serdes must exist*/ st_param[1][1] = 1; /*serdes must exist*/
st_param[2][0] = MAC_INTERNALLOOP_PHY; /* only supporte phy node*/ st_param[2][0] = MAC_INTERNALLOOP_PHY; /* only supporte phy node*/
st_param[2][1] = ((!!(priv->ae_handle->phy_node)) && st_param[2][1] = ((!!(priv->ae_handle->phy_dev)) &&
(priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)); (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII));
if (eth_test->flags == ETH_TEST_FL_OFFLINE) { if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#include <linux/acpi.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -354,66 +355,63 @@ static int hns_mdio_reset(struct mii_bus *bus) ...@@ -354,66 +355,63 @@ static int hns_mdio_reset(struct mii_bus *bus)
struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv; struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
int ret; int ret;
if (!mdio_dev->subctrl_vbase) { if (dev_of_node(bus->parent)) {
dev_err(&bus->dev, "mdio sys ctl reg has not maped\n"); if (!mdio_dev->subctrl_vbase) {
return -ENODEV; dev_err(&bus->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(&bus->dev, "MDIO reset fail\n");
return ret;
}
/*2. dis clk, and read clk st check*/ /* 1. reset req, and read reset st check */
ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_DIS, ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_REQ, 0x1,
0x1, MDIO_SC_CLK_ST, 0x1, MDIO_SC_RESET_ST, 0x1,
MDIO_CHECK_CLR_ST); MDIO_CHECK_SET_ST);
if (ret) { if (ret) {
dev_err(&bus->dev, "MDIO dis clk fail\n"); dev_err(&bus->dev, "MDIO reset fail\n");
return ret; return ret;
} }
/*3. reset dreq, and read reset st check*/ /* 2. dis clk, and read clk st check */
ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_DREQ, 0x1, ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_DIS,
MDIO_SC_RESET_ST, 0x1, 0x1, MDIO_SC_CLK_ST, 0x1,
MDIO_CHECK_CLR_ST); MDIO_CHECK_CLR_ST);
if (ret) { if (ret) {
dev_err(&bus->dev, "MDIO dis clk fail\n"); dev_err(&bus->dev, "MDIO dis clk fail\n");
return ret; return ret;
} }
/*4. en clk, and read clk st check*/ /* 3. reset dreq, and read reset st check */
ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_EN, ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_DREQ, 0x1,
0x1, MDIO_SC_CLK_ST, 0x1, MDIO_SC_RESET_ST, 0x1,
MDIO_CHECK_SET_ST); MDIO_CHECK_CLR_ST);
if (ret) if (ret) {
dev_err(&bus->dev, "MDIO en clk fail\n"); dev_err(&bus->dev, "MDIO dis clk fail\n");
return ret;
}
/* 4. en clk, and read clk st check */
ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_EN,
0x1, MDIO_SC_CLK_ST, 0x1,
MDIO_CHECK_SET_ST);
if (ret)
dev_err(&bus->dev, "MDIO en clk fail\n");
} else if (is_acpi_node(bus->parent->fwnode)) {
acpi_status s;
s = acpi_evaluate_object(ACPI_HANDLE(bus->parent),
"_RST", NULL, NULL);
if (ACPI_FAILURE(s)) {
dev_err(&bus->dev, "Reset failed, return:%#x\n", s);
ret = -EBUSY;
} else {
ret = 0;
}
} else {
dev_err(&bus->dev, "Can not get cfg data from DT or ACPI\n");
ret = -ENXIO;
}
return ret; return ret;
} }
/**
* hns_mdio_bus_name - get mdio bus name
* @name: mdio bus name
* @np: mdio device node pointer
*/
static void hns_mdio_bus_name(char *name, struct device_node *np)
{
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);
}
/** /**
* hns_mdio_probe - probe mdio device * hns_mdio_probe - probe mdio device
* @pdev: mdio platform device * @pdev: mdio platform device
...@@ -422,17 +420,16 @@ static void hns_mdio_bus_name(char *name, struct device_node *np) ...@@ -422,17 +420,16 @@ static void hns_mdio_bus_name(char *name, struct device_node *np)
*/ */
static int hns_mdio_probe(struct platform_device *pdev) static int hns_mdio_probe(struct platform_device *pdev)
{ {
struct device_node *np;
struct hns_mdio_device *mdio_dev; struct hns_mdio_device *mdio_dev;
struct mii_bus *new_bus; struct mii_bus *new_bus;
struct resource *res; struct resource *res;
int ret; int ret = -ENODEV;
if (!pdev) { if (!pdev) {
dev_err(NULL, "pdev is NULL!\r\n"); dev_err(NULL, "pdev is NULL!\r\n");
return -ENODEV; return -ENODEV;
} }
np = pdev->dev.of_node;
mdio_dev = devm_kzalloc(&pdev->dev, sizeof(*mdio_dev), GFP_KERNEL); mdio_dev = devm_kzalloc(&pdev->dev, sizeof(*mdio_dev), GFP_KERNEL);
if (!mdio_dev) if (!mdio_dev)
return -ENOMEM; return -ENOMEM;
...@@ -448,7 +445,7 @@ static int hns_mdio_probe(struct platform_device *pdev) ...@@ -448,7 +445,7 @@ static int hns_mdio_probe(struct platform_device *pdev)
new_bus->write = hns_mdio_write; new_bus->write = hns_mdio_write;
new_bus->reset = hns_mdio_reset; new_bus->reset = hns_mdio_reset;
new_bus->priv = mdio_dev; new_bus->priv = mdio_dev;
hns_mdio_bus_name(new_bus->id, np); new_bus->parent = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mdio_dev->vbase = devm_ioremap_resource(&pdev->dev, res); mdio_dev->vbase = devm_ioremap_resource(&pdev->dev, res);
...@@ -457,16 +454,32 @@ static int hns_mdio_probe(struct platform_device *pdev) ...@@ -457,16 +454,32 @@ static int hns_mdio_probe(struct platform_device *pdev)
return ret; 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(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n");
mdio_dev->subctrl_vbase = NULL;
}
new_bus->parent = &pdev->dev;
platform_set_drvdata(pdev, new_bus); platform_set_drvdata(pdev, new_bus);
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%s", "Mii",
dev_name(&pdev->dev));
if (dev_of_node(&pdev->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(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n");
mdio_dev->subctrl_vbase = NULL;
}
ret = of_mdiobus_register(new_bus, pdev->dev.of_node);
} else if (is_acpi_node(pdev->dev.fwnode)) {
/* Clear all the IRQ properties */
memset(new_bus->irq, PHY_POLL, 4 * PHY_MAX_ADDR);
/* Mask out all PHYs from auto probing. */
new_bus->phy_mask = ~0;
/* Register the MDIO bus */
ret = mdiobus_register(new_bus);
} else {
dev_err(&pdev->dev, "Can not get cfg data from DT or ACPI\n");
ret = -ENXIO;
}
ret = of_mdiobus_register(new_bus, np);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Cannot register as MDIO bus!\n"); dev_err(&pdev->dev, "Cannot register as MDIO bus!\n");
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
...@@ -499,12 +512,19 @@ static const struct of_device_id hns_mdio_match[] = { ...@@ -499,12 +512,19 @@ static const struct of_device_id hns_mdio_match[] = {
{} {}
}; };
static const struct acpi_device_id hns_mdio_acpi_match[] = {
{ "HISI0141", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, hns_mdio_acpi_match);
static struct platform_driver hns_mdio_driver = { static struct platform_driver hns_mdio_driver = {
.probe = hns_mdio_probe, .probe = hns_mdio_probe,
.remove = hns_mdio_remove, .remove = hns_mdio_remove,
.driver = { .driver = {
.name = MDIO_DRV_NAME, .name = MDIO_DRV_NAME,
.of_match_table = hns_mdio_match, .of_match_table = hns_mdio_match,
.acpi_match_table = ACPI_PTR(hns_mdio_acpi_match),
}, },
}; };
......
...@@ -543,6 +543,11 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *); ...@@ -543,6 +543,11 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *);
struct fwnode_handle; struct fwnode_handle;
static inline bool acpi_dev_found(const char *hid)
{
return false;
}
static inline bool is_acpi_node(struct fwnode_handle *fwnode) static inline bool is_acpi_node(struct fwnode_handle *fwnode)
{ {
return false; return false;
...@@ -654,6 +659,14 @@ static inline bool acpi_driver_match_device(struct device *dev, ...@@ -654,6 +659,14 @@ static inline bool acpi_driver_match_device(struct device *dev,
return false; 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, static inline int acpi_device_uevent_modalias(struct device *dev,
struct kobj_uevent_env *env) struct kobj_uevent_env *env)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment