// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2014-2015 Hisilicon Limited.
*/
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include "hns_enet.h"
#define HNS_PHY_PAGE_MDIX 0
#define HNS_PHY_PAGE_LED 3
#define HNS_PHY_PAGE_COPPER 0
#define HNS_PHY_PAGE_REG 22 /* Page Selection Reg. */
#define HNS_PHY_CSC_REG 16 /* Copper Specific Control Register */
#define HNS_PHY_CSS_REG 17 /* Copper Specific Status Register */
#define HNS_LED_FC_REG 16 /* LED Function Control Reg. */
#define HNS_LED_PC_REG 17 /* LED Polarity Control Reg. */
#define HNS_LED_FORCE_ON 9
#define HNS_LED_FORCE_OFF 8
#define HNS_CHIP_VERSION 660
#define HNS_NET_STATS_CNT 26
#define PHY_MDIX_CTRL_S (5)
#define PHY_MDIX_CTRL_M (3 << PHY_MDIX_CTRL_S)
#define PHY_MDIX_STATUS_B (6)
#define PHY_SPEED_DUP_RESOLVE_B (11)
/**
*hns_nic_get_link - get current link status
*@net_dev: net_device
*retuen 0 - success , negative --fail
*/
static u32 hns_nic_get_link(struct net_device *net_dev)
{
struct hns_nic_priv *priv = netdev_priv(net_dev);
u32 link_stat = priv->link;
struct hnae_handle *h;
h = priv->ae_handle;
if (net_dev->phydev) {
if (!genphy_read_status(net_dev->phydev))
link_stat = net_dev->phydev->link;
else
link_stat = 0;
}
if (h->dev && h->dev->ops && h->dev->ops->get_status)
link_stat = link_stat && h->dev->ops->get_status(h);
else
link_stat = 0;
return link_stat;
}
static void hns_get_mdix_mode(struct net_device *net_dev,
struct ethtool_link_ksettings *cmd)
{
int mdix_ctrl, mdix, retval, is_resolved;
struct phy_device *phy_dev = net_dev->phydev;
if (!phy_dev || !phy_dev->mdio.bus) {
cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
cmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID;
return;
}
phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_MDIX);
retval = phy_read(phy_dev, HNS_PHY_CSC_REG);
mdix_ctrl = hnae_get_field(retval, PHY_MDIX_CTRL_M, PHY_MDIX_CTRL_S);
retval = phy_read(phy_dev, HNS_PHY_CSS_REG);
mdix = hnae_get_bit(retval, PHY_MDIX_STATUS_B);
is_resolved = hnae_get_bit(retval, PHY_SPEED_DUP_RESOLVE_B);
phy_write(phy_dev, HNS_PHY_PAGE_REG, HNS_PHY_PAGE_COPPER);
switch (mdix_ctr