From d0b2f91bede3bd5e3d24dd6803e56eee959c1797 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Thu, 20 Oct 2016 00:10:27 -0300 Subject: Linux-libre 4.8.2-gnu --- drivers/net/ethernet/hisilicon/hns/hnae.c | 19 +- drivers/net/ethernet/hisilicon/hns/hnae.h | 20 +- drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c | 60 ++-- drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c | 8 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 291 +++++++++++++----- drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h | 5 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 334 +++++++++++++-------- drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h | 45 ++- drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 302 ++++++++++++++++--- drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h | 7 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 16 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 7 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h | 2 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h | 21 +- .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c | 10 +- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 160 ++++++---- drivers/net/ethernet/hisilicon/hns/hns_enet.h | 2 +- drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 63 ++-- 18 files changed, 976 insertions(+), 396 deletions(-) (limited to 'drivers/net/ethernet/hisilicon/hns') diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c index 3bfe36f94..c54c6fac0 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.c +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c @@ -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); @@ -394,7 +400,6 @@ int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner) if (!hdev->ops || !hdev->ops->get_handle || !hdev->ops->toggle_ring_irq || - !hdev->ops->toggle_queue_status || !hdev->ops->get_status || !hdev->ops->adjust_link) return -EINVAL; diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h index e8d36aaea..e093cbf26 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.h +++ b/drivers/net/ethernet/hisilicon/hns/hnae.h @@ -27,6 +27,7 @@ * "cb" means control block */ +#include #include #include #include @@ -362,6 +363,14 @@ enum hnae_port_type { HNAE_PORT_DEBUG }; +/* mac media type */ +enum hnae_media_type { + HNAE_MEDIA_TYPE_UNKNOWN = 0, + HNAE_MEDIA_TYPE_FIBER, + HNAE_MEDIA_TYPE_COPPER, + HNAE_MEDIA_TYPE_BACKPLANE, +}; + /* This struct defines the operation on the handle. * * get_handle(): (mandatory) @@ -453,7 +462,6 @@ struct hnae_ae_ops { int (*get_info)(struct hnae_handle *handle, u8 *auto_neg, u16 *speed, u8 *duplex); void (*toggle_ring_irq)(struct hnae_ring *ring, u32 val); - void (*toggle_queue_status)(struct hnae_queue *queue, u32 val); void (*adjust_link)(struct hnae_handle *handle, int speed, int duplex); int (*set_loopback)(struct hnae_handle *handle, enum hnae_loop loop_mode, int en); @@ -472,6 +480,11 @@ struct hnae_ae_ops { int (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout); int (*set_coalesce_frames)(struct hnae_handle *handle, u32 coalesce_frames); + void (*get_coalesce_range)(struct hnae_handle *handle, + u32 *tx_frames_low, u32 *rx_frames_low, + u32 *tx_frames_high, u32 *rx_frames_high, + u32 *tx_usecs_low, u32 *rx_usecs_low, + u32 *tx_usecs_high, u32 *rx_usecs_high); void (*set_promisc_mode)(struct hnae_handle *handle, u32 en); int (*get_mac_addr)(struct hnae_handle *handle, void **p); int (*set_mac_addr)(struct hnae_handle *handle, void *p); @@ -512,7 +525,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; @@ -520,6 +533,7 @@ struct hnae_handle { u32 eport_id; u32 dport_id; /* v2 tx bd should fill the dport_id */ enum hnae_port_type port_type; + enum hnae_media_type media_type; struct list_head node; /* list to hnae_ae_dev->handle_list */ struct hnae_buf_ops *bops; /* operation for the buffer */ struct hnae_queue **qs; /* array base of all queues */ @@ -528,7 +542,7 @@ struct hnae_handle { #define ring_to_dev(ring) ((ring)->q->dev->dev) struct hnae_handle *hnae_get_handle(struct device *owner_dev, - const struct device_node *ae_node, + const struct fwnode_handle *fwnode, u32 port_id, struct hnae_buf_ops *bops); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c index 7a757e88c..e28d96099 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c @@ -131,9 +131,10 @@ 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->media_type = vf_cb->mac_cb->media_type; ae_handle->dport_id = port_id; return ae_handle; @@ -247,12 +248,21 @@ static void hns_ae_set_tso_stats(struct hnae_handle *handle, int enable) static int hns_ae_start(struct hnae_handle *handle) { int ret; + int k; struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle); ret = hns_mac_vm_config_bc_en(mac_cb, 0, true); if (ret) return ret; + for (k = 0; k < handle->q_num; k++) { + if (AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) + hns_rcb_int_clr_hw(handle->qs[k], + RCB_INT_FLAG_TX | RCB_INT_FLAG_RX); + else + hns_rcbv2_int_clr_hw(handle->qs[k], + RCB_INT_FLAG_TX | RCB_INT_FLAG_RX); + } hns_ae_ring_enable_all(handle, 1); msleep(100); @@ -313,18 +323,6 @@ static void hns_aev2_toggle_ring_irq(struct hnae_ring *ring, u32 mask) hns_rcbv2_int_ctrl_hw(ring->q, flag, mask); } -static void hns_ae_toggle_queue_status(struct hnae_queue *queue, u32 val) -{ - struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(queue->dev); - - if (AE_IS_VER1(dsaf_dev->dsaf_ver)) - hns_rcb_int_clr_hw(queue, RCB_INT_FLAG_TX | RCB_INT_FLAG_RX); - else - hns_rcbv2_int_clr_hw(queue, RCB_INT_FLAG_TX | RCB_INT_FLAG_RX); - - hns_rcb_start(queue, val); -} - static int hns_ae_get_link_status(struct hnae_handle *handle) { u32 link_status; @@ -465,6 +463,30 @@ static int hns_ae_set_coalesce_frames(struct hnae_handle *handle, ring_pair->port_id_in_comm, coalesce_frames); } +static void hns_ae_get_coalesce_range(struct hnae_handle *handle, + u32 *tx_frames_low, u32 *rx_frames_low, + u32 *tx_frames_high, u32 *rx_frames_high, + u32 *tx_usecs_low, u32 *rx_usecs_low, + u32 *tx_usecs_high, u32 *rx_usecs_high) +{ + struct dsaf_device *dsaf_dev; + + dsaf_dev = hns_ae_get_dsaf_dev(handle->dev); + + *tx_frames_low = HNS_RCB_MIN_COALESCED_FRAMES; + *rx_frames_low = HNS_RCB_MIN_COALESCED_FRAMES; + *tx_frames_high = + (dsaf_dev->desc_num - 1 > HNS_RCB_MAX_COALESCED_FRAMES) ? + HNS_RCB_MAX_COALESCED_FRAMES : dsaf_dev->desc_num - 1; + *rx_frames_high = + (dsaf_dev->desc_num - 1 > HNS_RCB_MAX_COALESCED_FRAMES) ? + HNS_RCB_MAX_COALESCED_FRAMES : dsaf_dev->desc_num - 1; + *tx_usecs_low = 0; + *rx_usecs_low = 0; + *tx_usecs_high = HNS_RCB_MAX_COALESCED_USECS; + *rx_usecs_high = HNS_RCB_MAX_COALESCED_USECS; +} + void hns_ae_update_stats(struct hnae_handle *handle, struct net_device_stats *net_stats) { @@ -587,6 +609,7 @@ void hns_ae_get_strings(struct hnae_handle *handle, int idx; struct hns_mac_cb *mac_cb; struct hns_ppe_cb *ppe_cb; + struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev); u8 *p = data; struct hnae_vf_cb *vf_cb; @@ -609,13 +632,14 @@ void hns_ae_get_strings(struct hnae_handle *handle, p += ETH_GSTRING_LEN * hns_mac_get_sset_count(mac_cb, stringset); if (mac_cb->mac_type == HNAE_PORT_SERVICE) - hns_dsaf_get_strings(stringset, p, port); + hns_dsaf_get_strings(stringset, p, port, dsaf_dev); } int hns_ae_get_sset_count(struct hnae_handle *handle, int stringset) { u32 sset_count = 0; struct hns_mac_cb *mac_cb; + struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev); assert(handle); @@ -626,7 +650,7 @@ int hns_ae_get_sset_count(struct hnae_handle *handle, int stringset) sset_count += hns_mac_get_sset_count(mac_cb, stringset); if (mac_cb->mac_type == HNAE_PORT_SERVICE) - sset_count += hns_dsaf_get_sset_count(stringset); + sset_count += hns_dsaf_get_sset_count(dsaf_dev, stringset); return sset_count; } @@ -637,13 +661,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); @@ -780,7 +806,6 @@ static struct hnae_ae_ops hns_dsaf_ops = { .stop = hns_ae_stop, .reset = hns_ae_reset, .toggle_ring_irq = hns_ae_toggle_ring_irq, - .toggle_queue_status = hns_ae_toggle_queue_status, .get_status = hns_ae_get_link_status, .get_info = hns_ae_get_mac_info, .adjust_link = hns_ae_adjust_link, @@ -794,6 +819,7 @@ static struct hnae_ae_ops hns_dsaf_ops = { .get_rx_max_coalesced_frames = hns_ae_get_rx_max_coalesced_frames, .set_coalesce_usecs = hns_ae_set_coalesce_usecs, .set_coalesce_frames = hns_ae_set_coalesce_frames, + .get_coalesce_range = hns_ae_get_coalesce_range, .set_promisc_mode = hns_ae_set_promisc_mode, .set_mac_addr = hns_ae_set_mac_address, .set_mc_addr = hns_ae_set_multicast_one, diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c index 44abb08de..1e1eb9299 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c @@ -17,7 +17,7 @@ static const struct mac_stats_string g_gmac_stats_string[] = { {"gmac_rx_octets_total_ok", MAC_STATS_FIELD_OFF(rx_good_bytes)}, {"gmac_rx_octets_bad", MAC_STATS_FIELD_OFF(rx_bad_bytes)}, {"gmac_rx_uc_pkts", MAC_STATS_FIELD_OFF(rx_uc_pkts)}, - {"gamc_rx_mc_pkts", MAC_STATS_FIELD_OFF(rx_mc_pkts)}, + {"gmac_rx_mc_pkts", MAC_STATS_FIELD_OFF(rx_mc_pkts)}, {"gmac_rx_bc_pkts", MAC_STATS_FIELD_OFF(rx_bc_pkts)}, {"gmac_rx_pkts_64octets", MAC_STATS_FIELD_OFF(rx_64bytes)}, {"gmac_rx_pkts_65to127", MAC_STATS_FIELD_OFF(rx_65to127)}, @@ -110,7 +110,7 @@ static void hns_gmac_free(void *mac_drv) u32 mac_id = drv->mac_id; - hns_dsaf_ge_srst_by_port(dsaf_dev, mac_id, 0); + dsaf_dev->misc_op->ge_srst(dsaf_dev, mac_id, 0); } static void hns_gmac_set_tx_auto_pause_frames(void *mac_drv, u16 newval) @@ -317,9 +317,9 @@ static void hns_gmac_init(void *mac_drv) port = drv->mac_id; - hns_dsaf_ge_srst_by_port(dsaf_dev, port, 0); + dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 0); mdelay(10); - hns_dsaf_ge_srst_by_port(dsaf_dev, port, 1); + dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 1); mdelay(10); hns_gmac_disable(mac_drv, MAC_COMM_MODE_RX_AND_TX); hns_gmac_tx_loop_pkt_dis(mac_drv); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c index 611581fcc..5c8afe1a5 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c @@ -7,6 +7,7 @@ * (at your option) any later version. */ +#include #include #include #include @@ -15,7 +16,8 @@ #include #include #include -#include +#include +#include #include #include "hns_dsaf_main.h" @@ -54,20 +56,6 @@ static const enum mac_mode g_mac_mode_1000[] = { [PHY_INTERFACE_MODE_RTBI] = MAC_MODE_RTBI_1000 }; -static enum mac_mode hns_mac_dev_to_enet_if(const struct hns_mac_cb *mac_cb) -{ - switch (mac_cb->max_speed) { - case MAC_SPEED_100: - return g_mac_mode_100[mac_cb->phy_if]; - case MAC_SPEED_1000: - return g_mac_mode_1000[mac_cb->phy_if]; - case MAC_SPEED_10000: - return MAC_MODE_XGMII_10000; - default: - return MAC_MODE_MII_100; - } -} - static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb) { switch (mac_cb->max_speed) { @@ -94,7 +82,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; @@ -132,7 +120,6 @@ void hns_mac_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex) mac_cb->speed = speed; mac_cb->half_duplex = !duplex; - mac_ctrl_drv->mac_mode = hns_mac_dev_to_enet_if(mac_cb); if (mac_ctrl_drv->adjust_link) { ret = mac_ctrl_drv->adjust_link(mac_ctrl_drv, @@ -511,7 +498,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 +624,127 @@ 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); +} + +#define MAC_MEDIA_TYPE_MAX_LEN 16 + +static const struct { + enum hnae_media_type value; + const char *name; +} media_type_defs[] = { + {HNAE_MEDIA_TYPE_UNKNOWN, "unknown" }, + {HNAE_MEDIA_TYPE_FIBER, "fiber" }, + {HNAE_MEDIA_TYPE_COPPER, "copper" }, + {HNAE_MEDIA_TYPE_BACKPLANE, "backplane" }, +}; + /** *hns_mac_get_info - get mac information from device node *@mac_cb: mac device @@ -645,13 +753,16 @@ 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; + const char *media_type; + u32 i; u32 ret; mac_cb->link = false; mac_cb->half_duplex = false; + mac_cb->media_type = HNAE_MEDIA_TYPE_UNKNOWN; mac_cb->speed = mac_phy_to_speed[mac_cb->phy_if]; mac_cb->max_speed = mac_cb->speed; @@ -672,62 +783,98 @@ 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); - 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; + mac_cb->mac_id, np->name); + } + of_node_put(np); - 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); + return 0; } - 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); - } + 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); + } + of_node_put(np); - 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); + np = of_parse_phandle(to_of_node(mac_cb->fw_port), + "serdes-syscon", 0); + syscon = syscon_node_to_regmap(np); + of_node_put(np); 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); + } + + if (!fwnode_property_read_string(mac_cb->fw_port, "media-type", + &media_type)) { + for (i = 0; i < ARRAY_SIZE(media_type_defs); i++) { + if (!strncmp(media_type_defs[i].name, media_type, + MAC_MEDIA_TYPE_MAX_LEN)) { + mac_cb->media_type = media_type_defs[i].value; + break; + } } } @@ -790,7 +937,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 +952,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 +1039,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 +1122,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 +1132,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); } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h index 97ce9a750..4cbdf14f5 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h @@ -335,10 +335,11 @@ struct hns_mac_cb { u64 txpkt_for_led; u64 rxpkt_for_led; enum hnae_port_type mac_type; + enum hnae_media_type media_type; 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 +449,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); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index 1c2ddb25e..afb5daa37 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -7,6 +7,7 @@ * (at your option) any later version. */ +#include #include #include #include @@ -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; @@ -42,15 +51,27 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) const char *mode_str; struct regmap *syscon; struct resource *res; - struct device_node *np = dsaf_dev->dev->of_node; + struct device_node *np = dsaf_dev->dev->of_node, *np_temp; 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,41 @@ 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)) { + np_temp = of_parse_phandle(np, "subctrl-syscon", 0); + syscon = syscon_node_to_regmap(np_temp); + of_node_put(np_temp); + 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->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; + dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev, + res); + if (IS_ERR(dsaf_dev->sc_base)) { + dev_err(dsaf_dev->dev, "subctrl can not map!\n"); + return PTR_ERR(dsaf_dev->sc_base); + } + + 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 (IS_ERR(dsaf_dev->sds_base)) { + dev_err(dsaf_dev->dev, "serdes-ctrl can not map!\n"); + return PTR_ERR(dsaf_dev->sds_base); + } + } else { + dsaf_dev->sub_ctrl = syscon; } - } else { - dsaf_dev->sub_ctrl = syscon; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe-base"); @@ -117,9 +147,9 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) } } dsaf_dev->ppe_base = devm_ioremap_resource(&pdev->dev, res); - if (!dsaf_dev->ppe_base) { + if (IS_ERR(dsaf_dev->ppe_base)) { dev_err(dsaf_dev->dev, "ppe-base resource can not map!\n"); - return -ENOMEM; + return PTR_ERR(dsaf_dev->ppe_base); } dsaf_dev->ppe_paddr = res->start; @@ -136,33 +166,34 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) } } dsaf_dev->io_base = devm_ioremap_resource(&pdev->dev, res); - if (!dsaf_dev->io_base) { + if (IS_ERR(dsaf_dev->io_base)) { dev_err(dsaf_dev->dev, "dsaf-base resource can not map!\n"); - return -ENOMEM; + return PTR_ERR(dsaf_dev->io_base); } } - 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", desc_num, ret); - goto unmap_base_addr; + return -EINVAL; } 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); - goto unmap_base_addr; + return ret; } dsaf_dev->buf_size = buf_size; @@ -170,41 +201,19 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) if (dsaf_dev->buf_size_type < 0) { dev_err(dsaf_dev->dev, "buf_size(%d) is wrong!\n", buf_size); - goto unmap_base_addr; + return -EINVAL; } + 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 dev_err(dsaf_dev->dev, "set mask to 64bit fail!\n"); return 0; - -unmap_base_addr: - if (dsaf_dev->io_base) - iounmap(dsaf_dev->io_base); - if (dsaf_dev->ppe_base) - iounmap(dsaf_dev->ppe_base); - if (dsaf_dev->sds_base) - iounmap(dsaf_dev->sds_base); - if (dsaf_dev->sc_base) - iounmap(dsaf_dev->sc_base); - return ret; -} - -static void hns_dsaf_free_cfg(struct dsaf_device *dsaf_dev) -{ - if (dsaf_dev->io_base) - iounmap(dsaf_dev->io_base); - - if (dsaf_dev->ppe_base) - iounmap(dsaf_dev->ppe_base); - - if (dsaf_dev->sds_base) - iounmap(dsaf_dev->sds_base); - - if (dsaf_dev->sc_base) - iounmap(dsaf_dev->sc_base); } /** @@ -508,10 +517,10 @@ static void hns_dsafv2_sbm_bp_wl_cfg(struct dsaf_device *dsaf_dev) o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_M, - DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_S, 110); + DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_S, 48); dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_M, - DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_S, 160); + DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_S, 80); dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); /* for no enable pfc mode */ @@ -519,29 +528,39 @@ static void hns_dsafv2_sbm_bp_wl_cfg(struct dsaf_device *dsaf_dev) o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_M, - DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_S, 128); + DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_S, 192); dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_M, - DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S, 192); + DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S, 240); dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); } /* PPE */ - reg = DSAF_SBM_BP_CFG_2_PPE_REG_0_REG + 0x80 * i; - o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); - dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG2_SET_BUF_NUM_M, - DSAFV2_SBM_CFG2_SET_BUF_NUM_S, 10); - dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG2_RESET_BUF_NUM_M, - DSAFV2_SBM_CFG2_RESET_BUF_NUM_S, 12); - dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); + for (i = 0; i < DSAFV2_SBM_PPE_CHN; i++) { + reg = DSAF_SBM_BP_CFG_2_PPE_REG_0_REG + 0x80 * i; + o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_PPE_SET_BUF_NUM_M, + DSAFV2_SBM_CFG2_PPE_SET_BUF_NUM_S, 2); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_PPE_RESET_BUF_NUM_M, + DSAFV2_SBM_CFG2_PPE_RESET_BUF_NUM_S, 3); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_PPE_CFG_USEFUL_NUM_M, + DSAFV2_SBM_CFG2_PPE_CFG_USEFUL_NUM_S, 52); + dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); + } + /* RoCEE */ for (i = 0; i < DASFV2_ROCEE_CRD_NUM; i++) { reg = DSAFV2_SBM_BP_CFG_2_ROCEE_REG_0_REG + 0x80 * i; o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); - dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG2_SET_BUF_NUM_M, - DSAFV2_SBM_CFG2_SET_BUF_NUM_S, 2); - dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG2_RESET_BUF_NUM_M, - DSAFV2_SBM_CFG2_RESET_BUF_NUM_S, 4); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_ROCEE_SET_BUF_NUM_M, + DSAFV2_SBM_CFG2_ROCEE_SET_BUF_NUM_S, 2); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_ROCEE_RESET_BUF_NUM_M, + DSAFV2_SBM_CFG2_ROCEE_RESET_BUF_NUM_S, 4); dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); } } @@ -852,6 +871,8 @@ static void hns_dsaf_single_line_tbl_cfg( struct dsaf_device *dsaf_dev, u32 address, struct dsaf_tbl_line_cfg *ptbl_line) { + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_line_addr_cfg(dsaf_dev, address); @@ -860,6 +881,8 @@ static void hns_dsaf_single_line_tbl_cfg( /*Write Plus*/ hns_dsaf_tbl_line_pul(dsaf_dev); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -873,6 +896,8 @@ static void hns_dsaf_tcam_uc_cfg( struct dsaf_tbl_tcam_data *ptbl_tcam_data, struct dsaf_tbl_tcam_ucast_cfg *ptbl_tcam_ucast) { + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); /*Write Tcam Data*/ @@ -881,6 +906,8 @@ static void hns_dsaf_tcam_uc_cfg( hns_dsaf_tbl_tcam_ucast_cfg(dsaf_dev, ptbl_tcam_ucast); /*Write Plus*/ hns_dsaf_tbl_tcam_data_ucast_pul(dsaf_dev); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -895,6 +922,8 @@ static void hns_dsaf_tcam_mc_cfg( struct dsaf_tbl_tcam_data *ptbl_tcam_data, struct dsaf_tbl_tcam_mcast_cfg *ptbl_tcam_mcast) { + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); /*Write Tcam Data*/ @@ -903,6 +932,8 @@ static void hns_dsaf_tcam_mc_cfg( hns_dsaf_tbl_tcam_mcast_cfg(dsaf_dev, ptbl_tcam_mcast); /*Write Plus*/ hns_dsaf_tbl_tcam_data_mcast_pul(dsaf_dev); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -912,6 +943,8 @@ static void hns_dsaf_tcam_mc_cfg( */ static void hns_dsaf_tcam_mc_invld(struct dsaf_device *dsaf_dev, u32 address) { + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); @@ -924,6 +957,8 @@ static void hns_dsaf_tcam_mc_invld(struct dsaf_device *dsaf_dev, u32 address) /*Write Plus*/ hns_dsaf_tbl_tcam_mcast_pul(dsaf_dev); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -941,6 +976,8 @@ static void hns_dsaf_tcam_uc_get( u32 tcam_read_data0; u32 tcam_read_data4; + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); @@ -949,9 +986,9 @@ static void hns_dsaf_tcam_uc_get( /*read tcam data*/ ptbl_tcam_data->tbl_tcam_data_high - = dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_LOW_0_REG); - ptbl_tcam_data->tbl_tcam_data_low = dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_HIGH_0_REG); + ptbl_tcam_data->tbl_tcam_data_low + = dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_LOW_0_REG); /*read tcam mcast*/ tcam_read_data0 = dsaf_read_dev(dsaf_dev, @@ -973,6 +1010,8 @@ static void hns_dsaf_tcam_uc_get( DSAF_TBL_UCAST_CFG1_OUT_PORT_S); ptbl_tcam_ucast->tbl_ucast_dvc = dsaf_get_bit(tcam_read_data0, DSAF_TBL_UCAST_CFG1_DVC_S); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -989,6 +1028,8 @@ static void hns_dsaf_tcam_mc_get( { u32 data_tmp; + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); @@ -997,9 +1038,9 @@ static void hns_dsaf_tcam_mc_get( /*read tcam data*/ ptbl_tcam_data->tbl_tcam_data_high = - dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_LOW_0_REG); - ptbl_tcam_data->tbl_tcam_data_low = dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_HIGH_0_REG); + ptbl_tcam_data->tbl_tcam_data_low = + dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_LOW_0_REG); /*read tcam mcast*/ ptbl_tcam_mcast->tbl_mcast_port_msk[0] = @@ -1019,6 +1060,8 @@ static void hns_dsaf_tcam_mc_get( ptbl_tcam_mcast->tbl_mcast_port_msk[4] = dsaf_get_field(data_tmp, DSAF_TBL_MCAST_CFG4_VM128_112_M, DSAF_TBL_MCAST_CFG4_VM128_112_S); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -1080,10 +1123,10 @@ int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id, u32 en) { if (AE_IS_VER1(dsaf_dev->dsaf_ver)) { - if (!en) + if (!en) { dev_err(dsaf_dev->dev, "dsafv1 can't close rx_pause!\n"); - - return -EINVAL; + return -EINVAL; + } } dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4, @@ -1295,9 +1338,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 +1368,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); } /** @@ -1343,6 +1386,7 @@ static int hns_dsaf_init(struct dsaf_device *dsaf_dev) if (HNS_DSAF_IS_DEBUG(dsaf_dev)) return 0; + spin_lock_init(&dsaf_dev->tcam_lock); ret = hns_dsaf_init_hw(dsaf_dev); if (ret) return ret; @@ -2088,11 +2132,24 @@ void hns_dsaf_fix_mac_mode(struct hns_mac_cb *mac_cb) hns_dsaf_port_work_rate_cfg(dsaf_dev, mac_id, mode); } +static u32 hns_dsaf_get_inode_prio_reg(int index) +{ + int base_index, offset; + u32 base_addr = DSAF_INODE_IN_PRIO_PAUSE_BASE_REG; + + base_index = (index + 1) / DSAF_REG_PER_ZONE; + offset = (index + 1) % DSAF_REG_PER_ZONE; + + return base_addr + DSAF_INODE_IN_PRIO_PAUSE_BASE_OFFSET * base_index + + DSAF_INODE_IN_PRIO_PAUSE_OFFSET * offset; +} + void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num) { struct dsaf_hw_stats *hw_stats = &dsaf_dev->hw_stats[node_num]; bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver); + int i; u32 reg_tmp; hw_stats->pad_drop += dsaf_read_dev(dsaf_dev, @@ -2127,6 +2184,18 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num) hw_stats->stp_drop += dsaf_read_dev(dsaf_dev, DSAF_INODE_IN_DATA_STP_DISC_0_REG + 0x80 * (u64)node_num); + /* pfc pause frame statistics stored in dsaf inode*/ + if ((node_num < DSAF_SERVICE_NW_NUM) && !is_ver1) { + for (i = 0; i < DSAF_PRIO_NR; i++) { + reg_tmp = hns_dsaf_get_inode_prio_reg(i); + hw_stats->rx_pfc[i] += dsaf_read_dev(dsaf_dev, + reg_tmp + 0x4 * (u64)node_num); + hw_stats->tx_pfc[i] += dsaf_read_dev(dsaf_dev, + DSAF_XOD_XGE_PFC_PRIO_CNT_BASE_REG + + DSAF_XOD_XGE_PFC_PRIO_CNT_OFFSET * i + + 0xF0 * (u64)node_num); + } + } hw_stats->tx_pkts += dsaf_read_dev(dsaf_dev, DSAF_XOD_RCVPKT_CNT_0_REG + 0x90 * (u64)node_num); } @@ -2464,38 +2533,53 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) p[i] = 0xdddddddd; } -static char *hns_dsaf_get_node_stats_strings(char *data, int node) +static char *hns_dsaf_get_node_stats_strings(char *data, int node, + struct dsaf_device *dsaf_dev) { char *buff = data; + int i; + bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver); snprintf(buff, ETH_GSTRING_LEN, "innod%d_pad_drop_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_manage_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_rx_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_rx_pkt_id", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_rx_pause_frame", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_release_buf_num", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_sbm_drop_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_crc_false_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_bp_drop_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_lookup_rslt_drop_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_local_rslt_fail_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_vlan_drop_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_stp_drop_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; + if (node < DSAF_SERVICE_NW_NUM && !is_ver1) { + for (i = 0; i < DSAF_PRIO_NR; i++) { + snprintf(buff + 0 * ETH_GSTRING_LEN * DSAF_PRIO_NR, + ETH_GSTRING_LEN, "inod%d_pfc_prio%d_pkts", + node, i); + snprintf(buff + 1 * ETH_GSTRING_LEN * DSAF_PRIO_NR, + ETH_GSTRING_LEN, "onod%d_pfc_prio%d_pkts", + node, i); + buff += ETH_GSTRING_LEN; + } + buff += 1 * DSAF_PRIO_NR * ETH_GSTRING_LEN; + } snprintf(buff, ETH_GSTRING_LEN, "onnod%d_tx_pkts", node); - buff = buff + ETH_GSTRING_LEN; + buff += ETH_GSTRING_LEN; return buff; } @@ -2504,7 +2588,9 @@ static u64 *hns_dsaf_get_node_stats(struct dsaf_device *ddev, u64 *data, int node_num) { u64 *p = data; + int i; struct dsaf_hw_stats *hw_stats = &ddev->hw_stats[node_num]; + bool is_ver1 = AE_IS_VER1(ddev->dsaf_ver); p[0] = hw_stats->pad_drop; p[1] = hw_stats->man_pkts; @@ -2519,8 +2605,16 @@ static u64 *hns_dsaf_get_node_stats(struct dsaf_device *ddev, u64 *data, p[10] = hw_stats->local_addr_false; p[11] = hw_stats->vlan_drop; p[12] = hw_stats->stp_drop; - p[13] = hw_stats->tx_pkts; + if (node_num < DSAF_SERVICE_NW_NUM && !is_ver1) { + for (i = 0; i < DSAF_PRIO_NR; i++) { + p[13 + i + 0 * DSAF_PRIO_NR] = hw_stats->rx_pfc[i]; + p[13 + i + 1 * DSAF_PRIO_NR] = hw_stats->tx_pfc[i]; + } + p[29] = hw_stats->tx_pkts; + return &p[30]; + } + p[13] = hw_stats->tx_pkts; return &p[14]; } @@ -2548,11 +2642,16 @@ void hns_dsaf_get_stats(struct dsaf_device *ddev, u64 *data, int port) *@stringset: type of values in data *return dsaf string name count */ -int hns_dsaf_get_sset_count(int stringset) +int hns_dsaf_get_sset_count(struct dsaf_device *dsaf_dev, int stringset) { - if (stringset == ETH_SS_STATS) - return DSAF_STATIC_NUM; + bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver); + if (stringset == ETH_SS_STATS) { + if (is_ver1) + return DSAF_STATIC_NUM; + else + return DSAF_V2_STATIC_NUM; + } return 0; } @@ -2562,7 +2661,8 @@ int hns_dsaf_get_sset_count(int stringset) *@data:strings name value *@port:port index */ -void hns_dsaf_get_strings(int stringset, u8 *data, int port) +void hns_dsaf_get_strings(int stringset, u8 *data, int port, + struct dsaf_device *dsaf_dev) { char *buff = (char *)data; int node = port; @@ -2571,11 +2671,11 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port) return; /* for ge/xge node info */ - buff = hns_dsaf_get_node_stats_strings(buff, node); + buff = hns_dsaf_get_node_stats_strings(buff, node, dsaf_dev); /* for ppe node info */ node = port + DSAF_PPE_INODE_BASE; - (void)hns_dsaf_get_node_stats_strings(buff, node); + (void)hns_dsaf_get_node_stats_strings(buff, node, dsaf_dev); } /** @@ -2611,7 +2711,7 @@ static int hns_dsaf_probe(struct platform_device *pdev) ret = hns_dsaf_init(dsaf_dev); if (ret) - goto free_cfg; + goto free_dev; ret = hns_mac_init(dsaf_dev); if (ret) @@ -2636,9 +2736,6 @@ uninit_mac: uninit_dsaf: hns_dsaf_free(dsaf_dev); -free_cfg: - hns_dsaf_free_cfg(dsaf_dev); - free_dev: hns_dsaf_free_dev(dsaf_dev); @@ -2661,8 +2758,6 @@ static int hns_dsaf_remove(struct platform_device *pdev) hns_dsaf_free(dsaf_dev); - hns_dsaf_free_cfg(dsaf_dev); - hns_dsaf_free_dev(dsaf_dev); return 0; @@ -2680,6 +2775,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, }, }; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h index f0502ba0a..1daf018d9 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h @@ -39,6 +39,9 @@ struct hns_mac_cb; #define DSAF_DUMP_REGS_NUM 504 #define DSAF_STATIC_NUM 28 +#define DSAF_V2_STATIC_NUM 44 +#define DSAF_PRIO_NR 8 +#define DSAF_REG_PER_ZONE 3 #define DSAF_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset)))) #define HNS_DSAF_IS_DEBUG(dev) (dev->dsaf_mode == DSAF_MODE_DISABLE_SP) @@ -176,6 +179,8 @@ struct dsaf_hw_stats { u64 local_addr_false; u64 vlan_drop; u64 stp_drop; + u64 rx_pfc[DSAF_PRIO_NR]; + u64 tx_pfc[DSAF_PRIO_NR]; u64 tx_pkts; }; @@ -268,6 +273,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,9 +318,12 @@ 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; + /* make sure tcam table config spinlock */ + spinlock_t tcam_lock; }; static inline void *hns_dsaf_dev_priv(const struct dsaf_device *dsaf_dev) @@ -388,27 +417,17 @@ 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); +int hns_dsaf_get_sset_count(struct dsaf_device *dsaf_dev, int stringset); void hns_dsaf_get_stats(struct dsaf_device *ddev, u64 *data, int port); -void hns_dsaf_get_strings(int stringset, u8 *data, int port); +void hns_dsaf_get_strings(int stringset, u8 *data, int port, + struct dsaf_device *dsaf_dev); void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data); int hns_dsaf_get_regs_count(void); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c index a837bb9e3..611b67b6f 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c @@ -12,6 +12,27 @@ #include "hns_dsaf_ppe.h" #include "hns_dsaf_reg.h" +enum _dsm_op_index { + HNS_OP_RESET_FUNC = 0x1, + HNS_OP_SERDES_LP_FUNC = 0x2, + HNS_OP_LED_SET_FUNC = 0x3, + HNS_OP_GET_PORT_TYPE_FUNC = 0x4, + HNS_OP_GET_SFP_STAT_FUNC = 0x5, +}; + +enum _dsm_rst_type { + HNS_DSAF_RESET_FUNC = 0x1, + HNS_PPE_RESET_FUNC = 0x2, + HNS_XGE_CORE_RESET_FUNC = 0x3, + HNS_XGE_RESET_FUNC = 0x4, + HNS_GE_RESET_FUNC = 0x5, +}; + +const u8 hns_dsaf_acpi_dsm_uuid[] = { + 0x1A, 0xAA, 0x85, 0x1A, 0x93, 0xE2, 0x5E, 0x41, + 0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A +}; + static void dsaf_write_sub(struct dsaf_device *dsaf_dev, u32 reg, u32 val) { if (dsaf_dev->sub_ctrl) @@ -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; @@ -65,13 +86,14 @@ void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, mac_cb->cpld_led_value = value; } } else { - dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, - CPLD_LED_DEFAULT_VALUE); - mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE; + value = (mac_cb->cpld_led_value) & (0x1 << DSAF_LED_ANCHOR_B); + dsaf_write_syscon(mac_cb->cpld_ctrl, + mac_cb->cpld_ctrl_reg, value); + mac_cb->cpld_led_value = value; } } -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 +103,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: @@ -93,7 +115,7 @@ int cpld_set_led_id(struct hns_mac_cb *mac_cb, CPLD_LED_ON_VALUE); dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, mac_cb->cpld_led_value); - return 2; + break; case HNAE_LED_INACTIVE: dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B, CPLD_LED_DEFAULT_VALUE); @@ -101,7 +123,8 @@ int cpld_set_led_id(struct hns_mac_cb *mac_cb, mac_cb->cpld_led_value); break; default: - break; + dev_err(mac_cb->dev, "invalid led state: %d!", status); + return -EINVAL; } return 0; @@ -109,12 +132,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 +177,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 +196,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 +204,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 +223,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 +231,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; @@ -178,12 +253,11 @@ void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) reg_val_1 = 0x1 << port; port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off; /* there is difference between V1 and V2 in register.*/ - if (AE_IS_VER1(dsaf_dev->dsaf_ver)) - reg_val_2 = 0x1041041 << port_rst_off; - else - reg_val_2 = 0x2082082 << port_rst_off; + reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? + 0x1041041 : 0x2082082; + reg_val_2 <<= port_rst_off; - if (val == 0) { + if (!dereset) { dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG, reg_val_1); @@ -197,10 +271,13 @@ void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) reg_val_1); } } else { - reg_val_1 = 0x15540 << dsaf_dev->reset_offset; - reg_val_2 = 0x100 << dsaf_dev->reset_offset; + reg_val_1 = 0x15540; + reg_val_2 = AE_IS_VER1(dsaf_dev->dsaf_ver) ? 0x100 : 0x40; + + reg_val_1 <<= dsaf_dev->reset_offset; + reg_val_2 <<= 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 +293,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 +316,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 +341,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 +355,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 +387,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,13 +433,8 @@ 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 - */ - u8 *base_addr = (u8 *)mac_cb->serdes_vaddr + - (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000); const u8 lane_id[] = { 0, /* mac 0 -> lane 0 */ 1, /* mac 1 -> lane 1 */ @@ -332,7 +451,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 @@ -341,13 +460,110 @@ 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); + u32 origin; + + if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) { +#define HILINK_ACCESS_SEL_CFG 0x40008 + /* hilink4 & hilink3 use the same xge training and + * xge u adaptor. There is a hilink access sel cfg + * register to select which one to be configed + */ + if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) && + (mac_cb->mac_id <= 3)) + dsaf_write_syscon(mac_cb->serdes_ctrl, + HILINK_ACCESS_SEL_CFG, 0); + else + dsaf_write_syscon(mac_cb->serdes_ctrl, + HILINK_ACCESS_SEL_CFG, 3); + } - dsaf_set_field(origin, 1ull << 10, 10, !!en); + origin = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset); + + 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); + u8 *base_addr = (u8 *)mac_cb->serdes_vaddr + + (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000); + 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; +} diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h index 419f07aa9..f06bb03d4 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h @@ -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 diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c index 8cd151a52..6ea872287 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c @@ -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); @@ -330,8 +330,10 @@ static void hns_ppe_uninit_hw(struct hns_ppe_cb *ppe_cb) u32 port; if (ppe_cb->ppe_common_cb) { + struct dsaf_device *dsaf_dev = ppe_cb->ppe_common_cb->dsaf_dev; + 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); } } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index 4ef6d23d9..ef1107777 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c @@ -458,7 +458,6 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common) u32 i; u32 ring_num = rcb_common->ring_num; int base_irq_idx = hns_rcb_get_base_irq_idx(rcb_common); - struct device_node *np = rcb_common->dsaf_dev->dev->of_node; struct platform_device *pdev = to_platform_device(rcb_common->dsaf_dev->dev); bool is_ver1 = AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver); @@ -473,10 +472,10 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common) ring_pair_cb->port_id_in_comm = hns_rcb_get_port_in_comm(rcb_common, i); ring_pair_cb->virq[HNS_RCB_IRQ_IDX_TX] = - is_ver1 ? irq_of_parse_and_map(np, base_irq_idx + i * 2) : + is_ver1 ? platform_get_irq(pdev, base_irq_idx + i * 2) : platform_get_irq(pdev, base_irq_idx + i * 3 + 1); ring_pair_cb->virq[HNS_RCB_IRQ_IDX_RX] = - is_ver1 ? irq_of_parse_and_map(np, base_irq_idx + i * 2 + 1) : + is_ver1 ? platform_get_irq(pdev, base_irq_idx + i * 2 + 1) : platform_get_irq(pdev, base_irq_idx + i * 3); ring_pair_cb->q.phy_base = RCB_COMM_BASE_TO_RING_BASE(rcb_common->phy_base, i); @@ -541,7 +540,7 @@ int hns_rcb_set_coalesce_usecs( } if (timeout > HNS_RCB_MAX_COALESCED_USECS) { dev_err(rcb_common->dsaf_dev->dev, - "error: not support coalesce %dus!\n", timeout); + "error: coalesce_usecs setting supports 0~1023us\n"); return -EINVAL; } hns_rcb_set_port_timeout(rcb_common, port_idx, timeout); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h index bd54dac82..99b4e1ba0 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h @@ -40,7 +40,7 @@ struct rcb_common_cb; #define HNS_RCB_DEF_COALESCED_FRAMES 50 #define HNS_RCB_CLK_FREQ_MHZ 350 #define HNS_RCB_MAX_COALESCED_USECS 0x3ff -#define HNS_RCB_DEF_COALESCED_USECS 3 +#define HNS_RCB_DEF_COALESCED_USECS 50 #define HNS_RCB_COMMON_ENDIAN 1 diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h index 7c3b5103d..235f74444 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h @@ -32,7 +32,7 @@ #define DSAFV2_SBM_NUM 8 #define DSAFV2_SBM_XGE_CHN 6 #define DSAFV2_SBM_PPE_CHN 1 -#define DASFV2_ROCEE_CRD_NUM 8 +#define DASFV2_ROCEE_CRD_NUM 1 #define DSAF_VOQ_NUM DSAF_NODE_NUM #define DSAF_INODE_NUM DSAF_NODE_NUM @@ -166,6 +166,9 @@ #define DSAF_INODE_GE_FC_EN_0_REG 0x1B00 #define DSAF_INODE_VC0_IN_PKT_NUM_0_REG 0x1B50 #define DSAF_INODE_VC1_IN_PKT_NUM_0_REG 0x1C00 +#define DSAF_INODE_IN_PRIO_PAUSE_BASE_REG 0x1C00 +#define DSAF_INODE_IN_PRIO_PAUSE_BASE_OFFSET 0x100 +#define DSAF_INODE_IN_PRIO_PAUSE_OFFSET 0x50 #define DSAF_SBM_CFG_REG_0_REG 0x2000 #define DSAF_SBM_BP_CFG_0_XGE_REG_0_REG 0x2004 @@ -175,7 +178,7 @@ #define DSAF_SBM_BP_CFG_2_XGE_REG_0_REG 0x200C #define DSAF_SBM_BP_CFG_2_PPE_REG_0_REG 0x230C #define DSAF_SBM_BP_CFG_2_ROCEE_REG_0_REG 0x260C -#define DSAFV2_SBM_BP_CFG_2_ROCEE_REG_0_REG 0x238C +#define DSAFV2_SBM_BP_CFG_2_ROCEE_REG_0_REG 0x238C #define DSAF_SBM_FREE_CNT_0_0_REG 0x2010 #define DSAF_SBM_FREE_CNT_1_0_REG 0x2014 #define DSAF_SBM_BP_CNT_0_0_REG 0x2018 @@ -232,6 +235,8 @@ #define DSAF_XOD_ROCEE_RCVIN0_CNT_0_REG 0x3074 #define DSAF_XOD_ROCEE_RCVIN1_CNT_0_REG 0x3078 #define DSAF_XOD_FIFO_STATUS_0_REG 0x307C +#define DSAF_XOD_XGE_PFC_PRIO_CNT_BASE_REG 0x3A00 +#define DSAF_XOD_XGE_PFC_PRIO_CNT_OFFSET 0x4 #define DSAF_VOQ_ECC_INVERT_EN_0_REG 0x4004 #define DSAF_VOQ_SRAM_PKT_NUM_0_REG 0x4008 @@ -791,6 +796,18 @@ #define DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S 9 #define DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_M (((1ULL << 9) - 1) << 9) +#define DSAFV2_SBM_CFG2_ROCEE_SET_BUF_NUM_S 0 +#define DSAFV2_SBM_CFG2_ROCEE_SET_BUF_NUM_M (((1ULL << 8) - 1) << 0) +#define DSAFV2_SBM_CFG2_ROCEE_RESET_BUF_NUM_S 8 +#define DSAFV2_SBM_CFG2_ROCEE_RESET_BUF_NUM_M (((1ULL << 8) - 1) << 8) + +#define DSAFV2_SBM_CFG2_PPE_SET_BUF_NUM_S (0) +#define DSAFV2_SBM_CFG2_PPE_SET_BUF_NUM_M (((1ULL << 6) - 1) << 0) +#define DSAFV2_SBM_CFG2_PPE_RESET_BUF_NUM_S (6) +#define DSAFV2_SBM_CFG2_PPE_RESET_BUF_NUM_M (((1ULL << 6) - 1) << 6) +#define DSAFV2_SBM_CFG2_PPE_CFG_USEFUL_NUM_S (12) +#define DSAFV2_SBM_CFG2_PPE_CFG_USEFUL_NUM_M (((1ULL << 6) - 1) << 12) + #define DSAF_TBL_TCAM_ADDR_S 0 #define DSAF_TBL_TCAM_ADDR_M ((1ULL << 9) - 1) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c index fd90f3737..8f4f0e8da 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c @@ -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); } /** diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index e621636e6..d7e1f8c7a 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -132,6 +132,13 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv, ring_ptr_move_fw(ring, next_to_use); } +static const struct acpi_device_id hns_enet_acpi_match[] = { + { "HISI00C1", 0 }, + { "HISI00C2", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, hns_enet_acpi_match); + static void fill_desc(struct hnae_ring *ring, void *priv, int size, dma_addr_t dma, int frag_end, int buf_num, enum hns_desc_type type, int mtu) @@ -593,6 +600,7 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data, ring->stats.sw_err_cnt++; return -ENOMEM; } + skb_reset_mac_header(skb); prefetchw(skb->data); length = le16_to_cpu(desc->rx.pkt_len); @@ -754,16 +762,16 @@ static int hns_nic_rx_poll_one(struct hns_nic_ring_data *ring_data, recv_pkts = 0, recv_bds = 0, clean_count = 0; recv: while (recv_pkts < budget && recv_bds < num) { - /* reuse or realloc buffers*/ + /* reuse or realloc buffers */ if (clean_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) { hns_nic_alloc_rx_buffers(ring_data, clean_count); clean_count = 0; } - /* poll one pkg*/ + /* poll one pkt */ err = hns_nic_poll_rx_skb(ring_data, &skb, &bnum); if (unlikely(!skb)) /* this fault cannot be repaired */ - break; + goto out; recv_bds += bnum; clean_count += bnum; @@ -789,6 +797,7 @@ recv: } } +out: /* make all data has been write before submit */ if (clean_count > 0) hns_nic_alloc_rx_buffers(ring_data, clean_count); @@ -983,8 +992,26 @@ static void hns_nic_adjust_link(struct net_device *ndev) { struct hns_nic_priv *priv = netdev_priv(ndev); struct hnae_handle *h = priv->ae_handle; + int state = 1; + + if (priv->phy) { + h->dev->ops->adjust_link(h, ndev->phydev->speed, + ndev->phydev->duplex); + state = priv->phy->link; + } + state = state && h->dev->ops->get_status(h); - h->dev->ops->adjust_link(h, ndev->phydev->speed, ndev->phydev->duplex); + if (state != priv->link) { + if (state) { + netif_carrier_on(ndev); + netif_tx_wake_all_queues(ndev); + netdev_info(ndev, "link up\n"); + } else { + netif_carrier_off(ndev); + netdev_info(ndev, "link down\n"); + } + priv->link = state; + } } /** @@ -996,19 +1023,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 +1097,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); @@ -1176,7 +1201,7 @@ static int hns_nic_net_up(struct net_device *ndev) { struct hns_nic_priv *priv = netdev_priv(ndev); struct hnae_handle *h = priv->ae_handle; - int i, j, k; + int i, j; int ret; ret = hns_nic_init_irq(priv); @@ -1191,9 +1216,6 @@ static int hns_nic_net_up(struct net_device *ndev) goto out_has_some_queues; } - for (k = 0; k < h->q_num; k++) - h->dev->ops->toggle_queue_status(h->qs[k], 1); - ret = h->dev->ops->set_mac_addr(h, ndev->dev_addr); if (ret) goto out_set_mac_addr_err; @@ -1213,8 +1235,6 @@ static int hns_nic_net_up(struct net_device *ndev) out_start_err: netif_stop_queue(ndev); out_set_mac_addr_err: - for (k = 0; k < h->q_num; k++) - h->dev->ops->toggle_queue_status(h->qs[k], 0); out_has_some_queues: for (j = i - 1; j >= 0; j--) hns_nic_ring_close(ndev, j); @@ -1421,7 +1441,6 @@ static int hns_nic_set_features(struct net_device *netdev, netdev_features_t features) { struct hns_nic_priv *priv = netdev_priv(netdev); - struct hnae_handle *h = priv->ae_handle; switch (priv->enet_ver) { case AE_VERSION_1: @@ -1434,11 +1453,9 @@ static int hns_nic_set_features(struct net_device *netdev, priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; /* The chip only support 7*4096 */ netif_set_gso_max_size(netdev, 7 * 4096); - h->dev->ops->set_tso_stats(h, 1); } else { priv->ops.fill_desc = fill_v2_desc; priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; - h->dev->ops->set_tso_stats(h, 0); } break; } @@ -1571,27 +1588,14 @@ static void hns_nic_update_link_status(struct net_device *netdev) struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_handle *h = priv->ae_handle; - int state = 1; - if (priv->phy) { - if (!genphy_update_link(priv->phy)) - state = priv->phy->link; - else - state = 0; - } - state = state && h->dev->ops->get_status(h); + if (h->phy_dev) { + if (h->phy_if != PHY_INTERFACE_MODE_XGMII) + return; - if (state != priv->link) { - if (state) { - netif_carrier_on(netdev); - netif_tx_wake_all_queues(netdev); - netdev_info(netdev, "link up\n"); - } else { - netif_carrier_off(netdev); - netdev_info(netdev, "link down\n"); - } - priv->link = state; + (void)genphy_read_status(h->phy_dev); } + hns_nic_adjust_link(netdev); } /* for dumping key regs*/ @@ -1627,7 +1631,7 @@ static void hns_nic_dump(struct hns_nic_priv *priv) } } -/* for resetting suntask*/ +/* for resetting subtask */ static void hns_nic_reset_subtask(struct hns_nic_priv *priv) { enum hnae_port_type type = priv->ae_handle->port_type; @@ -1797,11 +1801,14 @@ static void hns_nic_set_priv_ops(struct net_device *netdev) priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; /* This chip only support 7*4096 */ netif_set_gso_max_size(netdev, 7 * 4096); - h->dev->ops->set_tso_stats(h, 1); } else { priv->ops.fill_desc = fill_v2_desc; priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; } + /* enable tso when init + * control tso on/off through TSE bit in bd + */ + h->dev->ops->set_tso_stats(h, 1); } } @@ -1812,7 +1819,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 +1879,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 +1892,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 */ @@ -1940,7 +1973,7 @@ static int hns_nic_dev_probe(struct platform_device *pdev) if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) dev_dbg(dev, "set mask to 64bit\n"); else - dev_err(dev, "set mask to 32bit fail!\n"); + dev_err(dev, "set mask to 64bit fail!\n"); /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(ndev); @@ -2014,6 +2047,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, diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h index 337efa582..44bb3015e 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h @@ -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; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index 67a648c7d..ab33487a5 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -49,7 +49,7 @@ static u32 hns_nic_get_link(struct net_device *net_dev) h = priv->ae_handle; if (priv->phy) { - if (!genphy_update_link(priv->phy)) + if (!genphy_read_status(priv->phy)) link_stat = priv->phy->link; else link_stat = 0; @@ -165,13 +165,21 @@ static int hns_nic_get_settings(struct net_device *net_dev, cmd->advertising |= ADVERTISED_10000baseKR_Full; } - if (h->port_type == HNAE_PORT_SERVICE) { + switch (h->media_type) { + case HNAE_MEDIA_TYPE_FIBER: cmd->port = PORT_FIBRE; - cmd->supported |= SUPPORTED_Pause; - } else { + break; + case HNAE_MEDIA_TYPE_COPPER: cmd->port = PORT_TP; + break; + case HNAE_MEDIA_TYPE_UNKNOWN: + default: + break; } + if (!(AE_IS_VER1(priv->enet_ver) && h->port_type == HNAE_PORT_DEBUG)) + cmd->supported |= SUPPORTED_Pause; + cmd->transceiver = XCVR_EXTERNAL; cmd->mdio_support = (ETH_MDIO_SUPPORTS_C45 | ETH_MDIO_SUPPORTS_C22); hns_get_mdix_mode(net_dev, cmd); @@ -242,6 +250,7 @@ static const char hns_nic_test_strs[][ETH_GSTRING_LEN] = { static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en) { #define COPPER_CONTROL_REG 0 +#define PHY_POWER_DOWN BIT(11) #define PHY_LOOP_BACK BIT(14) u16 val = 0; @@ -252,33 +261,40 @@ static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en) /* speed : 1000M */ phy_write(phy_dev, HNS_PHY_PAGE_REG, 2); phy_write(phy_dev, 21, 0x1046); + + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); /* Force Master */ phy_write(phy_dev, 9, 0x1F00); + /* Soft-reset */ phy_write(phy_dev, 0, 0x9140); /* If autoneg disabled,two soft-reset operations */ phy_write(phy_dev, 0, 0x9140); - phy_write(phy_dev, 22, 0xFA); + + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA); /* Default is 0x0400 */ phy_write(phy_dev, 1, 0x418); /* Force 1000M Link, Default is 0x0200 */ phy_write(phy_dev, 7, 0x20C); - phy_write(phy_dev, 22, 0); + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); - /* Enable MAC loop-back */ + /* Enable PHY loop-back */ val = phy_read(phy_dev, COPPER_CONTROL_REG); val |= PHY_LOOP_BACK; + val &= ~PHY_POWER_DOWN; phy_write(phy_dev, COPPER_CONTROL_REG, val); } else { - phy_write(phy_dev, 22, 0xFA); + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA); phy_write(phy_dev, 1, 0x400); phy_write(phy_dev, 7, 0x200); - phy_write(phy_dev, 22, 0); + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); + phy_write(phy_dev, 9, 0xF00); val = phy_read(phy_dev, COPPER_CONTROL_REG); val &= ~PHY_LOOP_BACK; + val |= PHY_POWER_DOWN; phy_write(phy_dev, COPPER_CONTROL_REG, val); } return 0; @@ -339,28 +355,16 @@ static int __lb_up(struct net_device *ndev, hns_nic_net_reset(ndev); - if (priv->phy) { - phy_disconnect(priv->phy); - msleep(100); - - ret = hns_nic_init_phy(ndev, h); - if (ret) - return ret; - } - ret = __lb_setup(ndev, loop_mode); if (ret) return ret; - msleep(100); + msleep(200); ret = h->dev->ops->start ? h->dev->ops->start(h) : 0; if (ret) return ret; - if (priv->phy) - phy_start(priv->phy); - /* link adjust duplex*/ if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII) speed = 1000; @@ -561,9 +565,6 @@ static int __lb_down(struct net_device *ndev) __func__, ret); - if (priv->phy) - phy_stop(priv->phy); - if (h->dev->ops->stop) h->dev->ops->stop(h); @@ -596,7 +597,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) { @@ -758,6 +759,16 @@ static int hns_get_coalesce(struct net_device *net_dev, &ec->tx_max_coalesced_frames, &ec->rx_max_coalesced_frames); + ops->get_coalesce_range(priv->ae_handle, + &ec->tx_max_coalesced_frames_low, + &ec->rx_max_coalesced_frames_low, + &ec->tx_max_coalesced_frames_high, + &ec->rx_max_coalesced_frames_high, + &ec->tx_coalesce_usecs_low, + &ec->rx_coalesce_usecs_low, + &ec->tx_coalesce_usecs_high, + &ec->rx_coalesce_usecs_high); + return 0; } -- cgit v1.2.3-54-g00ecf