cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

stmmac_pci.c (7902B)


      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
     18struct stmmac_pci_info {
     19	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
     20};
     21
     22static void common_default_data(struct plat_stmmacenet_data *plat)
     23{
     24	plat->clk_csr = 2;	/* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
     25	plat->has_gmac = 1;
     26	plat->force_sf_dma_mode = 1;
     27
     28	plat->mdio_bus_data->needs_reset = true;
     29
     30	/* Set default value for multicast hash bins */
     31	plat->multicast_filter_bins = HASH_TABLE_SIZE;
     32
     33	/* Set default value for unicast filter entries */
     34	plat->unicast_filter_entries = 1;
     35
     36	/* Set the maxmtu to a default of JUMBO_LEN */
     37	plat->maxmtu = JUMBO_LEN;
     38
     39	/* Set default number of RX and TX queues to use */
     40	plat->tx_queues_to_use = 1;
     41	plat->rx_queues_to_use = 1;
     42
     43	/* Disable Priority config by default */
     44	plat->tx_queues_cfg[0].use_prio = false;
     45	plat->rx_queues_cfg[0].use_prio = false;
     46
     47	/* Disable RX queues routing by default */
     48	plat->rx_queues_cfg[0].pkt_route = 0x0;
     49}
     50
     51static int stmmac_default_data(struct pci_dev *pdev,
     52			       struct plat_stmmacenet_data *plat)
     53{
     54	/* Set common default data first */
     55	common_default_data(plat);
     56
     57	plat->bus_id = 1;
     58	plat->phy_addr = 0;
     59	plat->phy_interface = PHY_INTERFACE_MODE_GMII;
     60
     61	plat->dma_cfg->pbl = 32;
     62	plat->dma_cfg->pblx8 = true;
     63	/* TODO: AXI */
     64
     65	return 0;
     66}
     67
     68static const struct stmmac_pci_info stmmac_pci_info = {
     69	.setup = stmmac_default_data,
     70};
     71
     72static int snps_gmac5_default_data(struct pci_dev *pdev,
     73				   struct plat_stmmacenet_data *plat)
     74{
     75	int i;
     76
     77	plat->clk_csr = 5;
     78	plat->has_gmac4 = 1;
     79	plat->force_sf_dma_mode = 1;
     80	plat->tso_en = 1;
     81	plat->pmt = 1;
     82
     83	/* Set default value for multicast hash bins */
     84	plat->multicast_filter_bins = HASH_TABLE_SIZE;
     85
     86	/* Set default value for unicast filter entries */
     87	plat->unicast_filter_entries = 1;
     88
     89	/* Set the maxmtu to a default of JUMBO_LEN */
     90	plat->maxmtu = JUMBO_LEN;
     91
     92	/* Set default number of RX and TX queues to use */
     93	plat->tx_queues_to_use = 4;
     94	plat->rx_queues_to_use = 4;
     95
     96	plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR;
     97	for (i = 0; i < plat->tx_queues_to_use; i++) {
     98		plat->tx_queues_cfg[i].use_prio = false;
     99		plat->tx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
    100		plat->tx_queues_cfg[i].weight = 25;
    101		if (i > 0)
    102			plat->tx_queues_cfg[i].tbs_en = 1;
    103	}
    104
    105	plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
    106	for (i = 0; i < plat->rx_queues_to_use; i++) {
    107		plat->rx_queues_cfg[i].use_prio = false;
    108		plat->rx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;
    109		plat->rx_queues_cfg[i].pkt_route = 0x0;
    110		plat->rx_queues_cfg[i].chan = i;
    111	}
    112
    113	plat->bus_id = 1;
    114	plat->phy_addr = -1;
    115	plat->phy_interface = PHY_INTERFACE_MODE_GMII;
    116
    117	plat->dma_cfg->pbl = 32;
    118	plat->dma_cfg->pblx8 = true;
    119
    120	/* Axi Configuration */
    121	plat->axi = devm_kzalloc(&pdev->dev, sizeof(*plat->axi), GFP_KERNEL);
    122	if (!plat->axi)
    123		return -ENOMEM;
    124
    125	plat->axi->axi_wr_osr_lmt = 31;
    126	plat->axi->axi_rd_osr_lmt = 31;
    127
    128	plat->axi->axi_fb = false;
    129	plat->axi->axi_blen[0] = 4;
    130	plat->axi->axi_blen[1] = 8;
    131	plat->axi->axi_blen[2] = 16;
    132	plat->axi->axi_blen[3] = 32;
    133
    134	return 0;
    135}
    136
    137static const struct stmmac_pci_info snps_gmac5_pci_info = {
    138	.setup = snps_gmac5_default_data,
    139};
    140
    141/**
    142 * stmmac_pci_probe
    143 *
    144 * @pdev: pci device pointer
    145 * @id: pointer to table of device id/id's.
    146 *
    147 * Description: This probing function gets called for all PCI devices which
    148 * match the ID table and are not "owned" by other driver yet. This function
    149 * gets passed a "struct pci_dev *" for each device whose entry in the ID table
    150 * matches the device. The probe functions returns zero when the driver choose
    151 * to take "ownership" of the device or an error code(-ve no) otherwise.
    152 */
    153static int stmmac_pci_probe(struct pci_dev *pdev,
    154			    const struct pci_device_id *id)
    155{
    156	struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data;
    157	struct plat_stmmacenet_data *plat;
    158	struct stmmac_resources res;
    159	int i;
    160	int ret;
    161
    162	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
    163	if (!plat)
    164		return -ENOMEM;
    165
    166	plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
    167					   sizeof(*plat->mdio_bus_data),
    168					   GFP_KERNEL);
    169	if (!plat->mdio_bus_data)
    170		return -ENOMEM;
    171
    172	plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg),
    173				     GFP_KERNEL);
    174	if (!plat->dma_cfg)
    175		return -ENOMEM;
    176
    177	plat->safety_feat_cfg = devm_kzalloc(&pdev->dev,
    178					     sizeof(*plat->safety_feat_cfg),
    179					     GFP_KERNEL);
    180	if (!plat->safety_feat_cfg)
    181		return -ENOMEM;
    182
    183	/* Enable pci device */
    184	ret = pcim_enable_device(pdev);
    185	if (ret) {
    186		dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n",
    187			__func__);
    188		return ret;
    189	}
    190
    191	/* Get the base address of device */
    192	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
    193		if (pci_resource_len(pdev, i) == 0)
    194			continue;
    195		ret = pcim_iomap_regions(pdev, BIT(i), pci_name(pdev));
    196		if (ret)
    197			return ret;
    198		break;
    199	}
    200
    201	pci_set_master(pdev);
    202
    203	ret = info->setup(pdev, plat);
    204	if (ret)
    205		return ret;
    206
    207	memset(&res, 0, sizeof(res));
    208	res.addr = pcim_iomap_table(pdev)[i];
    209	res.wol_irq = pdev->irq;
    210	res.irq = pdev->irq;
    211
    212	plat->safety_feat_cfg->tsoee = 1;
    213	plat->safety_feat_cfg->mrxpee = 1;
    214	plat->safety_feat_cfg->mestee = 1;
    215	plat->safety_feat_cfg->mrxee = 1;
    216	plat->safety_feat_cfg->mtxee = 1;
    217	plat->safety_feat_cfg->epsi = 1;
    218	plat->safety_feat_cfg->edpp = 1;
    219	plat->safety_feat_cfg->prtyen = 1;
    220	plat->safety_feat_cfg->tmouten = 1;
    221
    222	return stmmac_dvr_probe(&pdev->dev, plat, &res);
    223}
    224
    225/**
    226 * stmmac_pci_remove
    227 *
    228 * @pdev: platform device pointer
    229 * Description: this function calls the main to free the net resources
    230 * and releases the PCI resources.
    231 */
    232static void stmmac_pci_remove(struct pci_dev *pdev)
    233{
    234	int i;
    235
    236	stmmac_dvr_remove(&pdev->dev);
    237
    238	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
    239		if (pci_resource_len(pdev, i) == 0)
    240			continue;
    241		pcim_iounmap_regions(pdev, BIT(i));
    242		break;
    243	}
    244}
    245
    246static int __maybe_unused stmmac_pci_suspend(struct device *dev)
    247{
    248	struct pci_dev *pdev = to_pci_dev(dev);
    249	int ret;
    250
    251	ret = stmmac_suspend(dev);
    252	if (ret)
    253		return ret;
    254
    255	ret = pci_save_state(pdev);
    256	if (ret)
    257		return ret;
    258
    259	pci_disable_device(pdev);
    260	pci_wake_from_d3(pdev, true);
    261	return 0;
    262}
    263
    264static int __maybe_unused stmmac_pci_resume(struct device *dev)
    265{
    266	struct pci_dev *pdev = to_pci_dev(dev);
    267	int ret;
    268
    269	pci_restore_state(pdev);
    270	pci_set_power_state(pdev, PCI_D0);
    271
    272	ret = pci_enable_device(pdev);
    273	if (ret)
    274		return ret;
    275
    276	pci_set_master(pdev);
    277
    278	return stmmac_resume(dev);
    279}
    280
    281static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume);
    282
    283/* synthetic ID, no official vendor */
    284#define PCI_VENDOR_ID_STMMAC		0x0700
    285
    286#define PCI_DEVICE_ID_STMMAC_STMMAC		0x1108
    287#define PCI_DEVICE_ID_SYNOPSYS_GMAC5_ID		0x7102
    288
    289static const struct pci_device_id stmmac_id_table[] = {
    290	{ PCI_DEVICE_DATA(STMMAC, STMMAC, &stmmac_pci_info) },
    291	{ PCI_DEVICE_DATA(STMICRO, MAC, &stmmac_pci_info) },
    292	{ PCI_DEVICE_DATA(SYNOPSYS, GMAC5_ID, &snps_gmac5_pci_info) },
    293	{}
    294};
    295
    296MODULE_DEVICE_TABLE(pci, stmmac_id_table);
    297
    298static struct pci_driver stmmac_pci_driver = {
    299	.name = STMMAC_RESOURCE_NAME,
    300	.id_table = stmmac_id_table,
    301	.probe = stmmac_pci_probe,
    302	.remove = stmmac_pci_remove,
    303	.driver         = {
    304		.pm     = &stmmac_pm_ops,
    305	},
    306};
    307
    308module_pci_driver(stmmac_pci_driver);
    309
    310MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver");
    311MODULE_AUTHOR("Rayagond Kokatanur <rayagond.kokatanur@vayavyalabs.com>");
    312MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
    313MODULE_LICENSE("GPL");