From a6c3cc22e040dbe947ac27e3b7685744f73c4f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Fri, 17 Jun 2022 22:20:21 +0200 Subject: [PATCH] [WIP] NC/SI debugging Sometimes ncsi_free_request schedules ndp->work when the NCSI device state is ncsi_dev_state_functional. Change ncsi_dev_work to expect being called in this state. --- drivers/net/ethernet/nuvoton/nuvoton-emc.c | 27 ++++++++++++++++------ net/ncsi/ncsi-manage.c | 18 +++++++++++++-- net/ncsi/ncsi-rsp.c | 1 + 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/nuvoton/nuvoton-emc.c b/drivers/net/ethernet/nuvoton/nuvoton-emc.c index 6e32f2f1822ef0..f1b4dd8c0fded9 100644 --- a/drivers/net/ethernet/nuvoton/nuvoton-emc.c +++ b/drivers/net/ethernet/nuvoton/nuvoton-emc.c @@ -222,6 +222,20 @@ static void emc_link_change(struct net_device *netdev) __raw_writel(val, priv->reg + REG_MCMDR); } +static void emc_set_link_mode_for_ncsi(struct net_device *netdev) +{ + struct emc_priv *priv = netdev_priv(netdev); + unsigned int val; + + val = __raw_readl(priv->reg + REG_MCMDR); + + /* Force 100 Mbit/s and full duplex */ + val |= MCMDR_OPMOD | MCMDR_FDUP; + + __raw_writel(val, priv->reg + REG_MCMDR); +} + + static void emc_write_cam(struct net_device *netdev, unsigned int x, const unsigned char *pval) { @@ -342,13 +356,11 @@ static void emc_enable_mac_interrupt(struct net_device *netdev) } static void emc_get_and_clear_int(struct net_device *netdev, - unsigned int *val) + unsigned int mask, unsigned int *val) { struct emc_priv *priv = netdev_priv(netdev); - // TODO: clear interrupts selectively, so we don't clear TX interrupts in the RX ISR - // (add mask param) - *val = __raw_readl(priv->reg + REG_MISTA); + *val = __raw_readl(priv->reg + REG_MISTA) & mask; __raw_writel(*val, priv->reg + REG_MISTA); } @@ -569,7 +581,7 @@ static irqreturn_t emc_tx_interrupt(int irq, void *dev_id) priv = netdev_priv(netdev); pdev = priv->pdev; - emc_get_and_clear_int(netdev, &status); + emc_get_and_clear_int(netdev, MISTA_TXBERR | MISTA_TDU | MISTA_TXCP, &status); cur_entry = __raw_readl(priv->reg + REG_CTXDSA); @@ -693,7 +705,7 @@ static irqreturn_t emc_rx_interrupt(int irq, void *dev_id) priv = netdev_priv(netdev); pdev = priv->pdev; - emc_get_and_clear_int(netdev, &status); + emc_get_and_clear_int(netdev, MISTA_RXGD, &status); if (status & MISTA_RDU) { emc_netdev_rx(netdev); @@ -746,6 +758,7 @@ static int emc_open(struct net_device *netdev) if (priv->phy) phy_start(priv->phy); else if (priv->ncsi) { + emc_set_link_mode_for_ncsi(netdev); netif_carrier_on(netdev); int err = ncsi_start_dev(priv->ncsi); @@ -915,7 +928,7 @@ static int emc_init_mdio(struct emc_priv *priv, struct device_node *np) val |= MCMDR_ENMDC; __raw_writel(val, priv->reg + REG_MCMDR); - res = of_mdiobus_register(mdio, np); + res = devm_of_mdiobus_register(&pdev->dev, mdio, np); if (res) { dev_info(&pdev->dev, "failed to register MDIO bus: %d\n", res); return res; diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c index 3e0ea3b7fc5add..6754b63ce9011d 100644 --- a/net/ncsi/ncsi-manage.c +++ b/net/ncsi/ncsi-manage.c @@ -390,6 +390,7 @@ struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp, void ncsi_free_request(struct ncsi_request *nr) { struct ncsi_dev_priv *ndp = nr->ndp; + struct ncsi_dev *nd = &ndp->ndev; struct sk_buff *cmd, *rsp; unsigned long flags; bool driven; @@ -408,8 +409,10 @@ void ncsi_free_request(struct ncsi_request *nr) driven = !!(nr->flags & NCSI_REQ_FLAG_EVENT_DRIVEN); spin_unlock_irqrestore(&ndp->lock, flags); - if (driven && cmd && --ndp->pending_req_num == 0) + if (driven && cmd && --ndp->pending_req_num == 0) { + pr_info("%s: schedule_work, state=%#x, cmd=%p, pending_req_num=%d\n", __func__, nd->state, cmd, ndp->pending_req_num); schedule_work(&ndp->work); + } /* Release command and response */ consume_skb(cmd); @@ -1050,8 +1053,10 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) nca.type = NCSI_PKT_CMD_OEM; ret = ncsi_gma_handler(&nca, nc->version.mf_id); } - if (ret < 0) + if (ret < 0) { + pr_info("%s: schedule_work, state=%#x\n", __func__, nd->state); schedule_work(&ndp->work); + } break; case ncsi_dev_state_config_clear_vids: @@ -1074,6 +1079,7 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) ret = clear_one_vid(ndp, nc, &nca); if (ret) { nd->state = ncsi_dev_state_config_svf; + pr_info("%s: schedule_work, state=%#x\n", __func__, nd->state); schedule_work(&ndp->work); break; } @@ -1084,6 +1090,7 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp) ret = set_one_vid(ndp, nc, &nca); if (ret) { nd->state = ncsi_dev_state_config_ev; + pr_info("%s: schedule_work, state=%#x\n", __func__, nd->state); schedule_work(&ndp->work); break; } @@ -1391,6 +1398,7 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) if (!ndp->active_package) { /* No response */ nd->state = ncsi_dev_state_probe_dp; + pr_info("%s: schedule_work, state=%#x\n", __func__, nd->state); schedule_work(&ndp->work); break; } @@ -1399,6 +1407,7 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp) ndp->mlx_multi_host) nd->state = ncsi_dev_state_probe_mlx_gma; + pr_info("%s: schedule_work, state=%#x\n", __func__, nd->state); schedule_work(&ndp->work); break; case ncsi_dev_state_probe_mlx_gma: @@ -1530,6 +1539,9 @@ static void ncsi_dev_work(struct work_struct *work) struct ncsi_dev *nd = &ndp->ndev; switch (nd->state & ncsi_dev_state_major) { + case ncsi_dev_state_functional: + /* nothing to do. */ + break; case ncsi_dev_state_probe: ncsi_probe_channel(ndp); break; @@ -1817,6 +1829,7 @@ int ncsi_start_dev(struct ncsi_dev *nd) ndp->package_probe_id = 0; nd->state = ncsi_dev_state_probe; schedule_work(&ndp->work); + pr_info("%s: schedule_work, state=%#x\n", __func__, nd->state); return 0; } @@ -1938,6 +1951,7 @@ int ncsi_reset_dev(struct ncsi_dev *nd) spin_unlock_irqrestore(&ndp->lock, flags); nd->state = ncsi_dev_state_suspend; + pr_info("%s: schedule_work, state=%#x\n", __func__, nd->state); schedule_work(&ndp->work); return 0; } diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c index bee290d0f48b6f..9424324cfee7be 100644 --- a/net/ncsi/ncsi-rsp.c +++ b/net/ncsi/ncsi-rsp.c @@ -786,6 +786,7 @@ static int ncsi_rsp_handler_gvi(struct ncsi_request *nr) for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++) ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]); ncv->mf_id = ntohl(rsp->mf_id); + pr_info("%s: got mfid=%#x\n", __func__, ncv->mf_id); return 0; }