FILE
stmmac_pci.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
1// SPDX-License-Identifier: GPL-2.0-only 2/******************************************************************************* 3 This contains the functions to handle the pci driver. 4 5 Copyright (C) 2011-2012 Vayavya Labs Pvt Ltd 6 7 8 Author: Rayagond Kokatanur <rayagond@vayavyalabs.com> 9 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 10*******************************************************************************/ 11 12#include <linux/clk-provider.h> 13#include <linux/pci.h> 14#include <linux/dmi.h> 15 16#include "stmmac.h" 17#include "stmmac_libpci.h" 18 19struct stmmac_pci_info { 20 int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat); 21}; 22 23static void common_default_data(struct plat_stmmacenet_data *plat) 24{ 25 /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ 26 plat->clk_csr = STMMAC_CSR_20_35M; 27 plat->core_type = DWMAC_CORE_GMAC; 28 plat->force_sf_dma_mode = 1; 29 30 plat->mdio_bus_data->needs_reset = true; 31} 32 33static int stmmac_default_data(struct pci_dev *pdev, 34 struct plat_stmmacenet_data *plat) 35{ 36 /* Set common default data first */ 37 common_default_data(plat); 38 39 plat->bus_id = 1; 40 plat->phy_addr = 0; 41 plat->phy_interface = PHY_INTERFACE_MODE_GMII; 42 43 plat->dma_cfg->pbl = 32; 44 plat->dma_cfg->pblx8 = true; 45 /* TODO: AXI */ 46 47 return 0; 48} 49 50static const struct stmmac_pci_info stmmac_pci_info = { 51 .setup = stmmac_default_data, 52}; 53 54static int snps_gmac5_default_data(struct pci_dev *pdev, 55 struct plat_stmmacenet_data *plat) 56{ 57 int i; 58 59 plat->clk_csr = STMMAC_CSR_250_300M; 60 plat->core_type = DWMAC_CORE_GMAC4; 61 plat->force_sf_dma_mode = 1; 62 plat->flags |= STMMAC_FLAG_TSO_EN; 63 plat->pmt = 1; 64 65 /* Set default number of RX and TX queues to use */ 66 plat->tx_queues_to_use = 4; 67 plat->rx_queues_to_use = 4; 68 69 plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR; 70 for (i = 0; i < plat->tx_queues_to_use; i++) { 71 plat->tx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB; 72 plat->tx_queues_cfg[i].weight = 25; 73 if (i > 0) 74 plat->tx_queues_cfg[i].tbs_en = 1; 75 } 76 77 plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; 78 for (i = 0; i < plat->rx_queues_to_use; i++) 79 plat->rx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB; 80 81 plat->bus_id = 1; 82 plat->phy_interface = PHY_INTERFACE_MODE_GMII; 83 84 plat->dma_cfg->pbl = 32; 85 plat->dma_cfg->pblx8 = true; 86 87 /* Axi Configuration */ 88 plat->axi = devm_kzalloc(&pdev->dev, sizeof(*plat->axi), GFP_KERNEL); 89 if (!plat->axi) 90 return -ENOMEM; 91 92 plat->axi->axi_wr_osr_lmt = 31; 93 plat->axi->axi_rd_osr_lmt = 31; 94 95 plat->axi->axi_fb = false; 96 plat->axi->axi_blen_regval = DMA_AXI_BLEN4 | DMA_AXI_BLEN8 | 97 DMA_AXI_BLEN16 | DMA_AXI_BLEN32; 98 99 return 0; 100} 101 102static const struct stmmac_pci_info snps_gmac5_pci_info = { 103 .setup = snps_gmac5_default_data, 104}; 105 106/** 107 * stmmac_pci_probe 108 * 109 * @pdev: pci device pointer 110 * @id: pointer to table of device id/id's. 111 * 112 * Description: This probing function gets called for all PCI devices which 113 * match the ID table and are not "owned" by other driver yet. This function 114 * gets passed a "struct pci_dev *" for each device whose entry in the ID table 115 * matches the device. The probe functions returns zero when the driver choose 116 * to take "ownership" of the device or an error code(-ve no) otherwise. 117 */ 118static int stmmac_pci_probe(struct pci_dev *pdev, 119 const struct pci_device_id *id) 120{ 121 struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data; 122 struct plat_stmmacenet_data *plat; 123 struct stmmac_resources res = {}; 124 int ret; 125 int i; 126 127 plat = stmmac_plat_dat_alloc(&pdev->dev); 128 if (!plat) 129 return -ENOMEM; 130 131 plat->mdio_bus_data = devm_kzalloc(&pdev->dev, 132 sizeof(*plat->mdio_bus_data), 133 GFP_KERNEL); 134 if (!plat->mdio_bus_data) 135 return -ENOMEM; 136 137 plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), 138 GFP_KERNEL); 139 if (!plat->dma_cfg) 140 return -ENOMEM; 141 142 plat->safety_feat_cfg = devm_kzalloc(&pdev->dev, 143 sizeof(*plat->safety_feat_cfg), 144 GFP_KERNEL); 145 if (!plat->safety_feat_cfg) 146 return -ENOMEM; 147 148 /* Enable pci device */ 149 ret = pcim_enable_device(pdev); 150 if (ret) { 151 dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", 152 __func__); 153 return ret; 154 } 155 156 /* Get the base address of device */ 157 for (i = 0; i < PCI_STD_NUM_BARS; i++) { 158 if (pci_resource_len(pdev, i) == 0) 159 continue; 160 res.addr = pcim_iomap_region(pdev, i, STMMAC_RESOURCE_NAME); 161 if (IS_ERR(res.addr)) 162 return PTR_ERR(res.addr); 163 break; 164 } 165 166 pci_set_master(pdev); 167 168 ret = info->setup(pdev, plat); 169 if (ret) 170 return ret; 171 172 res.wol_irq = pdev->irq; 173 res.irq = pdev->irq; 174 175 plat->safety_feat_cfg->tsoee = 1; 176 plat->safety_feat_cfg->mrxpee = 1; 177 plat->safety_feat_cfg->mestee = 1; 178 plat->safety_feat_cfg->mrxee = 1; 179 plat->safety_feat_cfg->mtxee = 1; 180 plat->safety_feat_cfg->epsi = 1; 181 plat->safety_feat_cfg->edpp = 1; 182 plat->safety_feat_cfg->prtyen = 1; 183 plat->safety_feat_cfg->tmouten = 1; 184 185 plat->suspend = stmmac_pci_plat_suspend; 186 plat->resume = stmmac_pci_plat_resume; 187 188 return stmmac_dvr_probe(&pdev->dev, plat, &res); 189} 190 191/** 192 * stmmac_pci_remove 193 * 194 * @pdev: platform device pointer 195 * Description: this function calls the main to free the net resources. 196 */ 197static void stmmac_pci_remove(struct pci_dev *pdev) 198{ 199 stmmac_dvr_remove(&pdev->dev); 200} 201 202/* synthetic ID, no official vendor */ 203#define PCI_VENDOR_ID_STMMAC 0x0700 204 205#define PCI_DEVICE_ID_STMMAC_STMMAC 0x1108 206#define PCI_DEVICE_ID_SYNOPSYS_GMAC5_ID 0x7102 207 208static const struct pci_device_id stmmac_id_table[] = { 209 { PCI_DEVICE_DATA(STMMAC, STMMAC, &stmmac_pci_info) }, 210 { PCI_DEVICE_DATA(STMICRO, MAC, &stmmac_pci_info) }, 211 { PCI_DEVICE_DATA(SYNOPSYS, GMAC5_ID, &snps_gmac5_pci_info) }, 212 {} 213}; 214 215MODULE_DEVICE_TABLE(pci, stmmac_id_table); 216 217static struct pci_driver stmmac_pci_driver = { 218 .name = STMMAC_RESOURCE_NAME, 219 .id_table = stmmac_id_table, 220 .probe = stmmac_pci_probe, 221 .remove = stmmac_pci_remove, 222 .driver = { 223 .pm = &stmmac_simple_pm_ops, 224 }, 225}; 226 227module_pci_driver(stmmac_pci_driver); 228 229MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver"); 230MODULE_AUTHOR("Rayagond Kokatanur <rayagond.kokatanur@vayavyalabs.com>"); 231MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 232MODULE_LICENSE("GPL");
~/
Read-only file preview.