realtek: add support for Netgear GS108T v3
[openwrt/openwrt.git] / target / linux / bcm4908 / patches-5.4 / 170-0002-net-broadcom-bcm4908_enet-add-BCM4908-controller-dri.patch
1 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
2 Date: Fri, 5 Feb 2021 21:59:51 +0100
3 Subject: [PATCH 2/2] net: broadcom: bcm4908_enet: add BCM4908 controller
4 driver
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 BCM4908 SoCs family has integrated Ethernel controller that includes
10 UniMAC but uses different DMA engine (than other controllers) and
11 requires different programming.
12
13 Ethernet controller in BCM4908 is always connected to the internal SF2
14 switch's port and uses fixed link.
15
16 Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
17 ---
18 MAINTAINERS | 9 +
19 drivers/net/ethernet/broadcom/Kconfig | 8 +
20 drivers/net/ethernet/broadcom/Makefile | 1 +
21 drivers/net/ethernet/broadcom/bcm4908_enet.c | 671 +++++++++++++++++++
22 drivers/net/ethernet/broadcom/bcm4908_enet.h | 96 +++
23 5 files changed, 785 insertions(+)
24 create mode 100644 drivers/net/ethernet/broadcom/bcm4908_enet.c
25 create mode 100644 drivers/net/ethernet/broadcom/bcm4908_enet.h
26
27 --- a/MAINTAINERS
28 +++ b/MAINTAINERS
29 @@ -3207,6 +3207,15 @@ F: Documentation/devicetree/bindings/mip
30 F: arch/mips/bcm47xx/*
31 F: arch/mips/include/asm/mach-bcm47xx/*
32
33 +BROADCOM BCM4908 ETHERNET DRIVER
34 +M: Rafał Miłecki <rafal@milecki.pl>
35 +M: bcm-kernel-feedback-list@broadcom.com
36 +L: netdev@vger.kernel.org
37 +S: Maintained
38 +F: Documentation/devicetree/bindings/net/brcm,bcm4908-enet.yaml
39 +F: drivers/net/ethernet/broadcom/bcm4908_enet.*
40 +F: drivers/net/ethernet/broadcom/unimac.h
41 +
42 BROADCOM BCM5301X ARM ARCHITECTURE
43 M: Hauke Mehrtens <hauke@hauke-m.de>
44 M: Rafał Miłecki <zajec5@gmail.com>
45 --- a/drivers/net/ethernet/broadcom/Kconfig
46 +++ b/drivers/net/ethernet/broadcom/Kconfig
47 @@ -51,6 +51,14 @@ config B44_PCI
48 depends on B44_PCI_AUTOSELECT && B44_PCICORE_AUTOSELECT
49 default y
50
51 +config BCM4908_ENET
52 + tristate "Broadcom BCM4908 internal mac support"
53 + depends on ARCH_BCM4908 || COMPILE_TEST
54 + default ARCH_BCM4908
55 + help
56 + This driver supports Ethernet controller integrated into Broadcom
57 + BCM4908 family SoCs.
58 +
59 config BCM63XX_ENET
60 tristate "Broadcom 63xx internal mac support"
61 depends on BCM63XX
62 --- a/drivers/net/ethernet/broadcom/Makefile
63 +++ b/drivers/net/ethernet/broadcom/Makefile
64 @@ -4,6 +4,7 @@
65 #
66
67 obj-$(CONFIG_B44) += b44.o
68 +obj-$(CONFIG_BCM4908_ENET) += bcm4908_enet.o
69 obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
70 obj-$(CONFIG_BCMGENET) += genet/
71 obj-$(CONFIG_BNX2) += bnx2.o
72 --- /dev/null
73 +++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
74 @@ -0,0 +1,671 @@
75 +// SPDX-License-Identifier: GPL-2.0-only
76 +/*
77 + * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
78 + */
79 +
80 +#include <linux/delay.h>
81 +#include <linux/etherdevice.h>
82 +#include <linux/interrupt.h>
83 +#include <linux/module.h>
84 +#include <linux/of.h>
85 +#include <linux/platform_device.h>
86 +#include <linux/slab.h>
87 +#include <linux/string.h>
88 +
89 +#include "bcm4908_enet.h"
90 +#include "unimac.h"
91 +
92 +#define ENET_DMA_CH_RX_CFG ENET_DMA_CH0_CFG
93 +#define ENET_DMA_CH_TX_CFG ENET_DMA_CH1_CFG
94 +#define ENET_DMA_CH_RX_STATE_RAM ENET_DMA_CH0_STATE_RAM
95 +#define ENET_DMA_CH_TX_STATE_RAM ENET_DMA_CH1_STATE_RAM
96 +
97 +#define ENET_TX_BDS_NUM 200
98 +#define ENET_RX_BDS_NUM 200
99 +#define ENET_RX_BDS_NUM_MAX 8192
100 +
101 +#define ENET_DMA_INT_DEFAULTS (ENET_DMA_CH_CFG_INT_DONE | \
102 + ENET_DMA_CH_CFG_INT_NO_DESC | \
103 + ENET_DMA_CH_CFG_INT_BUFF_DONE)
104 +#define ENET_DMA_MAX_BURST_LEN 8 /* in 64 bit words */
105 +
106 +#define ENET_MTU_MIN 60
107 +#define ENET_MTU_MAX 1500 /* Is it possible to support 2044? */
108 +#define ENET_MTU_MAX_EXTRA_SIZE 32 /* L2 */
109 +
110 +struct bcm4908_enet_dma_ring_bd {
111 + __le32 ctl;
112 + __le32 addr;
113 +} __packed;
114 +
115 +struct bcm4908_enet_dma_ring_slot {
116 + struct sk_buff *skb;
117 + unsigned int len;
118 + dma_addr_t dma_addr;
119 +};
120 +
121 +struct bcm4908_enet_dma_ring {
122 + int is_tx;
123 + int read_idx;
124 + int write_idx;
125 + int length;
126 + u16 cfg_block;
127 + u16 st_ram_block;
128 +
129 + union {
130 + void *cpu_addr;
131 + struct bcm4908_enet_dma_ring_bd *buf_desc;
132 + };
133 + dma_addr_t dma_addr;
134 +
135 + struct bcm4908_enet_dma_ring_slot *slots;
136 +};
137 +
138 +struct bcm4908_enet {
139 + struct device *dev;
140 + struct net_device *netdev;
141 + struct napi_struct napi;
142 + void __iomem *base;
143 +
144 + struct bcm4908_enet_dma_ring tx_ring;
145 + struct bcm4908_enet_dma_ring rx_ring;
146 +};
147 +
148 +/***
149 + * R/W ops
150 + */
151 +
152 +static u32 enet_read(struct bcm4908_enet *enet, u16 offset)
153 +{
154 + return readl(enet->base + offset);
155 +}
156 +
157 +static void enet_write(struct bcm4908_enet *enet, u16 offset, u32 value)
158 +{
159 + writel(value, enet->base + offset);
160 +}
161 +
162 +static void enet_maskset(struct bcm4908_enet *enet, u16 offset, u32 mask, u32 set)
163 +{
164 + u32 val;
165 +
166 + WARN_ON(set & ~mask);
167 +
168 + val = enet_read(enet, offset);
169 + val = (val & ~mask) | (set & mask);
170 + enet_write(enet, offset, val);
171 +}
172 +
173 +static void enet_set(struct bcm4908_enet *enet, u16 offset, u32 set)
174 +{
175 + enet_maskset(enet, offset, set, set);
176 +}
177 +
178 +static u32 enet_umac_read(struct bcm4908_enet *enet, u16 offset)
179 +{
180 + return enet_read(enet, ENET_UNIMAC + offset);
181 +}
182 +
183 +static void enet_umac_write(struct bcm4908_enet *enet, u16 offset, u32 value)
184 +{
185 + enet_write(enet, ENET_UNIMAC + offset, value);
186 +}
187 +
188 +static void enet_umac_set(struct bcm4908_enet *enet, u16 offset, u32 set)
189 +{
190 + enet_set(enet, ENET_UNIMAC + offset, set);
191 +}
192 +
193 +/***
194 + * Helpers
195 + */
196 +
197 +static void bcm4908_enet_intrs_on(struct bcm4908_enet *enet)
198 +{
199 + enet_write(enet, ENET_DMA_CH_RX_CFG + ENET_DMA_CH_CFG_INT_MASK, ENET_DMA_INT_DEFAULTS);
200 +}
201 +
202 +static void bcm4908_enet_intrs_off(struct bcm4908_enet *enet)
203 +{
204 + enet_write(enet, ENET_DMA_CH_RX_CFG + ENET_DMA_CH_CFG_INT_MASK, 0);
205 +}
206 +
207 +static void bcm4908_enet_intrs_ack(struct bcm4908_enet *enet)
208 +{
209 + enet_write(enet, ENET_DMA_CH_RX_CFG + ENET_DMA_CH_CFG_INT_STAT, ENET_DMA_INT_DEFAULTS);
210 +}
211 +
212 +/***
213 + * DMA
214 + */
215 +
216 +static int bcm4908_dma_alloc_buf_descs(struct bcm4908_enet *enet,
217 + struct bcm4908_enet_dma_ring *ring)
218 +{
219 + int size = ring->length * sizeof(struct bcm4908_enet_dma_ring_bd);
220 + struct device *dev = enet->dev;
221 +
222 + ring->cpu_addr = dma_alloc_coherent(dev, size, &ring->dma_addr, GFP_KERNEL);
223 + if (!ring->cpu_addr)
224 + return -ENOMEM;
225 +
226 + if (((uintptr_t)ring->cpu_addr) & (0x40 - 1)) {
227 + dev_err(dev, "Invalid DMA ring alignment\n");
228 + goto err_free_buf_descs;
229 + }
230 +
231 + ring->slots = kzalloc(ring->length * sizeof(*ring->slots), GFP_KERNEL);
232 + if (!ring->slots)
233 + goto err_free_buf_descs;
234 +
235 + ring->read_idx = 0;
236 + ring->write_idx = 0;
237 +
238 + return 0;
239 +
240 +err_free_buf_descs:
241 + dma_free_coherent(dev, size, ring->cpu_addr, ring->dma_addr);
242 + return -ENOMEM;
243 +}
244 +
245 +static void bcm4908_enet_dma_free(struct bcm4908_enet *enet)
246 +{
247 + struct bcm4908_enet_dma_ring *tx_ring = &enet->tx_ring;
248 + struct bcm4908_enet_dma_ring *rx_ring = &enet->rx_ring;
249 + struct device *dev = enet->dev;
250 + int size;
251 +
252 + size = rx_ring->length * sizeof(struct bcm4908_enet_dma_ring_bd);
253 + if (rx_ring->cpu_addr)
254 + dma_free_coherent(dev, size, rx_ring->cpu_addr, rx_ring->dma_addr);
255 + kfree(rx_ring->slots);
256 +
257 + size = tx_ring->length * sizeof(struct bcm4908_enet_dma_ring_bd);
258 + if (tx_ring->cpu_addr)
259 + dma_free_coherent(dev, size, tx_ring->cpu_addr, tx_ring->dma_addr);
260 + kfree(tx_ring->slots);
261 +}
262 +
263 +static int bcm4908_enet_dma_alloc(struct bcm4908_enet *enet)
264 +{
265 + struct bcm4908_enet_dma_ring *tx_ring = &enet->tx_ring;
266 + struct bcm4908_enet_dma_ring *rx_ring = &enet->rx_ring;
267 + struct device *dev = enet->dev;
268 + int err;
269 +
270 + tx_ring->length = ENET_TX_BDS_NUM;
271 + tx_ring->is_tx = 1;
272 + tx_ring->cfg_block = ENET_DMA_CH_TX_CFG;
273 + tx_ring->st_ram_block = ENET_DMA_CH_TX_STATE_RAM;
274 + err = bcm4908_dma_alloc_buf_descs(enet, tx_ring);
275 + if (err) {
276 + dev_err(dev, "Failed to alloc TX buf descriptors: %d\n", err);
277 + return err;
278 + }
279 +
280 + rx_ring->length = ENET_RX_BDS_NUM;
281 + rx_ring->is_tx = 0;
282 + rx_ring->cfg_block = ENET_DMA_CH_RX_CFG;
283 + rx_ring->st_ram_block = ENET_DMA_CH_RX_STATE_RAM;
284 + err = bcm4908_dma_alloc_buf_descs(enet, rx_ring);
285 + if (err) {
286 + dev_err(dev, "Failed to alloc RX buf descriptors: %d\n", err);
287 + bcm4908_enet_dma_free(enet);
288 + return err;
289 + }
290 +
291 + return 0;
292 +}
293 +
294 +static void bcm4908_enet_dma_reset(struct bcm4908_enet *enet)
295 +{
296 + struct bcm4908_enet_dma_ring *rings[] = { &enet->rx_ring, &enet->tx_ring };
297 + int i;
298 +
299 + /* Disable the DMA controller and channel */
300 + for (i = 0; i < ARRAY_SIZE(rings); i++)
301 + enet_write(enet, rings[i]->cfg_block + ENET_DMA_CH_CFG, 0);
302 + enet_maskset(enet, ENET_DMA_CONTROLLER_CFG, ENET_DMA_CTRL_CFG_MASTER_EN, 0);
303 +
304 + /* Reset channels state */
305 + for (i = 0; i < ARRAY_SIZE(rings); i++) {
306 + struct bcm4908_enet_dma_ring *ring = rings[i];
307 +
308 + enet_write(enet, ring->st_ram_block + ENET_DMA_CH_STATE_RAM_BASE_DESC_PTR, 0);
309 + enet_write(enet, ring->st_ram_block + ENET_DMA_CH_STATE_RAM_STATE_DATA, 0);
310 + enet_write(enet, ring->st_ram_block + ENET_DMA_CH_STATE_RAM_DESC_LEN_STATUS, 0);
311 + enet_write(enet, ring->st_ram_block + ENET_DMA_CH_STATE_RAM_DESC_BASE_BUFPTR, 0);
312 + }
313 +}
314 +
315 +static int bcm4908_enet_dma_alloc_rx_buf(struct bcm4908_enet *enet, unsigned int idx)
316 +{
317 + struct bcm4908_enet_dma_ring_bd *buf_desc = &enet->rx_ring.buf_desc[idx];
318 + struct bcm4908_enet_dma_ring_slot *slot = &enet->rx_ring.slots[idx];
319 + struct device *dev = enet->dev;
320 + u32 tmp;
321 + int err;
322 +
323 + slot->len = ENET_MTU_MAX + ENET_MTU_MAX_EXTRA_SIZE;
324 +
325 + slot->skb = netdev_alloc_skb(enet->netdev, slot->len);
326 + if (!slot->skb)
327 + return -ENOMEM;
328 +
329 + slot->dma_addr = dma_map_single(dev, slot->skb->data, slot->len, DMA_FROM_DEVICE);
330 + err = dma_mapping_error(dev, slot->dma_addr);
331 + if (err) {
332 + dev_err(dev, "Failed to map DMA buffer: %d\n", err);
333 + kfree_skb(slot->skb);
334 + slot->skb = NULL;
335 + return err;
336 + }
337 +
338 + tmp = slot->len << DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT;
339 + tmp |= DMA_CTL_STATUS_OWN;
340 + if (idx == enet->rx_ring.length - 1)
341 + tmp |= DMA_CTL_STATUS_WRAP;
342 + buf_desc->ctl = cpu_to_le32(tmp);
343 + buf_desc->addr = cpu_to_le32(slot->dma_addr);
344 +
345 + return 0;
346 +}
347 +
348 +static void bcm4908_enet_dma_ring_init(struct bcm4908_enet *enet,
349 + struct bcm4908_enet_dma_ring *ring)
350 +{
351 + int reset_channel = 0; /* We support only 1 main channel (with TX and RX) */
352 + int reset_subch = ring->is_tx ? 1 : 0;
353 +
354 + /* Reset the DMA channel */
355 + enet_write(enet, ENET_DMA_CTRL_CHANNEL_RESET, BIT(reset_channel * 2 + reset_subch));
356 + enet_write(enet, ENET_DMA_CTRL_CHANNEL_RESET, 0);
357 +
358 + enet_write(enet, ring->cfg_block + ENET_DMA_CH_CFG, 0);
359 + enet_write(enet, ring->cfg_block + ENET_DMA_CH_CFG_MAX_BURST, ENET_DMA_MAX_BURST_LEN);
360 + enet_write(enet, ring->cfg_block + ENET_DMA_CH_CFG_INT_MASK, 0);
361 +
362 + enet_write(enet, ring->st_ram_block + ENET_DMA_CH_STATE_RAM_BASE_DESC_PTR,
363 + (uint32_t)ring->dma_addr);
364 +}
365 +
366 +static void bcm4908_enet_dma_uninit(struct bcm4908_enet *enet)
367 +{
368 + struct bcm4908_enet_dma_ring *rx_ring = &enet->rx_ring;
369 + struct bcm4908_enet_dma_ring_slot *slot;
370 + struct device *dev = enet->dev;
371 + int i;
372 +
373 + for (i = rx_ring->length - 1; i >= 0; i--) {
374 + slot = &rx_ring->slots[i];
375 + if (!slot->skb)
376 + continue;
377 + dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_FROM_DEVICE);
378 + kfree_skb(slot->skb);
379 + slot->skb = NULL;
380 + }
381 +}
382 +
383 +static int bcm4908_enet_dma_init(struct bcm4908_enet *enet)
384 +{
385 + struct bcm4908_enet_dma_ring *rx_ring = &enet->rx_ring;
386 + struct device *dev = enet->dev;
387 + int err;
388 + int i;
389 +
390 + for (i = 0; i < rx_ring->length; i++) {
391 + err = bcm4908_enet_dma_alloc_rx_buf(enet, i);
392 + if (err) {
393 + dev_err(dev, "Failed to alloc RX buffer: %d\n", err);
394 + bcm4908_enet_dma_uninit(enet);
395 + return err;
396 + }
397 + }
398 +
399 + bcm4908_enet_dma_ring_init(enet, &enet->tx_ring);
400 + bcm4908_enet_dma_ring_init(enet, &enet->rx_ring);
401 +
402 + return 0;
403 +}
404 +
405 +static void bcm4908_enet_dma_tx_ring_enable(struct bcm4908_enet *enet,
406 + struct bcm4908_enet_dma_ring *ring)
407 +{
408 + enet_write(enet, ring->cfg_block + ENET_DMA_CH_CFG, ENET_DMA_CH_CFG_ENABLE);
409 +}
410 +
411 +static void bcm4908_enet_dma_tx_ring_disable(struct bcm4908_enet *enet,
412 + struct bcm4908_enet_dma_ring *ring)
413 +{
414 + enet_write(enet, ring->cfg_block + ENET_DMA_CH_CFG, 0);
415 +}
416 +
417 +static void bcm4908_enet_dma_rx_ring_enable(struct bcm4908_enet *enet,
418 + struct bcm4908_enet_dma_ring *ring)
419 +{
420 + enet_set(enet, ring->cfg_block + ENET_DMA_CH_CFG, ENET_DMA_CH_CFG_ENABLE);
421 +}
422 +
423 +static void bcm4908_enet_dma_rx_ring_disable(struct bcm4908_enet *enet,
424 + struct bcm4908_enet_dma_ring *ring)
425 +{
426 + unsigned long deadline;
427 + u32 tmp;
428 +
429 + enet_maskset(enet, ring->cfg_block + ENET_DMA_CH_CFG, ENET_DMA_CH_CFG_ENABLE, 0);
430 +
431 + deadline = jiffies + usecs_to_jiffies(2000);
432 + do {
433 + tmp = enet_read(enet, ring->cfg_block + ENET_DMA_CH_CFG);
434 + if (!(tmp & ENET_DMA_CH_CFG_ENABLE))
435 + return;
436 + enet_maskset(enet, ring->cfg_block + ENET_DMA_CH_CFG, ENET_DMA_CH_CFG_ENABLE, 0);
437 + usleep_range(10, 30);
438 + } while (!time_after_eq(jiffies, deadline));
439 +
440 + dev_warn(enet->dev, "Timeout waiting for DMA TX stop\n");
441 +}
442 +
443 +/***
444 + * Ethernet driver
445 + */
446 +
447 +static void bcm4908_enet_gmac_init(struct bcm4908_enet *enet)
448 +{
449 + u32 cmd;
450 +
451 + cmd = enet_umac_read(enet, UMAC_CMD);
452 + enet_umac_write(enet, UMAC_CMD, cmd | CMD_SW_RESET);
453 + enet_umac_write(enet, UMAC_CMD, cmd & ~CMD_SW_RESET);
454 +
455 + enet_set(enet, ENET_FLUSH, ENET_FLUSH_RXFIFO_FLUSH | ENET_FLUSH_TXFIFO_FLUSH);
456 + enet_maskset(enet, ENET_FLUSH, ENET_FLUSH_RXFIFO_FLUSH | ENET_FLUSH_TXFIFO_FLUSH, 0);
457 +
458 + enet_set(enet, ENET_MIB_CTRL, ENET_MIB_CTRL_CLR_MIB);
459 + enet_maskset(enet, ENET_MIB_CTRL, ENET_MIB_CTRL_CLR_MIB, 0);
460 +
461 + cmd = enet_umac_read(enet, UMAC_CMD);
462 + cmd &= ~(CMD_SPEED_MASK << CMD_SPEED_SHIFT);
463 + cmd &= ~CMD_TX_EN;
464 + cmd &= ~CMD_RX_EN;
465 + cmd |= CMD_SPEED_1000 << CMD_SPEED_SHIFT;
466 + enet_umac_write(enet, UMAC_CMD, cmd);
467 +
468 + enet_maskset(enet, ENET_GMAC_STATUS,
469 + ENET_GMAC_STATUS_ETH_SPEED_MASK |
470 + ENET_GMAC_STATUS_HD |
471 + ENET_GMAC_STATUS_AUTO_CFG_EN |
472 + ENET_GMAC_STATUS_LINK_UP,
473 + ENET_GMAC_STATUS_ETH_SPEED_1000 |
474 + ENET_GMAC_STATUS_AUTO_CFG_EN |
475 + ENET_GMAC_STATUS_LINK_UP);
476 +}
477 +
478 +static irqreturn_t bcm4908_enet_irq_handler(int irq, void *dev_id)
479 +{
480 + struct bcm4908_enet *enet = dev_id;
481 +
482 + bcm4908_enet_intrs_off(enet);
483 + bcm4908_enet_intrs_ack(enet);
484 +
485 + napi_schedule(&enet->napi);
486 +
487 + return IRQ_HANDLED;
488 +}
489 +
490 +static int bcm4908_enet_open(struct net_device *netdev)
491 +{
492 + struct bcm4908_enet *enet = netdev_priv(netdev);
493 + struct device *dev = enet->dev;
494 + int err;
495 +
496 + err = request_irq(netdev->irq, bcm4908_enet_irq_handler, 0, "enet", enet);
497 + if (err) {
498 + dev_err(dev, "Failed to request IRQ %d: %d\n", netdev->irq, err);
499 + return err;
500 + }
501 +
502 + bcm4908_enet_gmac_init(enet);
503 + bcm4908_enet_dma_reset(enet);
504 + bcm4908_enet_dma_init(enet);
505 +
506 + enet_umac_set(enet, UMAC_CMD, CMD_TX_EN | CMD_RX_EN);
507 +
508 + enet_set(enet, ENET_DMA_CONTROLLER_CFG, ENET_DMA_CTRL_CFG_MASTER_EN);
509 + enet_maskset(enet, ENET_DMA_CONTROLLER_CFG, ENET_DMA_CTRL_CFG_FLOWC_CH1_EN, 0);
510 + bcm4908_enet_dma_rx_ring_enable(enet, &enet->rx_ring);
511 +
512 + napi_enable(&enet->napi);
513 + netif_carrier_on(netdev);
514 + netif_start_queue(netdev);
515 +
516 + bcm4908_enet_intrs_ack(enet);
517 + bcm4908_enet_intrs_on(enet);
518 +
519 + return 0;
520 +}
521 +
522 +static int bcm4908_enet_stop(struct net_device *netdev)
523 +{
524 + struct bcm4908_enet *enet = netdev_priv(netdev);
525 +
526 + netif_stop_queue(netdev);
527 + netif_carrier_off(netdev);
528 + napi_disable(&enet->napi);
529 +
530 + bcm4908_enet_dma_rx_ring_disable(enet, &enet->rx_ring);
531 + bcm4908_enet_dma_tx_ring_disable(enet, &enet->tx_ring);
532 +
533 + bcm4908_enet_dma_uninit(enet);
534 +
535 + free_irq(enet->netdev->irq, enet);
536 +
537 + return 0;
538 +}
539 +
540 +static int bcm4908_enet_start_xmit(struct sk_buff *skb, struct net_device *netdev)
541 +{
542 + struct bcm4908_enet *enet = netdev_priv(netdev);
543 + struct bcm4908_enet_dma_ring *ring = &enet->tx_ring;
544 + struct bcm4908_enet_dma_ring_slot *slot;
545 + struct device *dev = enet->dev;
546 + struct bcm4908_enet_dma_ring_bd *buf_desc;
547 + int free_buf_descs;
548 + u32 tmp;
549 +
550 + /* Free transmitted skbs */
551 + while (ring->read_idx != ring->write_idx) {
552 + buf_desc = &ring->buf_desc[ring->read_idx];
553 + if (le32_to_cpu(buf_desc->ctl) & DMA_CTL_STATUS_OWN)
554 + break;
555 + slot = &ring->slots[ring->read_idx];
556 +
557 + dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_TO_DEVICE);
558 + dev_kfree_skb(slot->skb);
559 + if (++ring->read_idx == ring->length)
560 + ring->read_idx = 0;
561 + }
562 +
563 + /* Don't use the last empty buf descriptor */
564 + if (ring->read_idx <= ring->write_idx)
565 + free_buf_descs = ring->read_idx - ring->write_idx + ring->length;
566 + else
567 + free_buf_descs = ring->read_idx - ring->write_idx;
568 + if (free_buf_descs < 2)
569 + return NETDEV_TX_BUSY;
570 +
571 + /* Hardware removes OWN bit after sending data */
572 + buf_desc = &ring->buf_desc[ring->write_idx];
573 + if (unlikely(le32_to_cpu(buf_desc->ctl) & DMA_CTL_STATUS_OWN)) {
574 + netif_stop_queue(netdev);
575 + return NETDEV_TX_BUSY;
576 + }
577 +
578 + slot = &ring->slots[ring->write_idx];
579 + slot->skb = skb;
580 + slot->len = skb->len;
581 + slot->dma_addr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE);
582 + if (unlikely(dma_mapping_error(dev, slot->dma_addr)))
583 + return NETDEV_TX_BUSY;
584 +
585 + tmp = skb->len << DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT;
586 + tmp |= DMA_CTL_STATUS_OWN;
587 + tmp |= DMA_CTL_STATUS_SOP;
588 + tmp |= DMA_CTL_STATUS_EOP;
589 + tmp |= DMA_CTL_STATUS_APPEND_CRC;
590 + if (ring->write_idx + 1 == ring->length - 1)
591 + tmp |= DMA_CTL_STATUS_WRAP;
592 +
593 + buf_desc->addr = cpu_to_le32((uint32_t)slot->dma_addr);
594 + buf_desc->ctl = cpu_to_le32(tmp);
595 +
596 + bcm4908_enet_dma_tx_ring_enable(enet, &enet->tx_ring);
597 +
598 + if (++ring->write_idx == ring->length - 1)
599 + ring->write_idx = 0;
600 + enet->netdev->stats.tx_bytes += skb->len;
601 + enet->netdev->stats.tx_packets++;
602 +
603 + return NETDEV_TX_OK;
604 +}
605 +
606 +static int bcm4908_enet_poll(struct napi_struct *napi, int weight)
607 +{
608 + struct bcm4908_enet *enet = container_of(napi, struct bcm4908_enet, napi);
609 + struct device *dev = enet->dev;
610 + int handled = 0;
611 +
612 + while (handled < weight) {
613 + struct bcm4908_enet_dma_ring_bd *buf_desc;
614 + struct bcm4908_enet_dma_ring_slot slot;
615 + u32 ctl;
616 + int len;
617 + int err;
618 +
619 + buf_desc = &enet->rx_ring.buf_desc[enet->rx_ring.read_idx];
620 + ctl = le32_to_cpu(buf_desc->ctl);
621 + if (ctl & DMA_CTL_STATUS_OWN)
622 + break;
623 +
624 + slot = enet->rx_ring.slots[enet->rx_ring.read_idx];
625 +
626 + /* Provide new buffer before unpinning the old one */
627 + err = bcm4908_enet_dma_alloc_rx_buf(enet, enet->rx_ring.read_idx);
628 + if (err)
629 + break;
630 +
631 + if (++enet->rx_ring.read_idx == enet->rx_ring.length)
632 + enet->rx_ring.read_idx = 0;
633 +
634 + len = (ctl & DMA_CTL_LEN_DESC_BUFLENGTH) >> DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT;
635 +
636 + if (len < ENET_MTU_MIN ||
637 + (ctl & (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) != (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) {
638 + kfree(slot.skb);
639 + enet->netdev->stats.rx_dropped++;
640 + break;
641 + }
642 +
643 + dma_unmap_single(dev, slot.dma_addr, slot.len, DMA_FROM_DEVICE);
644 +
645 + skb_put(slot.skb, len - ETH_FCS_LEN);
646 + slot.skb->protocol = eth_type_trans(slot.skb, enet->netdev);
647 + netif_receive_skb(slot.skb);
648 +
649 + enet->netdev->stats.rx_packets++;
650 + enet->netdev->stats.rx_bytes += len;
651 + }
652 +
653 + if (handled < weight) {
654 + napi_complete_done(napi, handled);
655 + bcm4908_enet_intrs_on(enet);
656 + }
657 +
658 + return handled;
659 +}
660 +
661 +static const struct net_device_ops bcm4908_enet_netdev_ops = {
662 + .ndo_open = bcm4908_enet_open,
663 + .ndo_stop = bcm4908_enet_stop,
664 + .ndo_start_xmit = bcm4908_enet_start_xmit,
665 + .ndo_set_mac_address = eth_mac_addr,
666 +};
667 +
668 +static int bcm4908_enet_probe(struct platform_device *pdev)
669 +{
670 + struct device *dev = &pdev->dev;
671 + struct net_device *netdev;
672 + struct bcm4908_enet *enet;
673 + int err;
674 +
675 + netdev = devm_alloc_etherdev(dev, sizeof(*enet));
676 + if (!netdev)
677 + return -ENOMEM;
678 +
679 + enet = netdev_priv(netdev);
680 + enet->dev = dev;
681 + enet->netdev = netdev;
682 +
683 + enet->base = devm_platform_ioremap_resource(pdev, 0);
684 + if (IS_ERR(enet->base)) {
685 + dev_err(dev, "Failed to map registers: %ld\n", PTR_ERR(enet->base));
686 + return PTR_ERR(enet->base);
687 + }
688 +
689 + netdev->irq = platform_get_irq(pdev, 0);
690 + if (netdev->irq < 0)
691 + return netdev->irq;
692 +
693 + dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
694 +
695 + err = bcm4908_enet_dma_alloc(enet);
696 + if (err)
697 + return err;
698 +
699 + SET_NETDEV_DEV(netdev, &pdev->dev);
700 + eth_hw_addr_random(netdev);
701 + netdev->netdev_ops = &bcm4908_enet_netdev_ops;
702 + netdev->min_mtu = ETH_ZLEN;
703 + netdev->mtu = ENET_MTU_MAX;
704 + netdev->max_mtu = ENET_MTU_MAX;
705 + netif_napi_add(netdev, &enet->napi, bcm4908_enet_poll, 64);
706 +
707 + err = register_netdev(netdev);
708 + if (err) {
709 + bcm4908_enet_dma_free(enet);
710 + return err;
711 + }
712 +
713 + platform_set_drvdata(pdev, enet);
714 +
715 + return 0;
716 +}
717 +
718 +static int bcm4908_enet_remove(struct platform_device *pdev)
719 +{
720 + struct bcm4908_enet *enet = platform_get_drvdata(pdev);
721 +
722 + unregister_netdev(enet->netdev);
723 + netif_napi_del(&enet->napi);
724 + bcm4908_enet_dma_free(enet);
725 +
726 + return 0;
727 +}
728 +
729 +static const struct of_device_id bcm4908_enet_of_match[] = {
730 + { .compatible = "brcm,bcm4908-enet"},
731 + {},
732 +};
733 +
734 +static struct platform_driver bcm4908_enet_driver = {
735 + .driver = {
736 + .name = "bcm4908_enet",
737 + .of_match_table = bcm4908_enet_of_match,
738 + },
739 + .probe = bcm4908_enet_probe,
740 + .remove = bcm4908_enet_remove,
741 +};
742 +module_platform_driver(bcm4908_enet_driver);
743 +
744 +MODULE_LICENSE("GPL v2");
745 +MODULE_DEVICE_TABLE(of, bcm4908_enet_of_match);
746 --- /dev/null
747 +++ b/drivers/net/ethernet/broadcom/bcm4908_enet.h
748 @@ -0,0 +1,96 @@
749 +/* SPDX-License-Identifier: GPL-2.0-only */
750 +#ifndef __BCM4908_ENET_H
751 +#define __BCM4908_ENET_H
752 +
753 +#define ENET_CONTROL 0x000
754 +#define ENET_MIB_CTRL 0x004
755 +#define ENET_MIB_CTRL_CLR_MIB 0x00000001
756 +#define ENET_RX_ERR_MASK 0x008
757 +#define ENET_MIB_MAX_PKT_SIZE 0x00C
758 +#define ENET_MIB_MAX_PKT_SIZE_VAL 0x00003fff
759 +#define ENET_DIAG_OUT 0x01c
760 +#define ENET_ENABLE_DROP_PKT 0x020
761 +#define ENET_IRQ_ENABLE 0x024
762 +#define ENET_IRQ_ENABLE_OVFL 0x00000001
763 +#define ENET_GMAC_STATUS 0x028
764 +#define ENET_GMAC_STATUS_ETH_SPEED_MASK 0x00000003
765 +#define ENET_GMAC_STATUS_ETH_SPEED_10 0x00000000
766 +#define ENET_GMAC_STATUS_ETH_SPEED_100 0x00000001
767 +#define ENET_GMAC_STATUS_ETH_SPEED_1000 0x00000002
768 +#define ENET_GMAC_STATUS_HD 0x00000004
769 +#define ENET_GMAC_STATUS_AUTO_CFG_EN 0x00000008
770 +#define ENET_GMAC_STATUS_LINK_UP 0x00000010
771 +#define ENET_IRQ_STATUS 0x02c
772 +#define ENET_IRQ_STATUS_OVFL 0x00000001
773 +#define ENET_OVERFLOW_COUNTER 0x030
774 +#define ENET_FLUSH 0x034
775 +#define ENET_FLUSH_RXFIFO_FLUSH 0x00000001
776 +#define ENET_FLUSH_TXFIFO_FLUSH 0x00000002
777 +#define ENET_RSV_SELECT 0x038
778 +#define ENET_BP_FORCE 0x03c
779 +#define ENET_BP_FORCE_FORCE 0x00000001
780 +#define ENET_DMA_RX_OK_TO_SEND_COUNT 0x040
781 +#define ENET_DMA_RX_OK_TO_SEND_COUNT_VAL 0x0000000f
782 +#define ENET_TX_CRC_CTRL 0x044
783 +#define ENET_MIB 0x200
784 +#define ENET_UNIMAC 0x400
785 +#define ENET_DMA 0x800
786 +#define ENET_DMA_CONTROLLER_CFG 0x800
787 +#define ENET_DMA_CTRL_CFG_MASTER_EN 0x00000001
788 +#define ENET_DMA_CTRL_CFG_FLOWC_CH1_EN 0x00000002
789 +#define ENET_DMA_CTRL_CFG_FLOWC_CH3_EN 0x00000004
790 +#define ENET_DMA_FLOWCTL_CH1_THRESH_LO 0x804
791 +#define ENET_DMA_FLOWCTL_CH1_THRESH_HI 0x808
792 +#define ENET_DMA_FLOWCTL_CH1_ALLOC 0x80c
793 +#define ENET_DMA_FLOWCTL_CH1_ALLOC_FORCE 0x80000000
794 +#define ENET_DMA_FLOWCTL_CH3_THRESH_LO 0x810
795 +#define ENET_DMA_FLOWCTL_CH3_THRESH_HI 0x814
796 +#define ENET_DMA_FLOWCTL_CH3_ALLOC 0x818
797 +#define ENET_DMA_FLOWCTL_CH5_THRESH_LO 0x81C
798 +#define ENET_DMA_FLOWCTL_CH5_THRESH_HI 0x820
799 +#define ENET_DMA_FLOWCTL_CH5_ALLOC 0x824
800 +#define ENET_DMA_FLOWCTL_CH7_THRESH_LO 0x828
801 +#define ENET_DMA_FLOWCTL_CH7_THRESH_HI 0x82C
802 +#define ENET_DMA_FLOWCTL_CH7_ALLOC 0x830
803 +#define ENET_DMA_CTRL_CHANNEL_RESET 0x834
804 +#define ENET_DMA_CTRL_CHANNEL_DEBUG 0x838
805 +#define ENET_DMA_CTRL_GLOBAL_INTERRUPT_STATUS 0x840
806 +#define ENET_DMA_CTRL_GLOBAL_INTERRUPT_MASK 0x844
807 +#define ENET_DMA_CH0_CFG 0xa00 /* RX */
808 +#define ENET_DMA_CH1_CFG 0xa10 /* TX */
809 +#define ENET_DMA_CH0_STATE_RAM 0xc00 /* RX */
810 +#define ENET_DMA_CH1_STATE_RAM 0xc10 /* TX */
811 +
812 +#define ENET_DMA_CH_CFG 0x00 /* assorted configuration */
813 +#define ENET_DMA_CH_CFG_ENABLE 0x00000001 /* set to enable channel */
814 +#define ENET_DMA_CH_CFG_PKT_HALT 0x00000002 /* idle after an EOP flag is detected */
815 +#define ENET_DMA_CH_CFG_BURST_HALT 0x00000004 /* idle after finish current memory burst */
816 +#define ENET_DMA_CH_CFG_INT_STAT 0x04 /* interrupts control and status */
817 +#define ENET_DMA_CH_CFG_INT_MASK 0x08 /* interrupts mask */
818 +#define ENET_DMA_CH_CFG_INT_BUFF_DONE 0x00000001 /* buffer done */
819 +#define ENET_DMA_CH_CFG_INT_DONE 0x00000002 /* packet xfer complete */
820 +#define ENET_DMA_CH_CFG_INT_NO_DESC 0x00000004 /* no valid descriptors */
821 +#define ENET_DMA_CH_CFG_INT_RX_ERROR 0x00000008 /* rxdma detect client protocol error */
822 +#define ENET_DMA_CH_CFG_MAX_BURST 0x0c /* max burst length permitted */
823 +#define ENET_DMA_CH_CFG_MAX_BURST_DESCSIZE_SEL 0x00040000 /* DMA Descriptor Size Selection */
824 +#define ENET_DMA_CH_CFG_SIZE 0x10
825 +
826 +#define ENET_DMA_CH_STATE_RAM_BASE_DESC_PTR 0x00 /* descriptor ring start address */
827 +#define ENET_DMA_CH_STATE_RAM_STATE_DATA 0x04 /* state/bytes done/ring offset */
828 +#define ENET_DMA_CH_STATE_RAM_DESC_LEN_STATUS 0x08 /* buffer descriptor status and len */
829 +#define ENET_DMA_CH_STATE_RAM_DESC_BASE_BUFPTR 0x0c /* buffer descrpitor current processing */
830 +#define ENET_DMA_CH_STATE_RAM_SIZE 0x10
831 +
832 +#define DMA_CTL_STATUS_APPEND_CRC 0x00000100
833 +#define DMA_CTL_STATUS_APPEND_BRCM_TAG 0x00000200
834 +#define DMA_CTL_STATUS_PRIO 0x00000C00 /* Prio for Tx */
835 +#define DMA_CTL_STATUS_WRAP 0x00001000 /* */
836 +#define DMA_CTL_STATUS_SOP 0x00002000 /* first buffer in packet */
837 +#define DMA_CTL_STATUS_EOP 0x00004000 /* last buffer in packet */
838 +#define DMA_CTL_STATUS_OWN 0x00008000 /* cleared by DMA, set by SW */
839 +#define DMA_CTL_LEN_DESC_BUFLENGTH 0x0fff0000
840 +#define DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT 16
841 +#define DMA_CTL_LEN_DESC_MULTICAST 0x40000000
842 +#define DMA_CTL_LEN_DESC_USEFPM 0x80000000
843 +
844 +#endif