diff options
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c')
| -rw-r--r-- | drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 96 |
1 files changed, 60 insertions, 36 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c index a97228c93831..bc6b269be299 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c @@ -1,10 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) 2014-2015 Hisilicon Limited. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include <linux/acpi.h> @@ -70,6 +66,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb) } } +static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv) +{ +#define HNS_MAC_LINK_WAIT_TIME 5 +#define HNS_MAC_LINK_WAIT_CNT 40 + + u32 link_status = 0; + int i; + + if (!mac_ctrl_drv->get_link_status) + return link_status; + + for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) { + msleep(HNS_MAC_LINK_WAIT_TIME); + mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status); + if (!link_status) + break; + } + + return link_status; +} + void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) { struct mac_driver *mac_ctrl_drv; @@ -87,6 +104,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) &sfp_prsnt); if (!ret) *link_status = *link_status && sfp_prsnt; + + /* for FIBER port, it may have a fake link up. + * when the link status changes from down to up, we need to do + * anti-shake. the anti-shake time is base on tests. + * only FIBER port need to do this. + */ + if (*link_status && !mac_cb->link) + *link_status = hns_mac_link_anti_shake(mac_ctrl_drv); } mac_cb->link = *link_status; @@ -115,7 +140,7 @@ int hns_mac_get_port_info(struct hns_mac_cb *mac_cb, } /** - *hns_mac_is_adjust_link - check is need change mac speed and duplex register + *hns_mac_need_adjust_link - check is need change mac speed and duplex register *@mac_cb: mac device *@speed: phy device speed *@duplex:phy device duplex @@ -244,7 +269,7 @@ int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb, u8 vmid, u8 *port_num) *@addr:mac address */ int hns_mac_change_vf_addr(struct hns_mac_cb *mac_cb, - u32 vmid, char *addr) + u32 vmid, const char *addr) { int ret; struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb); @@ -370,7 +395,7 @@ int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn) static void hns_mac_param_get(struct mac_params *param, struct hns_mac_cb *mac_cb) { - param->vaddr = (void *)mac_cb->vaddr; + param->vaddr = mac_cb->vaddr; param->mac_mode = hns_get_enet_interface(mac_cb); ether_addr_copy(param->addr, mac_cb->addr_entry_idx[0].addr); param->mac_id = mac_cb->mac_id; @@ -378,11 +403,12 @@ static void hns_mac_param_get(struct mac_params *param, } /** - *hns_mac_queue_config_bc_en - set broadcast rx&tx enable - *@mac_cb: mac device - *@queue: queue number - *@en:enable - *retuen 0 - success , negative --fail + * hns_mac_port_config_bc_en - set broadcast rx&tx enable + * @mac_cb: mac device + * @port_num: queue number + * @vlan_id: vlan id` + * @enable: enable + * return 0 - success , negative --fail */ static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb, u32 port_num, u16 vlan_id, bool enable) @@ -412,11 +438,11 @@ static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb, } /** - *hns_mac_vm_config_bc_en - set broadcast rx&tx enable - *@mac_cb: mac device - *@vmid: vm id - *@en:enable - *retuen 0 - success , negative --fail + * hns_mac_vm_config_bc_en - set broadcast rx&tx enable + * @mac_cb: mac device + * @vmid: vm id + * @enable: enable + * return 0 - success , negative --fail */ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable) { @@ -546,8 +572,8 @@ void hns_mac_stop(struct hns_mac_cb *mac_cb) /** * hns_mac_get_autoneg - get auto autonegotiation * @mac_cb: mac control block - * @enable: enable or not - * retuen 0 - success , negative --fail + * @auto_neg: output pointer to autoneg result + * return 0 - success , negative --fail */ void hns_mac_get_autoneg(struct hns_mac_cb *mac_cb, u32 *auto_neg) { @@ -564,7 +590,7 @@ void hns_mac_get_autoneg(struct hns_mac_cb *mac_cb, u32 *auto_neg) * @mac_cb: mac control block * @rx_en: rx enable status * @tx_en: tx enable status - * retuen 0 - success , negative --fail + * return 0 - success , negative --fail */ void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en) { @@ -582,7 +608,7 @@ void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en) * hns_mac_set_autoneg - set auto autonegotiation * @mac_cb: mac control block * @enable: enable or not - * retuen 0 - success , negative --fail + * return 0 - success , negative --fail */ int hns_mac_set_autoneg(struct hns_mac_cb *mac_cb, u8 enable) { @@ -600,7 +626,7 @@ int hns_mac_set_autoneg(struct hns_mac_cb *mac_cb, u8 enable) } /** - * hns_mac_set_autoneg - set rx & tx pause parameter + * hns_mac_set_pauseparam - set rx & tx pause parameter * @mac_cb: mac control block * @rx_en: rx enable or not * @tx_en: tx enable or not @@ -627,7 +653,7 @@ int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en) /** * hns_mac_init_ex - mac init * @mac_cb: mac control block - * retuen 0 - success , negative --fail + * return 0 - success , negative --fail */ static int hns_mac_init_ex(struct hns_mac_cb *mac_cb) { @@ -701,14 +727,14 @@ hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb, return rc; if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_XGMII))) - is_c45 = 1; + is_c45 = true; else if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_SGMII))) - is_c45 = 0; + is_c45 = false; else return -ENODATA; phy = get_phy_device(mdio, addr, is_c45); - if (!phy || IS_ERR(phy)) + if (IS_ERR_OR_NULL(phy)) return -EIO; phy->irq = mdio->irq[addr]; @@ -804,7 +830,6 @@ static const struct { /** *hns_mac_get_info - get mac information from device node *@mac_cb: mac device - *@np:device node * return: 0 --success, negative --fail */ static int hns_mac_get_info(struct hns_mac_cb *mac_cb) @@ -908,6 +933,7 @@ static int hns_mac_get_info(struct hns_mac_cb *mac_cb) mac_cb->cpld_ctrl = NULL; } else { syscon = syscon_node_to_regmap(cpld_args.np); + of_node_put(cpld_args.np); if (IS_ERR_OR_NULL(syscon)) { dev_dbg(mac_cb->dev, "no cpld-syscon found!\n"); mac_cb->cpld_ctrl = NULL; @@ -918,8 +944,7 @@ static int hns_mac_get_info(struct hns_mac_cb *mac_cb) } } else if (is_acpi_node(mac_cb->fw_port)) { ret = hns_mac_register_phy(mac_cb); - /* - * Mac can work well if there is phy or not.If the port don't + /* Mac can work well if there is phy or not.If the port don't * connect with phy, the return value will be ignored. Only * when there is phy but can't find mdio bus, the return value * will be handled. @@ -955,7 +980,7 @@ static int hns_mac_get_info(struct hns_mac_cb *mac_cb) /** * hns_mac_get_mode - get mac mode * @phy_if: phy interface - * retuen 0 - gmac, 1 - xgmac , negative --fail + * return 0 - gmac, 1 - xgmac , negative --fail */ static int hns_mac_get_mode(phy_interface_t phy_if) { @@ -1065,9 +1090,8 @@ int hns_mac_init(struct dsaf_device *dsaf_dev) u32 port_id; int max_port_num = hns_mac_get_max_port_num(dsaf_dev); struct hns_mac_cb *mac_cb; - struct fwnode_handle *child; - device_for_each_child_node(dsaf_dev->dev, child) { + device_for_each_child_node_scoped(dsaf_dev->dev, child) { ret = fwnode_property_read_u32(child, "reg", &port_id); if (ret) { dev_err(dsaf_dev->dev, @@ -1083,6 +1107,7 @@ int hns_mac_init(struct dsaf_device *dsaf_dev) GFP_KERNEL); if (!mac_cb) return -ENOMEM; + mac_cb->fw_port = child; mac_cb->mac_id = (u8)port_id; dsaf_dev->mac_cb[port_id] = mac_cb; @@ -1165,8 +1190,7 @@ void hns_mac_get_stats(struct hns_mac_cb *mac_cb, u64 *data) mac_ctrl_drv->get_ethtool_stats(mac_ctrl_drv, data); } -void hns_mac_get_strings(struct hns_mac_cb *mac_cb, - int stringset, u8 *data) +void hns_mac_get_strings(struct hns_mac_cb *mac_cb, int stringset, u8 **data) { struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb); @@ -1206,7 +1230,7 @@ void hns_mac_get_regs(struct hns_mac_cb *mac_cb, void *data) void hns_set_led_opt(struct hns_mac_cb *mac_cb) { - int nic_data = 0; + int nic_data; int txpkts, rxpkts; txpkts = mac_cb->txpkt_for_led - mac_cb->hw_stats.tx_good_pkts; |
