brcm47xx: add bgmac driver
[openwrt.git] / target / linux / brcm47xx / patches-3.6 / 750-bgmac.patch
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
4  }
5  
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)
9  {
10         struct bcma_bus *bus = cc->core->bus;
11  
12 @@ -292,6 +292,7 @@ static u32 bcma_pmu_get_bus_clock(struct
13         }
14         return BCMA_CC_PMU_HT_CLOCK;
15  }
16 +EXPORT_SYMBOL_GPL(bcma_pmu_get_bus_clock);
17  
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.
25  
26 +config BGMAC
27 +       tristate "Broadcom Gigabit driver"
28 +       depends on BCMA
29 +       ---help---
30 +         This driver supports Broadcom Gigabit core found in some BCM47xx SoCs.
31 +
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
40 --- /dev/null
41 +++ b/drivers/net/ethernet/broadcom/bgmac.c
42 @@ -0,0 +1,1202 @@
43 +#define pr_fmt(fmt)            KBUILD_MODNAME ": " fmt
44 +
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__)
53 +
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>
62 +
63 +#include "bgmac.h"
64 +
65 +#define ETHER_MAX_LEN   1518
66 +
67 +MODULE_LICENSE("GPL");
68 +
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),
72 +       BCMA_CORETABLE_END
73 +};
74 +MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
75 +
76 +static bool bgmac_wait_value(struct bcma_device *core, u16 reg, u32 mask,
77 +                            u32 value, int timeout)
78 +{
79 +       u32 val;
80 +       int i;
81 +
82 +       for (i = 0; i < timeout / 10; i++) {
83 +               val = bcma_read32(core, reg);
84 +               if ((val & mask) == value)
85 +                       return true;
86 +               udelay(10);
87 +       }
88 +       pr_err("Timeout waiting for reg 0x%X\n", reg);
89 +       return false;
90 +}
91 +
92 +/**************************************************
93 + * DMA
94 + **************************************************/
95 +
96 +static void bgmac_dma_tx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
97 +{
98 +       u32 val;
99 +       int i;
100 +
101 +       if (!ring->mmio_base)
102 +               return;
103 +
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.
107 +        */
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) {
115 +                       i = 0;
116 +                       break;
117 +               }
118 +               udelay(10);
119 +       }
120 +       if (i)
121 +               bgmac_err(bgmac, "Timeout suspending DMA TX ring 0x%X\n", ring->mmio_base);
122 +
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,
128 +                             10000)) {
129 +               bgmac_warn(bgmac, "DMA TX ring 0x%X wasn't disabled on time, waiting additional 300us\n", ring->mmio_base);
130 +               udelay(300);
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);
134 +       }
135 +}
136 +
137 +static void bgmac_dma_tx_enable(struct bgmac *bgmac,
138 +                               struct bgmac_dma_ring *ring)
139 +{
140 +       u32 ctl;
141 +
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);
146 +}
147 +
148 +static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
149 +                                   struct bgmac_dma_ring *ring,
150 +                                   struct sk_buff *skb)
151 +{
152 +       struct device *dma_dev = bgmac->core->dma_dev;
153 +       struct bgmac_dma_desc *dma_desc;
154 +       struct bgmac_slot_info *slot;
155 +       u32 ctl0, ctl1;
156 +       int free_slots;
157 +
158 +       if (skb->len > BGMAC_DESC_CTL1_LEN) {
159 +               bgmac_err(bgmac, "Too long skb (%d)\n", skb->len);
160 +               return NETDEV_TX_BUSY;
161 +       }
162 +
163 +       if (ring->start <= ring->end)
164 +               free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS;
165 +       else
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;
171 +       }
172 +
173 +       slot = &ring->slots[ring->end];
174 +       slot->skb = skb;
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;
179 +       }
180 +
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;
185 +
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);
192 +
193 +       wmb();
194 +
195 +       /* Increase ring->end to point empty slot. We tell hardware the first
196 +        * slot it shold *not* read.
197 +        */
198 +       if (++ring->end >= BGMAC_TX_RING_SLOTS)
199 +               ring->end = 0;
200 +       bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,
201 +                   ring->end * sizeof(struct bgmac_dma_desc));
202 +
203 +       return NETDEV_TX_OK;
204 +}
205 +
206 +/* Free transmitted packets */
207 +static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
208 +{
209 +       struct device *dma_dev = bgmac->core->dma_dev;
210 +       struct bgmac_dma_desc *dma_desc;
211 +       struct bgmac_slot_info *slot;
212 +       int empty_slot;
213 +
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);
218 +
219 +       while (ring->start != empty_slot) {
220 +               /* Set pointers */
221 +               dma_desc = ring->cpu_base;
222 +               dma_desc += ring->start;
223 +               slot = &ring->slots[ring->start];
224 +
225 +               if (slot->skb) {
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;
230 +
231 +                       /* Free memory!  */
232 +                       dev_kfree_skb_any(slot->skb);
233 +                       slot->skb = NULL;
234 +               } else {
235 +                       bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d", ring->start, ring->end);
236 +               }
237 +
238 +               if (++ring->start >= BGMAC_TX_RING_SLOTS)
239 +                       ring->start = 0;
240 +       }
241 +}
242 +
243 +static void bgmac_dma_rx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
244 +{
245 +       if (!ring->mmio_base)
246 +               return;
247 +
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,
252 +                             10000))
253 +               bgmac_err(bgmac, "Reset of ring 0x%X RX failed\n", ring->mmio_base);
254 +}
255 +
256 +static void bgmac_dma_rx_enable(struct bgmac *bgmac,
257 +                               struct bgmac_dma_ring *ring)
258 +{
259 +       u32 ctl;
260 +
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);
268 +}
269 +
270 +static void bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
271 +                                     struct bgmac_slot_info *slot)
272 +{
273 +       struct device *dma_dev = bgmac->core->dma_dev;
274 +       struct bgmac_rx_header *rx;
275 +
276 +       /* Alloc skb */
277 +       slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
278 +       if (!slot->skb)
279 +               bgmac_err(bgmac, "Allocation of skb failed!\n");
280 +
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);
285 +
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");
293 +}
294 +
295 +static void bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
296 +{
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;
302 +       u32 end_slot;
303 +       u16 len, flags;
304 +
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);
308 +
309 +       ring->end = end_slot;
310 +
311 +       while (ring->start != ring->end) {
312 +               /* Set pointers */
313 +               dma_desc = ring->cpu_base;
314 +               dma_desc += ring->start;
315 +               slot = &ring->slots[ring->start];
316 +               skb = slot->skb;
317 +
318 +               /* Unmap buffer to make it accessible to the CPU */
319 +               dma_unmap_single(dma_dev, slot->dma_addr, BGMAC_RX_BUF_SIZE,
320 +                                DMA_FROM_DEVICE);
321 +
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);
326 +
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);
331 +               } else {
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);
337 +               }
338 +
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));
343 +
344 +               if (++ring->start >= BGMAC_RX_RING_SLOTS)
345 +                       ring->start = 0;
346 +       }
347 +}
348 +
349 +/* Does ring support unaligned addressing? */
350 +static bool bgmac_dma_unaligned(struct bgmac *bgmac,
351 +                               struct bgmac_dma_ring *ring)
352 +{
353 +       if (ring->tx) {
354 +               bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
355 +                           0xff0);
356 +               if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO))
357 +                       return true;
358 +       } else {
359 +               bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
360 +                           0xff0);
361 +               if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO))
362 +                       return true;
363 +       }
364 +       return false;
365 +}
366 +
367 +static int bgmac_dma_alloc(struct bgmac *bgmac)
368 +{
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 */
374 +       int i;
375 +
376 +       BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base));
377 +       BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base));
378 +
379 +       if (!(bcma_aread32(bgmac->core, BCMA_IOST) & BCMA_IOST_DMA64)) {
380 +               bgmac_err(bgmac, "Core does not report 64-bit DMA\n");
381 +               return -ENOTSUPP;
382 +       }
383 +
384 +       for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
385 +               ring = &bgmac->tx_ring[i];
386 +               ring->tx = true;
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);
391 +
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,
395 +                                                    &(ring->dma_base),
396 +                                                    GFP_KERNEL);
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");
401 +
402 +               /* No need to alloc TX slots yet */
403 +       }
404 +
405 +       for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
406 +               ring = &bgmac->rx_ring[i];
407 +               ring->tx = false;
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);
412 +
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,
416 +                                                    &(ring->dma_base),
417 +                                                    GFP_KERNEL);
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");
422 +
423 +               /* Alloc RX slots */
424 +               for (i = 0; i < ring->num_slots; i++)
425 +                       bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[i]);
426 +       }
427 +
428 +       return 0;
429 +}
430 +
431 +static void bgmac_dma_init(struct bgmac *bgmac)
432 +{
433 +       struct bgmac_dma_ring *ring;
434 +       struct bgmac_dma_desc *dma_desc;
435 +       u32 ctl0, ctl1;
436 +       int i;
437 +
438 +       for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
439 +               ring = &bgmac->tx_ring[i];
440 +
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));
447 +
448 +               ring->start = 0;
449 +               ring->end = 0;  /* Points the slot that should *not* be read */
450 +       }
451 +
452 +       for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
453 +               ring = &bgmac->rx_ring[i];
454 +
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));
461 +
462 +               for (i = 0, dma_desc = ring->cpu_base; i < ring->num_slots;
463 +                    i++, dma_desc++) {
464 +                       ctl0 = ctl1 = 0;
465 +
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;
472 +                        */
473 +
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);
478 +               }
479 +
480 +               bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
481 +                           ring->num_slots * sizeof(struct bgmac_dma_desc));
482 +
483 +               ring->start = 0;
484 +               ring->end = 0;
485 +       }
486 +}
487 +
488 +/**************************************************
489 + * PHY ops
490 + **************************************************/
491 +
492 +u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg)
493 +{
494 +       struct bcma_device *core;
495 +       u16 phy_access_addr;
496 +       u16 phy_ctl_addr;
497 +       u32 tmp;
498 +
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);
510 +
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;
515 +       } else {
516 +               core = bgmac->core;
517 +               phy_access_addr = BGMAC_PHY_ACCESS;
518 +               phy_ctl_addr = BGMAC_PHY_CNTL;
519 +       }
520 +
521 +       tmp = bcma_read32(core, phy_ctl_addr);
522 +       tmp &= ~BGMAC_PC_EPA_MASK;
523 +       tmp |= phyaddr;
524 +       bcma_write32(core, phy_ctl_addr, tmp);
525 +
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);
530 +
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",
533 +                         phyaddr, reg);
534 +               return 0xffff;
535 +       }
536 +
537 +       return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK;
538 +}
539 +
540 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */
541 +void bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value)
542 +{
543 +       struct bcma_device *core;
544 +       u16 phy_access_addr;
545 +       u16 phy_ctl_addr;
546 +       u32 tmp;
547 +
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;
552 +       } else {
553 +               core = bgmac->core;
554 +               phy_access_addr = BGMAC_PHY_ACCESS;
555 +               phy_ctl_addr = BGMAC_PHY_CNTL;
556 +       }
557 +
558 +       tmp = bcma_read32(core, phy_ctl_addr);
559 +       tmp &= ~BGMAC_PC_EPA_MASK;
560 +       tmp |= phyaddr;
561 +       bcma_write32(core, phy_ctl_addr, tmp);
562 +
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");
566 +
567 +       tmp = BGMAC_PA_START;
568 +       tmp |= BGMAC_PA_WRITE;
569 +       tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
570 +       tmp |= reg << BGMAC_PA_REG_SHIFT;
571 +       tmp |= value;
572 +       bcma_write32(core, phy_access_addr, tmp);
573 +
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",
576 +                         phyaddr, reg);
577 +}
578 +
579 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyforce */
580 +static void bgmac_phy_force(struct bgmac *bgmac)
581 +{
582 +       u16 ctl;
583 +       u16 mask = ~(BGMAC_PHY_CTL_SPEED | BGMAC_PHY_CTL_SPEED_MSB |
584 +                    BGMAC_PHY_CTL_ANENAB | BGMAC_PHY_CTL_DUPLEX);
585 +
586 +       if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
587 +               return;
588 +
589 +       if (bgmac->autoneg)
590 +               return;
591 +
592 +       ctl = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL);
593 +       ctl &= mask;
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);
601 +}
602 +
603 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyadvertise */
604 +static void bgmac_phy_advertise(struct bgmac *bgmac)
605 +{
606 +       u16 adv;
607 +
608 +       if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
609 +               return;
610 +
611 +       if (bgmac->autoneg)
612 +               return;
613 +
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);
627 +
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);
636 +
637 +       /* Restart */
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);
641 +}
642 +
643 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */
644 +static void bgmac_phy_init(struct bgmac *bgmac)
645 +{
646 +       struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
647 +       struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
648 +       u8 i;
649 +
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);
657 +               }
658 +       }
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);
676 +               }
677 +       }
678 +}
679 +
680 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */
681 +static void bgmac_phy_reset(struct bgmac *bgmac)
682 +{
683 +       if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
684 +               return;
685 +
686 +       bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL,
687 +                       BGMAC_PHY_CTL_RESET);
688 +       udelay(100);
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);
693 +}
694 +
695 +/**************************************************
696 + * Chip ops
697 + **************************************************/
698 +
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.
701 + */
702 +static void bgmac_cmdcfg_maskset(struct bgmac *bgmac, u32 mask, u32 set,
703 +                                bool force)
704 +{
705 +       u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
706 +       u32 new_val = (cmdcfg & mask) | set;
707 +
708 +       bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR);
709 +       udelay(2);
710 +
711 +       if (new_val != cmdcfg || force)
712 +               bgmac_write(bgmac, BGMAC_CMDCFG, new_val);
713 +
714 +       bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR);
715 +       udelay(2);
716 +}
717 +
718 +static void bgmac_chip_stats_update(struct bgmac *bgmac)
719 +{
720 +       int i;
721 +
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] =
725 +                               bgmac_read(bgmac,
726 +                                          BGMAC_TX_GOOD_OCTETS + (i * 4));
727 +               for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
728 +                       bgmac->mib_rx_regs[i] =
729 +                               bgmac_read(bgmac,
730 +                                          BGMAC_RX_GOOD_OCTETS + (i * 4));
731 +       }
732 +
733 +       /* TODO: what else? how to handle BCM4706? */
734 +}
735 +
736 +static void bgmac_clear_mib(struct bgmac *bgmac)
737 +{
738 +       int i;
739 +
740 +       if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT)
741 +               return;
742 +
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));
748 +}
749 +
750 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_speed */
751 +static void bgmac_speed(struct bgmac *bgmac, int speed)
752 +{
753 +       u32 mask = ~(BGMAC_CMDCFG_ES_MASK | BGMAC_CMDCFG_HD);
754 +       u32 set = 0;
755 +
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);
765 +}
766 +
767 +static void bgmac_miiconfig(struct bgmac *bgmac)
768 +{
769 +       u8 imode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
770 +                       BGMAC_DS_MM_SHIFT;
771 +       if (imode == 0 || imode == 1) {
772 +               if (bgmac->autoneg)
773 +                       bgmac_speed(bgmac, BGMAC_SPEED_100);
774 +               else
775 +                       bgmac_speed(bgmac, bgmac->speed);
776 +       }
777 +}
778 +
779 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
780 +static void bgmac_chip_reset(struct bgmac *bgmac)
781 +{
782 +       struct bcma_device *core = bgmac->core;
783 +       struct bcma_bus *bus = core->bus;
784 +       struct bcma_chipinfo *ci = &bus->chipinfo;
785 +       u32 flags = 0;
786 +       u32 iost;
787 +       int i;
788 +
789 +       if (bcma_core_is_enabled(core)) {
790 +               if (!bgmac->stats_grabbed) {
791 +                       bgmac_chip_stats_update(bgmac);
792 +                       bgmac->stats_grabbed = true;
793 +               }
794 +
795 +               for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
796 +                       bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]);
797 +
798 +               bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
799 +               udelay(1);
800 +
801 +               for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
802 +                       bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]);
803 +
804 +               /* TODO: Clear software multicast filter list */
805 +       }
806 +
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;
812 +
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;
817 +       }
818 +
819 +       bcma_core_enable(core, flags);
820 +
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,
824 +                                1000);
825 +       }
826 +
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;
830 +               u8 et_swtype = 0;
831 +               u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
832 +                            BGMAC_CHIPCTL_1_IF_TYPE_RMII;
833 +               char buf[2];
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);
837 +                       et_swtype &= 0x0f;
838 +                       et_swtype <<= 4;
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;
842 +               } else if (0) {
843 +                       /* TODO */
844 +               }
845 +               bcma_chipco_chipctl_maskset(cc, 1,
846 +                                           ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
847 +                                             BGMAC_CHIPCTL_1_SW_TYPE_MASK),
848 +                                           sw_type);
849 +       }
850 +
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);
855 +
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.
860 +        */
861 +       bgmac_cmdcfg_maskset(bgmac,
862 +                            ~(BGMAC_CMDCFG_TE |
863 +                              BGMAC_CMDCFG_RE |
864 +                              BGMAC_CMDCFG_RPI |
865 +                              BGMAC_CMDCFG_TAI |
866 +                              BGMAC_CMDCFG_HD |
867 +                              BGMAC_CMDCFG_ML |
868 +                              BGMAC_CMDCFG_CFE |
869 +                              BGMAC_CMDCFG_RL |
870 +                              BGMAC_CMDCFG_RED |
871 +                              BGMAC_CMDCFG_PE |
872 +                              BGMAC_CMDCFG_TPI |
873 +                              BGMAC_CMDCFG_PAD_EN |
874 +                              BGMAC_CMDCFG_PF),
875 +                            BGMAC_CMDCFG_PROM |
876 +                            BGMAC_CMDCFG_NLC |
877 +                            BGMAC_CMDCFG_CFE |
878 +                            BGMAC_CMDCFG_SR,
879 +                            false);
880 +
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);
885 +       else
886 +               bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
887 +       bgmac_miiconfig(bgmac);
888 +       bgmac_phy_init(bgmac);
889 +
890 +       bgmac->int_status = 0;
891 +}
892 +
893 +static void bgmac_chip_intrs_on(struct bgmac *bgmac)
894 +{
895 +       bgmac_write(bgmac, BGMAC_INT_MASK, bgmac->int_mask);
896 +}
897 +
898 +static void bgmac_chip_intrs_off(struct bgmac *bgmac)
899 +{
900 +       bgmac_write(bgmac, BGMAC_INT_MASK, 0);
901 +}
902 +
903 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_enable */
904 +static void bgmac_enable(struct bgmac *bgmac)
905 +{
906 +       struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
907 +       u32 cmdcfg;
908 +       u32 mode;
909 +       u32 rxq_ctl;
910 +       u32 fl_ctl;
911 +       u16 bp_clk;
912 +       u8 mdp;
913 +
914 +       cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
915 +       bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE),
916 +                            BGMAC_CMDCFG_SR, true);
917 +       udelay(2);
918 +       cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE;
919 +       bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg);
920 +
921 +       mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
922 +               BGMAC_DS_MM_SHIFT;
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);
928 +
929 +       switch (ci->id) {
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)
939 +                       fl_ctl = 0x2300e1;
940 +               bgmac_write(bgmac, BGMAC_FLOW_CTL_THRESH, fl_ctl);
941 +               bgmac_write(bgmac, BGMAC_PAUSE_CTL, 0x27fff);
942 +               break;
943 +       }
944 +
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);
951 +}
952 +
953 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
954 +static void bgmac_chip_init(struct bgmac *bgmac, bool full_init)
955 +{
956 +       struct ssb_sprom *sprom = &bgmac->core->bus->sprom;
957 +       struct bgmac_dma_ring *ring;
958 +       u32 tmp;
959 +       u8 *mac;
960 +       int i;
961 +
962 +       /* 1 interrupt per received frame */
963 +       bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
964 +
965 +       /* enable 802.3x tx flow control (honor received PAUSE frames) */
966 +       bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true);
967 +
968 +       if (bgmac->net_dev->flags & IFF_PROMISC)
969 +               bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, false);
970 +       else
971 +               bgmac_warn(bgmac, "Software filtering is not supported yet\n");
972 +
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);
979 +
980 +       if (bgmac->loopback)
981 +               bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, true);
982 +       else
983 +               bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, true);
984 +
985 +       bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
986 +
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);
992 +       }
993 +
994 +       if (full_init) {
995 +               bgmac_dma_init(bgmac);
996 +               if (1) /* FIXME: is there any case we don't want IRQs? */
997 +                       bgmac_chip_intrs_on(bgmac);
998 +       } else {
999 +               for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
1000 +                       ring = &bgmac->rx_ring[i];
1001 +                       bgmac_dma_rx_enable(bgmac, ring);
1002 +               }
1003 +       }
1004 +
1005 +       bgmac_enable(bgmac);
1006 +}
1007 +
1008 +static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
1009 +{
1010 +       struct bgmac *bgmac = netdev_priv(dev_id);
1011 +
1012 +       u32 int_status = bgmac_read(bgmac, BGMAC_INT_STATUS);
1013 +       int_status &= bgmac->int_mask;
1014 +
1015 +       if (!int_status)
1016 +               return IRQ_NONE;
1017 +
1018 +       /* Ack */
1019 +       bgmac_write(bgmac, BGMAC_INT_STATUS, int_status);
1020 +
1021 +       /* Disable new interrupts until handling existing ones */
1022 +       bgmac_chip_intrs_off(bgmac);
1023 +
1024 +       bgmac->int_status = int_status;
1025 +
1026 +       return IRQ_WAKE_THREAD;
1027 +}
1028 +
1029 +static irqreturn_t bgmac_interrupt_thread(int irq, void *dev_id)
1030 +{
1031 +       struct bgmac *bgmac = netdev_priv(dev_id);
1032 +       struct bgmac_dma_ring *ring;
1033 +
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;
1038 +       }
1039 +
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;
1044 +       }
1045 +
1046 +       if (bgmac->int_status) {
1047 +               bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status);
1048 +               bgmac->int_status = 0;
1049 +       }
1050 +
1051 +       bgmac_chip_intrs_on(bgmac);
1052 +       return IRQ_HANDLED;
1053 +}
1054 +
1055 +/**************************************************
1056 + * net_device ops
1057 + **************************************************/
1058 +
1059 +static int bgmac_open(struct net_device *net_dev)
1060 +{
1061 +       struct bgmac *bgmac = netdev_priv(net_dev);
1062 +
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);
1066 +
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");
1071 +
1072 +       return 0;
1073 +}
1074 +
1075 +static int bgmac_stop(struct net_device *net_dev)
1076 +{
1077 +       struct bgmac *bgmac = netdev_priv(net_dev);
1078 +
1079 +       bgmac_chip_intrs_off(bgmac);
1080 +
1081 +       free_irq(bgmac->core->irq, net_dev);
1082 +
1083 +       /* TODO */
1084 +
1085 +       return 0;
1086 +}
1087 +
1088 +static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
1089 +{
1090 +       struct bgmac *bgmac = netdev_priv(net_dev);
1091 +       struct mii_ioctl_data *data = if_mii(ifr);
1092 +
1093 +       switch (cmd) {
1094 +       case SIOCGMIIPHY:
1095 +               data->phy_id = bgmac->phyaddr;
1096 +               /* fallthru */
1097 +       case SIOCGMIIREG:
1098 +               if (!netif_running(net_dev))
1099 +                       return -EAGAIN;
1100 +               data->val_out = bgmac_phy_read(bgmac, bgmac->phyaddr,
1101 +                                              data->reg_num & 0x1f);
1102 +               return 0;
1103 +       case SIOCSMIIREG:
1104 +               if (!netif_running(net_dev))
1105 +                       return -EAGAIN;
1106 +               bgmac_phy_write(bgmac, bgmac->phyaddr, data->reg_num & 0x1f,
1107 +                               data->val_in);
1108 +               return 0;
1109 +       default:
1110 +               return -EOPNOTSUPP;
1111 +       }
1112 +}
1113 +
1114 +static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb,
1115 +                                   struct net_device *net_dev)
1116 +{
1117 +       struct bgmac *bgmac = netdev_priv(net_dev);
1118 +       struct bgmac_dma_ring *ring;
1119 +
1120 +       /* No QOS support yet */
1121 +       ring = &bgmac->tx_ring[0];
1122 +       return bgmac_dma_tx_add(bgmac, ring, skb);
1123 +}
1124 +
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,
1130 +};
1131 +
1132 +/**************************************************
1133 + * BCMA bus ops
1134 + **************************************************/
1135 +
1136 +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
1137 +static int bgmac_probe(struct bcma_device *core)
1138 +{
1139 +       struct net_device *net_dev;
1140 +       struct bgmac *bgmac;
1141 +       struct ssb_sprom *sprom = &core->bus->sprom;
1142 +       int err;
1143 +
1144 +       /* Allocation and references */
1145 +       net_dev = alloc_etherdev(sizeof(*bgmac));
1146 +       if (!net_dev)
1147 +               return -ENOMEM;
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);
1154 +
1155 +       /* Defaults */
1156 +       bgmac->autoneg = true;
1157 +       bgmac->full_duplex = true;
1158 +       bgmac->speed = BGMAC_SPEED_10 | BGMAC_SPEED_100 | BGMAC_SPEED_1000;
1159 +
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");
1164 +               return -ENODEV;
1165 +       }
1166 +       bgmac->cmn = core->bus->drv_gmac_cmn.core;
1167 +
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");
1173 +               return -ENODEV;
1174 +       }
1175 +       bgmac_info(bgmac, "Found PHY addr: %d\n", bgmac->phyaddr);
1176 +
1177 +       if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
1178 +               bgmac_err(bgmac, "PCI setup not implemented\n");
1179 +               return -ENOTSUPP;
1180 +       }
1181 +
1182 +       bgmac_chip_reset(bgmac);
1183 +
1184 +       bgmac_dma_alloc(bgmac);
1185 +
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;
1189 +
1190 +       /* TODO: reset the external phy */
1191 +       bgmac_phy_reset(bgmac);
1192 +
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");
1197 +
1198 +       if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM)
1199 +               bgmac_err(bgmac, "Support for ADMtek ethernet switch not implemented\n");
1200 +
1201 +       err = register_netdev(bgmac->net_dev);
1202 +       if (err) {
1203 +               bgmac_err(bgmac, "Cannot register net device\n");
1204 +               return -ENOTSUPP;
1205 +       }
1206 +
1207 +       return 0;
1208 +}
1209 +
1210 +static void bgmac_remove(struct bcma_device *core)
1211 +{
1212 +       struct bgmac *bgmac = bcma_get_drvdata(core);
1213 +
1214 +       unregister_netdev(bgmac->net_dev);
1215 +       free_netdev(bgmac->net_dev);
1216 +       bcma_set_drvdata(core, NULL);
1217 +}
1218 +
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,
1224 +};
1225 +
1226 +static int __init bgmac_init(void)
1227 +{
1228 +       int err;
1229 +
1230 +       err = bcma_driver_register(&bgmac_bcma_driver);
1231 +       if (err)
1232 +               return err;
1233 +       pr_info("Broadcom 47xx GMAC driver loaded\n");
1234 +
1235 +       return 0;
1236 +}
1237 +
1238 +static void __exit bgmac_exit(void)
1239 +{
1240 +       bcma_driver_unregister(&bgmac_bcma_driver);
1241 +}
1242 +
1243 +module_init(bgmac_init)
1244 +module_exit(bgmac_exit)
1245 --- /dev/null
1246 +++ b/drivers/net/ethernet/broadcom/bgmac.h
1247 @@ -0,0 +1,424 @@
1248 +#ifndef _BGMAC_H
1249 +#define _BGMAC_H
1250 +
1251 +#include <linux/bcma/bcma.h>
1252 +
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
1453 +
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 */
1462 +/* Helpers */
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 */
1474 +
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 */
1478 +
1479 +/* BCMA GMAC core specific IO status (BCMA_IOST) flags */
1480 +#define BGMAC_BCMA_IOST_ATTACHED               0x00000800
1481 +
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)
1486 +
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
1544 +
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
1550 +
1551 +#define BGMAC_PHY_NOREGS                       0x1E
1552 +#define BGMAC_PHY_MASK                         0x1F
1553 +
1554 +#define BGMAC_MAX_TX_RINGS                     4
1555 +#define BGMAC_MAX_RX_RINGS                     1
1556 +
1557 +#define BGMAC_TX_RING_SLOTS                    128
1558 +#define BGMAC_RX_RING_SLOTS                    512 - 1         /* Why -1? Well, Broadcom does that... */
1559 +
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)
1564 +
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 */
1568 +
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
1579 +
1580 +#define BGMAC_SPEED_10                         0x0001
1581 +#define BGMAC_SPEED_100                                0x0002
1582 +#define BGMAC_SPEED_1000                       0x0004
1583 +
1584 +struct bgmac_slot_info {
1585 +       struct sk_buff *skb;
1586 +       dma_addr_t dma_addr;
1587 +};
1588 +
1589 +struct bgmac_dma_desc {
1590 +       __le32 ctl0;
1591 +       __le32 ctl1;
1592 +       __le32 addr_low;
1593 +       __le32 addr_high;
1594 +} __packed;
1595 +
1596 +struct bgmac_dma_ring {
1597 +       bool tx;
1598 +       u16 num_slots;
1599 +       u16 start;
1600 +       u16 end;
1601 +
1602 +       u16 mmio_base;
1603 +       void *cpu_base;
1604 +       dma_addr_t dma_base;
1605 +
1606 +       struct bgmac_slot_info slots[BGMAC_RX_RING_SLOTS];
1607 +};
1608 +
1609 +struct bgmac_rx_header {
1610 +       __le16 len;
1611 +       __le16 flags;
1612 +       __le16 pad[12];
1613 +};
1614 +
1615 +struct bgmac {
1616 +       struct bcma_device *core;
1617 +       struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */
1618 +       struct net_device *net_dev;
1619 +
1620 +       u8 phyaddr;
1621 +       bool has_robosw;
1622 +
1623 +       u32 int_mask;
1624 +       u32 int_status;
1625 +
1626 +       bool loopback;
1627 +
1628 +       bool autoneg;
1629 +       bool full_duplex;
1630 +       int speed;
1631 +
1632 +       /* DMA */
1633 +       struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS];
1634 +       struct bgmac_dma_ring rx_ring[BGMAC_MAX_RX_RINGS];
1635 +
1636 +       /* Stats */
1637 +       bool stats_grabbed;
1638 +       u32 mib_tx_regs[BGMAC_NUM_MIB_TX_REGS];
1639 +       u32 mib_rx_regs[BGMAC_NUM_MIB_RX_REGS];
1640 +};
1641 +
1642 +static inline u32 bgmac_read(struct bgmac *bgmac, u16 offset)
1643 +{
1644 +       return bcma_read32(bgmac->core, offset);
1645 +}
1646 +
1647 +static inline void bgmac_write(struct bgmac *bgmac, u16 offset, u32 value)
1648 +{
1649 +       bcma_write32(bgmac->core, offset, value);
1650 +}
1651 +
1652 +static inline void bgmac_maskset(struct bgmac *bgmac, u16 offset, u32 mask,
1653 +                                  u32 set)
1654 +{
1655 +       bgmac_write(bgmac, offset, (bgmac_read(bgmac, offset) & mask) | set);
1656 +}
1657 +
1658 +static inline void bgmac_mask(struct bgmac *bgmac, u16 offset, u32 mask)
1659 +{
1660 +       bgmac_maskset(bgmac, offset, mask, 0);
1661 +}
1662 +
1663 +static inline void bgmac_set(struct bgmac *bgmac, u16 offset, u32 set)
1664 +{
1665 +       bgmac_maskset(bgmac, offset, ~0, set);
1666 +}
1667 +
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);
1670 +
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);
1676  #endif
1677  
1678 +extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc);
1679 +
1680  #endif /* LINUX_BCMA_DRIVER_CC_H_ */