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

enetc_ierb.c (5111B)


      1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
      2/* Copyright 2021 NXP
      3 *
      4 * The Integrated Endpoint Register Block (IERB) is configured by pre-boot
      5 * software and is supposed to be to ENETC what a NVRAM is to a 'real' PCIe
      6 * card. Upon FLR, values from the IERB are transferred to the ENETC PFs, and
      7 * are read-only in the PF memory space.
      8 *
      9 * This driver fixes up the power-on reset values for the ENETC shared FIFO,
     10 * such that the TX and RX allocations are sufficient for jumbo frames, and
     11 * that intelligent FIFO dropping is enabled before the internal data
     12 * structures are corrupted.
     13 *
     14 * Even though not all ports might be used on a given board, we are not
     15 * concerned with partitioning the FIFO, because the default values configure
     16 * no strict reservations, so the entire FIFO can be used by the RX of a single
     17 * port, or the TX of a single port.
     18 */
     19
     20#include <linux/io.h>
     21#include <linux/module.h>
     22#include <linux/of_device.h>
     23#include <linux/pci.h>
     24#include <linux/platform_device.h>
     25#include "enetc.h"
     26#include "enetc_ierb.h"
     27
     28/* IERB registers */
     29#define ENETC_IERB_TXMBAR(port)			(((port) * 0x100) + 0x8080)
     30#define ENETC_IERB_RXMBER(port)			(((port) * 0x100) + 0x8090)
     31#define ENETC_IERB_RXMBLR(port)			(((port) * 0x100) + 0x8094)
     32#define ENETC_IERB_RXBCR(port)			(((port) * 0x100) + 0x80a0)
     33#define ENETC_IERB_TXBCR(port)			(((port) * 0x100) + 0x80a8)
     34#define ENETC_IERB_FMBDTR			0xa000
     35
     36#define ENETC_RESERVED_FOR_ICM			1024
     37
     38struct enetc_ierb {
     39	void __iomem *regs;
     40};
     41
     42static void enetc_ierb_write(struct enetc_ierb *ierb, u32 offset, u32 val)
     43{
     44	iowrite32(val, ierb->regs + offset);
     45}
     46
     47int enetc_ierb_register_pf(struct platform_device *pdev,
     48			   struct pci_dev *pf_pdev)
     49{
     50	struct enetc_ierb *ierb = platform_get_drvdata(pdev);
     51	int port = enetc_pf_to_port(pf_pdev);
     52	u16 tx_credit, rx_credit, tx_alloc;
     53
     54	if (port < 0)
     55		return -ENODEV;
     56
     57	if (!ierb)
     58		return -EPROBE_DEFER;
     59
     60	/* By default, it is recommended to set the Host Transfer Agent
     61	 * per port transmit byte credit to "1000 + max_frame_size/2".
     62	 * The power-on reset value (1800 bytes) is rounded up to the nearest
     63	 * 100 assuming a maximum frame size of 1536 bytes.
     64	 */
     65	tx_credit = roundup(1000 + ENETC_MAC_MAXFRM_SIZE / 2, 100);
     66
     67	/* Internal memory allocated for transmit buffering is guaranteed but
     68	 * not reserved; i.e. if the total transmit allocation is not used,
     69	 * then the unused portion is not left idle, it can be used for receive
     70	 * buffering but it will be reclaimed, if required, from receive by
     71	 * intelligently dropping already stored receive frames in the internal
     72	 * memory to ensure that the transmit allocation is respected.
     73	 *
     74	 * PaTXMBAR must be set to a value larger than
     75	 *     PaTXBCR + 2 * max_frame_size + 32
     76	 * if frame preemption is not enabled, or to
     77	 *     2 * PaTXBCR + 2 * p_max_frame_size (pMAC maximum frame size) +
     78	 *     2 * np_max_frame_size (eMAC maximum frame size) + 64
     79	 * if frame preemption is enabled.
     80	 */
     81	tx_alloc = roundup(2 * tx_credit + 4 * ENETC_MAC_MAXFRM_SIZE + 64, 16);
     82
     83	/* Initial credits, in units of 8 bytes, to the Ingress Congestion
     84	 * Manager for the maximum amount of bytes the port is allocated for
     85	 * pending traffic.
     86	 * It is recommended to set the initial credits to 2 times the maximum
     87	 * frame size (2 frames of maximum size).
     88	 */
     89	rx_credit = DIV_ROUND_UP(ENETC_MAC_MAXFRM_SIZE * 2, 8);
     90
     91	enetc_ierb_write(ierb, ENETC_IERB_TXBCR(port), tx_credit);
     92	enetc_ierb_write(ierb, ENETC_IERB_TXMBAR(port), tx_alloc);
     93	enetc_ierb_write(ierb, ENETC_IERB_RXBCR(port), rx_credit);
     94
     95	return 0;
     96}
     97EXPORT_SYMBOL(enetc_ierb_register_pf);
     98
     99static int enetc_ierb_probe(struct platform_device *pdev)
    100{
    101	struct enetc_ierb *ierb;
    102	void __iomem *regs;
    103
    104	ierb = devm_kzalloc(&pdev->dev, sizeof(*ierb), GFP_KERNEL);
    105	if (!ierb)
    106		return -ENOMEM;
    107
    108	regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
    109	if (IS_ERR(regs))
    110		return PTR_ERR(regs);
    111
    112	ierb->regs = regs;
    113
    114	/* Free buffer depletion threshold in bytes.
    115	 * This sets the minimum amount of free buffer memory that should be
    116	 * maintained in the datapath sub system, and when the amount of free
    117	 * buffer memory falls below this threshold, a depletion indication is
    118	 * asserted, which may trigger "intelligent drop" frame releases from
    119	 * the ingress queues in the ICM.
    120	 * It is recommended to set the free buffer depletion threshold to 1024
    121	 * bytes, since the ICM needs some FIFO memory for its own use.
    122	 */
    123	enetc_ierb_write(ierb, ENETC_IERB_FMBDTR, ENETC_RESERVED_FOR_ICM);
    124
    125	platform_set_drvdata(pdev, ierb);
    126
    127	return 0;
    128}
    129
    130static int enetc_ierb_remove(struct platform_device *pdev)
    131{
    132	return 0;
    133}
    134
    135static const struct of_device_id enetc_ierb_match[] = {
    136	{ .compatible = "fsl,ls1028a-enetc-ierb", },
    137	{},
    138};
    139MODULE_DEVICE_TABLE(of, enetc_ierb_match);
    140
    141static struct platform_driver enetc_ierb_driver = {
    142	.driver = {
    143		.name = "fsl-enetc-ierb",
    144		.of_match_table = enetc_ierb_match,
    145	},
    146	.probe = enetc_ierb_probe,
    147	.remove = enetc_ierb_remove,
    148};
    149
    150module_platform_driver(enetc_ierb_driver);
    151
    152MODULE_DESCRIPTION("NXP ENETC IERB");
    153MODULE_LICENSE("Dual BSD/GPL");