1From 23f2752638f0ec22fb848b46b2d16d65bd98b49d Mon Sep 17 00:00:00 2001 2From: David Wu <david.wu@rock-chips.com> 3Date: Thu, 03 Nov 2022 10:47:48 +0800 4Subject: [PATCH] net: ethernet: stmmac: Add uio support for stmmac 5 6Currently only supports single channel, and the network card 7name needs to be eth0 and eth1. 8 9Signed-off-by: David Wu <david.wu@rock-chips.com> 10Change-Id: I19975b10e2ed12931edc2e8bd50c003416a1109c 11--- 12 13diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig 14index 38039c9..c19cdd6 100644 15--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig 16+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig 17@@ -52,6 +52,13 @@ 18 19 If unsure, say N. 20 21+config STMMAC_UIO 22+ tristate "STMMAC_UIO ethernet controller" 23+ default n 24+ select UIO 25+ help 26+ Say M here if you want to use the stmmac_uio.ko for DPDK. 27+ 28 if STMMAC_PLATFORM 29 30 config DWMAC_DWC_QOS_ETH 31diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile 32index 05c792e..d017cbc 100644 33--- a/drivers/net/ethernet/stmicro/stmmac/Makefile 34+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile 35@@ -27,6 +27,7 @@ 36 obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rockchip.o 37 dwmac-rockchip-objs := dwmac-rk.o 38 dwmac-rockchip-$(CONFIG_DWMAC_ROCKCHIP_TOOL) += dwmac-rk-tool.o 39+obj-$(CONFIG_STMMAC_UIO) += stmmac_uio.o 40 obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o 41 obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o 42 obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o 43diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h 44index df7de50..37658d7 100644 45--- a/drivers/net/ethernet/stmicro/stmmac/common.h 46+++ b/drivers/net/ethernet/stmicro/stmmac/common.h 47@@ -48,10 +48,18 @@ 48 */ 49 #define DMA_MIN_TX_SIZE 64 50 #define DMA_MAX_TX_SIZE 1024 51+#if IS_ENABLED(CONFIG_STMMAC_UIO) 52+#define DMA_DEFAULT_TX_SIZE 1024 53+#else 54 #define DMA_DEFAULT_TX_SIZE 512 55+#endif 56 #define DMA_MIN_RX_SIZE 64 57 #define DMA_MAX_RX_SIZE 1024 58+#if IS_ENABLED(CONFIG_STMMAC_UIO) 59+#define DMA_DEFAULT_RX_SIZE 1024 60+#else 61 #define DMA_DEFAULT_RX_SIZE 512 62+#endif 63 #define STMMAC_GET_ENTRY(x, size) ((x + 1) & (size - 1)) 64 65 #undef FRAME_FILTER_DEBUG 66diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 67index 7c1a14b..8a29921 100644 68--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 69+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 70@@ -396,6 +396,7 @@ 71 #endif 72 return 0; 73 } 74+EXPORT_SYMBOL(stmmac_mdio_reset); 75 76 /** 77 * stmmac_mdio_register 78diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_uio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_uio.c 79new file mode 100644 80index 0000000..11ec4b7 81--- /dev/null 82+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_uio.c 83@@ -0,0 +1,1050 @@ 84+// SPDX-License-Identifier: GPL-2.0 85+/** 86+ * Copyright 2023 ROCKCHIP 87+ */ 88+ 89+#include <linux/module.h> 90+#include <linux/kernel.h> 91+#include <linux/of_address.h> 92+#include <linux/of_platform.h> 93+#include <linux/of_net.h> 94+#include <linux/uio_driver.h> 95+#include <linux/list.h> 96+ 97+#include <linux/clk.h> 98+#include <linux/kernel.h> 99+#include <linux/interrupt.h> 100+#include <linux/ip.h> 101+#include <linux/tcp.h> 102+#include <linux/ethtool.h> 103+#include <linux/if_ether.h> 104+#include <linux/crc32.h> 105+#include <linux/mii.h> 106+#include <linux/if.h> 107+#include <linux/if_vlan.h> 108+#include <linux/dma-mapping.h> 109+#include <linux/slab.h> 110+#include <linux/prefetch.h> 111+#include <linux/pinctrl/consumer.h> 112+#ifdef CONFIG_DEBUG_FS 113+#include <linux/debugfs.h> 114+#include <linux/seq_file.h> 115+#endif /* CONFIG_DEBUG_FS */ 116+#include <linux/net_tstamp.h> 117+#include <linux/udp.h> 118+#include <net/pkt_cls.h> 119+#include "stmmac_ptp.h" 120+#include "stmmac.h" 121+#include <linux/reset.h> 122+#include <linux/of_mdio.h> 123+#include "dwmac1000.h" 124+#include "dwxgmac2.h" 125+#include "hwif.h" 126+#include "mmc.h" 127+ 128+#define DRIVER_NAME "rockchip_gmac_uio_drv" 129+#define DRIVER_VERSION "0.1" 130+ 131+#define TC_DEFAULT 64 132+static int tc = TC_DEFAULT; 133+ 134+#define DEFAULT_BUFSIZE 1536 135+static int buf_sz = DEFAULT_BUFSIZE; 136+ 137+#define STMMAC_RX_COPYBREAK 256 138+ 139+/** 140+ * rockchip_gmac_uio_pdev_info 141+ * local information for uio module driver 142+ * 143+ * @dev: device pointer 144+ * @ndev: network device pointer 145+ * @name: uio name 146+ * @uio: uio information 147+ * @map_num: number of uio memory regions 148+ */ 149+struct rockchip_gmac_uio_pdev_info { 150+ struct device *dev; 151+ struct net_device *ndev; 152+ char name[16]; 153+ struct uio_info uio; 154+ int map_num; 155+}; 156+ 157+static int rockchip_gmac_uio_open(struct uio_info *info, struct inode *inode) 158+{ 159+ return 0; 160+} 161+ 162+static int rockchip_gmac_uio_release(struct uio_info *info, 163+ struct inode *inode) 164+{ 165+ return 0; 166+} 167+ 168+static int rockchip_gmac_uio_mmap(struct uio_info *info, 169+ struct vm_area_struct *vma) 170+{ 171+ u32 ret; 172+ u32 pfn; 173+ 174+ pfn = (info->mem[vma->vm_pgoff].addr) >> PAGE_SHIFT; 175+ 176+ if (vma->vm_pgoff) 177+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 178+ else 179+ vma->vm_page_prot = pgprot_device(vma->vm_page_prot); 180+ 181+ ret = remap_pfn_range(vma, vma->vm_start, pfn, 182+ vma->vm_end - vma->vm_start, vma->vm_page_prot); 183+ if (ret) { 184+ /* Error Handle */ 185+ pr_err("remap_pfn_range failed"); 186+ } 187+ return ret; 188+} 189+ 190+/** 191+ * uio_free_dma_rx_desc_resources - free RX dma desc resources 192+ * @priv: private structure 193+ */ 194+static void uio_free_dma_rx_desc_resources(struct stmmac_priv *priv) 195+{ 196+ u32 rx_count = priv->plat->rx_queues_to_use; 197+ u32 queue; 198+ 199+ /* Free RX queue resources */ 200+ for (queue = 0; queue < rx_count; queue++) { 201+ struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; 202+ 203+ /* Free DMA regions of consistent memory previously allocated */ 204+ if (!priv->extend_desc) 205+ dma_free_coherent(priv->device, priv->dma_rx_size * 206+ sizeof(struct dma_desc), 207+ rx_q->dma_rx, rx_q->dma_rx_phy); 208+ else 209+ dma_free_coherent(priv->device, priv->dma_rx_size * 210+ sizeof(struct dma_extended_desc), 211+ rx_q->dma_erx, rx_q->dma_rx_phy); 212+ } 213+} 214+ 215+/** 216+ * uio_free_dma_tx_desc_resources - free TX dma desc resources 217+ * @priv: private structure 218+ */ 219+static void uio_free_dma_tx_desc_resources(struct stmmac_priv *priv) 220+{ 221+ u32 tx_count = priv->plat->tx_queues_to_use; 222+ u32 queue; 223+ 224+ /* Free TX queue resources */ 225+ for (queue = 0; queue < tx_count; queue++) { 226+ struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; 227+ size_t size; 228+ void *addr; 229+ 230+ if (priv->extend_desc) { 231+ size = sizeof(struct dma_extended_desc); 232+ addr = tx_q->dma_etx; 233+ } else if (tx_q->tbs & STMMAC_TBS_AVAIL) { 234+ size = sizeof(struct dma_edesc); 235+ addr = tx_q->dma_entx; 236+ } else { 237+ size = sizeof(struct dma_desc); 238+ addr = tx_q->dma_tx; 239+ } 240+ 241+ size *= priv->dma_tx_size; 242+ 243+ dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy); 244+ } 245+} 246+ 247+/** 248+ * uio_alloc_dma_rx_desc_resources - alloc RX resources. 249+ * @priv: private structure 250+ * Description: according to which descriptor can be used (extend or basic) 251+ * this function allocates the resources for TX and RX paths. In case of 252+ * reception, for example, it pre-allocated the RX socket buffer in order to 253+ * allow zero-copy mechanism. 254+ */ 255+static int uio_alloc_dma_rx_desc_resources(struct stmmac_priv *priv) 256+{ 257+ u32 rx_count = priv->plat->rx_queues_to_use; 258+ int ret = -ENOMEM; 259+ u32 queue; 260+ 261+ /* RX queues buffers and DMA */ 262+ for (queue = 0; queue < rx_count; queue++) { 263+ struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; 264+ 265+ if (priv->extend_desc) { 266+ rx_q->dma_erx = dma_alloc_coherent(priv->device, 267+ priv->dma_rx_size * 268+ sizeof(struct dma_extended_desc), 269+ &rx_q->dma_rx_phy, 270+ GFP_KERNEL); 271+ if (!rx_q->dma_erx) 272+ goto err_dma; 273+ } else { 274+ rx_q->dma_rx = dma_alloc_coherent(priv->device, 275+ priv->dma_rx_size * 276+ sizeof(struct dma_desc), 277+ &rx_q->dma_rx_phy, 278+ GFP_KERNEL); 279+ if (!rx_q->dma_rx) 280+ goto err_dma; 281+ } 282+ } 283+ 284+ return 0; 285+ 286+err_dma: 287+ uio_free_dma_rx_desc_resources(priv); 288+ 289+ return ret; 290+} 291+ 292+/** 293+ * uio_alloc_dma_tx_desc_resources - alloc TX resources. 294+ * @priv: private structure 295+ * Description: according to which descriptor can be used (extend or basic) 296+ * this function allocates the resources for TX and RX paths. In case of 297+ * reception, for example, it pre-allocated the RX socket buffer in order to 298+ * allow zero-copy mechanism. 299+ */ 300+static int uio_alloc_dma_tx_desc_resources(struct stmmac_priv *priv) 301+{ 302+ u32 tx_count = priv->plat->tx_queues_to_use; 303+ int ret = -ENOMEM; 304+ u32 queue; 305+ 306+ /* TX queues buffers and DMA */ 307+ for (queue = 0; queue < tx_count; queue++) { 308+ struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; 309+ size_t size; 310+ void *addr; 311+ 312+ tx_q->queue_index = queue; 313+ tx_q->priv_data = priv; 314+ 315+ if (priv->extend_desc) 316+ size = sizeof(struct dma_extended_desc); 317+ else if (tx_q->tbs & STMMAC_TBS_AVAIL) 318+ size = sizeof(struct dma_edesc); 319+ else 320+ size = sizeof(struct dma_desc); 321+ 322+ size *= priv->dma_tx_size; 323+ 324+ addr = dma_alloc_coherent(priv->device, size, 325+ &tx_q->dma_tx_phy, GFP_KERNEL); 326+ if (!addr) 327+ goto err_dma; 328+ 329+ if (priv->extend_desc) 330+ tx_q->dma_etx = addr; 331+ else if (tx_q->tbs & STMMAC_TBS_AVAIL) 332+ tx_q->dma_entx = addr; 333+ else 334+ tx_q->dma_tx = addr; 335+ } 336+ 337+ return 0; 338+ 339+err_dma: 340+ uio_free_dma_tx_desc_resources(priv); 341+ return ret; 342+} 343+ 344+/** 345+ * uio_alloc_dma_desc_resources - alloc TX/RX resources. 346+ * @priv: private structure 347+ * Description: according to which descriptor can be used (extend or basic) 348+ * this function allocates the resources for TX and RX paths. In case of 349+ * reception, for example, it pre-allocated the RX socket buffer in order to 350+ * allow zero-copy mechanism. 351+ */ 352+static int uio_alloc_dma_desc_resources(struct stmmac_priv *priv) 353+{ 354+ /* RX Allocation */ 355+ int ret = uio_alloc_dma_rx_desc_resources(priv); 356+ 357+ if (ret) 358+ return ret; 359+ 360+ ret = uio_alloc_dma_tx_desc_resources(priv); 361+ 362+ return ret; 363+} 364+ 365+/** 366+ * uio_free_dma_desc_resources - free dma desc resources 367+ * @priv: private structure 368+ */ 369+static void uio_free_dma_desc_resources(struct stmmac_priv *priv) 370+{ 371+ /* Release the DMA RX socket buffers */ 372+ uio_free_dma_rx_desc_resources(priv); 373+ 374+ /* Release the DMA TX socket buffers */ 375+ uio_free_dma_tx_desc_resources(priv); 376+} 377+ 378+/** 379+ * rockchip_gmac_uio_init_phy - PHY initialization 380+ * @dev: net device structure 381+ * Description: it initializes the driver's PHY state, and attaches the PHY 382+ * to the mac driver. 383+ * Return value: 384+ * 0 on success 385+ */ 386+static int rockchip_gmac_uio_init_phy(struct net_device *dev) 387+{ 388+ struct stmmac_priv *priv = netdev_priv(dev); 389+ struct device_node *node; 390+ int ret; 391+ 392+ node = priv->plat->phylink_node; 393+ 394+ if (node) 395+ ret = phylink_of_phy_connect(priv->phylink, node, 0); 396+ 397+ /* Some DT bindings do not set-up the PHY handle. Let's try to 398+ * manually parse it 399+ */ 400+ if (!node || ret) { 401+ int addr = priv->plat->phy_addr; 402+ struct phy_device *phydev; 403+ 404+ phydev = mdiobus_get_phy(priv->mii, addr); 405+ if (!phydev) { 406+ netdev_err(priv->dev, "no phy at addr %d\n", addr); 407+ return -ENODEV; 408+ } 409+ 410+ ret = phylink_connect_phy(priv->phylink, phydev); 411+ } 412+ 413+ if (!priv->plat->pmt) { 414+ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; 415+ 416+ phylink_ethtool_get_wol(priv->phylink, &wol); 417+ device_set_wakeup_capable(priv->device, !!wol.supported); 418+ } 419+ 420+ return ret; 421+} 422+ 423+/** 424+ * rockchip_gmac_uio_init_dma_engine - DMA init. 425+ * @priv: driver private structure 426+ * Description: 427+ * It inits the DMA invoking the specific MAC/GMAC callback. 428+ * Some DMA parameters can be passed from the platform; 429+ * in case of these are not passed a default is kept for the MAC or GMAC. 430+ */ 431+static int rockchip_gmac_uio_init_dma_engine(struct stmmac_priv *priv) 432+{ 433+ u32 rx_channels_count = priv->plat->rx_queues_to_use; 434+ u32 tx_channels_count = priv->plat->tx_queues_to_use; 435+ u32 dma_csr_ch = max(rx_channels_count, tx_channels_count); 436+ struct stmmac_rx_queue *rx_q; 437+ struct stmmac_tx_queue *tx_q; 438+ u32 chan = 0; 439+ int atds = 0; 440+ int ret = 0; 441+ 442+ if (!priv->plat->dma_cfg || !priv->plat->dma_cfg->pbl) { 443+ dev_err(priv->device, "Invalid DMA configuration\n"); 444+ return -EINVAL; 445+ } 446+ 447+ if (priv->extend_desc && priv->mode == STMMAC_RING_MODE) 448+ atds = 1; 449+ 450+ ret = stmmac_reset(priv, priv->ioaddr); 451+ if (ret) { 452+ dev_err(priv->device, "Failed to reset the dma\n"); 453+ return ret; 454+ } 455+ 456+ /* DMA Configuration */ 457+ stmmac_dma_init(priv, priv->ioaddr, priv->plat->dma_cfg, atds); 458+ 459+ if (priv->plat->axi) 460+ stmmac_axi(priv, priv->ioaddr, priv->plat->axi); 461+ 462+ /* DMA CSR Channel configuration */ 463+ for (chan = 0; chan < dma_csr_ch; chan++) 464+ stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan); 465+ 466+ /* DMA RX Channel Configuration */ 467+ for (chan = 0; chan < rx_channels_count; chan++) { 468+ rx_q = &priv->rx_queue[chan]; 469+ 470+ stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, 471+ rx_q->dma_rx_phy, chan); 472+ 473+ rx_q->rx_tail_addr = rx_q->dma_rx_phy + 474+ (priv->dma_rx_size * 475+ sizeof(struct dma_desc)); 476+ stmmac_set_rx_tail_ptr(priv, priv->ioaddr, 477+ rx_q->rx_tail_addr, chan); 478+ } 479+ 480+ /* DMA TX Channel Configuration */ 481+ for (chan = 0; chan < tx_channels_count; chan++) { 482+ tx_q = &priv->tx_queue[chan]; 483+ 484+ stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, 485+ tx_q->dma_tx_phy, chan); 486+ 487+ tx_q->tx_tail_addr = tx_q->dma_tx_phy; 488+ stmmac_set_tx_tail_ptr(priv, priv->ioaddr, 489+ tx_q->tx_tail_addr, chan); 490+ } 491+ 492+ return ret; 493+} 494+ 495+static void uio_set_rings_length(struct stmmac_priv *priv) 496+{ 497+ u32 rx_channels_count = priv->plat->rx_queues_to_use; 498+ u32 tx_channels_count = priv->plat->tx_queues_to_use; 499+ u32 chan; 500+ 501+ /* set TX ring length */ 502+ for (chan = 0; chan < tx_channels_count; chan++) 503+ stmmac_set_tx_ring_len(priv, priv->ioaddr, 504+ (priv->dma_tx_size - 1), chan); 505+ 506+ /* set RX ring length */ 507+ for (chan = 0; chan < rx_channels_count; chan++) 508+ stmmac_set_rx_ring_len(priv, priv->ioaddr, 509+ (priv->dma_rx_size - 1), chan); 510+} 511+ 512+/** 513+ * uio_set_tx_queue_weight - Set TX queue weight 514+ * @priv: driver private structure 515+ * Description: It is used for setting TX queues weight 516+ */ 517+static void uio_set_tx_queue_weight(struct stmmac_priv *priv) 518+{ 519+ u32 tx_queues_count = priv->plat->tx_queues_to_use; 520+ u32 weight; 521+ u32 queue; 522+ 523+ for (queue = 0; queue < tx_queues_count; queue++) { 524+ weight = priv->plat->tx_queues_cfg[queue].weight; 525+ stmmac_set_mtl_tx_queue_weight(priv, priv->hw, weight, queue); 526+ } 527+} 528+ 529+/** 530+ * uio_configure_cbs - Configure CBS in TX queue 531+ * @priv: driver private structure 532+ * Description: It is used for configuring CBS in AVB TX queues 533+ */ 534+static void uio_configure_cbs(struct stmmac_priv *priv) 535+{ 536+ u32 tx_queues_count = priv->plat->tx_queues_to_use; 537+ u32 mode_to_use; 538+ u32 queue; 539+ 540+ /* queue 0 is reserved for legacy traffic */ 541+ for (queue = 1; queue < tx_queues_count; queue++) { 542+ mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use; 543+ if (mode_to_use == MTL_QUEUE_DCB) 544+ continue; 545+ 546+ stmmac_config_cbs(priv, priv->hw, 547+ priv->plat->tx_queues_cfg[queue].send_slope, 548+ priv->plat->tx_queues_cfg[queue].idle_slope, 549+ priv->plat->tx_queues_cfg[queue].high_credit, 550+ priv->plat->tx_queues_cfg[queue].low_credit, 551+ queue); 552+ } 553+} 554+ 555+/** 556+ * uio_rx_queue_dma_chan_map - Map RX queue to RX dma channel 557+ * @priv: driver private structure 558+ * Description: It is used for mapping RX queues to RX dma channels 559+ */ 560+static void uio_rx_queue_dma_chan_map(struct stmmac_priv *priv) 561+{ 562+ u32 rx_queues_count = priv->plat->rx_queues_to_use; 563+ u32 queue; 564+ u32 chan; 565+ 566+ for (queue = 0; queue < rx_queues_count; queue++) { 567+ chan = priv->plat->rx_queues_cfg[queue].chan; 568+ stmmac_map_mtl_to_dma(priv, priv->hw, queue, chan); 569+ } 570+} 571+ 572+/** 573+ * uio_mac_config_rx_queues_prio - Configure RX Queue priority 574+ * @priv: driver private structure 575+ * Description: It is used for configuring the RX Queue Priority 576+ */ 577+static void uio_mac_config_rx_queues_prio(struct stmmac_priv *priv) 578+{ 579+ u32 rx_queues_count = priv->plat->rx_queues_to_use; 580+ u32 queue; 581+ u32 prio; 582+ 583+ for (queue = 0; queue < rx_queues_count; queue++) { 584+ if (!priv->plat->rx_queues_cfg[queue].use_prio) 585+ continue; 586+ 587+ prio = priv->plat->rx_queues_cfg[queue].prio; 588+ stmmac_rx_queue_prio(priv, priv->hw, prio, queue); 589+ } 590+} 591+ 592+/** 593+ * uio_mac_config_tx_queues_prio - Configure TX Queue priority 594+ * @priv: driver private structure 595+ * Description: It is used for configuring the TX Queue Priority 596+ */ 597+static void uio_mac_config_tx_queues_prio(struct stmmac_priv *priv) 598+{ 599+ u32 tx_queues_count = priv->plat->tx_queues_to_use; 600+ u32 queue; 601+ u32 prio; 602+ 603+ for (queue = 0; queue < tx_queues_count; queue++) { 604+ if (!priv->plat->tx_queues_cfg[queue].use_prio) 605+ continue; 606+ 607+ prio = priv->plat->tx_queues_cfg[queue].prio; 608+ stmmac_tx_queue_prio(priv, priv->hw, prio, queue); 609+ } 610+} 611+ 612+/** 613+ * uio_mac_config_rx_queues_routing - Configure RX Queue Routing 614+ * @priv: driver private structure 615+ * Description: It is used for configuring the RX queue routing 616+ */ 617+static void uio_mac_config_rx_queues_routing(struct stmmac_priv *priv) 618+{ 619+ u32 rx_queues_count = priv->plat->rx_queues_to_use; 620+ u32 queue; 621+ u8 packet; 622+ 623+ for (queue = 0; queue < rx_queues_count; queue++) { 624+ /* no specific packet type routing specified for the queue */ 625+ if (priv->plat->rx_queues_cfg[queue].pkt_route == 0x0) 626+ continue; 627+ 628+ packet = priv->plat->rx_queues_cfg[queue].pkt_route; 629+ stmmac_rx_queue_routing(priv, priv->hw, packet, queue); 630+ } 631+} 632+ 633+static void uio_mac_config_rss(struct stmmac_priv *priv) 634+{ 635+ if (!priv->dma_cap.rssen || !priv->plat->rss_en) { 636+ priv->rss.enable = false; 637+ return; 638+ } 639+ 640+ if (priv->dev->features & NETIF_F_RXHASH) 641+ priv->rss.enable = true; 642+ else 643+ priv->rss.enable = false; 644+ 645+ stmmac_rss_configure(priv, priv->hw, &priv->rss, 646+ priv->plat->rx_queues_to_use); 647+} 648+ 649+/** 650+ * uio_mac_enable_rx_queues - Enable MAC rx queues 651+ * @priv: driver private structure 652+ * Description: It is used for enabling the rx queues in the MAC 653+ */ 654+static void uio_mac_enable_rx_queues(struct stmmac_priv *priv) 655+{ 656+ u32 rx_queues_count = priv->plat->rx_queues_to_use; 657+ int queue; 658+ u8 mode; 659+ 660+ for (queue = 0; queue < rx_queues_count; queue++) { 661+ mode = priv->plat->rx_queues_cfg[queue].mode_to_use; 662+ stmmac_rx_queue_enable(priv, priv->hw, mode, queue); 663+ } 664+} 665+ 666+/** 667+ * rockchip_gmac_uio_mtl_configuration - Configure MTL 668+ * @priv: driver private structure 669+ * Description: It is used for configuring MTL 670+ */ 671+static void rockchip_gmac_uio_mtl_configuration(struct stmmac_priv *priv) 672+{ 673+ u32 rx_queues_count = priv->plat->rx_queues_to_use; 674+ u32 tx_queues_count = priv->plat->tx_queues_to_use; 675+ 676+ if (tx_queues_count > 1) 677+ uio_set_tx_queue_weight(priv); 678+ 679+ /* Configure MTL RX algorithms */ 680+ if (rx_queues_count > 1) 681+ stmmac_prog_mtl_rx_algorithms(priv, priv->hw, 682+ priv->plat->rx_sched_algorithm); 683+ 684+ /* Configure MTL TX algorithms */ 685+ if (tx_queues_count > 1) 686+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw, 687+ priv->plat->tx_sched_algorithm); 688+ 689+ /* Configure CBS in AVB TX queues */ 690+ if (tx_queues_count > 1) 691+ uio_configure_cbs(priv); 692+ 693+ /* Map RX MTL to DMA channels */ 694+ uio_rx_queue_dma_chan_map(priv); 695+ 696+ /* Enable MAC RX Queues */ 697+ uio_mac_enable_rx_queues(priv); 698+ 699+ /* Set RX priorities */ 700+ if (rx_queues_count > 1) 701+ uio_mac_config_rx_queues_prio(priv); 702+ 703+ /* Set TX priorities */ 704+ if (tx_queues_count > 1) 705+ uio_mac_config_tx_queues_prio(priv); 706+ 707+ /* Set RX routing */ 708+ if (rx_queues_count > 1) 709+ uio_mac_config_rx_queues_routing(priv); 710+ 711+ /* Receive Side Scaling */ 712+ if (rx_queues_count > 1) 713+ uio_mac_config_rss(priv); 714+} 715+ 716+static void uio_safety_feat_configuration(struct stmmac_priv *priv) 717+{ 718+ if (priv->dma_cap.asp) { 719+ netdev_info(priv->dev, "Enabling Safety Features\n"); 720+ stmmac_safety_feat_config(priv, priv->ioaddr, priv->dma_cap.asp); 721+ } else { 722+ netdev_info(priv->dev, "No Safety Features support found\n"); 723+ } 724+} 725+ 726+/** 727+ * uio_dma_operation_mode - HW DMA operation mode 728+ * @priv: driver private structure 729+ * Description: it is used for configuring the DMA operation mode register in 730+ * order to program the tx/rx DMA thresholds or Store-And-Forward mode. 731+ */ 732+static void uio_dma_operation_mode(struct stmmac_priv *priv) 733+{ 734+ u32 rx_channels_count = priv->plat->rx_queues_to_use; 735+ u32 tx_channels_count = priv->plat->tx_queues_to_use; 736+ int rxfifosz = priv->plat->rx_fifo_size; 737+ int txfifosz = priv->plat->tx_fifo_size; 738+ u32 txmode = 0; 739+ u32 rxmode = 0; 740+ u32 chan = 0; 741+ u8 qmode = 0; 742+ 743+ if (rxfifosz == 0) 744+ rxfifosz = priv->dma_cap.rx_fifo_size; 745+ if (txfifosz == 0) 746+ txfifosz = priv->dma_cap.tx_fifo_size; 747+ 748+ /* Adjust for real per queue fifo size */ 749+ rxfifosz /= rx_channels_count; 750+ txfifosz /= tx_channels_count; 751+ 752+ if (priv->plat->force_thresh_dma_mode) { 753+ txmode = tc; 754+ rxmode = tc; 755+ } else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) { 756+ /* In case of GMAC, SF mode can be enabled 757+ * to perform the TX COE in HW. This depends on: 758+ * 1) TX COE if actually supported 759+ * 2) There is no bugged Jumbo frame support 760+ * that needs to not insert csum in the TDES. 761+ */ 762+ txmode = SF_DMA_MODE; 763+ rxmode = SF_DMA_MODE; 764+ priv->xstats.threshold = SF_DMA_MODE; 765+ } else { 766+ txmode = tc; 767+ rxmode = SF_DMA_MODE; 768+ } 769+ 770+ /* configure all channels */ 771+ for (chan = 0; chan < rx_channels_count; chan++) { 772+ qmode = priv->plat->rx_queues_cfg[chan].mode_to_use; 773+ 774+ stmmac_dma_rx_mode(priv, priv->ioaddr, rxmode, chan, 775+ rxfifosz, qmode); 776+ stmmac_set_dma_bfsize(priv, priv->ioaddr, priv->dma_buf_sz, 777+ chan); 778+ } 779+ 780+ for (chan = 0; chan < tx_channels_count; chan++) { 781+ qmode = priv->plat->tx_queues_cfg[chan].mode_to_use; 782+ 783+ stmmac_dma_tx_mode(priv, priv->ioaddr, txmode, chan, 784+ txfifosz, qmode); 785+ } 786+} 787+ 788+/** 789+ * rockchip_gmac_uio_hw_setup - setup mac in a usable state. 790+ * @dev : pointer to the device structure. 791+ * @init_ptp: initialize PTP if set 792+ * Description: 793+ * this is the main function to setup the HW in a usable state because the 794+ * dma engine is reset, the core registers are configured (e.g. AXI, 795+ * Checksum features, timers). The DMA is ready to start receiving and 796+ * transmitting. 797+ * Return value: 798+ * 0 on success and an appropriate (-)ve integer as defined in errno.h 799+ * file on failure. 800+ */ 801+static int rockchip_gmac_uio_hw_setup(struct net_device *dev, bool init_ptp) 802+{ 803+ struct stmmac_priv *priv = netdev_priv(dev); 804+ int ret; 805+ 806+ /* DMA initialization and SW reset */ 807+ ret = rockchip_gmac_uio_init_dma_engine(priv); 808+ if (ret < 0) { 809+ netdev_err(priv->dev, "%s: DMA engine initialization failed\n", 810+ __func__); 811+ return ret; 812+ } 813+ 814+ /* Copy the MAC addr into the HW */ 815+ stmmac_set_umac_addr(priv, priv->hw, dev->dev_addr, 0); 816+ 817+ /* PS and related bits will be programmed according to the speed */ 818+ if (priv->hw->pcs) { 819+ int speed = priv->plat->mac_port_sel_speed; 820+ 821+ if (speed == SPEED_10 || speed == SPEED_100 || 822+ speed == SPEED_1000) { 823+ priv->hw->ps = speed; 824+ } else { 825+ dev_warn(priv->device, "invalid port speed\n"); 826+ priv->hw->ps = 0; 827+ } 828+ } 829+ 830+ /* Initialize the MAC Core */ 831+ stmmac_core_init(priv, priv->hw, dev); 832+ 833+ /* Initialize MTL*/ 834+ rockchip_gmac_uio_mtl_configuration(priv); 835+ 836+ /* Initialize Safety Features */ 837+ uio_safety_feat_configuration(priv); 838+ 839+ ret = stmmac_rx_ipc(priv, priv->hw); 840+ if (!ret) { 841+ netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n"); 842+ priv->plat->rx_coe = STMMAC_RX_COE_NONE; 843+ priv->hw->rx_csum = 0; 844+ } 845+ 846+ /* Enable the MAC Rx/Tx */ 847+ stmmac_mac_set(priv, priv->ioaddr, true); 848+ 849+ /* Set the HW DMA mode and the COE */ 850+ uio_dma_operation_mode(priv); 851+ 852+ if (priv->hw->pcs) 853+ stmmac_pcs_ctrl_ane(priv, priv->hw, 1, priv->hw->ps, 0); 854+ 855+ /* set TX and RX rings length */ 856+ uio_set_rings_length(priv); 857+ 858+ return 0; 859+} 860+ 861+static int uio_set_bfsize(int mtu, int bufsize) 862+{ 863+ int ret = bufsize; 864+ 865+ if (mtu >= BUF_SIZE_8KiB) 866+ ret = BUF_SIZE_16KiB; 867+ else if (mtu >= BUF_SIZE_4KiB) 868+ ret = BUF_SIZE_8KiB; 869+ else if (mtu >= BUF_SIZE_2KiB) 870+ ret = BUF_SIZE_4KiB; 871+ else if (mtu > DEFAULT_BUFSIZE) 872+ ret = BUF_SIZE_2KiB; 873+ else 874+ ret = DEFAULT_BUFSIZE; 875+ 876+ return ret; 877+} 878+ 879+/** 880+ * uio_open - open entry point of the driver 881+ * @dev : pointer to the device structure. 882+ * Description: 883+ * This function is the open entry point of the driver. 884+ * Return value: 885+ * 0 on success and an appropriate (-)ve integer as defined in errno.h 886+ * file on failure. 887+ */ 888+static int uio_open(struct net_device *dev) 889+{ 890+ struct stmmac_priv *priv = netdev_priv(dev); 891+ int bfsize = 0; 892+ int ret; 893+ 894+ if (priv->hw->pcs != STMMAC_PCS_TBI && 895+ priv->hw->pcs != STMMAC_PCS_RTBI && 896+ !priv->hw->xpcs) { 897+ ret = rockchip_gmac_uio_init_phy(dev); 898+ if (ret) { 899+ netdev_err(priv->dev, 900+ "%s: Cannot attach to PHY (error: %d)\n", 901+ __func__, ret); 902+ return ret; 903+ } 904+ } 905+ 906+ /* Extra statistics */ 907+ priv->xstats.threshold = tc; 908+ 909+ bfsize = stmmac_set_16kib_bfsize(priv, dev->mtu); 910+ if (bfsize < 0) 911+ bfsize = 0; 912+ 913+ if (bfsize < BUF_SIZE_16KiB) 914+ bfsize = uio_set_bfsize(dev->mtu, priv->dma_buf_sz); 915+ 916+ priv->dma_buf_sz = bfsize; 917+ buf_sz = bfsize; 918+ 919+ priv->rx_copybreak = STMMAC_RX_COPYBREAK; 920+ 921+ if (!priv->dma_tx_size) 922+ priv->dma_tx_size = DMA_DEFAULT_TX_SIZE; 923+ if (!priv->dma_rx_size) 924+ priv->dma_rx_size = DMA_DEFAULT_RX_SIZE; 925+ 926+ ret = uio_alloc_dma_desc_resources(priv); 927+ if (ret < 0) { 928+ netdev_err(priv->dev, "%s: DMA descriptors allocation failed\n", 929+ __func__); 930+ goto dma_desc_error; 931+ } 932+ 933+ ret = rockchip_gmac_uio_hw_setup(dev, true); 934+ if (ret < 0) { 935+ netdev_err(priv->dev, "%s: Hw setup failed\n", __func__); 936+ goto init_error; 937+ } 938+ 939+ phylink_start(priv->phylink); 940+ /* We may have called phylink_speed_down before */ 941+ phylink_speed_up(priv->phylink); 942+ 943+ return 0; 944+ 945+init_error: 946+ uio_free_dma_desc_resources(priv); 947+dma_desc_error: 948+ phylink_disconnect_phy(priv->phylink); 949+ return ret; 950+} 951+ 952+/** 953+ * uio_release - close entry point of the driver 954+ * @dev : device pointer. 955+ * Description: 956+ * This is the stop entry point of the driver. 957+ */ 958+static int uio_release(struct net_device *dev) 959+{ 960+ struct stmmac_priv *priv = netdev_priv(dev); 961+ 962+ /* Stop and disconnect the PHY */ 963+ if (dev->phydev) { 964+ phy_stop(dev->phydev); 965+ phy_disconnect(dev->phydev); 966+ if (priv->plat->integrated_phy_power) 967+ priv->plat->integrated_phy_power(priv->plat->bsp_priv, 968+ false); 969+ } 970+ 971+ /* Release and free the Rx/Tx resources */ 972+ uio_free_dma_desc_resources(priv); 973+ 974+ /* Disable the MAC Rx/Tx */ 975+ stmmac_mac_set(priv, priv->ioaddr, false); 976+ 977+ netif_carrier_off(dev); 978+ 979+ return 0; 980+} 981+ 982+/** 983+ * rockchip_gmac_uio_probe() platform driver probe routine 984+ * - register uio devices filled with memory maps retrieved 985+ * from device tree 986+ */ 987+static int rockchip_gmac_uio_probe(struct platform_device *pdev) 988+{ 989+ struct device *dev = &pdev->dev; 990+ struct device_node *np = dev->of_node, *mac_node; 991+ struct rockchip_gmac_uio_pdev_info *pdev_info; 992+ struct net_device *netdev; 993+ struct stmmac_priv *priv; 994+ struct uio_info *uio; 995+ struct resource *res; 996+ int err = 0; 997+ 998+ pdev_info = devm_kzalloc(dev, sizeof(struct rockchip_gmac_uio_pdev_info), 999+ GFP_KERNEL); 1000+ if (!pdev_info) 1001+ return -ENOMEM; 1002+ 1003+ uio = &pdev_info->uio; 1004+ pdev_info->dev = dev; 1005+ mac_node = of_parse_phandle(np, "rockchip,ethernet", 0); 1006+ if (!mac_node) 1007+ return -ENODEV; 1008+ 1009+ if (of_device_is_available(mac_node)) { 1010+ netdev = of_find_net_device_by_node(mac_node); 1011+ of_node_put(mac_node); 1012+ if (!netdev) 1013+ return -ENODEV; 1014+ } else { 1015+ of_node_put(mac_node); 1016+ return -EINVAL; 1017+ } 1018+ 1019+ pdev_info->ndev = netdev; 1020+ rtnl_lock(); 1021+ dev_close(netdev); 1022+ rtnl_unlock(); 1023+ 1024+ rtnl_lock(); 1025+ err = uio_open(netdev); 1026+ if (err) { 1027+ rtnl_unlock(); 1028+ dev_err(dev, "Failed to open stmmac resource: %d\n", err); 1029+ return err; 1030+ } 1031+ rtnl_unlock(); 1032+ 1033+ priv = netdev_priv(netdev); 1034+ snprintf(pdev_info->name, sizeof(pdev_info->name), "uio_%s", 1035+ netdev->name); 1036+ uio->name = pdev_info->name; 1037+ uio->version = DRIVER_VERSION; 1038+ 1039+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1040+ if (!res) 1041+ return -ENODEV; 1042+ 1043+ uio->mem[0].name = "eth_regs"; 1044+ uio->mem[0].addr = res->start & PAGE_MASK; 1045+ uio->mem[0].size = PAGE_ALIGN(resource_size(res)); 1046+ uio->mem[0].memtype = UIO_MEM_PHYS; 1047+ 1048+ uio->mem[1].name = "eth_rx_bd"; 1049+ uio->mem[1].addr = priv->rx_queue[0].dma_rx_phy; 1050+ uio->mem[1].size = priv->dma_rx_size * sizeof(struct dma_desc); 1051+ uio->mem[1].memtype = UIO_MEM_PHYS; 1052+ 1053+ uio->mem[2].name = "eth_tx_bd"; 1054+ uio->mem[2].addr = priv->tx_queue[0].dma_tx_phy; 1055+ uio->mem[2].size = priv->dma_tx_size * sizeof(struct dma_desc); 1056+ uio->mem[2].memtype = UIO_MEM_PHYS; 1057+ 1058+ uio->open = rockchip_gmac_uio_open; 1059+ uio->release = rockchip_gmac_uio_release; 1060+ /* Custom mmap function. */ 1061+ uio->mmap = rockchip_gmac_uio_mmap; 1062+ uio->priv = pdev_info; 1063+ 1064+ err = uio_register_device(dev, uio); 1065+ if (err) { 1066+ dev_err(dev, "Failed to register uio device: %d\n", err); 1067+ return err; 1068+ } 1069+ 1070+ pdev_info->map_num = 3; 1071+ 1072+ dev_info(dev, "Registered %s uio devices, %d register maps attached\n", 1073+ pdev_info->name, pdev_info->map_num); 1074+ 1075+ platform_set_drvdata(pdev, pdev_info); 1076+ 1077+ return 0; 1078+} 1079+ 1080+/** 1081+ * rockchip_gmac_uio_remove() - ROCKCHIP ETH UIO platform driver release 1082+ * routine - unregister uio devices 1083+ */ 1084+static int rockchip_gmac_uio_remove(struct platform_device *pdev) 1085+{ 1086+ struct rockchip_gmac_uio_pdev_info *pdev_info = 1087+ platform_get_drvdata(pdev); 1088+ struct net_device *netdev; 1089+ 1090+ if (!pdev_info) 1091+ return -EINVAL; 1092+ 1093+ netdev = pdev_info->ndev; 1094+ 1095+ uio_unregister_device(&pdev_info->uio); 1096+ 1097+ if (netdev) { 1098+ rtnl_lock(); 1099+ uio_release(netdev); 1100+ rtnl_unlock(); 1101+ } 1102+ 1103+ platform_set_drvdata(pdev, NULL); 1104+ 1105+ if (netdev) { 1106+ rtnl_lock(); 1107+ dev_open(netdev, NULL); 1108+ rtnl_unlock(); 1109+ } 1110+ 1111+ return 0; 1112+} 1113+ 1114+static const struct of_device_id rockchip_gmac_uio_of_match[] = { 1115+ { .compatible = "rockchip,uio-gmac", }, 1116+ { } 1117+}; 1118+ 1119+static struct platform_driver rockchip_gmac_uio_driver = { 1120+ .driver = { 1121+ .owner = THIS_MODULE, 1122+ .name = DRIVER_NAME, 1123+ .of_match_table = rockchip_gmac_uio_of_match, 1124+ }, 1125+ .probe = rockchip_gmac_uio_probe, 1126+ .remove = rockchip_gmac_uio_remove, 1127+}; 1128+ 1129+module_platform_driver(rockchip_gmac_uio_driver); 1130+ 1131+MODULE_LICENSE("GPL"); 1132+MODULE_AUTHOR("ROCKCHIP"); 1133+MODULE_DESCRIPTION("ROCKCHIP GMAC UIO Driver"); 1134