From 78054284302851f54b0604d43ce46a37ccba66d1 Mon Sep 17 00:00:00 2001 From: Feiyang Chen Date: Fri, 10 Nov 2023 12:24:52 +0000 Subject: [PATCH] stmmac: Expose module parameters for kernel-6.6 Expose module parameters so that we can use them in specific device configurations. Add the 'stmmac_' prefix for them to avoid conflicts. Meanwhile, there was a 'buf_sz' local variable in stmmac_rx() with the same name as the global variable, and now we can distinguish them. --- .../ethernet/stmicro/stmmac/dwmac-loongson.c | 173 +++++++++++++----- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 11 ++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 115 ++++++------ 3 files changed, 194 insertions(+), 105 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c index 9e40c28d453a..ee91ae18b505 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c @@ -9,14 +9,22 @@ #include #include "stmmac.h" -static int loongson_default_data(struct plat_stmmacenet_data *plat) +struct stmmac_pci_info { + int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat); +}; + +static void common_default_data(struct pci_dev *pdev, + struct plat_stmmacenet_data *plat) { + plat->bus_id = (pci_domain_nr(pdev->bus) << 16) | PCI_DEVID(pdev->bus->number, pdev->devfn); + plat->mac_interface = PHY_INTERFACE_MODE_GMII; + plat->clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ plat->has_gmac = 1; plat->force_sf_dma_mode = 1; /* Set default value for multicast hash bins */ - plat->multicast_filter_bins = HASH_TABLE_SIZE; + plat->multicast_filter_bins = 256; /* Set default value for unicast filter entries */ plat->unicast_filter_entries = 1; @@ -35,27 +43,81 @@ static int loongson_default_data(struct plat_stmmacenet_data *plat) /* Disable RX queues routing by default */ plat->rx_queues_cfg[0].pkt_route = 0x0; - /* Default to phy auto-detection */ - plat->phy_addr = -1; - plat->dma_cfg->pbl = 32; plat->dma_cfg->pblx8 = true; - plat->multicast_filter_bins = 256; + plat->clk_ref_rate = 125000000; + plat->clk_ptp_rate = 125000000; +} + +static int loongson_gmac_data(struct pci_dev *pdev, + struct plat_stmmacenet_data *plat) +{ + common_default_data(pdev, plat); + + plat->mdio_bus_data->phy_mask = 0; + + plat->phy_addr = -1; + plat->phy_interface = PHY_INTERFACE_MODE_RGMII_ID; + + stmmac_flow_ctrl = FLOW_OFF; + + return 0; +} + +static struct stmmac_pci_info loongson_gmac_pci_info = { + .setup = loongson_gmac_data, +}; + +static void loongson_gnet_fix_speed(void *priv, unsigned int speed, unsigned int mode) +{ + struct net_device *ndev = (struct net_device *)(*(unsigned long *)priv); + struct stmmac_priv *ptr = netdev_priv(ndev); + + if (speed == SPEED_1000) { + if (readl(ptr->ioaddr + MAC_CTRL_REG) & (1 << 15) /* PS */) { + /* reset phy */ + phy_set_bits(ndev->phydev, 0 /*MII_BMCR*/, + 0x200 /*BMCR_ANRESTART*/); + } + } +} + +static int loongson_gnet_data(struct pci_dev *pdev, + struct plat_stmmacenet_data *plat) +{ + common_default_data(pdev, plat); + + plat->mdio_bus_data->phy_mask = 0xfffffffb; + + plat->phy_addr = 2; + plat->phy_interface = PHY_INTERFACE_MODE_GMII; + + /* GNET 1000M speed need workaround */ + plat->fix_mac_speed = loongson_gnet_fix_speed; + + /* Get netdev pointer address */ + plat->bsp_priv = &(pdev->dev.driver_data); + return 0; } -static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id *id) +static struct stmmac_pci_info loongson_gnet_pci_info = { + .setup = loongson_gnet_data, +}; + +static int loongson_dwmac_probe(struct pci_dev *pdev, + const struct pci_device_id *id) { struct plat_stmmacenet_data *plat; + struct stmmac_pci_info *info; struct stmmac_resources res; struct device_node *np; - int ret, i, phy_mode; + int ret, i, bus_id, phy_mode; np = dev_of_node(&pdev->dev); - - if (!np) { - pr_info("dwmac_loongson_pci: No OF node\n"); + if (np && !of_device_is_compatible(np, "loongson, pci-gmac")) { + pr_info("dwmac_loongson_pci: Incompatible OF node\n"); return -ENODEV; } @@ -64,10 +126,11 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id return -ENOMEM; plat->mdio_bus_data = devm_kzalloc(&pdev->dev, - sizeof(*plat->mdio_bus_data), - GFP_KERNEL); - if (!plat->mdio_bus_data) - return -ENOMEM; + sizeof(*plat->mdio_bus_data), GFP_KERNEL); + if (!plat->mdio_bus_data) { + ret = -ENOMEM; + goto err_put_node; + } plat->mdio_node = of_get_child_by_name(np, "mdio"); if (plat->mdio_node) { @@ -98,45 +161,55 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id break; } - plat->bus_id = of_alias_get_id(np, "ethernet"); - if (plat->bus_id < 0) - plat->bus_id = pci_dev_id(pdev); + pci_set_master(pdev); - phy_mode = device_get_phy_mode(&pdev->dev); - if (phy_mode < 0) { - dev_err(&pdev->dev, "phy_mode not found\n"); - ret = phy_mode; - goto err_disable_device; - } + info = (struct stmmac_pci_info *)id->driver_data; + ret = info->setup(pdev, plat); + if (ret) + return ret; - plat->phy_interface = phy_mode; - plat->mac_interface = PHY_INTERFACE_MODE_GMII; + if (np) { + bus_id = of_alias_get_id(np, "ethernet"); + if (bus_id >= 0) + plat->bus_id = bus_id; - pci_set_master(pdev); + phy_mode = device_get_phy_mode(&pdev->dev); + if (phy_mode < 0) { + dev_err(&pdev->dev, "phy_mode not found\n"); + ret = phy_mode; + goto err_disable_device; + } + plat->phy_interface = phy_mode; + } - loongson_default_data(plat); pci_enable_msi(pdev); + memset(&res, 0, sizeof(res)); res.addr = pcim_iomap_table(pdev)[0]; - - res.irq = of_irq_get_byname(np, "macirq"); - if (res.irq < 0) { - dev_err(&pdev->dev, "IRQ macirq not found\n"); - ret = -ENODEV; - goto err_disable_msi; - } - - res.wol_irq = of_irq_get_byname(np, "eth_wake_irq"); - if (res.wol_irq < 0) { - dev_info(&pdev->dev, "IRQ eth_wake_irq not found, using macirq\n"); - res.wol_irq = res.irq; - } - - res.lpi_irq = of_irq_get_byname(np, "eth_lpi"); - if (res.lpi_irq < 0) { - dev_err(&pdev->dev, "IRQ eth_lpi not found\n"); - ret = -ENODEV; - goto err_disable_msi; + if (np) { + res.irq = of_irq_get_byname(np, "macirq"); + if (res.irq < 0) { + dev_err(&pdev->dev, "IRQ macirq not found\n"); + ret = -ENODEV; + goto err_disable_msi; + } + + res.wol_irq = of_irq_get_byname(np, "eth_wake_irq"); + if (res.wol_irq < 0) { + dev_info(&pdev->dev, + "IRQ eth_wake_irq not found, using macirq\n"); + res.wol_irq = res.irq; + } + + res.lpi_irq = of_irq_get_byname(np, "eth_lpi"); + if (res.lpi_irq < 0) { + dev_err(&pdev->dev, "IRQ eth_lpi not found\n"); + ret = -ENODEV; + goto err_disable_msi; + } + } else { + res.irq = pdev->irq; + res.wol_irq = pdev->irq; } ret = stmmac_dvr_probe(&pdev->dev, plat, &res); @@ -212,8 +285,12 @@ static int __maybe_unused loongson_dwmac_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(loongson_dwmac_pm_ops, loongson_dwmac_suspend, loongson_dwmac_resume); +#define PCI_DEVICE_ID_LOONGSON_GMAC 0x7a03 +#define PCI_DEVICE_ID_LOONGSON_GNET 0x7a13 + static const struct pci_device_id loongson_dwmac_id_table[] = { - { PCI_VDEVICE(LOONGSON, 0x7a03) }, + { PCI_DEVICE_DATA(LOONGSON, GMAC, &loongson_gmac_pci_info) }, + { PCI_DEVICE_DATA(LOONGSON, GNET, &loongson_gnet_pci_info) }, {} }; MODULE_DEVICE_TABLE(pci, loongson_dwmac_id_table); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index b8c93b881a65..df0922aaf71d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -341,6 +341,17 @@ enum stmmac_state { STMMAC_SERVICE_SCHED, }; +/* Module parameters */ +extern int stmmac_watchdog; +extern int stmmac_debug; +extern int stmmac_phyaddr; +extern int stmmac_flow_ctrl; +extern int stmmac_pause; +extern int stmmac_tc; +extern int stmmac_buf_sz; +extern int stmmac_eee_timer; +extern unsigned int stmmac_chain_mode; + int stmmac_mdio_unregister(struct net_device *ndev); int stmmac_mdio_register(struct net_device *ndev); int stmmac_mdio_reset(struct mii_bus *mii); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d1adb102a1d4..92a8ad011572 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -63,16 +63,16 @@ /* Module parameters */ #define TX_TIMEO 5000 -static int watchdog = TX_TIMEO; -module_param(watchdog, int, 0644); +int stmmac_watchdog = TX_TIMEO; +module_param_named(watchdog, stmmac_watchdog, int, 0644); MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds (default 5s)"); -static int debug = -1; -module_param(debug, int, 0644); +int stmmac_debug = -1; +module_param_named(debug, stmmac_debug, int, 0644); MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)"); -static int phyaddr = -1; -module_param(phyaddr, int, 0444); +int stmmac_phyaddr = -1; +module_param_named(phyaddr, stmmac_phyaddr, int, 0444); MODULE_PARM_DESC(phyaddr, "Physical device address"); #define STMMAC_TX_THRESH(x) ((x)->dma_conf.dma_tx_size / 4) @@ -88,22 +88,22 @@ MODULE_PARM_DESC(phyaddr, "Physical device address"); #define STMMAC_XDP_TX BIT(1) #define STMMAC_XDP_REDIRECT BIT(2) -static int flow_ctrl = FLOW_AUTO; -module_param(flow_ctrl, int, 0644); +int stmmac_flow_ctrl = FLOW_AUTO; +module_param_named(flow_ctrl, stmmac_flow_ctrl, int, 0644); MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]"); -static int pause = PAUSE_TIME; -module_param(pause, int, 0644); +int stmmac_pause = PAUSE_TIME; +module_param_named(pause, stmmac_pause, int, 0644); MODULE_PARM_DESC(pause, "Flow Control Pause Time"); #define TC_DEFAULT 64 -static int tc = TC_DEFAULT; -module_param(tc, int, 0644); +int stmmac_tc = TC_DEFAULT; +module_param_named(tc, stmmac_tc, int, 0644); MODULE_PARM_DESC(tc, "DMA threshold control value"); #define DEFAULT_BUFSIZE 1536 -static int buf_sz = DEFAULT_BUFSIZE; -module_param(buf_sz, int, 0644); +int stmmac_buf_sz = DEFAULT_BUFSIZE; +module_param_named(buf_sz, stmmac_buf_sz, int, 0644); MODULE_PARM_DESC(buf_sz, "DMA buffer size"); #define STMMAC_RX_COPYBREAK 256 @@ -113,16 +113,16 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); #define STMMAC_DEFAULT_LPI_TIMER 1000 -static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; -module_param(eee_timer, int, 0644); +int stmmac_eee_timer = STMMAC_DEFAULT_LPI_TIMER; +module_param_named(eee_timer, stmmac_eee_timer, int, 0644); MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); #define STMMAC_LPI_T(x) (jiffies + usecs_to_jiffies(x)) /* By default the driver will use the ring mode to manage tx and rx descriptors, * but allow user to force to use the chain instead of the ring */ -static unsigned int chain_mode; -module_param(chain_mode, int, 0444); +unsigned int stmmac_chain_mode; +module_param_named(chain_mode, stmmac_chain_mode, int, 0444); MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode"); static irqreturn_t stmmac_interrupt(int irq, void *dev_id); @@ -186,18 +186,19 @@ EXPORT_SYMBOL_GPL(stmmac_bus_clks_config); */ static void stmmac_verify_args(void) { - if (unlikely(watchdog < 0)) - watchdog = TX_TIMEO; - if (unlikely((buf_sz < DEFAULT_BUFSIZE) || (buf_sz > BUF_SIZE_16KiB))) - buf_sz = DEFAULT_BUFSIZE; - if (unlikely(flow_ctrl > 1)) - flow_ctrl = FLOW_AUTO; - else if (likely(flow_ctrl < 0)) - flow_ctrl = FLOW_OFF; - if (unlikely((pause < 0) || (pause > 0xffff))) - pause = PAUSE_TIME; - if (eee_timer < 0) - eee_timer = STMMAC_DEFAULT_LPI_TIMER; + if (unlikely(stmmac_watchdog < 0)) + stmmac_watchdog = TX_TIMEO; + if (unlikely((stmmac_buf_sz < DEFAULT_BUFSIZE) || + (stmmac_buf_sz > BUF_SIZE_16KiB))) + stmmac_buf_sz = DEFAULT_BUFSIZE; + if (unlikely(stmmac_flow_ctrl > 1)) + stmmac_flow_ctrl = FLOW_AUTO; + else if (likely(stmmac_flow_ctrl < 0)) + stmmac_flow_ctrl = FLOW_OFF; + if (unlikely((stmmac_pause < 0) || (stmmac_pause > 0xffff))) + stmmac_pause = PAUSE_TIME; + if (stmmac_eee_timer < 0) + stmmac_eee_timer = STMMAC_DEFAULT_LPI_TIMER; } static void __stmmac_disable_all_queues(struct stmmac_priv *priv) @@ -2383,8 +2384,8 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) txfifosz /= tx_channels_count; if (priv->plat->force_thresh_dma_mode) { - txmode = tc; - rxmode = tc; + txmode = stmmac_tc; + rxmode = stmmac_tc; } else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) { /* * In case of GMAC, SF mode can be enabled @@ -2397,7 +2398,7 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) rxmode = SF_DMA_MODE; priv->xstats.threshold = SF_DMA_MODE; } else { - txmode = tc; + txmode = stmmac_tc; rxmode = SF_DMA_MODE; } @@ -2533,16 +2534,16 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) static void stmmac_bump_dma_threshold(struct stmmac_priv *priv, u32 chan) { - if (unlikely(priv->xstats.threshold != SF_DMA_MODE) && tc <= 256) { - tc += 64; + if (unlikely(priv->xstats.threshold != SF_DMA_MODE) && stmmac_tc <= 256) { + stmmac_tc += 64; if (priv->plat->force_thresh_dma_mode) - stmmac_set_dma_operation_mode(priv, tc, tc, chan); + stmmac_set_dma_operation_mode(priv, stmmac_tc, stmmac_tc, chan); else - stmmac_set_dma_operation_mode(priv, tc, SF_DMA_MODE, + stmmac_set_dma_operation_mode(priv, stmmac_tc, SF_DMA_MODE, chan); - priv->xstats.threshold = tc; + priv->xstats.threshold = stmmac_tc; } } @@ -3394,7 +3395,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register) /* Convert the timer from msec to usec */ if (!priv->tx_lpi_timer) - priv->tx_lpi_timer = eee_timer * 1000; + priv->tx_lpi_timer = stmmac_eee_timer * 1000; if (priv->use_riwt) { u32 queue; @@ -7040,8 +7041,8 @@ static int stmmac_hw_init(struct stmmac_priv *priv) /* dwmac-sun8i only work in chain mode */ if (priv->plat->flags & STMMAC_FLAG_HAS_SUN8I) - chain_mode = 1; - priv->chain_mode = chain_mode; + stmmac_chain_mode = 1; + priv->chain_mode = stmmac_chain_mode; /* Initialize HW Interface */ ret = stmmac_hwif_init(priv); @@ -7362,7 +7363,7 @@ int stmmac_dvr_probe(struct device *device, return -ENOMEM; stmmac_set_ethtool_ops(ndev); - priv->pause = pause; + priv->pause = stmmac_pause; priv->plat = plat_dat; priv->ioaddr = res->addr; priv->dev->base_addr = (unsigned long)res->addr; @@ -7407,8 +7408,8 @@ int stmmac_dvr_probe(struct device *device, /* Override with kernel parameters if supplied XXX CRS XXX * this needs to have multiple instances */ - if ((phyaddr >= 0) && (phyaddr <= 31)) - priv->plat->phy_addr = phyaddr; + if ((stmmac_phyaddr >= 0) && (stmmac_phyaddr <= 31)) + priv->plat->phy_addr = stmmac_phyaddr; if (priv->plat->stmmac_rst) { ret = reset_control_assert(priv->plat->stmmac_rst); @@ -7505,7 +7506,7 @@ int stmmac_dvr_probe(struct device *device, } ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; - ndev->watchdog_timeo = msecs_to_jiffies(watchdog); + ndev->watchdog_timeo = msecs_to_jiffies(stmmac_watchdog); #ifdef STMMAC_VLAN_TAG_USED /* Both mac100 and gmac support receive VLAN tag detection */ ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX; @@ -7519,9 +7520,9 @@ int stmmac_dvr_probe(struct device *device, ndev->features |= NETIF_F_HW_VLAN_STAG_TX; } #endif - priv->msg_enable = netif_msg_init(debug, default_msg_level); + priv->msg_enable = netif_msg_init(stmmac_debug, default_msg_level); - priv->xstats.threshold = tc; + priv->xstats.threshold = stmmac_tc; /* Initialize RSS */ rxq = priv->plat->rx_queues_to_use; @@ -7555,7 +7556,7 @@ int stmmac_dvr_probe(struct device *device, "%s: warning: maxmtu having invalid value (%d)\n", __func__, priv->plat->maxmtu); - if (flow_ctrl) + if (stmmac_flow_ctrl) priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; @@ -7884,31 +7885,31 @@ static int __init stmmac_cmdline_opt(char *str) return 1; while ((opt = strsep(&str, ",")) != NULL) { if (!strncmp(opt, "debug:", 6)) { - if (kstrtoint(opt + 6, 0, &debug)) + if (kstrtoint(opt + 6, 0, &stmmac_debug)) goto err; } else if (!strncmp(opt, "phyaddr:", 8)) { - if (kstrtoint(opt + 8, 0, &phyaddr)) + if (kstrtoint(opt + 8, 0, &stmmac_phyaddr)) goto err; } else if (!strncmp(opt, "buf_sz:", 7)) { - if (kstrtoint(opt + 7, 0, &buf_sz)) + if (kstrtoint(opt + 7, 0, &stmmac_buf_sz)) goto err; } else if (!strncmp(opt, "tc:", 3)) { - if (kstrtoint(opt + 3, 0, &tc)) + if (kstrtoint(opt + 3, 0, &stmmac_tc)) goto err; } else if (!strncmp(opt, "watchdog:", 9)) { - if (kstrtoint(opt + 9, 0, &watchdog)) + if (kstrtoint(opt + 9, 0, &stmmac_watchdog)) goto err; } else if (!strncmp(opt, "flow_ctrl:", 10)) { - if (kstrtoint(opt + 10, 0, &flow_ctrl)) + if (kstrtoint(opt + 10, 0, &stmmac_flow_ctrl)) goto err; } else if (!strncmp(opt, "pause:", 6)) { - if (kstrtoint(opt + 6, 0, &pause)) + if (kstrtoint(opt + 6, 0, &stmmac_pause)) goto err; } else if (!strncmp(opt, "eee_timer:", 10)) { - if (kstrtoint(opt + 10, 0, &eee_timer)) + if (kstrtoint(opt + 10, 0, &stmmac_eee_timer)) goto err; } else if (!strncmp(opt, "chain_mode:", 11)) { - if (kstrtoint(opt + 11, 0, &chain_mode)) + if (kstrtoint(opt + 11, 0, &stmmac_chain_mode)) goto err; } } -- 2.43.0