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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
b1c6a3a46b
@ -96,16 +96,22 @@ 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;
|
||||
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;
|
||||
|
||||
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 +318,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 +327,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);
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
* "cb" means control block
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
@ -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;
|
||||
@ -528,7 +529,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);
|
||||
|
||||
|
@ -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;
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -7,6 +7,7 @@
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -15,7 +16,8 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/of.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 "hns_dsaf_main.h"
|
||||
@ -94,7 +96,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, &sfp_prsnt);
|
||||
ret = mac_cb->dsaf_dev->misc_op->get_sfp_prsnt(mac_cb, &sfp_prsnt);
|
||||
if (!ret)
|
||||
*link_status = *link_status && sfp_prsnt;
|
||||
|
||||
@ -511,7 +513,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -637,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", &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
|
||||
*@mac_cb: mac device
|
||||
@ -645,7 +756,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,63 +783,85 @@ 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(&mac_cb->phy_dev->mdio.dev);
|
||||
|
||||
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,
|
||||
"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);
|
||||
}
|
||||
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);
|
||||
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",
|
||||
mac_cb->mac_id, np->name);
|
||||
}
|
||||
|
||||
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;
|
||||
} else {
|
||||
syscon = syscon_node_to_regmap(cpld_args.np);
|
||||
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_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;
|
||||
} else {
|
||||
mac_cb->cpld_ctrl = syscon;
|
||||
mac_cb->cpld_ctrl_reg = cpld_args.args[0];
|
||||
syscon = syscon_node_to_regmap(cpld_args.np);
|
||||
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;
|
||||
@ -790,7 +923,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) {
|
||||
@ -805,7 +938,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;
|
||||
@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -975,7 +1108,7 @@ void hns_set_led_opt(struct hns_mac_cb *mac_cb)
|
||||
nic_data = 0;
|
||||
mac_cb->txpkt_for_led = mac_cb->hw_stats.tx_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);
|
||||
}
|
||||
|
||||
@ -985,5 +1118,5 @@ int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb,
|
||||
if (!mac_cb || !mac_cb->cpld_ctrl)
|
||||
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 {
|
||||
phy_interface_t phy_if;
|
||||
enum hnae_loop loop_mode;
|
||||
|
||||
struct device_node *phy_node;
|
||||
struct phy_device *phy_dev;
|
||||
|
||||
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);
|
||||
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,
|
||||
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,
|
||||
enum hnae_loop loop, int en);
|
||||
void hns_mac_update_stats(struct hns_mac_cb *mac_cb);
|
||||
|
@ -7,6 +7,7 @@
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -24,6 +25,7 @@
|
||||
#include "hns_dsaf_main.h"
|
||||
#include "hns_dsaf_ppe.h"
|
||||
#include "hns_dsaf_rcb.h"
|
||||
#include "hns_dsaf_misc.h"
|
||||
|
||||
const char *g_dsaf_mode_match[DSAF_MODE_MAX] = {
|
||||
[DSAF_MODE_DISABLE_2PORT_64VM] = "2port-64vf",
|
||||
@ -32,6 +34,13 @@ const char *g_dsaf_mode_match[DSAF_MODE_MAX] = {
|
||||
[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 ret, i;
|
||||
@ -45,12 +54,24 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
|
||||
struct device_node *np = dsaf_dev->dev->of_node;
|
||||
struct platform_device *pdev = to_platform_device(dsaf_dev->dev);
|
||||
|
||||
if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1"))
|
||||
dsaf_dev->dsaf_ver = AE_VERSION_1;
|
||||
else
|
||||
dsaf_dev->dsaf_ver = AE_VERSION_2;
|
||||
if (dev_of_node(dsaf_dev->dev)) {
|
||||
if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1"))
|
||||
dsaf_dev->dsaf_ver = AE_VERSION_1;
|
||||
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) {
|
||||
dev_err(dsaf_dev->dev, "get dsaf mode fail, ret=%d!\n", ret);
|
||||
return ret;
|
||||
@ -80,32 +101,40 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
|
||||
else
|
||||
dsaf_dev->dsaf_tc_mode = HRD_DSAF_4TC_MODE;
|
||||
|
||||
syscon = syscon_node_to_regmap(
|
||||
of_parse_phandle(np, "subctrl-syscon", 0));
|
||||
if (IS_ERR_OR_NULL(syscon)) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++);
|
||||
if (!res) {
|
||||
dev_err(dsaf_dev->dev, "subctrl info is needed!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (!dsaf_dev->sc_base) {
|
||||
dev_err(dsaf_dev->dev, "subctrl can not map!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (dev_of_node(dsaf_dev->dev)) {
|
||||
syscon = syscon_node_to_regmap(
|
||||
of_parse_phandle(np, "subctrl-syscon", 0));
|
||||
if (IS_ERR_OR_NULL(syscon)) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM,
|
||||
res_idx++);
|
||||
if (!res) {
|
||||
dev_err(dsaf_dev->dev, "subctrl info is needed!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++);
|
||||
if (!res) {
|
||||
dev_err(dsaf_dev->dev, "serdes-ctrl info is needed!\n");
|
||||
return -ENOMEM;
|
||||
dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev,
|
||||
res);
|
||||
if (!dsaf_dev->sc_base) {
|
||||
dev_err(dsaf_dev->dev, "subctrl can not map!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM,
|
||||
res_idx++);
|
||||
if (!res) {
|
||||
dev_err(dsaf_dev->dev, "serdes-ctrl info is needed!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dsaf_dev->sds_base = devm_ioremap_resource(&pdev->dev,
|
||||
res);
|
||||
if (!dsaf_dev->sds_base) {
|
||||
dev_err(dsaf_dev->dev, "serdes-ctrl can not map!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
dsaf_dev->sub_ctrl = syscon;
|
||||
}
|
||||
dsaf_dev->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;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe-base");
|
||||
@ -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 ||
|
||||
desc_num > HNS_DSAF_MAX_DESC_CNT) {
|
||||
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)
|
||||
}
|
||||
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) {
|
||||
dev_dbg(dsaf_dev->dev,
|
||||
"get reset-field-offset fail, ret=%d!\r\n", ret);
|
||||
}
|
||||
dsaf_dev->reset_offset = reset_offset;
|
||||
|
||||
ret = of_property_read_u32(np, "buf-size", &buf_size);
|
||||
ret = device_property_read_u32(dsaf_dev->dev, "buf-size", &buf_size);
|
||||
if (ret < 0) {
|
||||
dev_err(dsaf_dev->dev,
|
||||
"get buf-size fail, ret=%d!\r\n", ret);
|
||||
@ -173,6 +203,10 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev)
|
||||
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)))
|
||||
dev_dbg(dsaf_dev->dev, "set mask to 64bit\n");
|
||||
else
|
||||
@ -1295,9 +1329,9 @@ static int hns_dsaf_init_hw(struct dsaf_device *dsaf_dev)
|
||||
dev_dbg(dsaf_dev->dev,
|
||||
"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);
|
||||
hns_dsaf_rst(dsaf_dev, 1);
|
||||
dsaf_dev->misc_op->dsaf_reset(dsaf_dev, 1);
|
||||
|
||||
hns_dsaf_comm_init(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)
|
||||
{
|
||||
/*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 = {
|
||||
.driver = {
|
||||
.name = DSAF_DRV_NAME,
|
||||
.of_match_table = g_dsaf_match,
|
||||
.acpi_match_table = hns_dsaf_acpi_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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 */
|
||||
struct dsaf_device {
|
||||
struct device *dev;
|
||||
@ -292,6 +313,7 @@ struct dsaf_device {
|
||||
struct ppe_common_cb *ppe_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 dsaf_misc_op *misc_op;
|
||||
|
||||
struct dsaf_hw_stats hw_stats[DSAF_NODE_NUM];
|
||||
struct dsaf_int_stat int_stat;
|
||||
@ -388,22 +410,11 @@ int hns_dsaf_get_mac_entry_by_index(
|
||||
u16 entry_index,
|
||||
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);
|
||||
|
||||
int hns_dsaf_ae_init(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);
|
||||
|
||||
int hns_dsaf_get_sset_count(int stringset);
|
||||
|
@ -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)
|
||||
@ -32,8 +53,8 @@ static u32 dsaf_read_sub(struct dsaf_device *dsaf_dev, u32 reg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
|
||||
u16 speed, int data)
|
||||
static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
|
||||
u16 speed, int data)
|
||||
{
|
||||
int speed_reg = 0;
|
||||
u8 value;
|
||||
@ -71,7 +92,7 @@ void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
|
||||
}
|
||||
}
|
||||
|
||||
void cpld_led_reset(struct hns_mac_cb *mac_cb)
|
||||
static void cpld_led_reset(struct hns_mac_cb *mac_cb)
|
||||
{
|
||||
if (!mac_cb || !mac_cb->cpld_ctrl)
|
||||
return;
|
||||
@ -81,8 +102,8 @@ void cpld_led_reset(struct hns_mac_cb *mac_cb)
|
||||
mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
int cpld_set_led_id(struct hns_mac_cb *mac_cb,
|
||||
enum hnae_led_state status)
|
||||
static int cpld_set_led_id(struct hns_mac_cb *mac_cb,
|
||||
enum hnae_led_state status)
|
||||
{
|
||||
switch (status) {
|
||||
case HNAE_LED_ACTIVE:
|
||||
@ -109,12 +130,40 @@ int cpld_set_led_id(struct hns_mac_cb *mac_cb,
|
||||
|
||||
#define RESET_REQ_OR_DREQ 1
|
||||
|
||||
void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val)
|
||||
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, &argv4);
|
||||
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;
|
||||
u32 nt_reg_addr;
|
||||
|
||||
if (!val) {
|
||||
if (!dereset) {
|
||||
xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG;
|
||||
nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG;
|
||||
} else {
|
||||
@ -126,7 +175,15 @@ void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val)
|
||||
dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ);
|
||||
}
|
||||
|
||||
void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
|
||||
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)
|
||||
{
|
||||
u32 reg_val = 0;
|
||||
u32 reg_addr;
|
||||
@ -137,7 +194,7 @@ void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
|
||||
reg_val |= RESET_REQ_OR_DREQ;
|
||||
reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off;
|
||||
|
||||
if (val == 0)
|
||||
if (!dereset)
|
||||
reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
|
||||
else
|
||||
reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
|
||||
@ -145,8 +202,15 @@ void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
|
||||
dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
|
||||
}
|
||||
|
||||
void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
|
||||
u32 port, u32 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)
|
||||
{
|
||||
u32 reg_val = 0;
|
||||
u32 reg_addr;
|
||||
@ -157,7 +221,7 @@ void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
|
||||
reg_val |= XGMAC_TRX_CORE_SRST_M
|
||||
<< dsaf_dev->mac_cb[port]->port_rst_off;
|
||||
|
||||
if (val == 0)
|
||||
if (!dereset)
|
||||
reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
|
||||
else
|
||||
reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
|
||||
@ -165,7 +229,16 @@ void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
|
||||
dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
|
||||
}
|
||||
|
||||
void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 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)
|
||||
{
|
||||
u32 reg_val_1;
|
||||
u32 reg_val_2;
|
||||
@ -183,7 +256,7 @@ void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
|
||||
else
|
||||
reg_val_2 = 0x2082082 << port_rst_off;
|
||||
|
||||
if (val == 0) {
|
||||
if (!dereset) {
|
||||
dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
|
||||
reg_val_1);
|
||||
|
||||
@ -200,7 +273,7 @@ void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
|
||||
reg_val_1 = 0x15540 << dsaf_dev->reset_offset;
|
||||
reg_val_2 = 0x100 << dsaf_dev->reset_offset;
|
||||
|
||||
if (val == 0) {
|
||||
if (!dereset) {
|
||||
dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG,
|
||||
reg_val_1);
|
||||
|
||||
@ -216,14 +289,22 @@ void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
|
||||
}
|
||||
}
|
||||
|
||||
void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
|
||||
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_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
|
||||
bool dereset)
|
||||
{
|
||||
u32 reg_val = 0;
|
||||
u32 reg_addr;
|
||||
|
||||
reg_val |= RESET_REQ_OR_DREQ << dsaf_dev->mac_cb[port]->port_rst_off;
|
||||
|
||||
if (val == 0)
|
||||
if (!dereset)
|
||||
reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
|
||||
else
|
||||
reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
|
||||
@ -231,15 +312,24 @@ void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val)
|
||||
dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
|
||||
}
|
||||
|
||||
void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val)
|
||||
static void
|
||||
hns_ppe_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_PPE_RESET_FUNC, port, dereset);
|
||||
}
|
||||
|
||||
static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset)
|
||||
{
|
||||
struct dsaf_device *dsaf_dev = ppe_common->dsaf_dev;
|
||||
u32 reg_val;
|
||||
u32 reg_addr;
|
||||
|
||||
if (!(dev_of_node(dsaf_dev->dev)))
|
||||
return;
|
||||
|
||||
if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
|
||||
reg_val = RESET_REQ_OR_DREQ;
|
||||
if (val == 0)
|
||||
if (!dereset)
|
||||
reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG;
|
||||
else
|
||||
reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG;
|
||||
@ -247,7 +337,7 @@ void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val)
|
||||
} else {
|
||||
reg_val = 0x100 << dsaf_dev->reset_offset;
|
||||
|
||||
if (val == 0)
|
||||
if (!dereset)
|
||||
reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG;
|
||||
else
|
||||
reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG;
|
||||
@ -261,7 +351,7 @@ void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val)
|
||||
* @mac_cb: mac control block
|
||||
* retuen phy interface
|
||||
*/
|
||||
phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
|
||||
static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
|
||||
{
|
||||
u32 mode;
|
||||
u32 reg;
|
||||
@ -293,6 +383,36 @@ phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb)
|
||||
return phy_if;
|
||||
}
|
||||
|
||||
static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb)
|
||||
{
|
||||
phy_interface_t phy_if = PHY_INTERFACE_MODE_NA;
|
||||
union acpi_object *obj;
|
||||
union acpi_object obj_args, argv4;
|
||||
|
||||
obj_args.integer.type = ACPI_TYPE_INTEGER;
|
||||
obj_args.integer.value = mac_cb->mac_id;
|
||||
|
||||
argv4.type = ACPI_TYPE_PACKAGE,
|
||||
argv4.package.count = 1,
|
||||
argv4.package.elements = &obj_args,
|
||||
|
||||
obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
|
||||
hns_dsaf_acpi_dsm_uuid, 0,
|
||||
HNS_OP_GET_PORT_TYPE_FUNC, &argv4);
|
||||
|
||||
if (!obj || obj->type != ACPI_TYPE_INTEGER)
|
||||
return phy_if;
|
||||
|
||||
phy_if = obj->integer.value ?
|
||||
PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII;
|
||||
|
||||
dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if);
|
||||
|
||||
ACPI_FREE(obj);
|
||||
|
||||
return phy_if;
|
||||
}
|
||||
|
||||
int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
|
||||
{
|
||||
if (!mac_cb->cpld_ctrl)
|
||||
@ -309,7 +429,7 @@ int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt)
|
||||
* @mac_cb: mac control block
|
||||
* retuen 0 == success
|
||||
*/
|
||||
int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en)
|
||||
static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en)
|
||||
{
|
||||
/* port 0-3 hilink4 base is serdes_vaddr + 0x00280000
|
||||
* port 4-7 hilink3 base is serdes_vaddr + 0x00200000
|
||||
@ -332,7 +452,7 @@ int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en)
|
||||
int sfp_prsnt;
|
||||
int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
|
||||
|
||||
if (!mac_cb->phy_node) {
|
||||
if (!mac_cb->phy_dev) {
|
||||
if (ret)
|
||||
pr_info("please confirm sfp is present or not\n");
|
||||
else
|
||||
@ -343,11 +463,89 @@ int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en)
|
||||
if (mac_cb->serdes_ctrl) {
|
||||
u32 origin = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset);
|
||||
|
||||
dsaf_set_field(origin, 1ull << 10, 10, !!en);
|
||||
dsaf_set_field(origin, 1ull << 10, 10, en);
|
||||
dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin);
|
||||
} else {
|
||||
dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, !!en);
|
||||
dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en)
|
||||
{
|
||||
union acpi_object *obj;
|
||||
union acpi_object obj_args[3], argv4;
|
||||
|
||||
obj_args[0].integer.type = ACPI_TYPE_INTEGER;
|
||||
obj_args[0].integer.value = mac_cb->mac_id;
|
||||
obj_args[1].integer.type = ACPI_TYPE_INTEGER;
|
||||
obj_args[1].integer.value = !!en;
|
||||
|
||||
argv4.type = ACPI_TYPE_PACKAGE;
|
||||
argv4.package.count = 2;
|
||||
argv4.package.elements = obj_args;
|
||||
|
||||
obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev),
|
||||
hns_dsaf_acpi_dsm_uuid, 0,
|
||||
HNS_OP_SERDES_LP_FUNC, &argv4);
|
||||
if (!obj) {
|
||||
dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!",
|
||||
mac_cb->mac_id);
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
ACPI_FREE(obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
|
||||
{
|
||||
struct dsaf_misc_op *misc_op;
|
||||
|
||||
misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL);
|
||||
if (!misc_op)
|
||||
return NULL;
|
||||
|
||||
if (dev_of_node(dsaf_dev->dev)) {
|
||||
misc_op->cpld_set_led = hns_cpld_set_led;
|
||||
misc_op->cpld_reset_led = cpld_led_reset;
|
||||
misc_op->cpld_set_led_id = cpld_set_led_id;
|
||||
|
||||
misc_op->dsaf_reset = hns_dsaf_rst;
|
||||
misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
|
||||
misc_op->xge_core_srst = hns_dsaf_xge_core_srst_by_port;
|
||||
misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
|
||||
misc_op->ppe_srst = hns_ppe_srst_by_port;
|
||||
misc_op->ppe_comm_srst = hns_ppe_com_srst;
|
||||
|
||||
misc_op->get_phy_if = hns_mac_get_phy_if;
|
||||
misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;
|
||||
|
||||
misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback;
|
||||
} else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
|
||||
misc_op->cpld_set_led = hns_cpld_set_led;
|
||||
misc_op->cpld_reset_led = cpld_led_reset;
|
||||
misc_op->cpld_set_led_id = cpld_set_led_id;
|
||||
|
||||
misc_op->dsaf_reset = hns_dsaf_rst_acpi;
|
||||
misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
|
||||
misc_op->xge_core_srst = hns_dsaf_xge_core_srst_by_port_acpi;
|
||||
misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
|
||||
misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
|
||||
misc_op->ppe_comm_srst = hns_ppe_com_srst;
|
||||
|
||||
misc_op->get_phy_if = hns_mac_get_phy_if_acpi;
|
||||
misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt;
|
||||
|
||||
misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi;
|
||||
} else {
|
||||
devm_kfree(dsaf_dev->dev, (void *)misc_op);
|
||||
misc_op = NULL;
|
||||
}
|
||||
|
||||
return (void *)misc_op;
|
||||
}
|
||||
|
@ -33,11 +33,6 @@
|
||||
#define DSAF_LED_DATA_B 4
|
||||
#define DSAF_LED_ANCHOR_B 5
|
||||
|
||||
void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
|
||||
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);
|
||||
struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev);
|
||||
|
||||
#endif
|
||||
|
@ -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,
|
||||
int ppe_idx)
|
||||
{
|
||||
|
||||
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,
|
||||
static int hns_ppe_common_init_hw(struct ppe_common_cb *ppe_common)
|
||||
{
|
||||
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);
|
||||
hns_ppe_com_srst(ppe_common, 1);
|
||||
dsaf_dev->misc_op->ppe_comm_srst(dsaf_dev, 1);
|
||||
mdelay(100);
|
||||
|
||||
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)
|
||||
/* get default RSS key */
|
||||
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);
|
||||
hns_ppe_srst_by_port(dsaf_dev, port, 1);
|
||||
dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 1);
|
||||
|
||||
/* clr and msk except irq*/
|
||||
hns_ppe_exc_irq_en(ppe_cb, 0);
|
||||
@ -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)
|
||||
{
|
||||
u32 port;
|
||||
struct dsaf_device *dsaf_dev = ppe_cb->ppe_common_cb->dsaf_dev;
|
||||
|
||||
if (ppe_cb->ppe_common_cb) {
|
||||
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)
|
||||
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);
|
||||
|
@ -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);
|
||||
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);
|
||||
|
||||
/*enable XGE rX/tX */
|
||||
@ -157,7 +157,7 @@ static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode)
|
||||
}
|
||||
|
||||
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)
|
||||
= (struct dsaf_device *)dev_get_drvdata(drv->dev);
|
||||
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);
|
||||
hns_dsaf_xge_srst_by_port(dsaf_dev, port, 1);
|
||||
dsaf_dev->misc_op->xge_srst(dsaf_dev, port, 1);
|
||||
|
||||
mdelay(100);
|
||||
hns_xgmac_exc_irq_en(drv, 0);
|
||||
@ -425,7 +425,7 @@ static void hns_xgmac_free(void *mac_drv)
|
||||
|
||||
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,
|
||||
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)
|
||||
@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
if (h->phy_if != PHY_INTERFACE_MODE_XGMII)
|
||||
phy_dev = of_phy_connect(ndev, h->phy_node,
|
||||
hns_nic_adjust_link, 0, h->phy_if);
|
||||
else
|
||||
phy_dev = of_phy_attach(ndev, h->phy_node, 0, h->phy_if);
|
||||
if (h->phy_if != PHY_INTERFACE_MODE_XGMII) {
|
||||
phy_dev->dev_flags = 0;
|
||||
|
||||
if (unlikely(!phy_dev) || IS_ERR(phy_dev))
|
||||
return !phy_dev ? -ENODEV : PTR_ERR(phy_dev);
|
||||
ret = phy_connect_direct(ndev, phy_dev, hns_nic_adjust_link,
|
||||
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->advertising = phy_dev->supported;
|
||||
@ -1067,13 +1077,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);
|
||||
@ -1812,7 +1817,7 @@ static int hns_nic_try_get_ae(struct net_device *ndev)
|
||||
int ret;
|
||||
|
||||
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)) {
|
||||
ret = -ENODEV;
|
||||
dev_dbg(priv->dev, "has not handle, register notifier!\n");
|
||||
@ -1872,7 +1877,6 @@ static int hns_nic_dev_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
struct net_device *ndev;
|
||||
struct hns_nic_priv *priv;
|
||||
struct device_node *node = dev->of_node;
|
||||
u32 port_id;
|
||||
int ret;
|
||||
|
||||
@ -1886,22 +1890,49 @@ 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"))
|
||||
priv->enet_ver = AE_VERSION_1;
|
||||
else
|
||||
priv->enet_ver = AE_VERSION_2;
|
||||
if (dev_of_node(dev)) {
|
||||
struct device_node *ae_node;
|
||||
|
||||
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);
|
||||
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 = &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) {
|
||||
/* 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)
|
||||
goto out_read_prop_fail;
|
||||
/* for old dts, we need to caculate the port offset */
|
||||
@ -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,
|
||||
|
@ -54,7 +54,7 @@ struct hns_nic_ops {
|
||||
};
|
||||
|
||||
struct hns_nic_priv {
|
||||
const struct device_node *ae_node;
|
||||
const struct fwnode_handle *fwnode;
|
||||
u32 enet_ver;
|
||||
u32 port_id;
|
||||
int phy_mode;
|
||||
|
@ -596,7 +596,7 @@ static void hns_nic_self_test(struct net_device *ndev,
|
||||
st_param[1][0] = MAC_INTERNALLOOP_SERDES;
|
||||
st_param[1][1] = 1; /*serdes must exist*/
|
||||
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));
|
||||
|
||||
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/init.h>
|
||||
@ -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;
|
||||
int ret;
|
||||
|
||||
if (!mdio_dev->subctrl_vbase) {
|
||||
dev_err(&bus->dev, "mdio sys ctl reg has not maped\n");
|
||||
return -ENODEV;
|
||||
if (dev_of_node(bus->parent)) {
|
||||
if (!mdio_dev->subctrl_vbase) {
|
||||
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 */
|
||||
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(&bus->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(&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;
|
||||
}
|
||||
|
||||
/*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*/
|
||||
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(&bus->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(&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");
|
||||
|
||||
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
|
||||
* @pdev: mdio platform device
|
||||
@ -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)
|
||||
{
|
||||
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(&pdev->dev, sizeof(*mdio_dev), GFP_KERNEL);
|
||||
if (!mdio_dev)
|
||||
return -ENOMEM;
|
||||
@ -448,7 +445,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 = &pdev->dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mdio_dev->vbase = devm_ioremap_resource(&pdev->dev, res);
|
||||
@ -457,16 +454,32 @@ 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(&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);
|
||||
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) {
|
||||
dev_err(&pdev->dev, "Cannot register as MDIO bus!\n");
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
@ -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 = {
|
||||
.probe = hns_mdio_probe,
|
||||
.remove = hns_mdio_remove,
|
||||
.driver = {
|
||||
.name = MDIO_DRV_NAME,
|
||||
.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 *);
|
||||
|
||||
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;
|
||||
@ -654,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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user