summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
diff options
context:
space:
mode:
authorDaode Huang <huangdaode@hisilicon.com>2016-11-09 21:13:52 +0300
committerDavid S. Miller <davem@davemloft.net>2016-11-10 19:45:37 +0300
commit20b3385aaab5af5127fa957bcfcaf0bd92b61447 (patch)
tree779d8a29d6515ddf23ec5437f26b333fd1d4bbed /drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
parent28b3012400ad349ad633187c7e6e37352a22dd6e (diff)
downloadlinux-20b3385aaab5af5127fa957bcfcaf0bd92b61447.tar.xz
net: hns: fix to intimate the link-status change by adding LF/RF method
In current scenario, when the interface is disabled we reset the XGMAC RX/TX functionality. This operation does not affects the PHY layer/SFP and which appears UP to the remote end(this behaviour is unlike GMAC). The result is remote end keeps on sending the packets which gets partly processed by XMAC and dropped. Since these are partly processed these appears as errored packets in the packet counter statistics. This patch fixes this behaviour and adds local-fault and remote-fault functionality which can be used to intimate the remote peer whenever the state of the interface changes. This patch also removes the existing hns_dsaf_xge_core_srst_by_port function which was being used to reset the RX/TX functionality at XGE Core. Reported-by: Jun He <hjat2005@huawei.com> Signed-off-by: Daode Huang <huangdaode@hisilicon.com> Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c')
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
index 8f4f0e8da984..aae830a93050 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
@@ -108,6 +108,31 @@ static void hns_xgmac_rx_enable(struct mac_driver *drv, u32 value)
}
/**
+ * hns_xgmac_tx_lf_rf_insert - insert lf rf control about xgmac
+ * @mac_drv: mac driver
+ * @mode: inserf rf or lf
+ */
+static void hns_xgmac_lf_rf_insert(struct mac_driver *mac_drv, u32 mode)
+{
+ dsaf_set_dev_field(mac_drv, XGMAC_MAC_TX_LF_RF_CONTROL_REG,
+ XGMAC_LF_RF_INSERT_M, XGMAC_LF_RF_INSERT_S, mode);
+}
+
+/**
+ * hns_xgmac__lf_rf_control_init - initial the lf rf control register
+ * @mac_drv: mac driver
+ */
+static void hns_xgmac_lf_rf_control_init(struct mac_driver *mac_drv)
+{
+ u32 val = 0;
+
+ dsaf_set_bit(val, XGMAC_UNIDIR_EN_B, 0);
+ dsaf_set_bit(val, XGMAC_RF_TX_EN_B, 1);
+ dsaf_set_field(val, XGMAC_LF_RF_INSERT_M, XGMAC_LF_RF_INSERT_S, 0);
+ dsaf_write_reg(mac_drv, XGMAC_MAC_TX_LF_RF_CONTROL_REG, val);
+}
+
+/**
*hns_xgmac_enable - enable xgmac port
*@drv: mac driver
*@mode: mode of mac port
@@ -115,12 +140,8 @@ static void hns_xgmac_rx_enable(struct mac_driver *drv, u32 value)
static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode)
{
struct mac_driver *drv = (struct mac_driver *)mac_drv;
- struct dsaf_device *dsaf_dev
- = (struct dsaf_device *)dev_get_drvdata(drv->dev);
- u32 port = drv->mac_id;
- dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 1);
- mdelay(10);
+ hns_xgmac_lf_rf_insert(drv, HNS_XGMAC_NO_LF_RF_INSERT);
/*enable XGE rX/tX */
if (mode == MAC_COMM_MODE_TX) {
@@ -143,9 +164,6 @@ static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode)
static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode)
{
struct mac_driver *drv = (struct mac_driver *)mac_drv;
- struct dsaf_device *dsaf_dev
- = (struct dsaf_device *)dev_get_drvdata(drv->dev);
- u32 port = drv->mac_id;
if (mode == MAC_COMM_MODE_TX) {
hns_xgmac_tx_enable(drv, 0);
@@ -155,9 +173,7 @@ static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode)
hns_xgmac_tx_enable(drv, 0);
hns_xgmac_rx_enable(drv, 0);
}
-
- mdelay(10);
- dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 0);
+ hns_xgmac_lf_rf_insert(drv, HNS_XGMAC_LF_INSERT);
}
/**
@@ -203,6 +219,7 @@ static void hns_xgmac_init(void *mac_drv)
dsaf_dev->misc_op->xge_srst(dsaf_dev, port, 1);
mdelay(100);
+ hns_xgmac_lf_rf_control_init(drv);
hns_xgmac_exc_irq_en(drv, 0);
hns_xgmac_pma_fec_enable(drv, 0x0, 0x0);
@@ -788,7 +805,7 @@ static int hns_xgmac_get_sset_count(int stringset)
*/
static int hns_xgmac_get_regs_count(void)
{
- return ETH_XGMAC_DUMP_NUM;
+ return HNS_XGMAC_DUMP_NUM;
}
void *hns_xgmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param)