1 --- a/drivers/bcma/driver_chipcommon_pmu.c
2 +++ b/drivers/bcma/driver_chipcommon_pmu.c
3 @@ -263,7 +263,7 @@ static u32 bcma_pmu_pll_clock_bcm4706(st
6 /* query bus clock frequency for PMU-enabled chipcommon */
7 -static u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc)
8 +u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc)
10 struct bcma_bus *bus = cc->core->bus;
12 @@ -292,6 +292,7 @@ static u32 bcma_pmu_get_bus_clock(struct
14 return BCMA_CC_PMU_HT_CLOCK;
16 +EXPORT_SYMBOL_GPL(bcma_pmu_get_bus_clock);
18 /* query cpu clock frequency for PMU-enabled chipcommon */
19 u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc)
20 --- a/drivers/net/ethernet/broadcom/Kconfig
21 +++ b/drivers/net/ethernet/broadcom/Kconfig
22 @@ -120,4 +120,10 @@ config BNX2X
23 To compile this driver as a module, choose M here: the module
24 will be called bnx2x. This is recommended.
27 + tristate "Broadcom Gigabit driver"
30 + This driver supports Broadcom Gigabit core found in some BCM47xx SoCs.
32 endif # NET_VENDOR_BROADCOM
33 --- a/drivers/net/ethernet/broadcom/Makefile
34 +++ b/drivers/net/ethernet/broadcom/Makefile
35 @@ -9,3 +9,4 @@ obj-$(CONFIG_CNIC) += cnic.o
36 obj-$(CONFIG_BNX2X) += bnx2x/
37 obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
38 obj-$(CONFIG_TIGON3) += tg3.o
39 +obj-$(CONFIG_BGMAC) += bgmac.o
41 +++ b/drivers/net/ethernet/broadcom/bgmac.c
43 +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
45 +#define bgmac_err(bgmac, fmt, ...) \
46 + pr_err("u%d: " fmt, (bgmac)->core->core_unit, ##__VA_ARGS__)
47 +#define bgmac_warn(bgmac, fmt, ...) \
48 + pr_warn("u%d: " fmt, (bgmac)->core->core_unit, ##__VA_ARGS__)
49 +#define bgmac_info(bgmac, fmt, ...) \
50 + pr_info("u%d: " fmt, (bgmac)->core->core_unit, ##__VA_ARGS__)
51 +#define bgmac_debug(bgmac, fmt, ...) \
52 + pr_debug("u%d: " fmt, (bgmac)->core->core_unit, ##__VA_ARGS__)
54 +#include <linux/kernel.h>
55 +#include <linux/module.h>
56 +#include <linux/delay.h>
57 +#include <linux/etherdevice.h>
58 +#include <linux/mii.h>
59 +#include <linux/interrupt.h>
60 +#include <linux/dma-mapping.h>
61 +#include <bcm47xx_nvram.h>
65 +#define ETHER_MAX_LEN 1518
67 +MODULE_LICENSE("GPL");
69 +static const struct bcma_device_id bgmac_bcma_tbl[] = {
70 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
71 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
74 +MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
76 +static bool bgmac_wait_value(struct bcma_device *core, u16 reg, u32 mask,
77 + u32 value, int timeout)
82 + for (i = 0; i < timeout / 10; i++) {
83 + val = bcma_read32(core, reg);
84 + if ((val & mask) == value)
88 + pr_err("Timeout waiting for reg 0x%X\n", reg);
92 +/**************************************************
94 + **************************************************/
96 +static void bgmac_dma_tx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
101 + if (!ring->mmio_base)
104 + /* Susend DMA TX ring first.
105 + * bgmac_wait_value doesn't support waiting for any of few values, so
106 + * implement whole loop here.
108 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL,
109 + BGMAC_DMA_TX_SUSPEND);
110 + for (i = 0; i < 10000 / 10; i++) {
111 + val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
112 + if (val == BGMAC_DMA_TX_STAT_DISABLED ||
113 + val == BGMAC_DMA_TX_STAT_IDLEWAIT ||
114 + val == BGMAC_DMA_TX_STAT_STOPPED) {
121 + bgmac_err(bgmac, "Timeout suspending DMA TX ring 0x%X\n", ring->mmio_base);
123 + /* Remove SUSPEND bit */
124 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, 0);
125 + if (!bgmac_wait_value(bgmac->core,
126 + ring->mmio_base + BGMAC_DMA_TX_STATUS,
127 + BGMAC_DMA_TX_STAT, BGMAC_DMA_TX_STAT_DISABLED,
129 + bgmac_warn(bgmac, "DMA TX ring 0x%X wasn't disabled on time, waiting additional 300us\n", ring->mmio_base);
131 + val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
132 + if ((val & BGMAC_DMA_TX_STAT) != BGMAC_DMA_TX_STAT_DISABLED)
133 + bgmac_err(bgmac, "Reset of DMA TX ring 0x%X failed\n", ring->mmio_base);
137 +static void bgmac_dma_tx_enable(struct bgmac *bgmac,
138 + struct bgmac_dma_ring *ring)
142 + ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL);
143 + ctl |= BGMAC_DMA_TX_ENABLE;
144 + ctl |= BGMAC_DMA_TX_PARITY_DISABLE;
145 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl);
148 +static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
149 + struct bgmac_dma_ring *ring,
150 + struct sk_buff *skb)
152 + struct device *dma_dev = bgmac->core->dma_dev;
153 + struct bgmac_dma_desc *dma_desc;
154 + struct bgmac_slot_info *slot;
158 + if (skb->len > BGMAC_DESC_CTL1_LEN) {
159 + bgmac_err(bgmac, "Too long skb (%d)\n", skb->len);
160 + return NETDEV_TX_BUSY;
163 + if (ring->start <= ring->end)
164 + free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS;
166 + free_slots = ring->start - ring->end;
167 + if (free_slots <= 1) {
168 + bgmac_err(bgmac, "No free slots on ring 0x%X!\n", ring->mmio_base);
169 + netif_stop_queue(bgmac->net_dev);
170 + return NETDEV_TX_BUSY;
173 + slot = &ring->slots[ring->end];
175 + slot->dma_addr = dma_map_single(dma_dev, skb->data, skb->len, DMA_TO_DEVICE);
176 + if (dma_mapping_error(dma_dev, slot->dma_addr)) {
177 + bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n", ring->mmio_base);
178 + return NETDEV_TX_BUSY;
181 + ctl0 = BGMAC_DESC_CTL0_IOC | BGMAC_DESC_CTL0_SOF | BGMAC_DESC_CTL0_EOF;
182 + if (ring->end == ring->num_slots - 1)
183 + ctl0 |= BGMAC_DESC_CTL0_EOT;
184 + ctl1 = skb->len & BGMAC_DESC_CTL1_LEN;
186 + dma_desc = ring->cpu_base;
187 + dma_desc += ring->end;
188 + dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr));
189 + dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr));
190 + dma_desc->ctl0 = cpu_to_le32(ctl0);
191 + dma_desc->ctl1 = cpu_to_le32(ctl1);
195 + /* Increase ring->end to point empty slot. We tell hardware the first
196 + * slot it shold *not* read.
198 + if (++ring->end >= BGMAC_TX_RING_SLOTS)
200 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,
201 + ring->end * sizeof(struct bgmac_dma_desc));
203 + return NETDEV_TX_OK;
206 +/* Free transmitted packets */
207 +static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
209 + struct device *dma_dev = bgmac->core->dma_dev;
210 + struct bgmac_dma_desc *dma_desc;
211 + struct bgmac_slot_info *slot;
214 + /* The last slot that hardware didn't consume yet */
215 + empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
216 + empty_slot &= BGMAC_DMA_TX_STATDPTR;
217 + empty_slot /= sizeof(struct bgmac_dma_desc);
219 + while (ring->start != empty_slot) {
221 + dma_desc = ring->cpu_base;
222 + dma_desc += ring->start;
223 + slot = &ring->slots[ring->start];
226 + /* Unmap no longer used buffer */
227 + dma_unmap_single(dma_dev, slot->dma_addr,
228 + slot->skb->len, DMA_TO_DEVICE);
229 + slot->dma_addr = 0;
232 + dev_kfree_skb_any(slot->skb);
235 + bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d", ring->start, ring->end);
238 + if (++ring->start >= BGMAC_TX_RING_SLOTS)
243 +static void bgmac_dma_rx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
245 + if (!ring->mmio_base)
248 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, 0);
249 + if (!bgmac_wait_value(bgmac->core,
250 + ring->mmio_base + BGMAC_DMA_RX_STATUS,
251 + BGMAC_DMA_RX_STAT, BGMAC_DMA_RX_STAT_DISABLED,
253 + bgmac_err(bgmac, "Reset of ring 0x%X RX failed\n", ring->mmio_base);
256 +static void bgmac_dma_rx_enable(struct bgmac *bgmac,
257 + struct bgmac_dma_ring *ring)
261 + ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL);
262 + ctl &= BGMAC_DMA_RX_ADDREXT_MASK;
263 + ctl |= BGMAC_DMA_RX_ENABLE;
264 + ctl |= BGMAC_DMA_RX_PARITY_DISABLE;
265 + ctl |= BGMAC_DMA_RX_OVERFLOW_CONT;
266 + ctl |= BGMAC_RX_FRAME_OFFSET << BGMAC_DMA_RX_FRAME_OFFSET_SHIFT;
267 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, ctl);
270 +static void bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
271 + struct bgmac_slot_info *slot)
273 + struct device *dma_dev = bgmac->core->dma_dev;
274 + struct bgmac_rx_header *rx;
277 + slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
279 + bgmac_err(bgmac, "Allocation of skb failed!\n");
281 + /* Poison - if everything goes fine, hardware will overwrite it */
282 + rx = (struct bgmac_rx_header *)slot->skb->data;
283 + rx->len = cpu_to_le16(0xdead);
284 + rx->flags = cpu_to_le16(0xbeef);
286 + /* Map skb for the DMA */
287 + slot->dma_addr = dma_map_single(dma_dev, slot->skb->data,
288 + BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
289 + if (dma_mapping_error(dma_dev, slot->dma_addr))
290 + bgmac_err(bgmac, "DMA mapping error\n");
291 + if (slot->dma_addr & 0xC0000000)
292 + bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
295 +static void bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
297 + struct device *dma_dev = bgmac->core->dma_dev;
298 + struct bgmac_dma_desc *dma_desc;
299 + struct bgmac_slot_info *slot;
300 + struct sk_buff *skb;
301 + struct bgmac_rx_header *rx;
305 + end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS);
306 + end_slot &= BGMAC_DMA_RX_STATDPTR;
307 + end_slot /= sizeof(struct bgmac_dma_desc);
309 + ring->end = end_slot;
311 + while (ring->start != ring->end) {
313 + dma_desc = ring->cpu_base;
314 + dma_desc += ring->start;
315 + slot = &ring->slots[ring->start];
318 + /* Unmap buffer to make it accessible to the CPU */
319 + dma_unmap_single(dma_dev, slot->dma_addr, BGMAC_RX_BUF_SIZE,
322 + /* Get info from the header */
323 + rx = (struct bgmac_rx_header *)skb->data;
324 + len = le16_to_cpu(rx->len);
325 + flags = le16_to_cpu(rx->flags);
327 + /* Check for poison and drop or pass packet */
328 + if (len == 0xdead && flags == 0xbeef) {
329 + bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", ring->start);
330 + dev_kfree_skb_any(skb);
332 + /* Remove header from the skb and pass it to the net */
333 + skb_put(skb, BGMAC_RX_FRAME_OFFSET + len);
334 + skb_pull(skb, BGMAC_RX_FRAME_OFFSET);
335 + skb->protocol = eth_type_trans(skb, bgmac->net_dev);
336 + netif_receive_skb(skb);
339 + /* Alloc new skb */
340 + bgmac_dma_rx_skb_for_slot(bgmac, slot);
341 + dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr));
342 + dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr));
344 + if (++ring->start >= BGMAC_RX_RING_SLOTS)
349 +/* Does ring support unaligned addressing? */
350 +static bool bgmac_dma_unaligned(struct bgmac *bgmac,
351 + struct bgmac_dma_ring *ring)
354 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
356 + if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO))
359 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
361 + if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO))
367 +static int bgmac_dma_alloc(struct bgmac *bgmac)
369 + struct device *dma_dev = bgmac->core->dma_dev;
370 + struct bgmac_dma_ring *ring;
371 + u16 ring_base[] = { BGMAC_DMA_BASE0, BGMAC_DMA_BASE1, BGMAC_DMA_BASE2,
372 + BGMAC_DMA_BASE3, };
373 + int size; /* ring size: different for Tx and Rx */
376 + BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base));
377 + BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base));
379 + if (!(bcma_aread32(bgmac->core, BCMA_IOST) & BCMA_IOST_DMA64)) {
380 + bgmac_err(bgmac, "Core does not report 64-bit DMA\n");
384 + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
385 + ring = &bgmac->tx_ring[i];
387 + ring->num_slots = BGMAC_TX_RING_SLOTS;
388 + ring->mmio_base = ring_base[i];
389 + if (bgmac_dma_unaligned(bgmac, ring))
390 + bgmac_warn(bgmac, "TX on ring 0x%X supports unaligned addressing but this feature is not implemented\n", ring->mmio_base);
392 + /* Alloc ring of descriptors */
393 + size = ring->num_slots * sizeof(struct bgmac_dma_desc);
394 + ring->cpu_base = dma_zalloc_coherent(dma_dev, size,
397 + if (!ring->cpu_base)
398 + bgmac_err(bgmac, "Allocation of TX ring failed\n");
399 + if (ring->dma_base & 0xC0000000)
400 + bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
402 + /* No need to alloc TX slots yet */
405 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
406 + ring = &bgmac->rx_ring[i];
408 + ring->num_slots = BGMAC_RX_RING_SLOTS;
409 + ring->mmio_base = ring_base[i];
410 + if (bgmac_dma_unaligned(bgmac, ring))
411 + bgmac_warn(bgmac, "RX on ring 0x%X supports unaligned addressing but this feature is not implemented\n", ring->mmio_base);
413 + /* Alloc ring of descriptors */
414 + size = ring->num_slots * sizeof(struct bgmac_dma_desc);
415 + ring->cpu_base = dma_zalloc_coherent(dma_dev, size,
418 + if (!ring->cpu_base)
419 + bgmac_err(bgmac, "Allocation of RX ring failed\n");
420 + if (ring->dma_base & 0xC0000000)
421 + bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
423 + /* Alloc RX slots */
424 + for (i = 0; i < ring->num_slots; i++)
425 + bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[i]);
431 +static void bgmac_dma_init(struct bgmac *bgmac)
433 + struct bgmac_dma_ring *ring;
434 + struct bgmac_dma_desc *dma_desc;
438 + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
439 + ring = &bgmac->tx_ring[i];
441 + /* We don't implement unaligned addressing, so enable first */
442 + bgmac_dma_tx_enable(bgmac, ring);
443 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
444 + lower_32_bits(ring->dma_base));
445 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGHI,
446 + upper_32_bits(ring->dma_base));
449 + ring->end = 0; /* Points the slot that should *not* be read */
452 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
453 + ring = &bgmac->rx_ring[i];
455 + /* We don't implement unaligned addressing, so enable first */
456 + bgmac_dma_rx_enable(bgmac, ring);
457 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
458 + lower_32_bits(ring->dma_base));
459 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGHI,
460 + upper_32_bits(ring->dma_base));
462 + for (i = 0, dma_desc = ring->cpu_base; i < ring->num_slots;
466 + if (i == ring->num_slots - 1)
467 + ctl0 |= BGMAC_DESC_CTL0_EOT;
468 + ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN;
469 + /* Is there any BGMAC device that requires extension? */
470 + /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) &
471 + * B43_DMA64_DCTL1_ADDREXT_MASK;
474 + dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[i].dma_addr));
475 + dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[i].dma_addr));
476 + dma_desc->ctl0 = cpu_to_le32(ctl0);
477 + dma_desc->ctl1 = cpu_to_le32(ctl1);
480 + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
481 + ring->num_slots * sizeof(struct bgmac_dma_desc));
488 +/**************************************************
490 + **************************************************/
492 +u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg)
494 + struct bcma_device *core;
495 + u16 phy_access_addr;
499 + BUILD_BUG_ON(BGMAC_PA_DATA_MASK != BCMA_GMAC_CMN_PA_DATA_MASK);
500 + BUILD_BUG_ON(BGMAC_PA_ADDR_MASK != BCMA_GMAC_CMN_PA_ADDR_MASK);
501 + BUILD_BUG_ON(BGMAC_PA_ADDR_SHIFT != BCMA_GMAC_CMN_PA_ADDR_SHIFT);
502 + BUILD_BUG_ON(BGMAC_PA_REG_MASK != BCMA_GMAC_CMN_PA_REG_MASK);
503 + BUILD_BUG_ON(BGMAC_PA_REG_SHIFT != BCMA_GMAC_CMN_PA_REG_SHIFT);
504 + BUILD_BUG_ON(BGMAC_PA_WRITE != BCMA_GMAC_CMN_PA_WRITE);
505 + BUILD_BUG_ON(BGMAC_PA_START != BCMA_GMAC_CMN_PA_START);
506 + BUILD_BUG_ON(BGMAC_PC_EPA_MASK != BCMA_GMAC_CMN_PC_EPA_MASK);
507 + BUILD_BUG_ON(BGMAC_PC_MCT_MASK != BCMA_GMAC_CMN_PC_MCT_MASK);
508 + BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT);
509 + BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE);
511 + if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
512 + core = bgmac->core->bus->drv_gmac_cmn.core;
513 + phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
514 + phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
516 + core = bgmac->core;
517 + phy_access_addr = BGMAC_PHY_ACCESS;
518 + phy_ctl_addr = BGMAC_PHY_CNTL;
521 + tmp = bcma_read32(core, phy_ctl_addr);
522 + tmp &= ~BGMAC_PC_EPA_MASK;
524 + bcma_write32(core, phy_ctl_addr, tmp);
526 + tmp = BGMAC_PA_START;
527 + tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
528 + tmp |= reg << BGMAC_PA_REG_SHIFT;
529 + bcma_write32(core, phy_access_addr, tmp);
531 + if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) {
532 + bgmac_err(bgmac, "Reading PHY %d register 0x%X failed\n",
537 + return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK;
540 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */
541 +void bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value)
543 + struct bcma_device *core;
544 + u16 phy_access_addr;
548 + if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
549 + core = bgmac->core->bus->drv_gmac_cmn.core;
550 + phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
551 + phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
553 + core = bgmac->core;
554 + phy_access_addr = BGMAC_PHY_ACCESS;
555 + phy_ctl_addr = BGMAC_PHY_CNTL;
558 + tmp = bcma_read32(core, phy_ctl_addr);
559 + tmp &= ~BGMAC_PC_EPA_MASK;
561 + bcma_write32(core, phy_ctl_addr, tmp);
563 + bgmac_write(bgmac, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
564 + if (bgmac_read(bgmac, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
565 + bgmac_warn(bgmac, "Error setting MDIO int\n");
567 + tmp = BGMAC_PA_START;
568 + tmp |= BGMAC_PA_WRITE;
569 + tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
570 + tmp |= reg << BGMAC_PA_REG_SHIFT;
572 + bcma_write32(core, phy_access_addr, tmp);
574 + if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000))
575 + bgmac_err(bgmac, "Writing to PHY %d register 0x%X failed\n",
579 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyforce */
580 +static void bgmac_phy_force(struct bgmac *bgmac)
583 + u16 mask = ~(BGMAC_PHY_CTL_SPEED | BGMAC_PHY_CTL_SPEED_MSB |
584 + BGMAC_PHY_CTL_ANENAB | BGMAC_PHY_CTL_DUPLEX);
586 + if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
589 + if (bgmac->autoneg)
592 + ctl = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL);
594 + if (bgmac->full_duplex)
595 + ctl |= BGMAC_PHY_CTL_DUPLEX;
596 + if (bgmac->speed == BGMAC_SPEED_100)
597 + ctl |= BGMAC_PHY_CTL_SPEED_100;
598 + else if (bgmac->speed == BGMAC_SPEED_1000)
599 + ctl |= BGMAC_PHY_CTL_SPEED_1000;
600 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL, ctl);
603 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyadvertise */
604 +static void bgmac_phy_advertise(struct bgmac *bgmac)
608 + if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
611 + if (!bgmac->autoneg)
614 + /* Adv selected 10/100 speeds */
615 + adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV);
616 + adv &= ~(BGMAC_PHY_ADV_10HALF | BGMAC_PHY_ADV_10FULL |
617 + BGMAC_PHY_ADV_100HALF | BGMAC_PHY_ADV_100FULL);
618 + if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10)
619 + adv |= BGMAC_PHY_ADV_10HALF;
620 + if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100)
621 + adv |= BGMAC_PHY_ADV_100HALF;
622 + if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10)
623 + adv |= BGMAC_PHY_ADV_10FULL;
624 + if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100)
625 + adv |= BGMAC_PHY_ADV_100FULL;
626 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV, adv);
628 + /* Adv selected 1000 speeds */
629 + adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2);
630 + adv &= ~(BGMAC_PHY_ADV2_1000HALF | BGMAC_PHY_ADV2_1000FULL);
631 + if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000)
632 + adv |= BGMAC_PHY_ADV2_1000HALF;
633 + if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000)
634 + adv |= BGMAC_PHY_ADV2_1000FULL;
635 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2, adv);
638 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL,
639 + bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) |
640 + BGMAC_PHY_CTL_RESTART);
643 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */
644 +static void bgmac_phy_init(struct bgmac *bgmac)
646 + struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
647 + struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
650 + if (ci->id == BCMA_CHIP_ID_BCM5356) {
651 + for (i = 0; i < 5; i++) {
652 + bgmac_phy_write(bgmac, i, 0x1f, 0x008b);
653 + bgmac_phy_write(bgmac, i, 0x15, 0x0100);
654 + bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
655 + bgmac_phy_write(bgmac, i, 0x12, 0x2aaa);
656 + bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
659 + if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) ||
660 + (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) ||
661 + (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) {
662 + bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0);
663 + bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0);
664 + for (i = 0; i < 5; i++) {
665 + bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
666 + bgmac_phy_write(bgmac, i, 0x16, 0x5284);
667 + bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
668 + bgmac_phy_write(bgmac, i, 0x17, 0x0010);
669 + bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
670 + bgmac_phy_write(bgmac, i, 0x16, 0x5296);
671 + bgmac_phy_write(bgmac, i, 0x17, 0x1073);
672 + bgmac_phy_write(bgmac, i, 0x17, 0x9073);
673 + bgmac_phy_write(bgmac, i, 0x16, 0x52b6);
674 + bgmac_phy_write(bgmac, i, 0x17, 0x9273);
675 + bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
680 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */
681 +static void bgmac_phy_reset(struct bgmac *bgmac)
683 + if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
686 + bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL,
687 + BGMAC_PHY_CTL_RESET);
689 + if (bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) &
690 + BGMAC_PHY_CTL_RESET)
691 + bgmac_err(bgmac, "PHY reset failed\n");
692 + bgmac_phy_init(bgmac);
695 +/**************************************************
697 + **************************************************/
699 +/* TODO: can we just drop @force? Can we don't reset MAC at all if there is
700 + * nothing to change? Try if after stabilizng driver.
702 +static void bgmac_cmdcfg_maskset(struct bgmac *bgmac, u32 mask, u32 set,
705 + u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
706 + u32 new_val = (cmdcfg & mask) | set;
708 + bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR);
711 + if (new_val != cmdcfg || force)
712 + bgmac_write(bgmac, BGMAC_CMDCFG, new_val);
714 + bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR);
718 +static void bgmac_chip_stats_update(struct bgmac *bgmac)
722 + if (bgmac->core->id.id != BCMA_CORE_4706_MAC_GBIT) {
723 + for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++)
724 + bgmac->mib_tx_regs[i] =
726 + BGMAC_TX_GOOD_OCTETS + (i * 4));
727 + for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
728 + bgmac->mib_rx_regs[i] =
730 + BGMAC_RX_GOOD_OCTETS + (i * 4));
733 + /* TODO: what else? how to handle BCM4706? */
736 +static void bgmac_clear_mib(struct bgmac *bgmac)
740 + if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT)
743 + bgmac_set(bgmac, BGMAC_DEV_CTL, BGMAC_DC_MROR);
744 + for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++)
745 + bgmac_read(bgmac, BGMAC_TX_GOOD_OCTETS + (i * 4));
746 + for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
747 + bgmac_read(bgmac, BGMAC_RX_GOOD_OCTETS + (i * 4));
750 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_speed */
751 +static void bgmac_speed(struct bgmac *bgmac, int speed)
753 + u32 mask = ~(BGMAC_CMDCFG_ES_MASK | BGMAC_CMDCFG_HD);
756 + if (speed & BGMAC_SPEED_10)
757 + set |= BGMAC_CMDCFG_ES_10;
758 + if (speed & BGMAC_SPEED_100)
759 + set |= BGMAC_CMDCFG_ES_100;
760 + if (speed & BGMAC_SPEED_1000)
761 + set |= BGMAC_CMDCFG_ES_1000;
762 + if (!bgmac->full_duplex)
763 + set |= BGMAC_CMDCFG_HD;
764 + bgmac_cmdcfg_maskset(bgmac, mask, set, true);
767 +static void bgmac_miiconfig(struct bgmac *bgmac)
769 + u8 imode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
771 + if (imode == 0 || imode == 1) {
772 + if (bgmac->autoneg)
773 + bgmac_speed(bgmac, BGMAC_SPEED_100);
775 + bgmac_speed(bgmac, bgmac->speed);
779 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
780 +static void bgmac_chip_reset(struct bgmac *bgmac)
782 + struct bcma_device *core = bgmac->core;
783 + struct bcma_bus *bus = core->bus;
784 + struct bcma_chipinfo *ci = &bus->chipinfo;
789 + if (bcma_core_is_enabled(core)) {
790 + if (!bgmac->stats_grabbed) {
791 + bgmac_chip_stats_update(bgmac);
792 + bgmac->stats_grabbed = true;
795 + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
796 + bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]);
798 + bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
801 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
802 + bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]);
804 + /* TODO: Clear software multicast filter list */
807 + iost = bcma_aread32(core, BCMA_IOST);
808 + if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 10) ||
809 + (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg == 10) ||
810 + (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == 9))
811 + iost &= ~BGMAC_BCMA_IOST_ATTACHED;
813 + if (iost & BGMAC_BCMA_IOST_ATTACHED) {
814 + flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
815 + if (!bgmac->has_robosw)
816 + flags |= BGMAC_BCMA_IOCTL_SW_RESET;
819 + bcma_core_enable(core, flags);
821 + if (core->id.rev > 2) {
822 + bgmac_set(bgmac, BCMA_CLKCTLST, 1 << 8);
823 + bgmac_wait_value(bgmac->core, BCMA_CLKCTLST, 1 << 24, 1 << 24,
827 + if (ci->id == BCMA_CHIP_ID_BCM5357 || ci->id == BCMA_CHIP_ID_BCM4749 ||
828 + ci->id == BCMA_CHIP_ID_BCM53572) {
829 + struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
831 + u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
832 + BGMAC_CHIPCTL_1_IF_TYPE_RMII;
834 + if (bcm47xx_nvram_getenv("et_swtype", buf, 1) > 0) {
835 + if (kstrtou8(buf, 0, &et_swtype))
836 + bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n", buf);
839 + sw_type = et_swtype;
840 + } else if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 9) {
841 + sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII;
845 + bcma_chipco_chipctl_maskset(cc, 1,
846 + ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
847 + BGMAC_CHIPCTL_1_SW_TYPE_MASK),
851 + if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
852 + bcma_awrite32(core, BCMA_IOCTL,
853 + bcma_aread32(core, BCMA_IOCTL) &
854 + ~BGMAC_BCMA_IOCTL_SW_RESET);
856 + /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset
857 + * Specs don't say about using BGMAC_CMDCFG_SR, but in this routine
858 + * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
859 + * be keps until taking MAC out of the reset.
861 + bgmac_cmdcfg_maskset(bgmac,
862 + ~(BGMAC_CMDCFG_TE |
873 + BGMAC_CMDCFG_PAD_EN |
875 + BGMAC_CMDCFG_PROM |
881 + bgmac_clear_mib(bgmac);
882 + if (core->id.id == BCMA_CORE_4706_MAC_GBIT)
883 + bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0,
884 + BCMA_GMAC_CMN_PC_MTE);
886 + bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
887 + bgmac_miiconfig(bgmac);
888 + bgmac_phy_init(bgmac);
890 + bgmac->int_status = 0;
893 +static void bgmac_chip_intrs_on(struct bgmac *bgmac)
895 + bgmac_write(bgmac, BGMAC_INT_MASK, bgmac->int_mask);
898 +static void bgmac_chip_intrs_off(struct bgmac *bgmac)
900 + bgmac_write(bgmac, BGMAC_INT_MASK, 0);
903 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_enable */
904 +static void bgmac_enable(struct bgmac *bgmac)
906 + struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
914 + cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
915 + bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE),
916 + BGMAC_CMDCFG_SR, true);
918 + cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE;
919 + bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg);
921 + mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
923 + if (ci->id != BCMA_CHIP_ID_BCM47162 || mode != 0)
924 + bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
925 + if (ci->id == BCMA_CHIP_ID_BCM47162 && mode == 2)
926 + bcma_chipco_chipctl_maskset(&bgmac->core->bus->drv_cc, 1, ~0,
927 + BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
930 + case BCMA_CHIP_ID_BCM5357:
931 + case BCMA_CHIP_ID_BCM4749:
932 + case BCMA_CHIP_ID_BCM53572:
933 + case BCMA_CHIP_ID_BCM4716:
934 + case BCMA_CHIP_ID_BCM47162:
935 + fl_ctl = 0x03cb04cb;
936 + if (ci->id == BCMA_CHIP_ID_BCM5357 ||
937 + ci->id == BCMA_CHIP_ID_BCM4749 ||
938 + ci->id == BCMA_CHIP_ID_BCM53572)
940 + bgmac_write(bgmac, BGMAC_FLOW_CTL_THRESH, fl_ctl);
941 + bgmac_write(bgmac, BGMAC_PAUSE_CTL, 0x27fff);
945 + rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL);
946 + rxq_ctl &= ~BGMAC_RXQ_CTL_MDP_MASK;
947 + bp_clk = bcma_pmu_get_bus_clock(&bgmac->core->bus->drv_cc) / 1000000;
948 + mdp = (bp_clk * 128 / 1000) - 3;
949 + rxq_ctl |= (mdp << BGMAC_RXQ_CTL_MDP_SHIFT);
950 + bgmac_write(bgmac, BGMAC_RXQ_CTL, rxq_ctl);
953 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
954 +static void bgmac_chip_init(struct bgmac *bgmac, bool full_init)
956 + struct ssb_sprom *sprom = &bgmac->core->bus->sprom;
957 + struct bgmac_dma_ring *ring;
962 + /* 1 interrupt per received frame */
963 + bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
965 + /* enable 802.3x tx flow control (honor received PAUSE frames) */
966 + bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true);
968 + if (bgmac->net_dev->flags & IFF_PROMISC)
969 + bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, false);
971 + bgmac_warn(bgmac, "Software filtering is not supported yet\n");
973 + mac = bgmac->core->core_unit ? sprom->et1mac : sprom->et0mac;
974 + tmp = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3];
975 + bgmac_write(bgmac, BGMAC_MACADDR_HIGH, tmp);
976 + tmp = (mac[4] << 8) | mac[5];
977 + bgmac_write(bgmac, BGMAC_MACADDR_LOW, tmp);
978 + memcpy(bgmac->net_dev->dev_addr, mac, 6);
980 + if (bgmac->loopback)
981 + bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, true);
983 + bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, true);
985 + bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
987 + if (!bgmac->autoneg) {
988 + bgmac_speed(bgmac, bgmac->speed);
989 + bgmac_phy_force(bgmac);
990 + } else if (bgmac->speed) { /* if there is anything to adv */
991 + bgmac_phy_advertise(bgmac);
995 + bgmac_dma_init(bgmac);
996 + if (1) /* FIXME: is there any case we don't want IRQs? */
997 + bgmac_chip_intrs_on(bgmac);
999 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
1000 + ring = &bgmac->rx_ring[i];
1001 + bgmac_dma_rx_enable(bgmac, ring);
1005 + bgmac_enable(bgmac);
1008 +static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
1010 + struct bgmac *bgmac = netdev_priv(dev_id);
1012 + u32 int_status = bgmac_read(bgmac, BGMAC_INT_STATUS);
1013 + int_status &= bgmac->int_mask;
1019 + bgmac_write(bgmac, BGMAC_INT_STATUS, int_status);
1021 + /* Disable new interrupts until handling existing ones */
1022 + bgmac_chip_intrs_off(bgmac);
1024 + bgmac->int_status = int_status;
1026 + return IRQ_WAKE_THREAD;
1029 +static irqreturn_t bgmac_interrupt_thread(int irq, void *dev_id)
1031 + struct bgmac *bgmac = netdev_priv(dev_id);
1032 + struct bgmac_dma_ring *ring;
1034 + if (bgmac->int_status & BGMAC_IS_TX0) {
1035 + ring = &bgmac->tx_ring[0];
1036 + bgmac_dma_tx_free(bgmac, ring);
1037 + bgmac->int_status &= ~BGMAC_IS_TX0;
1040 + if (bgmac->int_status & BGMAC_IS_RX) {
1041 + ring = &bgmac->rx_ring[0];
1042 + bgmac_dma_rx_read(bgmac, ring);
1043 + bgmac->int_status &= ~BGMAC_IS_RX;
1046 + if (bgmac->int_status) {
1047 + bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status);
1048 + bgmac->int_status = 0;
1051 + bgmac_chip_intrs_on(bgmac);
1052 + return IRQ_HANDLED;
1055 +/**************************************************
1057 + **************************************************/
1059 +static int bgmac_open(struct net_device *net_dev)
1061 + struct bgmac *bgmac = netdev_priv(net_dev);
1063 + bgmac_chip_reset(bgmac);
1064 + /* Specs say about reclaiming rings here, but we do that in DMA init */
1065 + bgmac_chip_init(bgmac, true);
1067 + if (request_threaded_irq(bgmac->core->irq, bgmac_interrupt,
1068 + bgmac_interrupt_thread, IRQF_SHARED,
1069 + KBUILD_MODNAME, net_dev) < 0)
1070 + bgmac_err(bgmac, "IRQ request error!\n");
1075 +static int bgmac_stop(struct net_device *net_dev)
1077 + struct bgmac *bgmac = netdev_priv(net_dev);
1079 + bgmac_chip_intrs_off(bgmac);
1081 + free_irq(bgmac->core->irq, net_dev);
1088 +static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
1090 + struct bgmac *bgmac = netdev_priv(net_dev);
1091 + struct mii_ioctl_data *data = if_mii(ifr);
1095 + data->phy_id = bgmac->phyaddr;
1098 + if (!netif_running(net_dev))
1100 + data->val_out = bgmac_phy_read(bgmac, data->phy_id,
1101 + data->reg_num & 0x1f);
1104 + if (!netif_running(net_dev))
1106 + bgmac_phy_write(bgmac, data->phy_id, data->reg_num & 0x1f,
1110 + return -EOPNOTSUPP;
1114 +static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb,
1115 + struct net_device *net_dev)
1117 + struct bgmac *bgmac = netdev_priv(net_dev);
1118 + struct bgmac_dma_ring *ring;
1120 + /* No QOS support yet */
1121 + ring = &bgmac->tx_ring[0];
1122 + return bgmac_dma_tx_add(bgmac, ring, skb);
1125 +static const struct net_device_ops bgmac_netdev_ops = {
1126 + .ndo_open = bgmac_open,
1127 + .ndo_stop = bgmac_stop,
1128 + .ndo_do_ioctl = bgmac_ioctl,
1129 + .ndo_start_xmit = bgmac_start_xmit,
1132 +/**************************************************
1134 + **************************************************/
1136 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
1137 +static int bgmac_probe(struct bcma_device *core)
1139 + struct net_device *net_dev;
1140 + struct bgmac *bgmac;
1141 + struct ssb_sprom *sprom = &core->bus->sprom;
1144 + /* Allocation and references */
1145 + net_dev = alloc_etherdev(sizeof(*bgmac));
1148 + net_dev->netdev_ops = &bgmac_netdev_ops;
1149 + net_dev->irq = core->irq;
1150 + bgmac = netdev_priv(net_dev);
1151 + bgmac->net_dev = net_dev;
1152 + bgmac->core = core;
1153 + bcma_set_drvdata(core, bgmac);
1156 + bgmac->autoneg = true;
1157 + bgmac->full_duplex = true;
1158 + bgmac->speed = BGMAC_SPEED_10 | BGMAC_SPEED_100 | BGMAC_SPEED_1000;
1160 + /* On BCM4706 we need common core to access PHY */
1161 + if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
1162 + !core->bus->drv_gmac_cmn.core) {
1163 + bgmac_err(bgmac, "GMAC CMN core not found (required for BCM4706)\n");
1166 + bgmac->cmn = core->bus->drv_gmac_cmn.core;
1168 + bgmac->phyaddr = core->core_unit ? sprom->et1phyaddr :
1169 + sprom->et0phyaddr;
1170 + bgmac->phyaddr &= BGMAC_PHY_MASK;
1171 + if (bgmac->phyaddr == BGMAC_PHY_MASK) {
1172 + bgmac_err(bgmac, "No PHY found\n");
1175 + bgmac_info(bgmac, "Found PHY addr: %d\n", bgmac->phyaddr);
1177 + if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
1178 + bgmac_err(bgmac, "PCI setup not implemented\n");
1182 + bgmac_chip_reset(bgmac);
1184 + bgmac_dma_alloc(bgmac);
1186 + bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK;
1187 + if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) > 0)
1188 + bgmac->int_mask &= ~BGMAC_IS_TX_MASK;
1190 + /* TODO: reset the external phy */
1191 + bgmac_phy_reset(bgmac);
1193 + bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo &
1194 + BGMAC_BFL_ENETROBO);
1195 + if (bgmac->has_robosw)
1196 + bgmac_err(bgmac, "Support for Roboswitch not implemented\n");
1198 + if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM)
1199 + bgmac_err(bgmac, "Support for ADMtek ethernet switch not implemented\n");
1201 + err = register_netdev(bgmac->net_dev);
1203 + bgmac_err(bgmac, "Cannot register net device\n");
1210 +static void bgmac_remove(struct bcma_device *core)
1212 + struct bgmac *bgmac = bcma_get_drvdata(core);
1214 + unregister_netdev(bgmac->net_dev);
1215 + free_netdev(bgmac->net_dev);
1216 + bcma_set_drvdata(core, NULL);
1219 +static struct bcma_driver bgmac_bcma_driver = {
1220 + .name = KBUILD_MODNAME,
1221 + .id_table = bgmac_bcma_tbl,
1222 + .probe = bgmac_probe,
1223 + .remove = bgmac_remove,
1226 +static int __init bgmac_init(void)
1230 + err = bcma_driver_register(&bgmac_bcma_driver);
1233 + pr_info("Broadcom 47xx GMAC driver loaded\n");
1238 +static void __exit bgmac_exit(void)
1240 + bcma_driver_unregister(&bgmac_bcma_driver);
1243 +module_init(bgmac_init)
1244 +module_exit(bgmac_exit)
1246 +++ b/drivers/net/ethernet/broadcom/bgmac.h
1251 +#include <linux/bcma/bcma.h>
1253 +#define BGMAC_DEV_CTL 0x000
1254 +#define BGMAC_DC_TSM 0x00000002
1255 +#define BGMAC_DC_CFCO 0x00000004
1256 +#define BGMAC_DC_RLSS 0x00000008
1257 +#define BGMAC_DC_MROR 0x00000010
1258 +#define BGMAC_DC_FCM_MASK 0x00000060
1259 +#define BGMAC_DC_FCM_SHIFT 5
1260 +#define BGMAC_DC_NAE 0x00000080
1261 +#define BGMAC_DC_TF 0x00000100
1262 +#define BGMAC_DC_RDS_MASK 0x00030000
1263 +#define BGMAC_DC_RDS_SHIFT 16
1264 +#define BGMAC_DC_TDS_MASK 0x000c0000
1265 +#define BGMAC_DC_TDS_SHIFT 18
1266 +#define BGMAC_DEV_STATUS 0x004 /* Configuration of the interface */
1267 +#define BGMAC_DS_RBF 0x00000001
1268 +#define BGMAC_DS_RDF 0x00000002
1269 +#define BGMAC_DS_RIF 0x00000004
1270 +#define BGMAC_DS_TBF 0x00000008
1271 +#define BGMAC_DS_TDF 0x00000010
1272 +#define BGMAC_DS_TIF 0x00000020
1273 +#define BGMAC_DS_PO 0x00000040
1274 +#define BGMAC_DS_MM_MASK 0x00000300 /* Mode of the interface */
1275 +#define BGMAC_DS_MM_SHIFT 8
1276 +#define BGMAC_BIST_STATUS 0x00c
1277 +#define BGMAC_INT_STATUS 0x020 /* Interrupt status */
1278 +#define BGMAC_IS_MRO 0x00000001
1279 +#define BGMAC_IS_MTO 0x00000002
1280 +#define BGMAC_IS_TFD 0x00000004
1281 +#define BGMAC_IS_LS 0x00000008
1282 +#define BGMAC_IS_MDIO 0x00000010
1283 +#define BGMAC_IS_MR 0x00000020
1284 +#define BGMAC_IS_MT 0x00000040
1285 +#define BGMAC_IS_TO 0x00000080
1286 +#define BGMAC_IS_DESC_ERR 0x00000400 /* Descriptor error */
1287 +#define BGMAC_IS_DATA_ERR 0x00000800 /* Data error */
1288 +#define BGMAC_IS_DESC_PROT_ERR 0x00001000 /* Descriptor protocol error */
1289 +#define BGMAC_IS_RX_DESC_UNDERF 0x00002000 /* Receive descriptor underflow */
1290 +#define BGMAC_IS_RX_F_OVERF 0x00004000 /* Receive fifi overflow */
1291 +#define BGMAC_IS_TX_F_UNDERF 0x00008000 /* Transmit fifo underflow */
1292 +#define BGMAC_IS_RX 0x00010000 /* Interrupt for RX queue 0 */
1293 +#define BGMAC_IS_TX0 0x01000000 /* Interrupt for TX queue 0 */
1294 +#define BGMAC_IS_TX1 0x02000000 /* Interrupt for TX queue 1 */
1295 +#define BGMAC_IS_TX2 0x04000000 /* Interrupt for TX queue 2 */
1296 +#define BGMAC_IS_TX3 0x08000000 /* Interrupt for TX queue 3 */
1297 +#define BGMAC_IS_TX_MASK 0x0f000000
1298 +#define BGMAC_IS_INTMASK 0x0f01fcff
1299 +#define BGMAC_IS_ERRMASK 0x0000fc00
1300 +#define BGMAC_INT_MASK 0x024 /* Interrupt mask */
1301 +#define BGMAC_GP_TIMER 0x028
1302 +#define BGMAC_INT_RECV_LAZY 0x100
1303 +#define BGMAC_IRL_TO_MASK 0x00ffffff
1304 +#define BGMAC_IRL_FC_MASK 0xff000000
1305 +#define BGMAC_IRL_FC_SHIFT 24 /* Shift the number of interrupts triggered per received frame */
1306 +#define BGMAC_FLOW_CTL_THRESH 0x104 /* Flow control thresholds */
1307 +#define BGMAC_WRRTHRESH 0x108
1308 +#define BGMAC_GMAC_IDLE_CNT_THRESH 0x10c
1309 +#define BGMAC_PHY_ACCESS 0x180 /* PHY access address */
1310 +#define BGMAC_PA_DATA_MASK 0x0000ffff
1311 +#define BGMAC_PA_ADDR_MASK 0x001f0000
1312 +#define BGMAC_PA_ADDR_SHIFT 16
1313 +#define BGMAC_PA_REG_MASK 0x1f000000
1314 +#define BGMAC_PA_REG_SHIFT 24
1315 +#define BGMAC_PA_WRITE 0x20000000
1316 +#define BGMAC_PA_START 0x40000000
1317 +#define BGMAC_PHY_CNTL 0x188 /* PHY control address */
1318 +#define BGMAC_PC_EPA_MASK 0x0000001f
1319 +#define BGMAC_PC_MCT_MASK 0x007f0000
1320 +#define BGMAC_PC_MCT_SHIFT 16
1321 +#define BGMAC_PC_MTE 0x00800000
1322 +#define BGMAC_TXQ_CTL 0x18c
1323 +#define BGMAC_TXQ_CTL_DBT_MASK 0x00000fff
1324 +#define BGMAC_TXQ_CTL_DBT_SHIFT 0
1325 +#define BGMAC_RXQ_CTL 0x190
1326 +#define BGMAC_RXQ_CTL_DBT_MASK 0x00000fff
1327 +#define BGMAC_RXQ_CTL_DBT_SHIFT 0
1328 +#define BGMAC_RXQ_CTL_PTE 0x00001000
1329 +#define BGMAC_RXQ_CTL_MDP_MASK 0x3f000000
1330 +#define BGMAC_RXQ_CTL_MDP_SHIFT 24
1331 +#define BGMAC_GPIO_SELECT 0x194
1332 +#define BGMAC_GPIO_OUTPUT_EN 0x198
1333 +/* For 0x1e0 see BCMA_CLKCTLST */
1334 +#define BGMAC_HW_WAR 0x1e4
1335 +#define BGMAC_PWR_CTL 0x1e8
1336 +#define BGMAC_DMA_BASE0 0x200 /* Tx and Rx controller */
1337 +#define BGMAC_DMA_BASE1 0x240 /* Tx controller only */
1338 +#define BGMAC_DMA_BASE2 0x280 /* Tx controller only */
1339 +#define BGMAC_DMA_BASE3 0x2C0 /* Tx controller only */
1340 +#define BGMAC_TX_GOOD_OCTETS 0x300
1341 +#define BGMAC_TX_GOOD_OCTETS_HIGH 0x304
1342 +#define BGMAC_TX_GOOD_PKTS 0x308
1343 +#define BGMAC_TX_OCTETS 0x30c
1344 +#define BGMAC_TX_OCTETS_HIGH 0x310
1345 +#define BGMAC_TX_PKTS 0x314
1346 +#define BGMAC_TX_BROADCAST_PKTS 0x318
1347 +#define BGMAC_TX_MULTICAST_PKTS 0x31c
1348 +#define BGMAC_TX_LEN_64 0x320
1349 +#define BGMAC_TX_LEN_65_TO_127 0x324
1350 +#define BGMAC_TX_LEN_128_TO_255 0x328
1351 +#define BGMAC_TX_LEN_256_TO_511 0x32c
1352 +#define BGMAC_TX_LEN_512_TO_1023 0x330
1353 +#define BGMAC_TX_LEN_1024_TO_1522 0x334
1354 +#define BGMAC_TX_LEN_1523_TO_2047 0x338
1355 +#define BGMAC_TX_LEN_2048_TO_4095 0x33c
1356 +#define BGMAC_TX_LEN_4095_TO_8191 0x340
1357 +#define BGMAC_TX_LEN_8192_TO_MAX 0x344
1358 +#define BGMAC_TX_JABBER_PKTS 0x348 /* Error */
1359 +#define BGMAC_TX_OVERSIZE_PKTS 0x34c /* Error */
1360 +#define BGMAC_TX_FRAGMENT_PKTS 0x350
1361 +#define BGMAC_TX_UNDERRUNS 0x354 /* Error */
1362 +#define BGMAC_TX_TOTAL_COLS 0x358
1363 +#define BGMAC_TX_SINGLE_COLS 0x35c
1364 +#define BGMAC_TX_MULTIPLE_COLS 0x360
1365 +#define BGMAC_TX_EXCESSIVE_COLS 0x364 /* Error */
1366 +#define BGMAC_TX_LATE_COLS 0x368 /* Error */
1367 +#define BGMAC_TX_DEFERED 0x36c
1368 +#define BGMAC_TX_CARRIER_LOST 0x370
1369 +#define BGMAC_TX_PAUSE_PKTS 0x374
1370 +#define BGMAC_TX_UNI_PKTS 0x378
1371 +#define BGMAC_TX_Q0_PKTS 0x37c
1372 +#define BGMAC_TX_Q0_OCTETS 0x380
1373 +#define BGMAC_TX_Q0_OCTETS_HIGH 0x384
1374 +#define BGMAC_TX_Q1_PKTS 0x388
1375 +#define BGMAC_TX_Q1_OCTETS 0x38c
1376 +#define BGMAC_TX_Q1_OCTETS_HIGH 0x390
1377 +#define BGMAC_TX_Q2_PKTS 0x394
1378 +#define BGMAC_TX_Q2_OCTETS 0x398
1379 +#define BGMAC_TX_Q2_OCTETS_HIGH 0x39c
1380 +#define BGMAC_TX_Q3_PKTS 0x3a0
1381 +#define BGMAC_TX_Q3_OCTETS 0x3a4
1382 +#define BGMAC_TX_Q3_OCTETS_HIGH 0x3a8
1383 +#define BGMAC_RX_GOOD_OCTETS 0x3b0
1384 +#define BGMAC_RX_GOOD_OCTETS_HIGH 0x3b4
1385 +#define BGMAC_RX_GOOD_PKTS 0x3b8
1386 +#define BGMAC_RX_OCTETS 0x3bc
1387 +#define BGMAC_RX_OCTETS_HIGH 0x3c0
1388 +#define BGMAC_RX_PKTS 0x3c4
1389 +#define BGMAC_RX_BROADCAST_PKTS 0x3c8
1390 +#define BGMAC_RX_MULTICAST_PKTS 0x3cc
1391 +#define BGMAC_RX_LEN_64 0x3d0
1392 +#define BGMAC_RX_LEN_65_TO_127 0x3d4
1393 +#define BGMAC_RX_LEN_128_TO_255 0x3d8
1394 +#define BGMAC_RX_LEN_256_TO_511 0x3dc
1395 +#define BGMAC_RX_LEN_512_TO_1023 0x3e0
1396 +#define BGMAC_RX_LEN_1024_TO_1522 0x3e4
1397 +#define BGMAC_RX_LEN_1523_TO_2047 0x3e8
1398 +#define BGMAC_RX_LEN_2048_TO_4095 0x3ec
1399 +#define BGMAC_RX_LEN_4095_TO_8191 0x3f0
1400 +#define BGMAC_RX_LEN_8192_TO_MAX 0x3f4
1401 +#define BGMAC_RX_JABBER_PKTS 0x3f8 /* Error */
1402 +#define BGMAC_RX_OVERSIZE_PKTS 0x3fc /* Error */
1403 +#define BGMAC_RX_FRAGMENT_PKTS 0x400
1404 +#define BGMAC_RX_MISSED_PKTS 0x404 /* Error */
1405 +#define BGMAC_RX_CRC_ALIGN_ERRS 0x408 /* Error */
1406 +#define BGMAC_RX_UNDERSIZE 0x40c /* Error */
1407 +#define BGMAC_RX_CRC_ERRS 0x410 /* Error */
1408 +#define BGMAC_RX_ALIGN_ERRS 0x414 /* Error */
1409 +#define BGMAC_RX_SYMBOL_ERRS 0x418 /* Error */
1410 +#define BGMAC_RX_PAUSE_PKTS 0x41c
1411 +#define BGMAC_RX_NONPAUSE_PKTS 0x420
1412 +#define BGMAC_RX_SACHANGES 0x424
1413 +#define BGMAC_RX_UNI_PKTS 0x428
1414 +#define BGMAC_UNIMAC_VERSION 0x800
1415 +#define BGMAC_HDBKP_CTL 0x804
1416 +#define BGMAC_CMDCFG 0x808 /* Configuration */
1417 +#define BGMAC_CMDCFG_TE 0x00000001 /* Set to activate TX */
1418 +#define BGMAC_CMDCFG_RE 0x00000002 /* Set to activate RX */
1419 +#define BGMAC_CMDCFG_ES_MASK 0x0000000c /* Ethernet speed see gmac_speed */
1420 +#define BGMAC_CMDCFG_ES_10 0x00000000
1421 +#define BGMAC_CMDCFG_ES_100 0x00000004
1422 +#define BGMAC_CMDCFG_ES_1000 0x00000008
1423 +#define BGMAC_CMDCFG_PROM 0x00000010 /* Set to activate promiscuous mode */
1424 +#define BGMAC_CMDCFG_PAD_EN 0x00000020
1425 +#define BGMAC_CMDCFG_CF 0x00000040
1426 +#define BGMAC_CMDCFG_PF 0x00000080
1427 +#define BGMAC_CMDCFG_RPI 0x00000100 /* Unset to enable 802.3x tx flow control */
1428 +#define BGMAC_CMDCFG_TAI 0x00000200
1429 +#define BGMAC_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */
1430 +#define BGMAC_CMDCFG_HD_SHIFT 10
1431 +#define BGMAC_CMDCFG_SR 0x00000800 /* Set to reset mode */
1432 +#define BGMAC_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */
1433 +#define BGMAC_CMDCFG_AE 0x00400000
1434 +#define BGMAC_CMDCFG_CFE 0x00800000
1435 +#define BGMAC_CMDCFG_NLC 0x01000000
1436 +#define BGMAC_CMDCFG_RL 0x02000000
1437 +#define BGMAC_CMDCFG_RED 0x04000000
1438 +#define BGMAC_CMDCFG_PE 0x08000000
1439 +#define BGMAC_CMDCFG_TPI 0x10000000
1440 +#define BGMAC_CMDCFG_AT 0x20000000
1441 +#define BGMAC_MACADDR_HIGH 0x80c /* High 4 octets of own mac address */
1442 +#define BGMAC_MACADDR_LOW 0x810 /* Low 2 octets of own mac address */
1443 +#define BGMAC_RXMAX_LENGTH 0x814 /* Max receive frame length with vlan tag */
1444 +#define BGMAC_PAUSEQUANTA 0x818
1445 +#define BGMAC_MAC_MODE 0x844
1446 +#define BGMAC_OUTERTAG 0x848
1447 +#define BGMAC_INNERTAG 0x84c
1448 +#define BGMAC_TXIPG 0x85c
1449 +#define BGMAC_PAUSE_CTL 0xb30
1450 +#define BGMAC_TX_FLUSH 0xb34
1451 +#define BGMAC_RX_STATUS 0xb38
1452 +#define BGMAC_TX_STATUS 0xb3c
1454 +#define BGMAC_PHY_CTL 0x00
1455 +#define BGMAC_PHY_CTL_SPEED_MSB 0x0040
1456 +#define BGMAC_PHY_CTL_DUPLEX 0x0100 /* duplex mode */
1457 +#define BGMAC_PHY_CTL_RESTART 0x0200 /* restart autonegotiation */
1458 +#define BGMAC_PHY_CTL_ANENAB 0x1000 /* enable autonegotiation */
1459 +#define BGMAC_PHY_CTL_SPEED 0x2000
1460 +#define BGMAC_PHY_CTL_LOOP 0x4000 /* loopback */
1461 +#define BGMAC_PHY_CTL_RESET 0x8000 /* reset */
1463 +#define BGMAC_PHY_CTL_SPEED_10 0
1464 +#define BGMAC_PHY_CTL_SPEED_100 BGMAC_PHY_CTL_SPEED
1465 +#define BGMAC_PHY_CTL_SPEED_1000 BGMAC_PHY_CTL_SPEED_MSB
1466 +#define BGMAC_PHY_ADV 0x04
1467 +#define BGMAC_PHY_ADV_10HALF 0x0020 /* advertise 10MBits/s half duplex */
1468 +#define BGMAC_PHY_ADV_10FULL 0x0040 /* advertise 10MBits/s full duplex */
1469 +#define BGMAC_PHY_ADV_100HALF 0x0080 /* advertise 100MBits/s half duplex */
1470 +#define BGMAC_PHY_ADV_100FULL 0x0100 /* advertise 100MBits/s full duplex */
1471 +#define BGMAC_PHY_ADV2 0x09
1472 +#define BGMAC_PHY_ADV2_1000HALF 0x0100 /* advertise 1000MBits/s half duplex */
1473 +#define BGMAC_PHY_ADV2_1000FULL 0x0200 /* advertise 1000MBits/s full duplex */
1475 +/* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */
1476 +#define BGMAC_BCMA_IOCTL_SW_CLKEN 0x00000004 /* PHY Clock Enable */
1477 +#define BGMAC_BCMA_IOCTL_SW_RESET 0x00000008 /* PHY Reset */
1479 +/* BCMA GMAC core specific IO status (BCMA_IOST) flags */
1480 +#define BGMAC_BCMA_IOST_ATTACHED 0x00000800
1482 +#define BGMAC_NUM_MIB_TX_REGS \
1483 + (((BGMAC_TX_Q3_OCTETS_HIGH - BGMAC_TX_GOOD_OCTETS) / 4) + 1)
1484 +#define BGMAC_NUM_MIB_RX_REGS \
1485 + (((BGMAC_RX_UNI_PKTS - BGMAC_RX_GOOD_OCTETS) / 4) + 1)
1487 +#define BGMAC_DMA_TX_CTL 0x00
1488 +#define BGMAC_DMA_TX_ENABLE 0x00000001
1489 +#define BGMAC_DMA_TX_SUSPEND 0x00000002
1490 +#define BGMAC_DMA_TX_LOOPBACK 0x00000004
1491 +#define BGMAC_DMA_TX_FLUSH 0x00000010
1492 +#define BGMAC_DMA_TX_PARITY_DISABLE 0x00000800
1493 +#define BGMAC_DMA_TX_ADDREXT_MASK 0x00030000
1494 +#define BGMAC_DMA_TX_ADDREXT_SHIFT 16
1495 +#define BGMAC_DMA_TX_INDEX 0x04
1496 +#define BGMAC_DMA_TX_RINGLO 0x08
1497 +#define BGMAC_DMA_TX_RINGHI 0x0C
1498 +#define BGMAC_DMA_TX_STATUS 0x10
1499 +#define BGMAC_DMA_TX_STATDPTR 0x00001FFF
1500 +#define BGMAC_DMA_TX_STAT 0xF0000000
1501 +#define BGMAC_DMA_TX_STAT_DISABLED 0x00000000
1502 +#define BGMAC_DMA_TX_STAT_ACTIVE 0x10000000
1503 +#define BGMAC_DMA_TX_STAT_IDLEWAIT 0x20000000
1504 +#define BGMAC_DMA_TX_STAT_STOPPED 0x30000000
1505 +#define BGMAC_DMA_TX_STAT_SUSP 0x40000000
1506 +#define BGMAC_DMA_TX_ERROR 0x14
1507 +#define BGMAC_DMA_TX_ERRDPTR 0x0001FFFF
1508 +#define BGMAC_DMA_TX_ERR 0xF0000000
1509 +#define BGMAC_DMA_TX_ERR_NOERR 0x00000000
1510 +#define BGMAC_DMA_TX_ERR_PROT 0x10000000
1511 +#define BGMAC_DMA_TX_ERR_UNDERRUN 0x20000000
1512 +#define BGMAC_DMA_TX_ERR_TRANSFER 0x30000000
1513 +#define BGMAC_DMA_TX_ERR_DESCREAD 0x40000000
1514 +#define BGMAC_DMA_TX_ERR_CORE 0x50000000
1515 +#define BGMAC_DMA_RX_CTL 0x20
1516 +#define BGMAC_DMA_RX_ENABLE 0x00000001
1517 +#define BGMAC_DMA_RX_FRAME_OFFSET_MASK 0x000000FE
1518 +#define BGMAC_DMA_RX_FRAME_OFFSET_SHIFT 1
1519 +#define BGMAC_DMA_RX_DIRECT_FIFO 0x00000100
1520 +#define BGMAC_DMA_RX_OVERFLOW_CONT 0x00000400
1521 +#define BGMAC_DMA_RX_PARITY_DISABLE 0x00000800
1522 +#define BGMAC_DMA_RX_ADDREXT_MASK 0x00030000
1523 +#define BGMAC_DMA_RX_ADDREXT_SHIFT 16
1524 +#define BGMAC_DMA_RX_INDEX 0x24
1525 +#define BGMAC_DMA_RX_RINGLO 0x28
1526 +#define BGMAC_DMA_RX_RINGHI 0x2C
1527 +#define BGMAC_DMA_RX_STATUS 0x30
1528 +#define BGMAC_DMA_RX_STATDPTR 0x00001FFF
1529 +#define BGMAC_DMA_RX_STAT 0xF0000000
1530 +#define BGMAC_DMA_RX_STAT_DISABLED 0x00000000
1531 +#define BGMAC_DMA_RX_STAT_ACTIVE 0x10000000
1532 +#define BGMAC_DMA_RX_STAT_IDLEWAIT 0x20000000
1533 +#define BGMAC_DMA_RX_STAT_STOPPED 0x30000000
1534 +#define BGMAC_DMA_RX_STAT_SUSP 0x40000000
1535 +#define BGMAC_DMA_RX_ERROR 0x34
1536 +#define BGMAC_DMA_RX_ERRDPTR 0x0001FFFF
1537 +#define BGMAC_DMA_RX_ERR 0xF0000000
1538 +#define BGMAC_DMA_RX_ERR_NOERR 0x00000000
1539 +#define BGMAC_DMA_RX_ERR_PROT 0x10000000
1540 +#define BGMAC_DMA_RX_ERR_UNDERRUN 0x20000000
1541 +#define BGMAC_DMA_RX_ERR_TRANSFER 0x30000000
1542 +#define BGMAC_DMA_RX_ERR_DESCREAD 0x40000000
1543 +#define BGMAC_DMA_RX_ERR_CORE 0x50000000
1545 +#define BGMAC_DESC_CTL0_EOT 0x10000000 /* End of ring */
1546 +#define BGMAC_DESC_CTL0_IOC 0x20000000 /* IRQ on complete */
1547 +#define BGMAC_DESC_CTL0_SOF 0x40000000 /* Start of frame */
1548 +#define BGMAC_DESC_CTL0_EOF 0x80000000 /* End of frame */
1549 +#define BGMAC_DESC_CTL1_LEN 0x00001FFF
1551 +#define BGMAC_PHY_NOREGS 0x1E
1552 +#define BGMAC_PHY_MASK 0x1F
1554 +#define BGMAC_MAX_TX_RINGS 4
1555 +#define BGMAC_MAX_RX_RINGS 1
1557 +#define BGMAC_TX_RING_SLOTS 128
1558 +#define BGMAC_RX_RING_SLOTS 512 - 1 /* Why -1? Well, Broadcom does that... */
1560 +#define BGMAC_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */
1561 +#define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */
1562 +#define BGMAC_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */
1563 +#define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
1565 +#define BGMAC_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */
1566 +#define BGMAC_BFL_ENETADM 0x0080 /* has ADMtek switch */
1567 +#define BGMAC_BFL_ENETVLAN 0x0100 /* can do vlan */
1569 +#define BGMAC_CHIPCTL_1_IF_TYPE_MASK 0x00000030
1570 +#define BGMAC_CHIPCTL_1_IF_TYPE_RMII 0x00000000
1571 +#define BGMAC_CHIPCTL_1_IF_TYPE_MI 0x00000010
1572 +#define BGMAC_CHIPCTL_1_IF_TYPE_RGMII 0x00000020
1573 +#define BGMAC_CHIPCTL_1_SW_TYPE_MASK 0x000000C0
1574 +#define BGMAC_CHIPCTL_1_SW_TYPE_EPHY 0x00000000
1575 +#define BGMAC_CHIPCTL_1_SW_TYPE_EPHYMII 0x00000040
1576 +#define BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII 0x00000080
1577 +#define BGMAC_CHIPCTL_1_SW_TYPE_RGMI 0x000000C0
1578 +#define BGMAC_CHIPCTL_1_RXC_DLL_BYPASS 0x00010000
1580 +#define BGMAC_SPEED_10 0x0001
1581 +#define BGMAC_SPEED_100 0x0002
1582 +#define BGMAC_SPEED_1000 0x0004
1584 +struct bgmac_slot_info {
1585 + struct sk_buff *skb;
1586 + dma_addr_t dma_addr;
1589 +struct bgmac_dma_desc {
1596 +struct bgmac_dma_ring {
1604 + dma_addr_t dma_base;
1606 + struct bgmac_slot_info slots[BGMAC_RX_RING_SLOTS];
1609 +struct bgmac_rx_header {
1616 + struct bcma_device *core;
1617 + struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */
1618 + struct net_device *net_dev;
1633 + struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS];
1634 + struct bgmac_dma_ring rx_ring[BGMAC_MAX_RX_RINGS];
1637 + bool stats_grabbed;
1638 + u32 mib_tx_regs[BGMAC_NUM_MIB_TX_REGS];
1639 + u32 mib_rx_regs[BGMAC_NUM_MIB_RX_REGS];
1642 +static inline u32 bgmac_read(struct bgmac *bgmac, u16 offset)
1644 + return bcma_read32(bgmac->core, offset);
1647 +static inline void bgmac_write(struct bgmac *bgmac, u16 offset, u32 value)
1649 + bcma_write32(bgmac->core, offset, value);
1652 +static inline void bgmac_maskset(struct bgmac *bgmac, u16 offset, u32 mask,
1655 + bgmac_write(bgmac, offset, (bgmac_read(bgmac, offset) & mask) | set);
1658 +static inline void bgmac_mask(struct bgmac *bgmac, u16 offset, u32 mask)
1660 + bgmac_maskset(bgmac, offset, mask, 0);
1663 +static inline void bgmac_set(struct bgmac *bgmac, u16 offset, u32 set)
1665 + bgmac_maskset(bgmac, offset, ~0, set);
1668 +u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg);
1669 +void bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value);
1671 +#endif /* _BGMAC_H */
1672 --- a/include/linux/bcma/bcma_driver_chipcommon.h
1673 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
1674 @@ -627,4 +627,6 @@ int bcma_nflash_erase(struct bcma_drv_cc
1675 int bcma_nflash_commit(struct bcma_drv_cc *cc, u32 offset, u32 len, const u8 *buf);
1678 +extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc);
1680 #endif /* LINUX_BCMA_DRIVER_CC_H_ */