brcm47xx: add initial support for kernel 3.8
[openwrt/svn-archive/archive.git] / target / linux / brcm47xx / patches-3.8 / 750-bgmac.patch
1 From dd4544f05469aaaeee891d7dc54d66430344321e Mon Sep 17 00:00:00 2001
2 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
3 Date: Tue, 8 Jan 2013 20:06:23 +0000
4 Subject: [PATCH] bgmac: driver for GBit MAC core on BCMA bus
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=utf8
7 Content-Transfer-Encoding: 8bit
8
9 BCMA is a Broadcom specific bus with devices AKA cores. All recent BCMA
10 based SoCs have gigabit ethernet provided by the GBit MAC core. This
11 patch adds driver for such a cores registering itself as a netdev. It
12 has been tested on a BCM4706 and BCM4718 chipsets.
13
14 In the kernel tree there is already b44 driver which has some common
15 things with bgmac, however there are many differences that has led to
16 the decision or writing a new driver:
17 1) GBit MAC cores appear on BCMA bus (not SSB as in case of b44)
18 2) There is 64bit DMA engine which differs from 32bit one
19 3) There is no CAM (Content Addressable Memory) in GBit MAC
20 4) We have 4 TX queues on GBit MAC devices (instead of 1)
21 5) Many registers have different addresses/values
22 6) RX header flags are also different
23
24 The driver in it's state is functional how, however there is of course
25 place for improvements:
26 1) Supporting more net_device_ops
27 2) SUpporting more ethtool_ops
28 3) Unaligned addressing in DMA
29 4) Writing separated PHY driver
30
31 Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
32 Signed-off-by: David S. Miller <davem@davemloft.net>
33 ---
34 drivers/bcma/driver_chipcommon_pmu.c | 3 +-
35 drivers/net/ethernet/broadcom/Kconfig | 9 +
36 drivers/net/ethernet/broadcom/Makefile | 1 +
37 drivers/net/ethernet/broadcom/bgmac.c | 1422 +++++++++++++++++++++++++++
38 drivers/net/ethernet/broadcom/bgmac.h | 456 +++++++++
39 include/linux/bcma/bcma_driver_chipcommon.h | 2 +
40 6 files changed, 1892 insertions(+), 1 deletions(-)
41 create mode 100644 drivers/net/ethernet/broadcom/bgmac.c
42 create mode 100644 drivers/net/ethernet/broadcom/bgmac.h
43
44 --- a/drivers/bcma/driver_chipcommon_pmu.c
45 +++ b/drivers/bcma/driver_chipcommon_pmu.c
46 @@ -264,7 +264,7 @@ static u32 bcma_pmu_pll_clock_bcm4706(st
47 }
48
49 /* query bus clock frequency for PMU-enabled chipcommon */
50 -static u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc)
51 +u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc)
52 {
53 struct bcma_bus *bus = cc->core->bus;
54
55 @@ -293,6 +293,7 @@ static u32 bcma_pmu_get_bus_clock(struct
56 }
57 return BCMA_CC_PMU_HT_CLOCK;
58 }
59 +EXPORT_SYMBOL_GPL(bcma_pmu_get_bus_clock);
60
61 /* query cpu clock frequency for PMU-enabled chipcommon */
62 u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc)
63 --- a/drivers/net/ethernet/broadcom/Kconfig
64 +++ b/drivers/net/ethernet/broadcom/Kconfig
65 @@ -121,4 +121,13 @@ config BNX2X
66 To compile this driver as a module, choose M here: the module
67 will be called bnx2x. This is recommended.
68
69 +config BGMAC
70 + tristate "BCMA bus GBit core support"
71 + depends on BCMA_HOST_SOC && HAS_DMA
72 + ---help---
73 + This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
74 + They can be found on BCM47xx SoCs and provide gigabit ethernet.
75 + In case of using this driver on BCM4706 it's also requires to enable
76 + BCMA_DRIVER_GMAC_CMN to make it work.
77 +
78 endif # NET_VENDOR_BROADCOM
79 --- a/drivers/net/ethernet/broadcom/Makefile
80 +++ b/drivers/net/ethernet/broadcom/Makefile
81 @@ -9,3 +9,4 @@ obj-$(CONFIG_CNIC) += cnic.o
82 obj-$(CONFIG_BNX2X) += bnx2x/
83 obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
84 obj-$(CONFIG_TIGON3) += tg3.o
85 +obj-$(CONFIG_BGMAC) += bgmac.o
86 --- /dev/null
87 +++ b/drivers/net/ethernet/broadcom/bgmac.c
88 @@ -0,0 +1,1422 @@
89 +/*
90 + * Driver for (BCM4706)? GBit MAC core on BCMA bus.
91 + *
92 + * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
93 + *
94 + * Licensed under the GNU/GPL. See COPYING for details.
95 + */
96 +
97 +#include "bgmac.h"
98 +
99 +#include <linux/kernel.h>
100 +#include <linux/module.h>
101 +#include <linux/delay.h>
102 +#include <linux/etherdevice.h>
103 +#include <linux/mii.h>
104 +#include <linux/interrupt.h>
105 +#include <linux/dma-mapping.h>
106 +#include <bcm47xx_nvram.h>
107 +
108 +static const struct bcma_device_id bgmac_bcma_tbl[] = {
109 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
110 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
111 + BCMA_CORETABLE_END
112 +};
113 +MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
114 +
115 +static bool bgmac_wait_value(struct bcma_device *core, u16 reg, u32 mask,
116 + u32 value, int timeout)
117 +{
118 + u32 val;
119 + int i;
120 +
121 + for (i = 0; i < timeout / 10; i++) {
122 + val = bcma_read32(core, reg);
123 + if ((val & mask) == value)
124 + return true;
125 + udelay(10);
126 + }
127 + pr_err("Timeout waiting for reg 0x%X\n", reg);
128 + return false;
129 +}
130 +
131 +/**************************************************
132 + * DMA
133 + **************************************************/
134 +
135 +static void bgmac_dma_tx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
136 +{
137 + u32 val;
138 + int i;
139 +
140 + if (!ring->mmio_base)
141 + return;
142 +
143 + /* Suspend DMA TX ring first.
144 + * bgmac_wait_value doesn't support waiting for any of few values, so
145 + * implement whole loop here.
146 + */
147 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL,
148 + BGMAC_DMA_TX_SUSPEND);
149 + for (i = 0; i < 10000 / 10; i++) {
150 + val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
151 + val &= BGMAC_DMA_TX_STAT;
152 + if (val == BGMAC_DMA_TX_STAT_DISABLED ||
153 + val == BGMAC_DMA_TX_STAT_IDLEWAIT ||
154 + val == BGMAC_DMA_TX_STAT_STOPPED) {
155 + i = 0;
156 + break;
157 + }
158 + udelay(10);
159 + }
160 + if (i)
161 + bgmac_err(bgmac, "Timeout suspending DMA TX ring 0x%X (BGMAC_DMA_TX_STAT: 0x%08X)\n",
162 + ring->mmio_base, val);
163 +
164 + /* Remove SUSPEND bit */
165 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, 0);
166 + if (!bgmac_wait_value(bgmac->core,
167 + ring->mmio_base + BGMAC_DMA_TX_STATUS,
168 + BGMAC_DMA_TX_STAT, BGMAC_DMA_TX_STAT_DISABLED,
169 + 10000)) {
170 + bgmac_warn(bgmac, "DMA TX ring 0x%X wasn't disabled on time, waiting additional 300us\n",
171 + ring->mmio_base);
172 + udelay(300);
173 + val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
174 + if ((val & BGMAC_DMA_TX_STAT) != BGMAC_DMA_TX_STAT_DISABLED)
175 + bgmac_err(bgmac, "Reset of DMA TX ring 0x%X failed\n",
176 + ring->mmio_base);
177 + }
178 +}
179 +
180 +static void bgmac_dma_tx_enable(struct bgmac *bgmac,
181 + struct bgmac_dma_ring *ring)
182 +{
183 + u32 ctl;
184 +
185 + ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL);
186 + ctl |= BGMAC_DMA_TX_ENABLE;
187 + ctl |= BGMAC_DMA_TX_PARITY_DISABLE;
188 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl);
189 +}
190 +
191 +static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
192 + struct bgmac_dma_ring *ring,
193 + struct sk_buff *skb)
194 +{
195 + struct device *dma_dev = bgmac->core->dma_dev;
196 + struct net_device *net_dev = bgmac->net_dev;
197 + struct bgmac_dma_desc *dma_desc;
198 + struct bgmac_slot_info *slot;
199 + u32 ctl0, ctl1;
200 + int free_slots;
201 +
202 + if (skb->len > BGMAC_DESC_CTL1_LEN) {
203 + bgmac_err(bgmac, "Too long skb (%d)\n", skb->len);
204 + goto err_stop_drop;
205 + }
206 +
207 + if (ring->start <= ring->end)
208 + free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS;
209 + else
210 + free_slots = ring->start - ring->end;
211 + if (free_slots == 1) {
212 + bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n");
213 + netif_stop_queue(net_dev);
214 + return NETDEV_TX_BUSY;
215 + }
216 +
217 + slot = &ring->slots[ring->end];
218 + slot->skb = skb;
219 + slot->dma_addr = dma_map_single(dma_dev, skb->data, skb->len,
220 + DMA_TO_DEVICE);
221 + if (dma_mapping_error(dma_dev, slot->dma_addr)) {
222 + bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n",
223 + ring->mmio_base);
224 + goto err_stop_drop;
225 + }
226 +
227 + ctl0 = BGMAC_DESC_CTL0_IOC | BGMAC_DESC_CTL0_SOF | BGMAC_DESC_CTL0_EOF;
228 + if (ring->end == ring->num_slots - 1)
229 + ctl0 |= BGMAC_DESC_CTL0_EOT;
230 + ctl1 = skb->len & BGMAC_DESC_CTL1_LEN;
231 +
232 + dma_desc = ring->cpu_base;
233 + dma_desc += ring->end;
234 + dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr));
235 + dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr));
236 + dma_desc->ctl0 = cpu_to_le32(ctl0);
237 + dma_desc->ctl1 = cpu_to_le32(ctl1);
238 +
239 + wmb();
240 +
241 + /* Increase ring->end to point empty slot. We tell hardware the first
242 + * slot it should *not* read.
243 + */
244 + if (++ring->end >= BGMAC_TX_RING_SLOTS)
245 + ring->end = 0;
246 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,
247 + ring->end * sizeof(struct bgmac_dma_desc));
248 +
249 + /* Always keep one slot free to allow detecting bugged calls. */
250 + if (--free_slots == 1)
251 + netif_stop_queue(net_dev);
252 +
253 + return NETDEV_TX_OK;
254 +
255 +err_stop_drop:
256 + netif_stop_queue(net_dev);
257 + dev_kfree_skb(skb);
258 + return NETDEV_TX_OK;
259 +}
260 +
261 +/* Free transmitted packets */
262 +static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
263 +{
264 + struct device *dma_dev = bgmac->core->dma_dev;
265 + int empty_slot;
266 + bool freed = false;
267 +
268 + /* The last slot that hardware didn't consume yet */
269 + empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
270 + empty_slot &= BGMAC_DMA_TX_STATDPTR;
271 + empty_slot /= sizeof(struct bgmac_dma_desc);
272 +
273 + while (ring->start != empty_slot) {
274 + struct bgmac_slot_info *slot = &ring->slots[ring->start];
275 +
276 + if (slot->skb) {
277 + /* Unmap no longer used buffer */
278 + dma_unmap_single(dma_dev, slot->dma_addr,
279 + slot->skb->len, DMA_TO_DEVICE);
280 + slot->dma_addr = 0;
281 +
282 + /* Free memory! :) */
283 + dev_kfree_skb(slot->skb);
284 + slot->skb = NULL;
285 + } else {
286 + bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n",
287 + ring->start, ring->end);
288 + }
289 +
290 + if (++ring->start >= BGMAC_TX_RING_SLOTS)
291 + ring->start = 0;
292 + freed = true;
293 + }
294 +
295 + if (freed && netif_queue_stopped(bgmac->net_dev))
296 + netif_wake_queue(bgmac->net_dev);
297 +}
298 +
299 +static void bgmac_dma_rx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
300 +{
301 + if (!ring->mmio_base)
302 + return;
303 +
304 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, 0);
305 + if (!bgmac_wait_value(bgmac->core,
306 + ring->mmio_base + BGMAC_DMA_RX_STATUS,
307 + BGMAC_DMA_RX_STAT, BGMAC_DMA_RX_STAT_DISABLED,
308 + 10000))
309 + bgmac_err(bgmac, "Reset of ring 0x%X RX failed\n",
310 + ring->mmio_base);
311 +}
312 +
313 +static void bgmac_dma_rx_enable(struct bgmac *bgmac,
314 + struct bgmac_dma_ring *ring)
315 +{
316 + u32 ctl;
317 +
318 + ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL);
319 + ctl &= BGMAC_DMA_RX_ADDREXT_MASK;
320 + ctl |= BGMAC_DMA_RX_ENABLE;
321 + ctl |= BGMAC_DMA_RX_PARITY_DISABLE;
322 + ctl |= BGMAC_DMA_RX_OVERFLOW_CONT;
323 + ctl |= BGMAC_RX_FRAME_OFFSET << BGMAC_DMA_RX_FRAME_OFFSET_SHIFT;
324 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, ctl);
325 +}
326 +
327 +static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
328 + struct bgmac_slot_info *slot)
329 +{
330 + struct device *dma_dev = bgmac->core->dma_dev;
331 + struct bgmac_rx_header *rx;
332 +
333 + /* Alloc skb */
334 + slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
335 + if (!slot->skb) {
336 + bgmac_err(bgmac, "Allocation of skb failed!\n");
337 + return -ENOMEM;
338 + }
339 +
340 + /* Poison - if everything goes fine, hardware will overwrite it */
341 + rx = (struct bgmac_rx_header *)slot->skb->data;
342 + rx->len = cpu_to_le16(0xdead);
343 + rx->flags = cpu_to_le16(0xbeef);
344 +
345 + /* Map skb for the DMA */
346 + slot->dma_addr = dma_map_single(dma_dev, slot->skb->data,
347 + BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
348 + if (dma_mapping_error(dma_dev, slot->dma_addr)) {
349 + bgmac_err(bgmac, "DMA mapping error\n");
350 + return -ENOMEM;
351 + }
352 + if (slot->dma_addr & 0xC0000000)
353 + bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
354 +
355 + return 0;
356 +}
357 +
358 +static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
359 + int weight)
360 +{
361 + u32 end_slot;
362 + int handled = 0;
363 +
364 + end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS);
365 + end_slot &= BGMAC_DMA_RX_STATDPTR;
366 + end_slot /= sizeof(struct bgmac_dma_desc);
367 +
368 + ring->end = end_slot;
369 +
370 + while (ring->start != ring->end) {
371 + struct device *dma_dev = bgmac->core->dma_dev;
372 + struct bgmac_slot_info *slot = &ring->slots[ring->start];
373 + struct sk_buff *skb = slot->skb;
374 + struct sk_buff *new_skb;
375 + struct bgmac_rx_header *rx;
376 + u16 len, flags;
377 +
378 + /* Unmap buffer to make it accessible to the CPU */
379 + dma_sync_single_for_cpu(dma_dev, slot->dma_addr,
380 + BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
381 +
382 + /* Get info from the header */
383 + rx = (struct bgmac_rx_header *)skb->data;
384 + len = le16_to_cpu(rx->len);
385 + flags = le16_to_cpu(rx->flags);
386 +
387 + /* Check for poison and drop or pass the packet */
388 + if (len == 0xdead && flags == 0xbeef) {
389 + bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
390 + ring->start);
391 + } else {
392 + new_skb = netdev_alloc_skb(bgmac->net_dev, len);
393 + if (new_skb) {
394 + skb_put(new_skb, len);
395 + skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET,
396 + new_skb->data,
397 + len);
398 + new_skb->protocol =
399 + eth_type_trans(new_skb, bgmac->net_dev);
400 + netif_receive_skb(new_skb);
401 + handled++;
402 + } else {
403 + bgmac->net_dev->stats.rx_dropped++;
404 + bgmac_err(bgmac, "Allocation of skb for copying packet failed!\n");
405 + }
406 +
407 + /* Poison the old skb */
408 + rx->len = cpu_to_le16(0xdead);
409 + rx->flags = cpu_to_le16(0xbeef);
410 + }
411 +
412 + /* Make it back accessible to the hardware */
413 + dma_sync_single_for_device(dma_dev, slot->dma_addr,
414 + BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
415 +
416 + if (++ring->start >= BGMAC_RX_RING_SLOTS)
417 + ring->start = 0;
418 +
419 + if (handled >= weight) /* Should never be greater */
420 + break;
421 + }
422 +
423 + return handled;
424 +}
425 +
426 +/* Does ring support unaligned addressing? */
427 +static bool bgmac_dma_unaligned(struct bgmac *bgmac,
428 + struct bgmac_dma_ring *ring,
429 + enum bgmac_dma_ring_type ring_type)
430 +{
431 + switch (ring_type) {
432 + case BGMAC_DMA_RING_TX:
433 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
434 + 0xff0);
435 + if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO))
436 + return true;
437 + break;
438 + case BGMAC_DMA_RING_RX:
439 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
440 + 0xff0);
441 + if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO))
442 + return true;
443 + break;
444 + }
445 + return false;
446 +}
447 +
448 +static void bgmac_dma_ring_free(struct bgmac *bgmac,
449 + struct bgmac_dma_ring *ring)
450 +{
451 + struct device *dma_dev = bgmac->core->dma_dev;
452 + struct bgmac_slot_info *slot;
453 + int size;
454 + int i;
455 +
456 + for (i = 0; i < ring->num_slots; i++) {
457 + slot = &ring->slots[i];
458 + if (slot->skb) {
459 + if (slot->dma_addr)
460 + dma_unmap_single(dma_dev, slot->dma_addr,
461 + slot->skb->len, DMA_TO_DEVICE);
462 + dev_kfree_skb(slot->skb);
463 + }
464 + }
465 +
466 + if (ring->cpu_base) {
467 + /* Free ring of descriptors */
468 + size = ring->num_slots * sizeof(struct bgmac_dma_desc);
469 + dma_free_coherent(dma_dev, size, ring->cpu_base,
470 + ring->dma_base);
471 + }
472 +}
473 +
474 +static void bgmac_dma_free(struct bgmac *bgmac)
475 +{
476 + int i;
477 +
478 + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
479 + bgmac_dma_ring_free(bgmac, &bgmac->tx_ring[i]);
480 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
481 + bgmac_dma_ring_free(bgmac, &bgmac->rx_ring[i]);
482 +}
483 +
484 +static int bgmac_dma_alloc(struct bgmac *bgmac)
485 +{
486 + struct device *dma_dev = bgmac->core->dma_dev;
487 + struct bgmac_dma_ring *ring;
488 + static const u16 ring_base[] = { BGMAC_DMA_BASE0, BGMAC_DMA_BASE1,
489 + BGMAC_DMA_BASE2, BGMAC_DMA_BASE3, };
490 + int size; /* ring size: different for Tx and Rx */
491 + int err;
492 + int i;
493 +
494 + BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base));
495 + BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base));
496 +
497 + if (!(bcma_aread32(bgmac->core, BCMA_IOST) & BCMA_IOST_DMA64)) {
498 + bgmac_err(bgmac, "Core does not report 64-bit DMA\n");
499 + return -ENOTSUPP;
500 + }
501 +
502 + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
503 + ring = &bgmac->tx_ring[i];
504 + ring->num_slots = BGMAC_TX_RING_SLOTS;
505 + ring->mmio_base = ring_base[i];
506 + if (bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_TX))
507 + bgmac_warn(bgmac, "TX on ring 0x%X supports unaligned addressing but this feature is not implemented\n",
508 + ring->mmio_base);
509 +
510 + /* Alloc ring of descriptors */
511 + size = ring->num_slots * sizeof(struct bgmac_dma_desc);
512 + ring->cpu_base = dma_zalloc_coherent(dma_dev, size,
513 + &ring->dma_base,
514 + GFP_KERNEL);
515 + if (!ring->cpu_base) {
516 + bgmac_err(bgmac, "Allocation of TX ring 0x%X failed\n",
517 + ring->mmio_base);
518 + goto err_dma_free;
519 + }
520 + if (ring->dma_base & 0xC0000000)
521 + bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
522 +
523 + /* No need to alloc TX slots yet */
524 + }
525 +
526 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
527 + ring = &bgmac->rx_ring[i];
528 + ring->num_slots = BGMAC_RX_RING_SLOTS;
529 + ring->mmio_base = ring_base[i];
530 + if (bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_RX))
531 + bgmac_warn(bgmac, "RX on ring 0x%X supports unaligned addressing but this feature is not implemented\n",
532 + ring->mmio_base);
533 +
534 + /* Alloc ring of descriptors */
535 + size = ring->num_slots * sizeof(struct bgmac_dma_desc);
536 + ring->cpu_base = dma_zalloc_coherent(dma_dev, size,
537 + &ring->dma_base,
538 + GFP_KERNEL);
539 + if (!ring->cpu_base) {
540 + bgmac_err(bgmac, "Allocation of RX ring 0x%X failed\n",
541 + ring->mmio_base);
542 + err = -ENOMEM;
543 + goto err_dma_free;
544 + }
545 + if (ring->dma_base & 0xC0000000)
546 + bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
547 +
548 + /* Alloc RX slots */
549 + for (i = 0; i < ring->num_slots; i++) {
550 + err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[i]);
551 + if (err) {
552 + bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n");
553 + goto err_dma_free;
554 + }
555 + }
556 + }
557 +
558 + return 0;
559 +
560 +err_dma_free:
561 + bgmac_dma_free(bgmac);
562 + return -ENOMEM;
563 +}
564 +
565 +static void bgmac_dma_init(struct bgmac *bgmac)
566 +{
567 + struct bgmac_dma_ring *ring;
568 + struct bgmac_dma_desc *dma_desc;
569 + u32 ctl0, ctl1;
570 + int i;
571 +
572 + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
573 + ring = &bgmac->tx_ring[i];
574 +
575 + /* We don't implement unaligned addressing, so enable first */
576 + bgmac_dma_tx_enable(bgmac, ring);
577 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
578 + lower_32_bits(ring->dma_base));
579 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGHI,
580 + upper_32_bits(ring->dma_base));
581 +
582 + ring->start = 0;
583 + ring->end = 0; /* Points the slot that should *not* be read */
584 + }
585 +
586 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
587 + ring = &bgmac->rx_ring[i];
588 +
589 + /* We don't implement unaligned addressing, so enable first */
590 + bgmac_dma_rx_enable(bgmac, ring);
591 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
592 + lower_32_bits(ring->dma_base));
593 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGHI,
594 + upper_32_bits(ring->dma_base));
595 +
596 + for (i = 0, dma_desc = ring->cpu_base; i < ring->num_slots;
597 + i++, dma_desc++) {
598 + ctl0 = ctl1 = 0;
599 +
600 + if (i == ring->num_slots - 1)
601 + ctl0 |= BGMAC_DESC_CTL0_EOT;
602 + ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN;
603 + /* Is there any BGMAC device that requires extension? */
604 + /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) &
605 + * B43_DMA64_DCTL1_ADDREXT_MASK;
606 + */
607 +
608 + dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[i].dma_addr));
609 + dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[i].dma_addr));
610 + dma_desc->ctl0 = cpu_to_le32(ctl0);
611 + dma_desc->ctl1 = cpu_to_le32(ctl1);
612 + }
613 +
614 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
615 + ring->num_slots * sizeof(struct bgmac_dma_desc));
616 +
617 + ring->start = 0;
618 + ring->end = 0;
619 + }
620 +}
621 +
622 +/**************************************************
623 + * PHY ops
624 + **************************************************/
625 +
626 +u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg)
627 +{
628 + struct bcma_device *core;
629 + u16 phy_access_addr;
630 + u16 phy_ctl_addr;
631 + u32 tmp;
632 +
633 + BUILD_BUG_ON(BGMAC_PA_DATA_MASK != BCMA_GMAC_CMN_PA_DATA_MASK);
634 + BUILD_BUG_ON(BGMAC_PA_ADDR_MASK != BCMA_GMAC_CMN_PA_ADDR_MASK);
635 + BUILD_BUG_ON(BGMAC_PA_ADDR_SHIFT != BCMA_GMAC_CMN_PA_ADDR_SHIFT);
636 + BUILD_BUG_ON(BGMAC_PA_REG_MASK != BCMA_GMAC_CMN_PA_REG_MASK);
637 + BUILD_BUG_ON(BGMAC_PA_REG_SHIFT != BCMA_GMAC_CMN_PA_REG_SHIFT);
638 + BUILD_BUG_ON(BGMAC_PA_WRITE != BCMA_GMAC_CMN_PA_WRITE);
639 + BUILD_BUG_ON(BGMAC_PA_START != BCMA_GMAC_CMN_PA_START);
640 + BUILD_BUG_ON(BGMAC_PC_EPA_MASK != BCMA_GMAC_CMN_PC_EPA_MASK);
641 + BUILD_BUG_ON(BGMAC_PC_MCT_MASK != BCMA_GMAC_CMN_PC_MCT_MASK);
642 + BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT);
643 + BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE);
644 +
645 + if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
646 + core = bgmac->core->bus->drv_gmac_cmn.core;
647 + phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
648 + phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
649 + } else {
650 + core = bgmac->core;
651 + phy_access_addr = BGMAC_PHY_ACCESS;
652 + phy_ctl_addr = BGMAC_PHY_CNTL;
653 + }
654 +
655 + tmp = bcma_read32(core, phy_ctl_addr);
656 + tmp &= ~BGMAC_PC_EPA_MASK;
657 + tmp |= phyaddr;
658 + bcma_write32(core, phy_ctl_addr, tmp);
659 +
660 + tmp = BGMAC_PA_START;
661 + tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
662 + tmp |= reg << BGMAC_PA_REG_SHIFT;
663 + bcma_write32(core, phy_access_addr, tmp);
664 +
665 + if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) {
666 + bgmac_err(bgmac, "Reading PHY %d register 0x%X failed\n",
667 + phyaddr, reg);
668 + return 0xffff;
669 + }
670 +
671 + return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK;
672 +}
673 +
674 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */
675 +void bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value)
676 +{
677 + struct bcma_device *core;
678 + u16 phy_access_addr;
679 + u16 phy_ctl_addr;
680 + u32 tmp;
681 +
682 + if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
683 + core = bgmac->core->bus->drv_gmac_cmn.core;
684 + phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
685 + phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
686 + } else {
687 + core = bgmac->core;
688 + phy_access_addr = BGMAC_PHY_ACCESS;
689 + phy_ctl_addr = BGMAC_PHY_CNTL;
690 + }
691 +
692 + tmp = bcma_read32(core, phy_ctl_addr);
693 + tmp &= ~BGMAC_PC_EPA_MASK;
694 + tmp |= phyaddr;
695 + bcma_write32(core, phy_ctl_addr, tmp);
696 +
697 + bgmac_write(bgmac, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
698 + if (bgmac_read(bgmac, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
699 + bgmac_warn(bgmac, "Error setting MDIO int\n");
700 +
701 + tmp = BGMAC_PA_START;
702 + tmp |= BGMAC_PA_WRITE;
703 + tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
704 + tmp |= reg << BGMAC_PA_REG_SHIFT;
705 + tmp |= value;
706 + bcma_write32(core, phy_access_addr, tmp);
707 +
708 + if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000))
709 + bgmac_err(bgmac, "Writing to PHY %d register 0x%X failed\n",
710 + phyaddr, reg);
711 +}
712 +
713 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyforce */
714 +static void bgmac_phy_force(struct bgmac *bgmac)
715 +{
716 + u16 ctl;
717 + u16 mask = ~(BGMAC_PHY_CTL_SPEED | BGMAC_PHY_CTL_SPEED_MSB |
718 + BGMAC_PHY_CTL_ANENAB | BGMAC_PHY_CTL_DUPLEX);
719 +
720 + if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
721 + return;
722 +
723 + if (bgmac->autoneg)
724 + return;
725 +
726 + ctl = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL);
727 + ctl &= mask;
728 + if (bgmac->full_duplex)
729 + ctl |= BGMAC_PHY_CTL_DUPLEX;
730 + if (bgmac->speed == BGMAC_SPEED_100)
731 + ctl |= BGMAC_PHY_CTL_SPEED_100;
732 + else if (bgmac->speed == BGMAC_SPEED_1000)
733 + ctl |= BGMAC_PHY_CTL_SPEED_1000;
734 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL, ctl);
735 +}
736 +
737 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyadvertise */
738 +static void bgmac_phy_advertise(struct bgmac *bgmac)
739 +{
740 + u16 adv;
741 +
742 + if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
743 + return;
744 +
745 + if (!bgmac->autoneg)
746 + return;
747 +
748 + /* Adv selected 10/100 speeds */
749 + adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV);
750 + adv &= ~(BGMAC_PHY_ADV_10HALF | BGMAC_PHY_ADV_10FULL |
751 + BGMAC_PHY_ADV_100HALF | BGMAC_PHY_ADV_100FULL);
752 + if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10)
753 + adv |= BGMAC_PHY_ADV_10HALF;
754 + if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100)
755 + adv |= BGMAC_PHY_ADV_100HALF;
756 + if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10)
757 + adv |= BGMAC_PHY_ADV_10FULL;
758 + if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100)
759 + adv |= BGMAC_PHY_ADV_100FULL;
760 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV, adv);
761 +
762 + /* Adv selected 1000 speeds */
763 + adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2);
764 + adv &= ~(BGMAC_PHY_ADV2_1000HALF | BGMAC_PHY_ADV2_1000FULL);
765 + if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000)
766 + adv |= BGMAC_PHY_ADV2_1000HALF;
767 + if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000)
768 + adv |= BGMAC_PHY_ADV2_1000FULL;
769 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2, adv);
770 +
771 + /* Restart */
772 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL,
773 + bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) |
774 + BGMAC_PHY_CTL_RESTART);
775 +}
776 +
777 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */
778 +static void bgmac_phy_init(struct bgmac *bgmac)
779 +{
780 + struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
781 + struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
782 + u8 i;
783 +
784 + if (ci->id == BCMA_CHIP_ID_BCM5356) {
785 + for (i = 0; i < 5; i++) {
786 + bgmac_phy_write(bgmac, i, 0x1f, 0x008b);
787 + bgmac_phy_write(bgmac, i, 0x15, 0x0100);
788 + bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
789 + bgmac_phy_write(bgmac, i, 0x12, 0x2aaa);
790 + bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
791 + }
792 + }
793 + if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) ||
794 + (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) ||
795 + (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) {
796 + bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0);
797 + bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0);
798 + for (i = 0; i < 5; i++) {
799 + bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
800 + bgmac_phy_write(bgmac, i, 0x16, 0x5284);
801 + bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
802 + bgmac_phy_write(bgmac, i, 0x17, 0x0010);
803 + bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
804 + bgmac_phy_write(bgmac, i, 0x16, 0x5296);
805 + bgmac_phy_write(bgmac, i, 0x17, 0x1073);
806 + bgmac_phy_write(bgmac, i, 0x17, 0x9073);
807 + bgmac_phy_write(bgmac, i, 0x16, 0x52b6);
808 + bgmac_phy_write(bgmac, i, 0x17, 0x9273);
809 + bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
810 + }
811 + }
812 +}
813 +
814 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */
815 +static void bgmac_phy_reset(struct bgmac *bgmac)
816 +{
817 + if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
818 + return;
819 +
820 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL,
821 + BGMAC_PHY_CTL_RESET);
822 + udelay(100);
823 + if (bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) &
824 + BGMAC_PHY_CTL_RESET)
825 + bgmac_err(bgmac, "PHY reset failed\n");
826 + bgmac_phy_init(bgmac);
827 +}
828 +
829 +/**************************************************
830 + * Chip ops
831 + **************************************************/
832 +
833 +/* TODO: can we just drop @force? Can we don't reset MAC at all if there is
834 + * nothing to change? Try if after stabilizng driver.
835 + */
836 +static void bgmac_cmdcfg_maskset(struct bgmac *bgmac, u32 mask, u32 set,
837 + bool force)
838 +{
839 + u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
840 + u32 new_val = (cmdcfg & mask) | set;
841 +
842 + bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR);
843 + udelay(2);
844 +
845 + if (new_val != cmdcfg || force)
846 + bgmac_write(bgmac, BGMAC_CMDCFG, new_val);
847 +
848 + bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR);
849 + udelay(2);
850 +}
851 +
852 +#if 0 /* We don't use that regs yet */
853 +static void bgmac_chip_stats_update(struct bgmac *bgmac)
854 +{
855 + int i;
856 +
857 + if (bgmac->core->id.id != BCMA_CORE_4706_MAC_GBIT) {
858 + for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++)
859 + bgmac->mib_tx_regs[i] =
860 + bgmac_read(bgmac,
861 + BGMAC_TX_GOOD_OCTETS + (i * 4));
862 + for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
863 + bgmac->mib_rx_regs[i] =
864 + bgmac_read(bgmac,
865 + BGMAC_RX_GOOD_OCTETS + (i * 4));
866 + }
867 +
868 + /* TODO: what else? how to handle BCM4706? Specs are needed */
869 +}
870 +#endif
871 +
872 +static void bgmac_clear_mib(struct bgmac *bgmac)
873 +{
874 + int i;
875 +
876 + if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT)
877 + return;
878 +
879 + bgmac_set(bgmac, BGMAC_DEV_CTL, BGMAC_DC_MROR);
880 + for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++)
881 + bgmac_read(bgmac, BGMAC_TX_GOOD_OCTETS + (i * 4));
882 + for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
883 + bgmac_read(bgmac, BGMAC_RX_GOOD_OCTETS + (i * 4));
884 +}
885 +
886 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_speed */
887 +static void bgmac_speed(struct bgmac *bgmac, int speed)
888 +{
889 + u32 mask = ~(BGMAC_CMDCFG_ES_MASK | BGMAC_CMDCFG_HD);
890 + u32 set = 0;
891 +
892 + if (speed & BGMAC_SPEED_10)
893 + set |= BGMAC_CMDCFG_ES_10;
894 + if (speed & BGMAC_SPEED_100)
895 + set |= BGMAC_CMDCFG_ES_100;
896 + if (speed & BGMAC_SPEED_1000)
897 + set |= BGMAC_CMDCFG_ES_1000;
898 + if (!bgmac->full_duplex)
899 + set |= BGMAC_CMDCFG_HD;
900 + bgmac_cmdcfg_maskset(bgmac, mask, set, true);
901 +}
902 +
903 +static void bgmac_miiconfig(struct bgmac *bgmac)
904 +{
905 + u8 imode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
906 + BGMAC_DS_MM_SHIFT;
907 + if (imode == 0 || imode == 1) {
908 + if (bgmac->autoneg)
909 + bgmac_speed(bgmac, BGMAC_SPEED_100);
910 + else
911 + bgmac_speed(bgmac, bgmac->speed);
912 + }
913 +}
914 +
915 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
916 +static void bgmac_chip_reset(struct bgmac *bgmac)
917 +{
918 + struct bcma_device *core = bgmac->core;
919 + struct bcma_bus *bus = core->bus;
920 + struct bcma_chipinfo *ci = &bus->chipinfo;
921 + u32 flags = 0;
922 + u32 iost;
923 + int i;
924 +
925 + if (bcma_core_is_enabled(core)) {
926 + if (!bgmac->stats_grabbed) {
927 + /* bgmac_chip_stats_update(bgmac); */
928 + bgmac->stats_grabbed = true;
929 + }
930 +
931 + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
932 + bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]);
933 +
934 + bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
935 + udelay(1);
936 +
937 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
938 + bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]);
939 +
940 + /* TODO: Clear software multicast filter list */
941 + }
942 +
943 + iost = bcma_aread32(core, BCMA_IOST);
944 + if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 10) ||
945 + (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg == 10) ||
946 + (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == 9))
947 + iost &= ~BGMAC_BCMA_IOST_ATTACHED;
948 +
949 + if (iost & BGMAC_BCMA_IOST_ATTACHED) {
950 + flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
951 + if (!bgmac->has_robosw)
952 + flags |= BGMAC_BCMA_IOCTL_SW_RESET;
953 + }
954 +
955 + bcma_core_enable(core, flags);
956 +
957 + if (core->id.rev > 2) {
958 + bgmac_set(bgmac, BCMA_CLKCTLST, 1 << 8);
959 + bgmac_wait_value(bgmac->core, BCMA_CLKCTLST, 1 << 24, 1 << 24,
960 + 1000);
961 + }
962 +
963 + if (ci->id == BCMA_CHIP_ID_BCM5357 || ci->id == BCMA_CHIP_ID_BCM4749 ||
964 + ci->id == BCMA_CHIP_ID_BCM53572) {
965 + struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
966 + u8 et_swtype = 0;
967 + u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
968 + BGMAC_CHIPCTL_1_IF_TYPE_RMII;
969 + char buf[2];
970 +
971 + if (bcm47xx_nvram_getenv("et_swtype", buf, 1) > 0) {
972 + if (kstrtou8(buf, 0, &et_swtype))
973 + bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n",
974 + buf);
975 + et_swtype &= 0x0f;
976 + et_swtype <<= 4;
977 + sw_type = et_swtype;
978 + } else if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 9) {
979 + sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII;
980 + } else if (0) {
981 + /* TODO */
982 + }
983 + bcma_chipco_chipctl_maskset(cc, 1,
984 + ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
985 + BGMAC_CHIPCTL_1_SW_TYPE_MASK),
986 + sw_type);
987 + }
988 +
989 + if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
990 + bcma_awrite32(core, BCMA_IOCTL,
991 + bcma_aread32(core, BCMA_IOCTL) &
992 + ~BGMAC_BCMA_IOCTL_SW_RESET);
993 +
994 + /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset
995 + * Specs don't say about using BGMAC_CMDCFG_SR, but in this routine
996 + * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
997 + * be keps until taking MAC out of the reset.
998 + */
999 + bgmac_cmdcfg_maskset(bgmac,
1000 + ~(BGMAC_CMDCFG_TE |
1001 + BGMAC_CMDCFG_RE |
1002 + BGMAC_CMDCFG_RPI |
1003 + BGMAC_CMDCFG_TAI |
1004 + BGMAC_CMDCFG_HD |
1005 + BGMAC_CMDCFG_ML |
1006 + BGMAC_CMDCFG_CFE |
1007 + BGMAC_CMDCFG_RL |
1008 + BGMAC_CMDCFG_RED |
1009 + BGMAC_CMDCFG_PE |
1010 + BGMAC_CMDCFG_TPI |
1011 + BGMAC_CMDCFG_PAD_EN |
1012 + BGMAC_CMDCFG_PF),
1013 + BGMAC_CMDCFG_PROM |
1014 + BGMAC_CMDCFG_NLC |
1015 + BGMAC_CMDCFG_CFE |
1016 + BGMAC_CMDCFG_SR,
1017 + false);
1018 +
1019 + bgmac_clear_mib(bgmac);
1020 + if (core->id.id == BCMA_CORE_4706_MAC_GBIT)
1021 + bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0,
1022 + BCMA_GMAC_CMN_PC_MTE);
1023 + else
1024 + bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
1025 + bgmac_miiconfig(bgmac);
1026 + bgmac_phy_init(bgmac);
1027 +
1028 + bgmac->int_status = 0;
1029 +}
1030 +
1031 +static void bgmac_chip_intrs_on(struct bgmac *bgmac)
1032 +{
1033 + bgmac_write(bgmac, BGMAC_INT_MASK, bgmac->int_mask);
1034 +}
1035 +
1036 +static void bgmac_chip_intrs_off(struct bgmac *bgmac)
1037 +{
1038 + bgmac_write(bgmac, BGMAC_INT_MASK, 0);
1039 +}
1040 +
1041 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_enable */
1042 +static void bgmac_enable(struct bgmac *bgmac)
1043 +{
1044 + struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
1045 + u32 cmdcfg;
1046 + u32 mode;
1047 + u32 rxq_ctl;
1048 + u32 fl_ctl;
1049 + u16 bp_clk;
1050 + u8 mdp;
1051 +
1052 + cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
1053 + bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE),
1054 + BGMAC_CMDCFG_SR, true);
1055 + udelay(2);
1056 + cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE;
1057 + bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg);
1058 +
1059 + mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
1060 + BGMAC_DS_MM_SHIFT;
1061 + if (ci->id != BCMA_CHIP_ID_BCM47162 || mode != 0)
1062 + bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
1063 + if (ci->id == BCMA_CHIP_ID_BCM47162 && mode == 2)
1064 + bcma_chipco_chipctl_maskset(&bgmac->core->bus->drv_cc, 1, ~0,
1065 + BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
1066 +
1067 + switch (ci->id) {
1068 + case BCMA_CHIP_ID_BCM5357:
1069 + case BCMA_CHIP_ID_BCM4749:
1070 + case BCMA_CHIP_ID_BCM53572:
1071 + case BCMA_CHIP_ID_BCM4716:
1072 + case BCMA_CHIP_ID_BCM47162:
1073 + fl_ctl = 0x03cb04cb;
1074 + if (ci->id == BCMA_CHIP_ID_BCM5357 ||
1075 + ci->id == BCMA_CHIP_ID_BCM4749 ||
1076 + ci->id == BCMA_CHIP_ID_BCM53572)
1077 + fl_ctl = 0x2300e1;
1078 + bgmac_write(bgmac, BGMAC_FLOW_CTL_THRESH, fl_ctl);
1079 + bgmac_write(bgmac, BGMAC_PAUSE_CTL, 0x27fff);
1080 + break;
1081 + }
1082 +
1083 + rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL);
1084 + rxq_ctl &= ~BGMAC_RXQ_CTL_MDP_MASK;
1085 + bp_clk = bcma_pmu_get_bus_clock(&bgmac->core->bus->drv_cc) / 1000000;
1086 + mdp = (bp_clk * 128 / 1000) - 3;
1087 + rxq_ctl |= (mdp << BGMAC_RXQ_CTL_MDP_SHIFT);
1088 + bgmac_write(bgmac, BGMAC_RXQ_CTL, rxq_ctl);
1089 +}
1090 +
1091 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
1092 +static void bgmac_chip_init(struct bgmac *bgmac, bool full_init)
1093 +{
1094 + struct bgmac_dma_ring *ring;
1095 + u8 *mac = bgmac->net_dev->dev_addr;
1096 + u32 tmp;
1097 + int i;
1098 +
1099 + /* 1 interrupt per received frame */
1100 + bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
1101 +
1102 + /* Enable 802.3x tx flow control (honor received PAUSE frames) */
1103 + bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true);
1104 +
1105 + if (bgmac->net_dev->flags & IFF_PROMISC)
1106 + bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, false);
1107 + else
1108 + bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_PROM, 0, false);
1109 +
1110 + /* Set MAC addr */
1111 + tmp = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3];
1112 + bgmac_write(bgmac, BGMAC_MACADDR_HIGH, tmp);
1113 + tmp = (mac[4] << 8) | mac[5];
1114 + bgmac_write(bgmac, BGMAC_MACADDR_LOW, tmp);
1115 +
1116 + if (bgmac->loopback)
1117 + bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, true);
1118 + else
1119 + bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, true);
1120 +
1121 + bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
1122 +
1123 + if (!bgmac->autoneg) {
1124 + bgmac_speed(bgmac, bgmac->speed);
1125 + bgmac_phy_force(bgmac);
1126 + } else if (bgmac->speed) { /* if there is anything to adv */
1127 + bgmac_phy_advertise(bgmac);
1128 + }
1129 +
1130 + if (full_init) {
1131 + bgmac_dma_init(bgmac);
1132 + if (1) /* FIXME: is there any case we don't want IRQs? */
1133 + bgmac_chip_intrs_on(bgmac);
1134 + } else {
1135 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
1136 + ring = &bgmac->rx_ring[i];
1137 + bgmac_dma_rx_enable(bgmac, ring);
1138 + }
1139 + }
1140 +
1141 + bgmac_enable(bgmac);
1142 +}
1143 +
1144 +static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
1145 +{
1146 + struct bgmac *bgmac = netdev_priv(dev_id);
1147 +
1148 + u32 int_status = bgmac_read(bgmac, BGMAC_INT_STATUS);
1149 + int_status &= bgmac->int_mask;
1150 +
1151 + if (!int_status)
1152 + return IRQ_NONE;
1153 +
1154 + /* Ack */
1155 + bgmac_write(bgmac, BGMAC_INT_STATUS, int_status);
1156 +
1157 + /* Disable new interrupts until handling existing ones */
1158 + bgmac_chip_intrs_off(bgmac);
1159 +
1160 + bgmac->int_status = int_status;
1161 +
1162 + napi_schedule(&bgmac->napi);
1163 +
1164 + return IRQ_HANDLED;
1165 +}
1166 +
1167 +static int bgmac_poll(struct napi_struct *napi, int weight)
1168 +{
1169 + struct bgmac *bgmac = container_of(napi, struct bgmac, napi);
1170 + struct bgmac_dma_ring *ring;
1171 + int handled = 0;
1172 +
1173 + if (bgmac->int_status & BGMAC_IS_TX0) {
1174 + ring = &bgmac->tx_ring[0];
1175 + bgmac_dma_tx_free(bgmac, ring);
1176 + bgmac->int_status &= ~BGMAC_IS_TX0;
1177 + }
1178 +
1179 + if (bgmac->int_status & BGMAC_IS_RX) {
1180 + ring = &bgmac->rx_ring[0];
1181 + handled += bgmac_dma_rx_read(bgmac, ring, weight);
1182 + bgmac->int_status &= ~BGMAC_IS_RX;
1183 + }
1184 +
1185 + if (bgmac->int_status) {
1186 + bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status);
1187 + bgmac->int_status = 0;
1188 + }
1189 +
1190 + if (handled < weight)
1191 + napi_complete(napi);
1192 +
1193 + bgmac_chip_intrs_on(bgmac);
1194 +
1195 + return handled;
1196 +}
1197 +
1198 +/**************************************************
1199 + * net_device_ops
1200 + **************************************************/
1201 +
1202 +static int bgmac_open(struct net_device *net_dev)
1203 +{
1204 + struct bgmac *bgmac = netdev_priv(net_dev);
1205 + int err = 0;
1206 +
1207 + bgmac_chip_reset(bgmac);
1208 + /* Specs say about reclaiming rings here, but we do that in DMA init */
1209 + bgmac_chip_init(bgmac, true);
1210 +
1211 + err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED,
1212 + KBUILD_MODNAME, net_dev);
1213 + if (err < 0) {
1214 + bgmac_err(bgmac, "IRQ request error: %d!\n", err);
1215 + goto err_out;
1216 + }
1217 + napi_enable(&bgmac->napi);
1218 +
1219 + netif_carrier_on(net_dev);
1220 +
1221 +err_out:
1222 + return err;
1223 +}
1224 +
1225 +static int bgmac_stop(struct net_device *net_dev)
1226 +{
1227 + struct bgmac *bgmac = netdev_priv(net_dev);
1228 +
1229 + netif_carrier_off(net_dev);
1230 +
1231 + napi_disable(&bgmac->napi);
1232 + bgmac_chip_intrs_off(bgmac);
1233 + free_irq(bgmac->core->irq, net_dev);
1234 +
1235 + bgmac_chip_reset(bgmac);
1236 +
1237 + return 0;
1238 +}
1239 +
1240 +static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb,
1241 + struct net_device *net_dev)
1242 +{
1243 + struct bgmac *bgmac = netdev_priv(net_dev);
1244 + struct bgmac_dma_ring *ring;
1245 +
1246 + /* No QOS support yet */
1247 + ring = &bgmac->tx_ring[0];
1248 + return bgmac_dma_tx_add(bgmac, ring, skb);
1249 +}
1250 +
1251 +static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
1252 +{
1253 + struct bgmac *bgmac = netdev_priv(net_dev);
1254 + struct mii_ioctl_data *data = if_mii(ifr);
1255 +
1256 + switch (cmd) {
1257 + case SIOCGMIIPHY:
1258 + data->phy_id = bgmac->phyaddr;
1259 + /* fallthru */
1260 + case SIOCGMIIREG:
1261 + if (!netif_running(net_dev))
1262 + return -EAGAIN;
1263 + data->val_out = bgmac_phy_read(bgmac, data->phy_id,
1264 + data->reg_num & 0x1f);
1265 + return 0;
1266 + case SIOCSMIIREG:
1267 + if (!netif_running(net_dev))
1268 + return -EAGAIN;
1269 + bgmac_phy_write(bgmac, data->phy_id, data->reg_num & 0x1f,
1270 + data->val_in);
1271 + return 0;
1272 + default:
1273 + return -EOPNOTSUPP;
1274 + }
1275 +}
1276 +
1277 +static const struct net_device_ops bgmac_netdev_ops = {
1278 + .ndo_open = bgmac_open,
1279 + .ndo_stop = bgmac_stop,
1280 + .ndo_start_xmit = bgmac_start_xmit,
1281 + .ndo_set_mac_address = eth_mac_addr, /* generic, sets dev_addr */
1282 + .ndo_do_ioctl = bgmac_ioctl,
1283 +};
1284 +
1285 +/**************************************************
1286 + * ethtool_ops
1287 + **************************************************/
1288 +
1289 +static int bgmac_get_settings(struct net_device *net_dev,
1290 + struct ethtool_cmd *cmd)
1291 +{
1292 + struct bgmac *bgmac = netdev_priv(net_dev);
1293 +
1294 + cmd->supported = SUPPORTED_10baseT_Half |
1295 + SUPPORTED_10baseT_Full |
1296 + SUPPORTED_100baseT_Half |
1297 + SUPPORTED_100baseT_Full |
1298 + SUPPORTED_1000baseT_Half |
1299 + SUPPORTED_1000baseT_Full |
1300 + SUPPORTED_Autoneg;
1301 +
1302 + if (bgmac->autoneg) {
1303 + WARN_ON(cmd->advertising);
1304 + if (bgmac->full_duplex) {
1305 + if (bgmac->speed & BGMAC_SPEED_10)
1306 + cmd->advertising |= ADVERTISED_10baseT_Full;
1307 + if (bgmac->speed & BGMAC_SPEED_100)
1308 + cmd->advertising |= ADVERTISED_100baseT_Full;
1309 + if (bgmac->speed & BGMAC_SPEED_1000)
1310 + cmd->advertising |= ADVERTISED_1000baseT_Full;
1311 + } else {
1312 + if (bgmac->speed & BGMAC_SPEED_10)
1313 + cmd->advertising |= ADVERTISED_10baseT_Half;
1314 + if (bgmac->speed & BGMAC_SPEED_100)
1315 + cmd->advertising |= ADVERTISED_100baseT_Half;
1316 + if (bgmac->speed & BGMAC_SPEED_1000)
1317 + cmd->advertising |= ADVERTISED_1000baseT_Half;
1318 + }
1319 + } else {
1320 + switch (bgmac->speed) {
1321 + case BGMAC_SPEED_10:
1322 + ethtool_cmd_speed_set(cmd, SPEED_10);
1323 + break;
1324 + case BGMAC_SPEED_100:
1325 + ethtool_cmd_speed_set(cmd, SPEED_100);
1326 + break;
1327 + case BGMAC_SPEED_1000:
1328 + ethtool_cmd_speed_set(cmd, SPEED_1000);
1329 + break;
1330 + }
1331 + }
1332 +
1333 + cmd->duplex = bgmac->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1334 +
1335 + cmd->autoneg = bgmac->autoneg;
1336 +
1337 + return 0;
1338 +}
1339 +
1340 +#if 0
1341 +static int bgmac_set_settings(struct net_device *net_dev,
1342 + struct ethtool_cmd *cmd)
1343 +{
1344 + struct bgmac *bgmac = netdev_priv(net_dev);
1345 +
1346 + return -1;
1347 +}
1348 +#endif
1349 +
1350 +static void bgmac_get_drvinfo(struct net_device *net_dev,
1351 + struct ethtool_drvinfo *info)
1352 +{
1353 + strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
1354 + strlcpy(info->bus_info, "BCMA", sizeof(info->bus_info));
1355 +}
1356 +
1357 +static const struct ethtool_ops bgmac_ethtool_ops = {
1358 + .get_settings = bgmac_get_settings,
1359 + .get_drvinfo = bgmac_get_drvinfo,
1360 +};
1361 +
1362 +/**************************************************
1363 + * BCMA bus ops
1364 + **************************************************/
1365 +
1366 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
1367 +static int bgmac_probe(struct bcma_device *core)
1368 +{
1369 + struct net_device *net_dev;
1370 + struct bgmac *bgmac;
1371 + struct ssb_sprom *sprom = &core->bus->sprom;
1372 + u8 *mac = core->core_unit ? sprom->et1mac : sprom->et0mac;
1373 + int err;
1374 +
1375 + /* We don't support 2nd, 3rd, ... units, SPROM has to be adjusted */
1376 + if (core->core_unit > 1) {
1377 + pr_err("Unsupported core_unit %d\n", core->core_unit);
1378 + return -ENOTSUPP;
1379 + }
1380 +
1381 + /* Allocation and references */
1382 + net_dev = alloc_etherdev(sizeof(*bgmac));
1383 + if (!net_dev)
1384 + return -ENOMEM;
1385 + net_dev->netdev_ops = &bgmac_netdev_ops;
1386 + net_dev->irq = core->irq;
1387 + SET_ETHTOOL_OPS(net_dev, &bgmac_ethtool_ops);
1388 + bgmac = netdev_priv(net_dev);
1389 + bgmac->net_dev = net_dev;
1390 + bgmac->core = core;
1391 + bcma_set_drvdata(core, bgmac);
1392 +
1393 + /* Defaults */
1394 + bgmac->autoneg = true;
1395 + bgmac->full_duplex = true;
1396 + bgmac->speed = BGMAC_SPEED_10 | BGMAC_SPEED_100 | BGMAC_SPEED_1000;
1397 + memcpy(bgmac->net_dev->dev_addr, mac, ETH_ALEN);
1398 +
1399 + /* On BCM4706 we need common core to access PHY */
1400 + if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
1401 + !core->bus->drv_gmac_cmn.core) {
1402 + bgmac_err(bgmac, "GMAC CMN core not found (required for BCM4706)\n");
1403 + err = -ENODEV;
1404 + goto err_netdev_free;
1405 + }
1406 + bgmac->cmn = core->bus->drv_gmac_cmn.core;
1407 +
1408 + bgmac->phyaddr = core->core_unit ? sprom->et1phyaddr :
1409 + sprom->et0phyaddr;
1410 + bgmac->phyaddr &= BGMAC_PHY_MASK;
1411 + if (bgmac->phyaddr == BGMAC_PHY_MASK) {
1412 + bgmac_err(bgmac, "No PHY found\n");
1413 + err = -ENODEV;
1414 + goto err_netdev_free;
1415 + }
1416 + bgmac_info(bgmac, "Found PHY addr: %d%s\n", bgmac->phyaddr,
1417 + bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : "");
1418 +
1419 + if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
1420 + bgmac_err(bgmac, "PCI setup not implemented\n");
1421 + err = -ENOTSUPP;
1422 + goto err_netdev_free;
1423 + }
1424 +
1425 + bgmac_chip_reset(bgmac);
1426 +
1427 + err = bgmac_dma_alloc(bgmac);
1428 + if (err) {
1429 + bgmac_err(bgmac, "Unable to alloc memory for DMA\n");
1430 + goto err_netdev_free;
1431 + }
1432 +
1433 + bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK;
1434 + if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0)
1435 + bgmac->int_mask &= ~BGMAC_IS_TX_MASK;
1436 +
1437 + /* TODO: reset the external phy. Specs are needed */
1438 + bgmac_phy_reset(bgmac);
1439 +
1440 + bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo &
1441 + BGMAC_BFL_ENETROBO);
1442 + if (bgmac->has_robosw)
1443 + bgmac_warn(bgmac, "Support for Roboswitch not implemented\n");
1444 +
1445 + if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM)
1446 + bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n");
1447 +
1448 + err = register_netdev(bgmac->net_dev);
1449 + if (err) {
1450 + bgmac_err(bgmac, "Cannot register net device\n");
1451 + err = -ENOTSUPP;
1452 + goto err_dma_free;
1453 + }
1454 +
1455 + netif_carrier_off(net_dev);
1456 +
1457 + netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT);
1458 +
1459 + return 0;
1460 +
1461 +err_dma_free:
1462 + bgmac_dma_free(bgmac);
1463 +
1464 +err_netdev_free:
1465 + bcma_set_drvdata(core, NULL);
1466 + free_netdev(net_dev);
1467 +
1468 + return err;
1469 +}
1470 +
1471 +static void bgmac_remove(struct bcma_device *core)
1472 +{
1473 + struct bgmac *bgmac = bcma_get_drvdata(core);
1474 +
1475 + netif_napi_del(&bgmac->napi);
1476 + unregister_netdev(bgmac->net_dev);
1477 + bgmac_dma_free(bgmac);
1478 + bcma_set_drvdata(core, NULL);
1479 + free_netdev(bgmac->net_dev);
1480 +}
1481 +
1482 +static struct bcma_driver bgmac_bcma_driver = {
1483 + .name = KBUILD_MODNAME,
1484 + .id_table = bgmac_bcma_tbl,
1485 + .probe = bgmac_probe,
1486 + .remove = bgmac_remove,
1487 +};
1488 +
1489 +static int __init bgmac_init(void)
1490 +{
1491 + int err;
1492 +
1493 + err = bcma_driver_register(&bgmac_bcma_driver);
1494 + if (err)
1495 + return err;
1496 + pr_info("Broadcom 47xx GBit MAC driver loaded\n");
1497 +
1498 + return 0;
1499 +}
1500 +
1501 +static void __exit bgmac_exit(void)
1502 +{
1503 + bcma_driver_unregister(&bgmac_bcma_driver);
1504 +}
1505 +
1506 +module_init(bgmac_init)
1507 +module_exit(bgmac_exit)
1508 +
1509 +MODULE_AUTHOR("Rafał Miłecki");
1510 +MODULE_LICENSE("GPL");
1511 --- /dev/null
1512 +++ b/drivers/net/ethernet/broadcom/bgmac.h
1513 @@ -0,0 +1,456 @@
1514 +#ifndef _BGMAC_H
1515 +#define _BGMAC_H
1516 +
1517 +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1518 +
1519 +#define bgmac_err(bgmac, fmt, ...) \
1520 + dev_err(&(bgmac)->core->dev, fmt, ##__VA_ARGS__)
1521 +#define bgmac_warn(bgmac, fmt, ...) \
1522 + dev_warn(&(bgmac)->core->dev, fmt, ##__VA_ARGS__)
1523 +#define bgmac_info(bgmac, fmt, ...) \
1524 + dev_info(&(bgmac)->core->dev, fmt, ##__VA_ARGS__)
1525 +#define bgmac_dbg(bgmac, fmt, ...) \
1526 + dev_dbg(&(bgmac)->core->dev, fmt, ##__VA_ARGS__)
1527 +
1528 +#include <linux/bcma/bcma.h>
1529 +#include <linux/netdevice.h>
1530 +
1531 +#define BGMAC_DEV_CTL 0x000
1532 +#define BGMAC_DC_TSM 0x00000002
1533 +#define BGMAC_DC_CFCO 0x00000004
1534 +#define BGMAC_DC_RLSS 0x00000008
1535 +#define BGMAC_DC_MROR 0x00000010
1536 +#define BGMAC_DC_FCM_MASK 0x00000060
1537 +#define BGMAC_DC_FCM_SHIFT 5
1538 +#define BGMAC_DC_NAE 0x00000080
1539 +#define BGMAC_DC_TF 0x00000100
1540 +#define BGMAC_DC_RDS_MASK 0x00030000
1541 +#define BGMAC_DC_RDS_SHIFT 16
1542 +#define BGMAC_DC_TDS_MASK 0x000c0000
1543 +#define BGMAC_DC_TDS_SHIFT 18
1544 +#define BGMAC_DEV_STATUS 0x004 /* Configuration of the interface */
1545 +#define BGMAC_DS_RBF 0x00000001
1546 +#define BGMAC_DS_RDF 0x00000002
1547 +#define BGMAC_DS_RIF 0x00000004
1548 +#define BGMAC_DS_TBF 0x00000008
1549 +#define BGMAC_DS_TDF 0x00000010
1550 +#define BGMAC_DS_TIF 0x00000020
1551 +#define BGMAC_DS_PO 0x00000040
1552 +#define BGMAC_DS_MM_MASK 0x00000300 /* Mode of the interface */
1553 +#define BGMAC_DS_MM_SHIFT 8
1554 +#define BGMAC_BIST_STATUS 0x00c
1555 +#define BGMAC_INT_STATUS 0x020 /* Interrupt status */
1556 +#define BGMAC_IS_MRO 0x00000001
1557 +#define BGMAC_IS_MTO 0x00000002
1558 +#define BGMAC_IS_TFD 0x00000004
1559 +#define BGMAC_IS_LS 0x00000008
1560 +#define BGMAC_IS_MDIO 0x00000010
1561 +#define BGMAC_IS_MR 0x00000020
1562 +#define BGMAC_IS_MT 0x00000040
1563 +#define BGMAC_IS_TO 0x00000080
1564 +#define BGMAC_IS_DESC_ERR 0x00000400 /* Descriptor error */
1565 +#define BGMAC_IS_DATA_ERR 0x00000800 /* Data error */
1566 +#define BGMAC_IS_DESC_PROT_ERR 0x00001000 /* Descriptor protocol error */
1567 +#define BGMAC_IS_RX_DESC_UNDERF 0x00002000 /* Receive descriptor underflow */
1568 +#define BGMAC_IS_RX_F_OVERF 0x00004000 /* Receive FIFO overflow */
1569 +#define BGMAC_IS_TX_F_UNDERF 0x00008000 /* Transmit FIFO underflow */
1570 +#define BGMAC_IS_RX 0x00010000 /* Interrupt for RX queue 0 */
1571 +#define BGMAC_IS_TX0 0x01000000 /* Interrupt for TX queue 0 */
1572 +#define BGMAC_IS_TX1 0x02000000 /* Interrupt for TX queue 1 */
1573 +#define BGMAC_IS_TX2 0x04000000 /* Interrupt for TX queue 2 */
1574 +#define BGMAC_IS_TX3 0x08000000 /* Interrupt for TX queue 3 */
1575 +#define BGMAC_IS_TX_MASK 0x0f000000
1576 +#define BGMAC_IS_INTMASK 0x0f01fcff
1577 +#define BGMAC_IS_ERRMASK 0x0000fc00
1578 +#define BGMAC_INT_MASK 0x024 /* Interrupt mask */
1579 +#define BGMAC_GP_TIMER 0x028
1580 +#define BGMAC_INT_RECV_LAZY 0x100
1581 +#define BGMAC_IRL_TO_MASK 0x00ffffff
1582 +#define BGMAC_IRL_FC_MASK 0xff000000
1583 +#define BGMAC_IRL_FC_SHIFT 24 /* Shift the number of interrupts triggered per received frame */
1584 +#define BGMAC_FLOW_CTL_THRESH 0x104 /* Flow control thresholds */
1585 +#define BGMAC_WRRTHRESH 0x108
1586 +#define BGMAC_GMAC_IDLE_CNT_THRESH 0x10c
1587 +#define BGMAC_PHY_ACCESS 0x180 /* PHY access address */
1588 +#define BGMAC_PA_DATA_MASK 0x0000ffff
1589 +#define BGMAC_PA_ADDR_MASK 0x001f0000
1590 +#define BGMAC_PA_ADDR_SHIFT 16
1591 +#define BGMAC_PA_REG_MASK 0x1f000000
1592 +#define BGMAC_PA_REG_SHIFT 24
1593 +#define BGMAC_PA_WRITE 0x20000000
1594 +#define BGMAC_PA_START 0x40000000
1595 +#define BGMAC_PHY_CNTL 0x188 /* PHY control address */
1596 +#define BGMAC_PC_EPA_MASK 0x0000001f
1597 +#define BGMAC_PC_MCT_MASK 0x007f0000
1598 +#define BGMAC_PC_MCT_SHIFT 16
1599 +#define BGMAC_PC_MTE 0x00800000
1600 +#define BGMAC_TXQ_CTL 0x18c
1601 +#define BGMAC_TXQ_CTL_DBT_MASK 0x00000fff
1602 +#define BGMAC_TXQ_CTL_DBT_SHIFT 0
1603 +#define BGMAC_RXQ_CTL 0x190
1604 +#define BGMAC_RXQ_CTL_DBT_MASK 0x00000fff
1605 +#define BGMAC_RXQ_CTL_DBT_SHIFT 0
1606 +#define BGMAC_RXQ_CTL_PTE 0x00001000
1607 +#define BGMAC_RXQ_CTL_MDP_MASK 0x3f000000
1608 +#define BGMAC_RXQ_CTL_MDP_SHIFT 24
1609 +#define BGMAC_GPIO_SELECT 0x194
1610 +#define BGMAC_GPIO_OUTPUT_EN 0x198
1611 +/* For 0x1e0 see BCMA_CLKCTLST */
1612 +#define BGMAC_HW_WAR 0x1e4
1613 +#define BGMAC_PWR_CTL 0x1e8
1614 +#define BGMAC_DMA_BASE0 0x200 /* Tx and Rx controller */
1615 +#define BGMAC_DMA_BASE1 0x240 /* Tx controller only */
1616 +#define BGMAC_DMA_BASE2 0x280 /* Tx controller only */
1617 +#define BGMAC_DMA_BASE3 0x2C0 /* Tx controller only */
1618 +#define BGMAC_TX_GOOD_OCTETS 0x300
1619 +#define BGMAC_TX_GOOD_OCTETS_HIGH 0x304
1620 +#define BGMAC_TX_GOOD_PKTS 0x308
1621 +#define BGMAC_TX_OCTETS 0x30c
1622 +#define BGMAC_TX_OCTETS_HIGH 0x310
1623 +#define BGMAC_TX_PKTS 0x314
1624 +#define BGMAC_TX_BROADCAST_PKTS 0x318
1625 +#define BGMAC_TX_MULTICAST_PKTS 0x31c
1626 +#define BGMAC_TX_LEN_64 0x320
1627 +#define BGMAC_TX_LEN_65_TO_127 0x324
1628 +#define BGMAC_TX_LEN_128_TO_255 0x328
1629 +#define BGMAC_TX_LEN_256_TO_511 0x32c
1630 +#define BGMAC_TX_LEN_512_TO_1023 0x330
1631 +#define BGMAC_TX_LEN_1024_TO_1522 0x334
1632 +#define BGMAC_TX_LEN_1523_TO_2047 0x338
1633 +#define BGMAC_TX_LEN_2048_TO_4095 0x33c
1634 +#define BGMAC_TX_LEN_4095_TO_8191 0x340
1635 +#define BGMAC_TX_LEN_8192_TO_MAX 0x344
1636 +#define BGMAC_TX_JABBER_PKTS 0x348 /* Error */
1637 +#define BGMAC_TX_OVERSIZE_PKTS 0x34c /* Error */
1638 +#define BGMAC_TX_FRAGMENT_PKTS 0x350
1639 +#define BGMAC_TX_UNDERRUNS 0x354 /* Error */
1640 +#define BGMAC_TX_TOTAL_COLS 0x358
1641 +#define BGMAC_TX_SINGLE_COLS 0x35c
1642 +#define BGMAC_TX_MULTIPLE_COLS 0x360
1643 +#define BGMAC_TX_EXCESSIVE_COLS 0x364 /* Error */
1644 +#define BGMAC_TX_LATE_COLS 0x368 /* Error */
1645 +#define BGMAC_TX_DEFERED 0x36c
1646 +#define BGMAC_TX_CARRIER_LOST 0x370
1647 +#define BGMAC_TX_PAUSE_PKTS 0x374
1648 +#define BGMAC_TX_UNI_PKTS 0x378
1649 +#define BGMAC_TX_Q0_PKTS 0x37c
1650 +#define BGMAC_TX_Q0_OCTETS 0x380
1651 +#define BGMAC_TX_Q0_OCTETS_HIGH 0x384
1652 +#define BGMAC_TX_Q1_PKTS 0x388
1653 +#define BGMAC_TX_Q1_OCTETS 0x38c
1654 +#define BGMAC_TX_Q1_OCTETS_HIGH 0x390
1655 +#define BGMAC_TX_Q2_PKTS 0x394
1656 +#define BGMAC_TX_Q2_OCTETS 0x398
1657 +#define BGMAC_TX_Q2_OCTETS_HIGH 0x39c
1658 +#define BGMAC_TX_Q3_PKTS 0x3a0
1659 +#define BGMAC_TX_Q3_OCTETS 0x3a4
1660 +#define BGMAC_TX_Q3_OCTETS_HIGH 0x3a8
1661 +#define BGMAC_RX_GOOD_OCTETS 0x3b0
1662 +#define BGMAC_RX_GOOD_OCTETS_HIGH 0x3b4
1663 +#define BGMAC_RX_GOOD_PKTS 0x3b8
1664 +#define BGMAC_RX_OCTETS 0x3bc
1665 +#define BGMAC_RX_OCTETS_HIGH 0x3c0
1666 +#define BGMAC_RX_PKTS 0x3c4
1667 +#define BGMAC_RX_BROADCAST_PKTS 0x3c8
1668 +#define BGMAC_RX_MULTICAST_PKTS 0x3cc
1669 +#define BGMAC_RX_LEN_64 0x3d0
1670 +#define BGMAC_RX_LEN_65_TO_127 0x3d4
1671 +#define BGMAC_RX_LEN_128_TO_255 0x3d8
1672 +#define BGMAC_RX_LEN_256_TO_511 0x3dc
1673 +#define BGMAC_RX_LEN_512_TO_1023 0x3e0
1674 +#define BGMAC_RX_LEN_1024_TO_1522 0x3e4
1675 +#define BGMAC_RX_LEN_1523_TO_2047 0x3e8
1676 +#define BGMAC_RX_LEN_2048_TO_4095 0x3ec
1677 +#define BGMAC_RX_LEN_4095_TO_8191 0x3f0
1678 +#define BGMAC_RX_LEN_8192_TO_MAX 0x3f4
1679 +#define BGMAC_RX_JABBER_PKTS 0x3f8 /* Error */
1680 +#define BGMAC_RX_OVERSIZE_PKTS 0x3fc /* Error */
1681 +#define BGMAC_RX_FRAGMENT_PKTS 0x400
1682 +#define BGMAC_RX_MISSED_PKTS 0x404 /* Error */
1683 +#define BGMAC_RX_CRC_ALIGN_ERRS 0x408 /* Error */
1684 +#define BGMAC_RX_UNDERSIZE 0x40c /* Error */
1685 +#define BGMAC_RX_CRC_ERRS 0x410 /* Error */
1686 +#define BGMAC_RX_ALIGN_ERRS 0x414 /* Error */
1687 +#define BGMAC_RX_SYMBOL_ERRS 0x418 /* Error */
1688 +#define BGMAC_RX_PAUSE_PKTS 0x41c
1689 +#define BGMAC_RX_NONPAUSE_PKTS 0x420
1690 +#define BGMAC_RX_SACHANGES 0x424
1691 +#define BGMAC_RX_UNI_PKTS 0x428
1692 +#define BGMAC_UNIMAC_VERSION 0x800
1693 +#define BGMAC_HDBKP_CTL 0x804
1694 +#define BGMAC_CMDCFG 0x808 /* Configuration */
1695 +#define BGMAC_CMDCFG_TE 0x00000001 /* Set to activate TX */
1696 +#define BGMAC_CMDCFG_RE 0x00000002 /* Set to activate RX */
1697 +#define BGMAC_CMDCFG_ES_MASK 0x0000000c /* Ethernet speed see gmac_speed */
1698 +#define BGMAC_CMDCFG_ES_10 0x00000000
1699 +#define BGMAC_CMDCFG_ES_100 0x00000004
1700 +#define BGMAC_CMDCFG_ES_1000 0x00000008
1701 +#define BGMAC_CMDCFG_PROM 0x00000010 /* Set to activate promiscuous mode */
1702 +#define BGMAC_CMDCFG_PAD_EN 0x00000020
1703 +#define BGMAC_CMDCFG_CF 0x00000040
1704 +#define BGMAC_CMDCFG_PF 0x00000080
1705 +#define BGMAC_CMDCFG_RPI 0x00000100 /* Unset to enable 802.3x tx flow control */
1706 +#define BGMAC_CMDCFG_TAI 0x00000200
1707 +#define BGMAC_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */
1708 +#define BGMAC_CMDCFG_HD_SHIFT 10
1709 +#define BGMAC_CMDCFG_SR 0x00000800 /* Set to reset mode */
1710 +#define BGMAC_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */
1711 +#define BGMAC_CMDCFG_AE 0x00400000
1712 +#define BGMAC_CMDCFG_CFE 0x00800000
1713 +#define BGMAC_CMDCFG_NLC 0x01000000
1714 +#define BGMAC_CMDCFG_RL 0x02000000
1715 +#define BGMAC_CMDCFG_RED 0x04000000
1716 +#define BGMAC_CMDCFG_PE 0x08000000
1717 +#define BGMAC_CMDCFG_TPI 0x10000000
1718 +#define BGMAC_CMDCFG_AT 0x20000000
1719 +#define BGMAC_MACADDR_HIGH 0x80c /* High 4 octets of own mac address */
1720 +#define BGMAC_MACADDR_LOW 0x810 /* Low 2 octets of own mac address */
1721 +#define BGMAC_RXMAX_LENGTH 0x814 /* Max receive frame length with vlan tag */
1722 +#define BGMAC_PAUSEQUANTA 0x818
1723 +#define BGMAC_MAC_MODE 0x844
1724 +#define BGMAC_OUTERTAG 0x848
1725 +#define BGMAC_INNERTAG 0x84c
1726 +#define BGMAC_TXIPG 0x85c
1727 +#define BGMAC_PAUSE_CTL 0xb30
1728 +#define BGMAC_TX_FLUSH 0xb34
1729 +#define BGMAC_RX_STATUS 0xb38
1730 +#define BGMAC_TX_STATUS 0xb3c
1731 +
1732 +#define BGMAC_PHY_CTL 0x00
1733 +#define BGMAC_PHY_CTL_SPEED_MSB 0x0040
1734 +#define BGMAC_PHY_CTL_DUPLEX 0x0100 /* duplex mode */
1735 +#define BGMAC_PHY_CTL_RESTART 0x0200 /* restart autonegotiation */
1736 +#define BGMAC_PHY_CTL_ANENAB 0x1000 /* enable autonegotiation */
1737 +#define BGMAC_PHY_CTL_SPEED 0x2000
1738 +#define BGMAC_PHY_CTL_LOOP 0x4000 /* loopback */
1739 +#define BGMAC_PHY_CTL_RESET 0x8000 /* reset */
1740 +/* Helpers */
1741 +#define BGMAC_PHY_CTL_SPEED_10 0
1742 +#define BGMAC_PHY_CTL_SPEED_100 BGMAC_PHY_CTL_SPEED
1743 +#define BGMAC_PHY_CTL_SPEED_1000 BGMAC_PHY_CTL_SPEED_MSB
1744 +#define BGMAC_PHY_ADV 0x04
1745 +#define BGMAC_PHY_ADV_10HALF 0x0020 /* advertise 10MBits/s half duplex */
1746 +#define BGMAC_PHY_ADV_10FULL 0x0040 /* advertise 10MBits/s full duplex */
1747 +#define BGMAC_PHY_ADV_100HALF 0x0080 /* advertise 100MBits/s half duplex */
1748 +#define BGMAC_PHY_ADV_100FULL 0x0100 /* advertise 100MBits/s full duplex */
1749 +#define BGMAC_PHY_ADV2 0x09
1750 +#define BGMAC_PHY_ADV2_1000HALF 0x0100 /* advertise 1000MBits/s half duplex */
1751 +#define BGMAC_PHY_ADV2_1000FULL 0x0200 /* advertise 1000MBits/s full duplex */
1752 +
1753 +/* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */
1754 +#define BGMAC_BCMA_IOCTL_SW_CLKEN 0x00000004 /* PHY Clock Enable */
1755 +#define BGMAC_BCMA_IOCTL_SW_RESET 0x00000008 /* PHY Reset */
1756 +
1757 +/* BCMA GMAC core specific IO status (BCMA_IOST) flags */
1758 +#define BGMAC_BCMA_IOST_ATTACHED 0x00000800
1759 +
1760 +#define BGMAC_NUM_MIB_TX_REGS \
1761 + (((BGMAC_TX_Q3_OCTETS_HIGH - BGMAC_TX_GOOD_OCTETS) / 4) + 1)
1762 +#define BGMAC_NUM_MIB_RX_REGS \
1763 + (((BGMAC_RX_UNI_PKTS - BGMAC_RX_GOOD_OCTETS) / 4) + 1)
1764 +
1765 +#define BGMAC_DMA_TX_CTL 0x00
1766 +#define BGMAC_DMA_TX_ENABLE 0x00000001
1767 +#define BGMAC_DMA_TX_SUSPEND 0x00000002
1768 +#define BGMAC_DMA_TX_LOOPBACK 0x00000004
1769 +#define BGMAC_DMA_TX_FLUSH 0x00000010
1770 +#define BGMAC_DMA_TX_PARITY_DISABLE 0x00000800
1771 +#define BGMAC_DMA_TX_ADDREXT_MASK 0x00030000
1772 +#define BGMAC_DMA_TX_ADDREXT_SHIFT 16
1773 +#define BGMAC_DMA_TX_INDEX 0x04
1774 +#define BGMAC_DMA_TX_RINGLO 0x08
1775 +#define BGMAC_DMA_TX_RINGHI 0x0C
1776 +#define BGMAC_DMA_TX_STATUS 0x10
1777 +#define BGMAC_DMA_TX_STATDPTR 0x00001FFF
1778 +#define BGMAC_DMA_TX_STAT 0xF0000000
1779 +#define BGMAC_DMA_TX_STAT_DISABLED 0x00000000
1780 +#define BGMAC_DMA_TX_STAT_ACTIVE 0x10000000
1781 +#define BGMAC_DMA_TX_STAT_IDLEWAIT 0x20000000
1782 +#define BGMAC_DMA_TX_STAT_STOPPED 0x30000000
1783 +#define BGMAC_DMA_TX_STAT_SUSP 0x40000000
1784 +#define BGMAC_DMA_TX_ERROR 0x14
1785 +#define BGMAC_DMA_TX_ERRDPTR 0x0001FFFF
1786 +#define BGMAC_DMA_TX_ERR 0xF0000000
1787 +#define BGMAC_DMA_TX_ERR_NOERR 0x00000000
1788 +#define BGMAC_DMA_TX_ERR_PROT 0x10000000
1789 +#define BGMAC_DMA_TX_ERR_UNDERRUN 0x20000000
1790 +#define BGMAC_DMA_TX_ERR_TRANSFER 0x30000000
1791 +#define BGMAC_DMA_TX_ERR_DESCREAD 0x40000000
1792 +#define BGMAC_DMA_TX_ERR_CORE 0x50000000
1793 +#define BGMAC_DMA_RX_CTL 0x20
1794 +#define BGMAC_DMA_RX_ENABLE 0x00000001
1795 +#define BGMAC_DMA_RX_FRAME_OFFSET_MASK 0x000000FE
1796 +#define BGMAC_DMA_RX_FRAME_OFFSET_SHIFT 1
1797 +#define BGMAC_DMA_RX_DIRECT_FIFO 0x00000100
1798 +#define BGMAC_DMA_RX_OVERFLOW_CONT 0x00000400
1799 +#define BGMAC_DMA_RX_PARITY_DISABLE 0x00000800
1800 +#define BGMAC_DMA_RX_ADDREXT_MASK 0x00030000
1801 +#define BGMAC_DMA_RX_ADDREXT_SHIFT 16
1802 +#define BGMAC_DMA_RX_INDEX 0x24
1803 +#define BGMAC_DMA_RX_RINGLO 0x28
1804 +#define BGMAC_DMA_RX_RINGHI 0x2C
1805 +#define BGMAC_DMA_RX_STATUS 0x30
1806 +#define BGMAC_DMA_RX_STATDPTR 0x00001FFF
1807 +#define BGMAC_DMA_RX_STAT 0xF0000000
1808 +#define BGMAC_DMA_RX_STAT_DISABLED 0x00000000
1809 +#define BGMAC_DMA_RX_STAT_ACTIVE 0x10000000
1810 +#define BGMAC_DMA_RX_STAT_IDLEWAIT 0x20000000
1811 +#define BGMAC_DMA_RX_STAT_STOPPED 0x30000000
1812 +#define BGMAC_DMA_RX_STAT_SUSP 0x40000000
1813 +#define BGMAC_DMA_RX_ERROR 0x34
1814 +#define BGMAC_DMA_RX_ERRDPTR 0x0001FFFF
1815 +#define BGMAC_DMA_RX_ERR 0xF0000000
1816 +#define BGMAC_DMA_RX_ERR_NOERR 0x00000000
1817 +#define BGMAC_DMA_RX_ERR_PROT 0x10000000
1818 +#define BGMAC_DMA_RX_ERR_UNDERRUN 0x20000000
1819 +#define BGMAC_DMA_RX_ERR_TRANSFER 0x30000000
1820 +#define BGMAC_DMA_RX_ERR_DESCREAD 0x40000000
1821 +#define BGMAC_DMA_RX_ERR_CORE 0x50000000
1822 +
1823 +#define BGMAC_DESC_CTL0_EOT 0x10000000 /* End of ring */
1824 +#define BGMAC_DESC_CTL0_IOC 0x20000000 /* IRQ on complete */
1825 +#define BGMAC_DESC_CTL0_SOF 0x40000000 /* Start of frame */
1826 +#define BGMAC_DESC_CTL0_EOF 0x80000000 /* End of frame */
1827 +#define BGMAC_DESC_CTL1_LEN 0x00001FFF
1828 +
1829 +#define BGMAC_PHY_NOREGS 0x1E
1830 +#define BGMAC_PHY_MASK 0x1F
1831 +
1832 +#define BGMAC_MAX_TX_RINGS 4
1833 +#define BGMAC_MAX_RX_RINGS 1
1834 +
1835 +#define BGMAC_TX_RING_SLOTS 128
1836 +#define BGMAC_RX_RING_SLOTS 512 - 1 /* Why -1? Well, Broadcom does that... */
1837 +
1838 +#define BGMAC_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */
1839 +#define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */
1840 +#define BGMAC_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */
1841 +#define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
1842 +
1843 +#define BGMAC_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */
1844 +#define BGMAC_BFL_ENETADM 0x0080 /* has ADMtek switch */
1845 +#define BGMAC_BFL_ENETVLAN 0x0100 /* can do vlan */
1846 +
1847 +#define BGMAC_CHIPCTL_1_IF_TYPE_MASK 0x00000030
1848 +#define BGMAC_CHIPCTL_1_IF_TYPE_RMII 0x00000000
1849 +#define BGMAC_CHIPCTL_1_IF_TYPE_MI 0x00000010
1850 +#define BGMAC_CHIPCTL_1_IF_TYPE_RGMII 0x00000020
1851 +#define BGMAC_CHIPCTL_1_SW_TYPE_MASK 0x000000C0
1852 +#define BGMAC_CHIPCTL_1_SW_TYPE_EPHY 0x00000000
1853 +#define BGMAC_CHIPCTL_1_SW_TYPE_EPHYMII 0x00000040
1854 +#define BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII 0x00000080
1855 +#define BGMAC_CHIPCTL_1_SW_TYPE_RGMI 0x000000C0
1856 +#define BGMAC_CHIPCTL_1_RXC_DLL_BYPASS 0x00010000
1857 +
1858 +#define BGMAC_SPEED_10 0x0001
1859 +#define BGMAC_SPEED_100 0x0002
1860 +#define BGMAC_SPEED_1000 0x0004
1861 +
1862 +#define BGMAC_WEIGHT 64
1863 +
1864 +#define ETHER_MAX_LEN 1518
1865 +
1866 +struct bgmac_slot_info {
1867 + struct sk_buff *skb;
1868 + dma_addr_t dma_addr;
1869 +};
1870 +
1871 +struct bgmac_dma_desc {
1872 + __le32 ctl0;
1873 + __le32 ctl1;
1874 + __le32 addr_low;
1875 + __le32 addr_high;
1876 +} __packed;
1877 +
1878 +enum bgmac_dma_ring_type {
1879 + BGMAC_DMA_RING_TX,
1880 + BGMAC_DMA_RING_RX,
1881 +};
1882 +
1883 +/**
1884 + * bgmac_dma_ring - contains info about DMA ring (either TX or RX one)
1885 + * @start: index of the first slot containing data
1886 + * @end: index of a slot that can *not* be read (yet)
1887 + *
1888 + * Be really aware of the specific @end meaning. It's an index of a slot *after*
1889 + * the one containing data that can be read. If @start equals @end the ring is
1890 + * empty.
1891 + */
1892 +struct bgmac_dma_ring {
1893 + u16 num_slots;
1894 + u16 start;
1895 + u16 end;
1896 +
1897 + u16 mmio_base;
1898 + struct bgmac_dma_desc *cpu_base;
1899 + dma_addr_t dma_base;
1900 +
1901 + struct bgmac_slot_info slots[BGMAC_RX_RING_SLOTS];
1902 +};
1903 +
1904 +struct bgmac_rx_header {
1905 + __le16 len;
1906 + __le16 flags;
1907 + __le16 pad[12];
1908 +};
1909 +
1910 +struct bgmac {
1911 + struct bcma_device *core;
1912 + struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */
1913 + struct net_device *net_dev;
1914 + struct napi_struct napi;
1915 +
1916 + /* DMA */
1917 + struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS];
1918 + struct bgmac_dma_ring rx_ring[BGMAC_MAX_RX_RINGS];
1919 +
1920 + /* Stats */
1921 + bool stats_grabbed;
1922 + u32 mib_tx_regs[BGMAC_NUM_MIB_TX_REGS];
1923 + u32 mib_rx_regs[BGMAC_NUM_MIB_RX_REGS];
1924 +
1925 + /* Int */
1926 + u32 int_mask;
1927 + u32 int_status;
1928 +
1929 + /* Speed-related */
1930 + int speed;
1931 + bool autoneg;
1932 + bool full_duplex;
1933 +
1934 + u8 phyaddr;
1935 + bool has_robosw;
1936 +
1937 + bool loopback;
1938 +};
1939 +
1940 +static inline u32 bgmac_read(struct bgmac *bgmac, u16 offset)
1941 +{
1942 + return bcma_read32(bgmac->core, offset);
1943 +}
1944 +
1945 +static inline void bgmac_write(struct bgmac *bgmac, u16 offset, u32 value)
1946 +{
1947 + bcma_write32(bgmac->core, offset, value);
1948 +}
1949 +
1950 +static inline void bgmac_maskset(struct bgmac *bgmac, u16 offset, u32 mask,
1951 + u32 set)
1952 +{
1953 + bgmac_write(bgmac, offset, (bgmac_read(bgmac, offset) & mask) | set);
1954 +}
1955 +
1956 +static inline void bgmac_mask(struct bgmac *bgmac, u16 offset, u32 mask)
1957 +{
1958 + bgmac_maskset(bgmac, offset, mask, 0);
1959 +}
1960 +
1961 +static inline void bgmac_set(struct bgmac *bgmac, u16 offset, u32 set)
1962 +{
1963 + bgmac_maskset(bgmac, offset, ~0, set);
1964 +}
1965 +
1966 +u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg);
1967 +void bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value);
1968 +
1969 +#endif /* _BGMAC_H */
1970 --- a/include/linux/bcma/bcma_driver_chipcommon.h
1971 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
1972 @@ -623,4 +623,6 @@ extern void bcma_chipco_regctl_maskset(s
1973 u32 offset, u32 mask, u32 set);
1974 extern void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid);
1975
1976 +extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc);
1977 +
1978 #endif /* LINUX_BCMA_DRIVER_CC_H_ */