Merge tag 'linux-kselftest-fixes-5.15-rc5' of git://git.kernel.org/pub/scm/linux...
[platform/kernel/linux-rpi.git] / drivers / net / ethernet / freescale / enetc / enetc_ierb.c
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
38 struct enetc_ierb {
39         void __iomem *regs;
40 };
41
42 static void enetc_ierb_write(struct enetc_ierb *ierb, u32 offset, u32 val)
43 {
44         iowrite32(val, ierb->regs + offset);
45 }
46
47 int 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 }
97 EXPORT_SYMBOL(enetc_ierb_register_pf);
98
99 static 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
130 static int enetc_ierb_remove(struct platform_device *pdev)
131 {
132         return 0;
133 }
134
135 static const struct of_device_id enetc_ierb_match[] = {
136         { .compatible = "fsl,ls1028a-enetc-ierb", },
137         {},
138 };
139 MODULE_DEVICE_TABLE(of, enetc_ierb_match);
140
141 static 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
150 module_platform_driver(enetc_ierb_driver);
151
152 MODULE_DESCRIPTION("NXP ENETC IERB");
153 MODULE_LICENSE("Dual BSD/GPL");