brcm47xx: add bgmac driver
[openwrt/svn-archive/archive.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_ */