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/mod_devicetable.h>
22#include <linux/module.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), val: tx_credit);
92 enetc_ierb_write(ierb, ENETC_IERB_TXMBAR(port), val: tx_alloc);
93 enetc_ierb_write(ierb, ENETC_IERB_RXBCR(port), val: 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(dev: &pdev->dev, size: sizeof(*ierb), GFP_KERNEL);
105 if (!ierb)
106 return -ENOMEM;
107
108 regs = devm_platform_get_and_ioremap_resource(pdev, index: 0, NULL);
109 if (IS_ERR(ptr: regs))
110 return PTR_ERR(ptr: 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, data: ierb);
126
127 return 0;
128}
129
130static const struct of_device_id enetc_ierb_match[] = {
131 { .compatible = "fsl,ls1028a-enetc-ierb", },
132 {},
133};
134MODULE_DEVICE_TABLE(of, enetc_ierb_match);
135
136static struct platform_driver enetc_ierb_driver = {
137 .driver = {
138 .name = "fsl-enetc-ierb",
139 .of_match_table = enetc_ierb_match,
140 },
141 .probe = enetc_ierb_probe,
142};
143
144module_platform_driver(enetc_ierb_driver);
145
146MODULE_DESCRIPTION("NXP ENETC IERB");
147MODULE_LICENSE("Dual BSD/GPL");
148

source code of linux/drivers/net/ethernet/freescale/enetc/enetc_ierb.c