blob: d6cb376b71e602275bab67c70b03957ffaffbd6f [file] [log] [blame]
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001/*
2 * Driver for (BCM4706)? GBit MAC core on BCMA bus.
3 *
4 * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
5 *
6 * Licensed under the GNU/GPL. See COPYING for details.
7 */
8
9#include "bgmac.h"
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/delay.h>
14#include <linux/etherdevice.h>
15#include <linux/mii.h>
Rafał Miłecki11e5e762013-03-07 01:53:28 +000016#include <linux/phy.h>
Rafał Miłeckidd4544f2013-01-08 20:06:23 +000017#include <linux/interrupt.h>
18#include <linux/dma-mapping.h>
Ralf Baechleedb15d82013-02-21 16:16:55 +010019#include <bcm47xx_nvram.h>
Rafał Miłeckidd4544f2013-01-08 20:06:23 +000020
21static const struct bcma_device_id bgmac_bcma_tbl[] = {
22 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
23 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
24 BCMA_CORETABLE_END
25};
26MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
27
28static bool bgmac_wait_value(struct bcma_device *core, u16 reg, u32 mask,
29 u32 value, int timeout)
30{
31 u32 val;
32 int i;
33
34 for (i = 0; i < timeout / 10; i++) {
35 val = bcma_read32(core, reg);
36 if ((val & mask) == value)
37 return true;
38 udelay(10);
39 }
40 pr_err("Timeout waiting for reg 0x%X\n", reg);
41 return false;
42}
43
44/**************************************************
45 * DMA
46 **************************************************/
47
48static void bgmac_dma_tx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
49{
50 u32 val;
51 int i;
52
53 if (!ring->mmio_base)
54 return;
55
56 /* Suspend DMA TX ring first.
57 * bgmac_wait_value doesn't support waiting for any of few values, so
58 * implement whole loop here.
59 */
60 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL,
61 BGMAC_DMA_TX_SUSPEND);
62 for (i = 0; i < 10000 / 10; i++) {
63 val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
64 val &= BGMAC_DMA_TX_STAT;
65 if (val == BGMAC_DMA_TX_STAT_DISABLED ||
66 val == BGMAC_DMA_TX_STAT_IDLEWAIT ||
67 val == BGMAC_DMA_TX_STAT_STOPPED) {
68 i = 0;
69 break;
70 }
71 udelay(10);
72 }
73 if (i)
74 bgmac_err(bgmac, "Timeout suspending DMA TX ring 0x%X (BGMAC_DMA_TX_STAT: 0x%08X)\n",
75 ring->mmio_base, val);
76
77 /* Remove SUSPEND bit */
78 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, 0);
79 if (!bgmac_wait_value(bgmac->core,
80 ring->mmio_base + BGMAC_DMA_TX_STATUS,
81 BGMAC_DMA_TX_STAT, BGMAC_DMA_TX_STAT_DISABLED,
82 10000)) {
83 bgmac_warn(bgmac, "DMA TX ring 0x%X wasn't disabled on time, waiting additional 300us\n",
84 ring->mmio_base);
85 udelay(300);
86 val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
87 if ((val & BGMAC_DMA_TX_STAT) != BGMAC_DMA_TX_STAT_DISABLED)
88 bgmac_err(bgmac, "Reset of DMA TX ring 0x%X failed\n",
89 ring->mmio_base);
90 }
91}
92
93static void bgmac_dma_tx_enable(struct bgmac *bgmac,
94 struct bgmac_dma_ring *ring)
95{
96 u32 ctl;
97
98 ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL);
99 ctl |= BGMAC_DMA_TX_ENABLE;
100 ctl |= BGMAC_DMA_TX_PARITY_DISABLE;
101 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl);
102}
103
104static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
105 struct bgmac_dma_ring *ring,
106 struct sk_buff *skb)
107{
108 struct device *dma_dev = bgmac->core->dma_dev;
109 struct net_device *net_dev = bgmac->net_dev;
110 struct bgmac_dma_desc *dma_desc;
111 struct bgmac_slot_info *slot;
112 u32 ctl0, ctl1;
113 int free_slots;
114
115 if (skb->len > BGMAC_DESC_CTL1_LEN) {
116 bgmac_err(bgmac, "Too long skb (%d)\n", skb->len);
117 goto err_stop_drop;
118 }
119
120 if (ring->start <= ring->end)
121 free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS;
122 else
123 free_slots = ring->start - ring->end;
124 if (free_slots == 1) {
125 bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n");
126 netif_stop_queue(net_dev);
127 return NETDEV_TX_BUSY;
128 }
129
130 slot = &ring->slots[ring->end];
131 slot->skb = skb;
132 slot->dma_addr = dma_map_single(dma_dev, skb->data, skb->len,
133 DMA_TO_DEVICE);
134 if (dma_mapping_error(dma_dev, slot->dma_addr)) {
135 bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n",
136 ring->mmio_base);
137 goto err_stop_drop;
138 }
139
140 ctl0 = BGMAC_DESC_CTL0_IOC | BGMAC_DESC_CTL0_SOF | BGMAC_DESC_CTL0_EOF;
141 if (ring->end == ring->num_slots - 1)
142 ctl0 |= BGMAC_DESC_CTL0_EOT;
143 ctl1 = skb->len & BGMAC_DESC_CTL1_LEN;
144
145 dma_desc = ring->cpu_base;
146 dma_desc += ring->end;
147 dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr));
148 dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr));
149 dma_desc->ctl0 = cpu_to_le32(ctl0);
150 dma_desc->ctl1 = cpu_to_le32(ctl1);
151
152 wmb();
153
154 /* Increase ring->end to point empty slot. We tell hardware the first
155 * slot it should *not* read.
156 */
157 if (++ring->end >= BGMAC_TX_RING_SLOTS)
158 ring->end = 0;
159 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,
160 ring->end * sizeof(struct bgmac_dma_desc));
161
162 /* Always keep one slot free to allow detecting bugged calls. */
163 if (--free_slots == 1)
164 netif_stop_queue(net_dev);
165
166 return NETDEV_TX_OK;
167
168err_stop_drop:
169 netif_stop_queue(net_dev);
170 dev_kfree_skb(skb);
171 return NETDEV_TX_OK;
172}
173
174/* Free transmitted packets */
175static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
176{
177 struct device *dma_dev = bgmac->core->dma_dev;
178 int empty_slot;
179 bool freed = false;
180
181 /* The last slot that hardware didn't consume yet */
182 empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
183 empty_slot &= BGMAC_DMA_TX_STATDPTR;
184 empty_slot /= sizeof(struct bgmac_dma_desc);
185
186 while (ring->start != empty_slot) {
187 struct bgmac_slot_info *slot = &ring->slots[ring->start];
188
189 if (slot->skb) {
190 /* Unmap no longer used buffer */
191 dma_unmap_single(dma_dev, slot->dma_addr,
192 slot->skb->len, DMA_TO_DEVICE);
193 slot->dma_addr = 0;
194
195 /* Free memory! :) */
196 dev_kfree_skb(slot->skb);
197 slot->skb = NULL;
198 } else {
199 bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n",
200 ring->start, ring->end);
201 }
202
203 if (++ring->start >= BGMAC_TX_RING_SLOTS)
204 ring->start = 0;
205 freed = true;
206 }
207
208 if (freed && netif_queue_stopped(bgmac->net_dev))
209 netif_wake_queue(bgmac->net_dev);
210}
211
212static void bgmac_dma_rx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
213{
214 if (!ring->mmio_base)
215 return;
216
217 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, 0);
218 if (!bgmac_wait_value(bgmac->core,
219 ring->mmio_base + BGMAC_DMA_RX_STATUS,
220 BGMAC_DMA_RX_STAT, BGMAC_DMA_RX_STAT_DISABLED,
221 10000))
222 bgmac_err(bgmac, "Reset of ring 0x%X RX failed\n",
223 ring->mmio_base);
224}
225
226static void bgmac_dma_rx_enable(struct bgmac *bgmac,
227 struct bgmac_dma_ring *ring)
228{
229 u32 ctl;
230
231 ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL);
232 ctl &= BGMAC_DMA_RX_ADDREXT_MASK;
233 ctl |= BGMAC_DMA_RX_ENABLE;
234 ctl |= BGMAC_DMA_RX_PARITY_DISABLE;
235 ctl |= BGMAC_DMA_RX_OVERFLOW_CONT;
236 ctl |= BGMAC_RX_FRAME_OFFSET << BGMAC_DMA_RX_FRAME_OFFSET_SHIFT;
237 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, ctl);
238}
239
240static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
241 struct bgmac_slot_info *slot)
242{
243 struct device *dma_dev = bgmac->core->dma_dev;
244 struct bgmac_rx_header *rx;
245
246 /* Alloc skb */
247 slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
248 if (!slot->skb) {
249 bgmac_err(bgmac, "Allocation of skb failed!\n");
250 return -ENOMEM;
251 }
252
253 /* Poison - if everything goes fine, hardware will overwrite it */
254 rx = (struct bgmac_rx_header *)slot->skb->data;
255 rx->len = cpu_to_le16(0xdead);
256 rx->flags = cpu_to_le16(0xbeef);
257
258 /* Map skb for the DMA */
259 slot->dma_addr = dma_map_single(dma_dev, slot->skb->data,
260 BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
261 if (dma_mapping_error(dma_dev, slot->dma_addr)) {
262 bgmac_err(bgmac, "DMA mapping error\n");
263 return -ENOMEM;
264 }
265 if (slot->dma_addr & 0xC0000000)
266 bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
267
268 return 0;
269}
270
271static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
272 int weight)
273{
274 u32 end_slot;
275 int handled = 0;
276
277 end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS);
278 end_slot &= BGMAC_DMA_RX_STATDPTR;
279 end_slot /= sizeof(struct bgmac_dma_desc);
280
281 ring->end = end_slot;
282
283 while (ring->start != ring->end) {
284 struct device *dma_dev = bgmac->core->dma_dev;
285 struct bgmac_slot_info *slot = &ring->slots[ring->start];
286 struct sk_buff *skb = slot->skb;
287 struct sk_buff *new_skb;
288 struct bgmac_rx_header *rx;
289 u16 len, flags;
290
291 /* Unmap buffer to make it accessible to the CPU */
292 dma_sync_single_for_cpu(dma_dev, slot->dma_addr,
293 BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
294
295 /* Get info from the header */
296 rx = (struct bgmac_rx_header *)skb->data;
297 len = le16_to_cpu(rx->len);
298 flags = le16_to_cpu(rx->flags);
299
300 /* Check for poison and drop or pass the packet */
301 if (len == 0xdead && flags == 0xbeef) {
302 bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
303 ring->start);
304 } else {
Hauke Mehrtens02e71122013-02-28 07:16:54 +0000305 /* Omit CRC. */
306 len -= ETH_FCS_LEN;
307
Hauke Mehrtens885d2992013-02-16 11:10:38 +0000308 new_skb = netdev_alloc_skb_ip_align(bgmac->net_dev, len);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000309 if (new_skb) {
310 skb_put(new_skb, len);
311 skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET,
312 new_skb->data,
313 len);
Hauke Mehrtens02e71122013-02-28 07:16:54 +0000314 skb_checksum_none_assert(skb);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000315 new_skb->protocol =
316 eth_type_trans(new_skb, bgmac->net_dev);
317 netif_receive_skb(new_skb);
318 handled++;
319 } else {
320 bgmac->net_dev->stats.rx_dropped++;
321 bgmac_err(bgmac, "Allocation of skb for copying packet failed!\n");
322 }
323
324 /* Poison the old skb */
325 rx->len = cpu_to_le16(0xdead);
326 rx->flags = cpu_to_le16(0xbeef);
327 }
328
329 /* Make it back accessible to the hardware */
330 dma_sync_single_for_device(dma_dev, slot->dma_addr,
331 BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
332
333 if (++ring->start >= BGMAC_RX_RING_SLOTS)
334 ring->start = 0;
335
336 if (handled >= weight) /* Should never be greater */
337 break;
338 }
339
340 return handled;
341}
342
343/* Does ring support unaligned addressing? */
344static bool bgmac_dma_unaligned(struct bgmac *bgmac,
345 struct bgmac_dma_ring *ring,
346 enum bgmac_dma_ring_type ring_type)
347{
348 switch (ring_type) {
349 case BGMAC_DMA_RING_TX:
350 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
351 0xff0);
352 if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO))
353 return true;
354 break;
355 case BGMAC_DMA_RING_RX:
356 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
357 0xff0);
358 if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO))
359 return true;
360 break;
361 }
362 return false;
363}
364
365static void bgmac_dma_ring_free(struct bgmac *bgmac,
366 struct bgmac_dma_ring *ring)
367{
368 struct device *dma_dev = bgmac->core->dma_dev;
369 struct bgmac_slot_info *slot;
370 int size;
371 int i;
372
373 for (i = 0; i < ring->num_slots; i++) {
374 slot = &ring->slots[i];
375 if (slot->skb) {
376 if (slot->dma_addr)
377 dma_unmap_single(dma_dev, slot->dma_addr,
378 slot->skb->len, DMA_TO_DEVICE);
379 dev_kfree_skb(slot->skb);
380 }
381 }
382
383 if (ring->cpu_base) {
384 /* Free ring of descriptors */
385 size = ring->num_slots * sizeof(struct bgmac_dma_desc);
386 dma_free_coherent(dma_dev, size, ring->cpu_base,
387 ring->dma_base);
388 }
389}
390
391static void bgmac_dma_free(struct bgmac *bgmac)
392{
393 int i;
394
395 for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
396 bgmac_dma_ring_free(bgmac, &bgmac->tx_ring[i]);
397 for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
398 bgmac_dma_ring_free(bgmac, &bgmac->rx_ring[i]);
399}
400
401static int bgmac_dma_alloc(struct bgmac *bgmac)
402{
403 struct device *dma_dev = bgmac->core->dma_dev;
404 struct bgmac_dma_ring *ring;
405 static const u16 ring_base[] = { BGMAC_DMA_BASE0, BGMAC_DMA_BASE1,
406 BGMAC_DMA_BASE2, BGMAC_DMA_BASE3, };
407 int size; /* ring size: different for Tx and Rx */
408 int err;
409 int i;
410
411 BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base));
412 BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base));
413
414 if (!(bcma_aread32(bgmac->core, BCMA_IOST) & BCMA_IOST_DMA64)) {
415 bgmac_err(bgmac, "Core does not report 64-bit DMA\n");
416 return -ENOTSUPP;
417 }
418
419 for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
420 ring = &bgmac->tx_ring[i];
421 ring->num_slots = BGMAC_TX_RING_SLOTS;
422 ring->mmio_base = ring_base[i];
423 if (bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_TX))
424 bgmac_warn(bgmac, "TX on ring 0x%X supports unaligned addressing but this feature is not implemented\n",
425 ring->mmio_base);
426
427 /* Alloc ring of descriptors */
428 size = ring->num_slots * sizeof(struct bgmac_dma_desc);
429 ring->cpu_base = dma_zalloc_coherent(dma_dev, size,
430 &ring->dma_base,
431 GFP_KERNEL);
432 if (!ring->cpu_base) {
433 bgmac_err(bgmac, "Allocation of TX ring 0x%X failed\n",
434 ring->mmio_base);
435 goto err_dma_free;
436 }
437 if (ring->dma_base & 0xC0000000)
438 bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
439
440 /* No need to alloc TX slots yet */
441 }
442
443 for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
Rafał Miłecki70a737b2013-02-25 08:22:26 +0000444 int j;
445
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000446 ring = &bgmac->rx_ring[i];
447 ring->num_slots = BGMAC_RX_RING_SLOTS;
448 ring->mmio_base = ring_base[i];
449 if (bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_RX))
450 bgmac_warn(bgmac, "RX on ring 0x%X supports unaligned addressing but this feature is not implemented\n",
451 ring->mmio_base);
452
453 /* Alloc ring of descriptors */
454 size = ring->num_slots * sizeof(struct bgmac_dma_desc);
455 ring->cpu_base = dma_zalloc_coherent(dma_dev, size,
456 &ring->dma_base,
457 GFP_KERNEL);
458 if (!ring->cpu_base) {
459 bgmac_err(bgmac, "Allocation of RX ring 0x%X failed\n",
460 ring->mmio_base);
461 err = -ENOMEM;
462 goto err_dma_free;
463 }
464 if (ring->dma_base & 0xC0000000)
465 bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
466
467 /* Alloc RX slots */
Rafał Miłecki70a737b2013-02-25 08:22:26 +0000468 for (j = 0; j < ring->num_slots; j++) {
469 err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000470 if (err) {
471 bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n");
472 goto err_dma_free;
473 }
474 }
475 }
476
477 return 0;
478
479err_dma_free:
480 bgmac_dma_free(bgmac);
481 return -ENOMEM;
482}
483
484static void bgmac_dma_init(struct bgmac *bgmac)
485{
486 struct bgmac_dma_ring *ring;
487 struct bgmac_dma_desc *dma_desc;
488 u32 ctl0, ctl1;
489 int i;
490
491 for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
492 ring = &bgmac->tx_ring[i];
493
494 /* We don't implement unaligned addressing, so enable first */
495 bgmac_dma_tx_enable(bgmac, ring);
496 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
497 lower_32_bits(ring->dma_base));
498 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGHI,
499 upper_32_bits(ring->dma_base));
500
501 ring->start = 0;
502 ring->end = 0; /* Points the slot that should *not* be read */
503 }
504
505 for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
Rafał Miłecki70a737b2013-02-25 08:22:26 +0000506 int j;
507
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000508 ring = &bgmac->rx_ring[i];
509
510 /* We don't implement unaligned addressing, so enable first */
511 bgmac_dma_rx_enable(bgmac, ring);
512 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
513 lower_32_bits(ring->dma_base));
514 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGHI,
515 upper_32_bits(ring->dma_base));
516
Rafał Miłecki70a737b2013-02-25 08:22:26 +0000517 for (j = 0, dma_desc = ring->cpu_base; j < ring->num_slots;
518 j++, dma_desc++) {
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000519 ctl0 = ctl1 = 0;
520
Rafał Miłecki70a737b2013-02-25 08:22:26 +0000521 if (j == ring->num_slots - 1)
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000522 ctl0 |= BGMAC_DESC_CTL0_EOT;
523 ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN;
524 /* Is there any BGMAC device that requires extension? */
525 /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) &
526 * B43_DMA64_DCTL1_ADDREXT_MASK;
527 */
528
Rafał Miłecki70a737b2013-02-25 08:22:26 +0000529 dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[j].dma_addr));
530 dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[j].dma_addr));
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000531 dma_desc->ctl0 = cpu_to_le32(ctl0);
532 dma_desc->ctl1 = cpu_to_le32(ctl1);
533 }
534
535 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
536 ring->num_slots * sizeof(struct bgmac_dma_desc));
537
538 ring->start = 0;
539 ring->end = 0;
540 }
541}
542
543/**************************************************
544 * PHY ops
545 **************************************************/
546
Rafał Miłecki217a55a2013-02-12 23:14:51 +0000547static u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg)
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000548{
549 struct bcma_device *core;
550 u16 phy_access_addr;
551 u16 phy_ctl_addr;
552 u32 tmp;
553
554 BUILD_BUG_ON(BGMAC_PA_DATA_MASK != BCMA_GMAC_CMN_PA_DATA_MASK);
555 BUILD_BUG_ON(BGMAC_PA_ADDR_MASK != BCMA_GMAC_CMN_PA_ADDR_MASK);
556 BUILD_BUG_ON(BGMAC_PA_ADDR_SHIFT != BCMA_GMAC_CMN_PA_ADDR_SHIFT);
557 BUILD_BUG_ON(BGMAC_PA_REG_MASK != BCMA_GMAC_CMN_PA_REG_MASK);
558 BUILD_BUG_ON(BGMAC_PA_REG_SHIFT != BCMA_GMAC_CMN_PA_REG_SHIFT);
559 BUILD_BUG_ON(BGMAC_PA_WRITE != BCMA_GMAC_CMN_PA_WRITE);
560 BUILD_BUG_ON(BGMAC_PA_START != BCMA_GMAC_CMN_PA_START);
561 BUILD_BUG_ON(BGMAC_PC_EPA_MASK != BCMA_GMAC_CMN_PC_EPA_MASK);
562 BUILD_BUG_ON(BGMAC_PC_MCT_MASK != BCMA_GMAC_CMN_PC_MCT_MASK);
563 BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT);
564 BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE);
565
566 if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
567 core = bgmac->core->bus->drv_gmac_cmn.core;
568 phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
569 phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
570 } else {
571 core = bgmac->core;
572 phy_access_addr = BGMAC_PHY_ACCESS;
573 phy_ctl_addr = BGMAC_PHY_CNTL;
574 }
575
576 tmp = bcma_read32(core, phy_ctl_addr);
577 tmp &= ~BGMAC_PC_EPA_MASK;
578 tmp |= phyaddr;
579 bcma_write32(core, phy_ctl_addr, tmp);
580
581 tmp = BGMAC_PA_START;
582 tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
583 tmp |= reg << BGMAC_PA_REG_SHIFT;
584 bcma_write32(core, phy_access_addr, tmp);
585
586 if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) {
587 bgmac_err(bgmac, "Reading PHY %d register 0x%X failed\n",
588 phyaddr, reg);
589 return 0xffff;
590 }
591
592 return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK;
593}
594
595/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */
Rafał Miłecki217a55a2013-02-12 23:14:51 +0000596static int bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value)
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000597{
598 struct bcma_device *core;
599 u16 phy_access_addr;
600 u16 phy_ctl_addr;
601 u32 tmp;
602
603 if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
604 core = bgmac->core->bus->drv_gmac_cmn.core;
605 phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
606 phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
607 } else {
608 core = bgmac->core;
609 phy_access_addr = BGMAC_PHY_ACCESS;
610 phy_ctl_addr = BGMAC_PHY_CNTL;
611 }
612
613 tmp = bcma_read32(core, phy_ctl_addr);
614 tmp &= ~BGMAC_PC_EPA_MASK;
615 tmp |= phyaddr;
616 bcma_write32(core, phy_ctl_addr, tmp);
617
618 bgmac_write(bgmac, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
619 if (bgmac_read(bgmac, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
620 bgmac_warn(bgmac, "Error setting MDIO int\n");
621
622 tmp = BGMAC_PA_START;
623 tmp |= BGMAC_PA_WRITE;
624 tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
625 tmp |= reg << BGMAC_PA_REG_SHIFT;
626 tmp |= value;
627 bcma_write32(core, phy_access_addr, tmp);
628
Rafał Miłecki217a55a2013-02-12 23:14:51 +0000629 if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) {
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000630 bgmac_err(bgmac, "Writing to PHY %d register 0x%X failed\n",
631 phyaddr, reg);
Rafał Miłecki217a55a2013-02-12 23:14:51 +0000632 return -ETIMEDOUT;
633 }
634
635 return 0;
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000636}
637
638/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyforce */
639static void bgmac_phy_force(struct bgmac *bgmac)
640{
641 u16 ctl;
642 u16 mask = ~(BGMAC_PHY_CTL_SPEED | BGMAC_PHY_CTL_SPEED_MSB |
643 BGMAC_PHY_CTL_ANENAB | BGMAC_PHY_CTL_DUPLEX);
644
645 if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
646 return;
647
648 if (bgmac->autoneg)
649 return;
650
651 ctl = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL);
652 ctl &= mask;
653 if (bgmac->full_duplex)
654 ctl |= BGMAC_PHY_CTL_DUPLEX;
655 if (bgmac->speed == BGMAC_SPEED_100)
656 ctl |= BGMAC_PHY_CTL_SPEED_100;
657 else if (bgmac->speed == BGMAC_SPEED_1000)
658 ctl |= BGMAC_PHY_CTL_SPEED_1000;
659 bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL, ctl);
660}
661
662/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyadvertise */
663static void bgmac_phy_advertise(struct bgmac *bgmac)
664{
665 u16 adv;
666
667 if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
668 return;
669
670 if (!bgmac->autoneg)
671 return;
672
673 /* Adv selected 10/100 speeds */
674 adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV);
675 adv &= ~(BGMAC_PHY_ADV_10HALF | BGMAC_PHY_ADV_10FULL |
676 BGMAC_PHY_ADV_100HALF | BGMAC_PHY_ADV_100FULL);
677 if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10)
678 adv |= BGMAC_PHY_ADV_10HALF;
679 if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100)
680 adv |= BGMAC_PHY_ADV_100HALF;
681 if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_10)
682 adv |= BGMAC_PHY_ADV_10FULL;
683 if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_100)
684 adv |= BGMAC_PHY_ADV_100FULL;
685 bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV, adv);
686
687 /* Adv selected 1000 speeds */
688 adv = bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2);
689 adv &= ~(BGMAC_PHY_ADV2_1000HALF | BGMAC_PHY_ADV2_1000FULL);
690 if (!bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000)
691 adv |= BGMAC_PHY_ADV2_1000HALF;
692 if (bgmac->full_duplex && bgmac->speed & BGMAC_SPEED_1000)
693 adv |= BGMAC_PHY_ADV2_1000FULL;
694 bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_ADV2, adv);
695
696 /* Restart */
697 bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL,
698 bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) |
699 BGMAC_PHY_CTL_RESTART);
700}
701
702/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */
703static void bgmac_phy_init(struct bgmac *bgmac)
704{
705 struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
706 struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
707 u8 i;
708
709 if (ci->id == BCMA_CHIP_ID_BCM5356) {
710 for (i = 0; i < 5; i++) {
711 bgmac_phy_write(bgmac, i, 0x1f, 0x008b);
712 bgmac_phy_write(bgmac, i, 0x15, 0x0100);
713 bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
714 bgmac_phy_write(bgmac, i, 0x12, 0x2aaa);
715 bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
716 }
717 }
718 if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) ||
719 (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) ||
720 (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) {
721 bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0);
722 bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0);
723 for (i = 0; i < 5; i++) {
724 bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
725 bgmac_phy_write(bgmac, i, 0x16, 0x5284);
726 bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
727 bgmac_phy_write(bgmac, i, 0x17, 0x0010);
728 bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
729 bgmac_phy_write(bgmac, i, 0x16, 0x5296);
730 bgmac_phy_write(bgmac, i, 0x17, 0x1073);
731 bgmac_phy_write(bgmac, i, 0x17, 0x9073);
732 bgmac_phy_write(bgmac, i, 0x16, 0x52b6);
733 bgmac_phy_write(bgmac, i, 0x17, 0x9273);
734 bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
735 }
736 }
737}
738
739/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */
740static void bgmac_phy_reset(struct bgmac *bgmac)
741{
742 if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
743 return;
744
745 bgmac_phy_write(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL,
746 BGMAC_PHY_CTL_RESET);
747 udelay(100);
748 if (bgmac_phy_read(bgmac, bgmac->phyaddr, BGMAC_PHY_CTL) &
749 BGMAC_PHY_CTL_RESET)
750 bgmac_err(bgmac, "PHY reset failed\n");
751 bgmac_phy_init(bgmac);
752}
753
754/**************************************************
755 * Chip ops
756 **************************************************/
757
758/* TODO: can we just drop @force? Can we don't reset MAC at all if there is
759 * nothing to change? Try if after stabilizng driver.
760 */
761static void bgmac_cmdcfg_maskset(struct bgmac *bgmac, u32 mask, u32 set,
762 bool force)
763{
764 u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
765 u32 new_val = (cmdcfg & mask) | set;
766
767 bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR);
768 udelay(2);
769
770 if (new_val != cmdcfg || force)
771 bgmac_write(bgmac, BGMAC_CMDCFG, new_val);
772
773 bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR);
774 udelay(2);
775}
776
Hauke Mehrtens4e209002013-02-06 04:44:58 +0000777static void bgmac_write_mac_address(struct bgmac *bgmac, u8 *addr)
778{
779 u32 tmp;
780
781 tmp = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
782 bgmac_write(bgmac, BGMAC_MACADDR_HIGH, tmp);
783 tmp = (addr[4] << 8) | addr[5];
784 bgmac_write(bgmac, BGMAC_MACADDR_LOW, tmp);
785}
786
Hauke Mehrtensc6edfe12013-02-06 05:51:49 +0000787static void bgmac_set_rx_mode(struct net_device *net_dev)
788{
789 struct bgmac *bgmac = netdev_priv(net_dev);
790
791 if (net_dev->flags & IFF_PROMISC)
Rafał Miłeckie9ba1032013-02-07 05:40:38 +0000792 bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, true);
Hauke Mehrtensc6edfe12013-02-06 05:51:49 +0000793 else
Rafał Miłeckie9ba1032013-02-07 05:40:38 +0000794 bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_PROM, 0, true);
Hauke Mehrtensc6edfe12013-02-06 05:51:49 +0000795}
796
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000797#if 0 /* We don't use that regs yet */
798static void bgmac_chip_stats_update(struct bgmac *bgmac)
799{
800 int i;
801
802 if (bgmac->core->id.id != BCMA_CORE_4706_MAC_GBIT) {
803 for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++)
804 bgmac->mib_tx_regs[i] =
805 bgmac_read(bgmac,
806 BGMAC_TX_GOOD_OCTETS + (i * 4));
807 for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
808 bgmac->mib_rx_regs[i] =
809 bgmac_read(bgmac,
810 BGMAC_RX_GOOD_OCTETS + (i * 4));
811 }
812
813 /* TODO: what else? how to handle BCM4706? Specs are needed */
814}
815#endif
816
817static void bgmac_clear_mib(struct bgmac *bgmac)
818{
819 int i;
820
821 if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT)
822 return;
823
824 bgmac_set(bgmac, BGMAC_DEV_CTL, BGMAC_DC_MROR);
825 for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++)
826 bgmac_read(bgmac, BGMAC_TX_GOOD_OCTETS + (i * 4));
827 for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
828 bgmac_read(bgmac, BGMAC_RX_GOOD_OCTETS + (i * 4));
829}
830
831/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_speed */
832static void bgmac_speed(struct bgmac *bgmac, int speed)
833{
834 u32 mask = ~(BGMAC_CMDCFG_ES_MASK | BGMAC_CMDCFG_HD);
835 u32 set = 0;
836
837 if (speed & BGMAC_SPEED_10)
838 set |= BGMAC_CMDCFG_ES_10;
839 if (speed & BGMAC_SPEED_100)
840 set |= BGMAC_CMDCFG_ES_100;
841 if (speed & BGMAC_SPEED_1000)
842 set |= BGMAC_CMDCFG_ES_1000;
843 if (!bgmac->full_duplex)
844 set |= BGMAC_CMDCFG_HD;
845 bgmac_cmdcfg_maskset(bgmac, mask, set, true);
846}
847
848static void bgmac_miiconfig(struct bgmac *bgmac)
849{
850 u8 imode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
851 BGMAC_DS_MM_SHIFT;
852 if (imode == 0 || imode == 1) {
853 if (bgmac->autoneg)
854 bgmac_speed(bgmac, BGMAC_SPEED_100);
855 else
856 bgmac_speed(bgmac, bgmac->speed);
857 }
858}
859
860/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
861static void bgmac_chip_reset(struct bgmac *bgmac)
862{
863 struct bcma_device *core = bgmac->core;
864 struct bcma_bus *bus = core->bus;
865 struct bcma_chipinfo *ci = &bus->chipinfo;
866 u32 flags = 0;
867 u32 iost;
868 int i;
869
870 if (bcma_core_is_enabled(core)) {
871 if (!bgmac->stats_grabbed) {
872 /* bgmac_chip_stats_update(bgmac); */
873 bgmac->stats_grabbed = true;
874 }
875
876 for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
877 bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]);
878
879 bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
880 udelay(1);
881
882 for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
883 bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]);
884
885 /* TODO: Clear software multicast filter list */
886 }
887
888 iost = bcma_aread32(core, BCMA_IOST);
889 if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 10) ||
890 (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg == 10) ||
891 (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == 9))
892 iost &= ~BGMAC_BCMA_IOST_ATTACHED;
893
894 if (iost & BGMAC_BCMA_IOST_ATTACHED) {
895 flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
896 if (!bgmac->has_robosw)
897 flags |= BGMAC_BCMA_IOCTL_SW_RESET;
898 }
899
900 bcma_core_enable(core, flags);
901
902 if (core->id.rev > 2) {
903 bgmac_set(bgmac, BCMA_CLKCTLST, 1 << 8);
904 bgmac_wait_value(bgmac->core, BCMA_CLKCTLST, 1 << 24, 1 << 24,
905 1000);
906 }
907
908 if (ci->id == BCMA_CHIP_ID_BCM5357 || ci->id == BCMA_CHIP_ID_BCM4749 ||
909 ci->id == BCMA_CHIP_ID_BCM53572) {
910 struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
911 u8 et_swtype = 0;
912 u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
913 BGMAC_CHIPCTL_1_IF_TYPE_RMII;
914 char buf[2];
915
Ralf Baechleedb15d82013-02-21 16:16:55 +0100916 if (bcm47xx_nvram_getenv("et_swtype", buf, 1) > 0) {
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000917 if (kstrtou8(buf, 0, &et_swtype))
918 bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n",
919 buf);
920 et_swtype &= 0x0f;
921 et_swtype <<= 4;
922 sw_type = et_swtype;
923 } else if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 9) {
924 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII;
Hauke Mehrtensb5a4c2f2013-02-06 04:44:57 +0000925 } else if ((ci->id != BCMA_CHIP_ID_BCM53572 && ci->pkg == 10) ||
926 (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == 9)) {
927 sw_type = BGMAC_CHIPCTL_1_IF_TYPE_RGMII |
928 BGMAC_CHIPCTL_1_SW_TYPE_RGMII;
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000929 }
930 bcma_chipco_chipctl_maskset(cc, 1,
931 ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
932 BGMAC_CHIPCTL_1_SW_TYPE_MASK),
933 sw_type);
934 }
935
936 if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
937 bcma_awrite32(core, BCMA_IOCTL,
938 bcma_aread32(core, BCMA_IOCTL) &
939 ~BGMAC_BCMA_IOCTL_SW_RESET);
940
941 /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset
942 * Specs don't say about using BGMAC_CMDCFG_SR, but in this routine
943 * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
944 * be keps until taking MAC out of the reset.
945 */
946 bgmac_cmdcfg_maskset(bgmac,
947 ~(BGMAC_CMDCFG_TE |
948 BGMAC_CMDCFG_RE |
949 BGMAC_CMDCFG_RPI |
950 BGMAC_CMDCFG_TAI |
951 BGMAC_CMDCFG_HD |
952 BGMAC_CMDCFG_ML |
953 BGMAC_CMDCFG_CFE |
954 BGMAC_CMDCFG_RL |
955 BGMAC_CMDCFG_RED |
956 BGMAC_CMDCFG_PE |
957 BGMAC_CMDCFG_TPI |
958 BGMAC_CMDCFG_PAD_EN |
959 BGMAC_CMDCFG_PF),
960 BGMAC_CMDCFG_PROM |
961 BGMAC_CMDCFG_NLC |
962 BGMAC_CMDCFG_CFE |
963 BGMAC_CMDCFG_SR,
964 false);
965
966 bgmac_clear_mib(bgmac);
967 if (core->id.id == BCMA_CORE_4706_MAC_GBIT)
968 bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0,
969 BCMA_GMAC_CMN_PC_MTE);
970 else
971 bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
972 bgmac_miiconfig(bgmac);
973 bgmac_phy_init(bgmac);
974
975 bgmac->int_status = 0;
976}
977
978static void bgmac_chip_intrs_on(struct bgmac *bgmac)
979{
980 bgmac_write(bgmac, BGMAC_INT_MASK, bgmac->int_mask);
981}
982
983static void bgmac_chip_intrs_off(struct bgmac *bgmac)
984{
985 bgmac_write(bgmac, BGMAC_INT_MASK, 0);
Nathan Hintz41608152013-02-13 19:14:10 +0000986 bgmac_read(bgmac, BGMAC_INT_MASK);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +0000987}
988
989/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_enable */
990static void bgmac_enable(struct bgmac *bgmac)
991{
992 struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
993 u32 cmdcfg;
994 u32 mode;
995 u32 rxq_ctl;
996 u32 fl_ctl;
997 u16 bp_clk;
998 u8 mdp;
999
1000 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
1001 bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE),
1002 BGMAC_CMDCFG_SR, true);
1003 udelay(2);
1004 cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE;
1005 bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg);
1006
1007 mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
1008 BGMAC_DS_MM_SHIFT;
1009 if (ci->id != BCMA_CHIP_ID_BCM47162 || mode != 0)
1010 bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
1011 if (ci->id == BCMA_CHIP_ID_BCM47162 && mode == 2)
1012 bcma_chipco_chipctl_maskset(&bgmac->core->bus->drv_cc, 1, ~0,
1013 BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
1014
1015 switch (ci->id) {
1016 case BCMA_CHIP_ID_BCM5357:
1017 case BCMA_CHIP_ID_BCM4749:
1018 case BCMA_CHIP_ID_BCM53572:
1019 case BCMA_CHIP_ID_BCM4716:
1020 case BCMA_CHIP_ID_BCM47162:
1021 fl_ctl = 0x03cb04cb;
1022 if (ci->id == BCMA_CHIP_ID_BCM5357 ||
1023 ci->id == BCMA_CHIP_ID_BCM4749 ||
1024 ci->id == BCMA_CHIP_ID_BCM53572)
1025 fl_ctl = 0x2300e1;
1026 bgmac_write(bgmac, BGMAC_FLOW_CTL_THRESH, fl_ctl);
1027 bgmac_write(bgmac, BGMAC_PAUSE_CTL, 0x27fff);
1028 break;
1029 }
1030
1031 rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL);
1032 rxq_ctl &= ~BGMAC_RXQ_CTL_MDP_MASK;
1033 bp_clk = bcma_pmu_get_bus_clock(&bgmac->core->bus->drv_cc) / 1000000;
1034 mdp = (bp_clk * 128 / 1000) - 3;
1035 rxq_ctl |= (mdp << BGMAC_RXQ_CTL_MDP_SHIFT);
1036 bgmac_write(bgmac, BGMAC_RXQ_CTL, rxq_ctl);
1037}
1038
1039/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
1040static void bgmac_chip_init(struct bgmac *bgmac, bool full_init)
1041{
1042 struct bgmac_dma_ring *ring;
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001043 int i;
1044
1045 /* 1 interrupt per received frame */
1046 bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
1047
1048 /* Enable 802.3x tx flow control (honor received PAUSE frames) */
1049 bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true);
1050
Hauke Mehrtensc6edfe12013-02-06 05:51:49 +00001051 bgmac_set_rx_mode(bgmac->net_dev);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001052
Hauke Mehrtens4e209002013-02-06 04:44:58 +00001053 bgmac_write_mac_address(bgmac, bgmac->net_dev->dev_addr);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001054
1055 if (bgmac->loopback)
Rafał Miłeckie9ba1032013-02-07 05:40:38 +00001056 bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001057 else
Rafał Miłeckie9ba1032013-02-07 05:40:38 +00001058 bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, false);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001059
1060 bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
1061
1062 if (!bgmac->autoneg) {
1063 bgmac_speed(bgmac, bgmac->speed);
1064 bgmac_phy_force(bgmac);
1065 } else if (bgmac->speed) { /* if there is anything to adv */
1066 bgmac_phy_advertise(bgmac);
1067 }
1068
1069 if (full_init) {
1070 bgmac_dma_init(bgmac);
1071 if (1) /* FIXME: is there any case we don't want IRQs? */
1072 bgmac_chip_intrs_on(bgmac);
1073 } else {
1074 for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
1075 ring = &bgmac->rx_ring[i];
1076 bgmac_dma_rx_enable(bgmac, ring);
1077 }
1078 }
1079
1080 bgmac_enable(bgmac);
1081}
1082
1083static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
1084{
1085 struct bgmac *bgmac = netdev_priv(dev_id);
1086
1087 u32 int_status = bgmac_read(bgmac, BGMAC_INT_STATUS);
1088 int_status &= bgmac->int_mask;
1089
1090 if (!int_status)
1091 return IRQ_NONE;
1092
1093 /* Ack */
1094 bgmac_write(bgmac, BGMAC_INT_STATUS, int_status);
1095
1096 /* Disable new interrupts until handling existing ones */
1097 bgmac_chip_intrs_off(bgmac);
1098
1099 bgmac->int_status = int_status;
1100
1101 napi_schedule(&bgmac->napi);
1102
1103 return IRQ_HANDLED;
1104}
1105
1106static int bgmac_poll(struct napi_struct *napi, int weight)
1107{
1108 struct bgmac *bgmac = container_of(napi, struct bgmac, napi);
1109 struct bgmac_dma_ring *ring;
1110 int handled = 0;
1111
1112 if (bgmac->int_status & BGMAC_IS_TX0) {
1113 ring = &bgmac->tx_ring[0];
1114 bgmac_dma_tx_free(bgmac, ring);
1115 bgmac->int_status &= ~BGMAC_IS_TX0;
1116 }
1117
1118 if (bgmac->int_status & BGMAC_IS_RX) {
1119 ring = &bgmac->rx_ring[0];
1120 handled += bgmac_dma_rx_read(bgmac, ring, weight);
1121 bgmac->int_status &= ~BGMAC_IS_RX;
1122 }
1123
1124 if (bgmac->int_status) {
1125 bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status);
1126 bgmac->int_status = 0;
1127 }
1128
1129 if (handled < weight)
1130 napi_complete(napi);
1131
1132 bgmac_chip_intrs_on(bgmac);
1133
1134 return handled;
1135}
1136
1137/**************************************************
1138 * net_device_ops
1139 **************************************************/
1140
1141static int bgmac_open(struct net_device *net_dev)
1142{
1143 struct bgmac *bgmac = netdev_priv(net_dev);
1144 int err = 0;
1145
1146 bgmac_chip_reset(bgmac);
1147 /* Specs say about reclaiming rings here, but we do that in DMA init */
1148 bgmac_chip_init(bgmac, true);
1149
1150 err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED,
1151 KBUILD_MODNAME, net_dev);
1152 if (err < 0) {
1153 bgmac_err(bgmac, "IRQ request error: %d!\n", err);
1154 goto err_out;
1155 }
1156 napi_enable(&bgmac->napi);
1157
1158 netif_carrier_on(net_dev);
1159
1160err_out:
1161 return err;
1162}
1163
1164static int bgmac_stop(struct net_device *net_dev)
1165{
1166 struct bgmac *bgmac = netdev_priv(net_dev);
1167
1168 netif_carrier_off(net_dev);
1169
1170 napi_disable(&bgmac->napi);
1171 bgmac_chip_intrs_off(bgmac);
1172 free_irq(bgmac->core->irq, net_dev);
1173
1174 bgmac_chip_reset(bgmac);
1175
1176 return 0;
1177}
1178
1179static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb,
1180 struct net_device *net_dev)
1181{
1182 struct bgmac *bgmac = netdev_priv(net_dev);
1183 struct bgmac_dma_ring *ring;
1184
1185 /* No QOS support yet */
1186 ring = &bgmac->tx_ring[0];
1187 return bgmac_dma_tx_add(bgmac, ring, skb);
1188}
1189
Hauke Mehrtens4e209002013-02-06 04:44:58 +00001190static int bgmac_set_mac_address(struct net_device *net_dev, void *addr)
1191{
1192 struct bgmac *bgmac = netdev_priv(net_dev);
1193 int ret;
1194
1195 ret = eth_prepare_mac_addr_change(net_dev, addr);
1196 if (ret < 0)
1197 return ret;
1198 bgmac_write_mac_address(bgmac, (u8 *)addr);
1199 eth_commit_mac_addr_change(net_dev, addr);
1200 return 0;
1201}
1202
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001203static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
1204{
1205 struct bgmac *bgmac = netdev_priv(net_dev);
1206 struct mii_ioctl_data *data = if_mii(ifr);
1207
1208 switch (cmd) {
1209 case SIOCGMIIPHY:
1210 data->phy_id = bgmac->phyaddr;
1211 /* fallthru */
1212 case SIOCGMIIREG:
1213 if (!netif_running(net_dev))
1214 return -EAGAIN;
1215 data->val_out = bgmac_phy_read(bgmac, data->phy_id,
1216 data->reg_num & 0x1f);
1217 return 0;
1218 case SIOCSMIIREG:
1219 if (!netif_running(net_dev))
1220 return -EAGAIN;
1221 bgmac_phy_write(bgmac, data->phy_id, data->reg_num & 0x1f,
1222 data->val_in);
1223 return 0;
1224 default:
1225 return -EOPNOTSUPP;
1226 }
1227}
1228
1229static const struct net_device_ops bgmac_netdev_ops = {
1230 .ndo_open = bgmac_open,
1231 .ndo_stop = bgmac_stop,
1232 .ndo_start_xmit = bgmac_start_xmit,
Hauke Mehrtensc6edfe12013-02-06 05:51:49 +00001233 .ndo_set_rx_mode = bgmac_set_rx_mode,
Hauke Mehrtens4e209002013-02-06 04:44:58 +00001234 .ndo_set_mac_address = bgmac_set_mac_address,
Hauke Mehrtens522c5902013-02-06 04:44:59 +00001235 .ndo_validate_addr = eth_validate_addr,
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001236 .ndo_do_ioctl = bgmac_ioctl,
1237};
1238
1239/**************************************************
1240 * ethtool_ops
1241 **************************************************/
1242
1243static int bgmac_get_settings(struct net_device *net_dev,
1244 struct ethtool_cmd *cmd)
1245{
1246 struct bgmac *bgmac = netdev_priv(net_dev);
1247
1248 cmd->supported = SUPPORTED_10baseT_Half |
1249 SUPPORTED_10baseT_Full |
1250 SUPPORTED_100baseT_Half |
1251 SUPPORTED_100baseT_Full |
1252 SUPPORTED_1000baseT_Half |
1253 SUPPORTED_1000baseT_Full |
1254 SUPPORTED_Autoneg;
1255
1256 if (bgmac->autoneg) {
1257 WARN_ON(cmd->advertising);
1258 if (bgmac->full_duplex) {
1259 if (bgmac->speed & BGMAC_SPEED_10)
1260 cmd->advertising |= ADVERTISED_10baseT_Full;
1261 if (bgmac->speed & BGMAC_SPEED_100)
1262 cmd->advertising |= ADVERTISED_100baseT_Full;
1263 if (bgmac->speed & BGMAC_SPEED_1000)
1264 cmd->advertising |= ADVERTISED_1000baseT_Full;
1265 } else {
1266 if (bgmac->speed & BGMAC_SPEED_10)
1267 cmd->advertising |= ADVERTISED_10baseT_Half;
1268 if (bgmac->speed & BGMAC_SPEED_100)
1269 cmd->advertising |= ADVERTISED_100baseT_Half;
1270 if (bgmac->speed & BGMAC_SPEED_1000)
1271 cmd->advertising |= ADVERTISED_1000baseT_Half;
1272 }
1273 } else {
1274 switch (bgmac->speed) {
1275 case BGMAC_SPEED_10:
1276 ethtool_cmd_speed_set(cmd, SPEED_10);
1277 break;
1278 case BGMAC_SPEED_100:
1279 ethtool_cmd_speed_set(cmd, SPEED_100);
1280 break;
1281 case BGMAC_SPEED_1000:
1282 ethtool_cmd_speed_set(cmd, SPEED_1000);
1283 break;
1284 }
1285 }
1286
1287 cmd->duplex = bgmac->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1288
1289 cmd->autoneg = bgmac->autoneg;
1290
1291 return 0;
1292}
1293
1294#if 0
1295static int bgmac_set_settings(struct net_device *net_dev,
1296 struct ethtool_cmd *cmd)
1297{
1298 struct bgmac *bgmac = netdev_priv(net_dev);
1299
1300 return -1;
1301}
1302#endif
1303
1304static void bgmac_get_drvinfo(struct net_device *net_dev,
1305 struct ethtool_drvinfo *info)
1306{
1307 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
1308 strlcpy(info->bus_info, "BCMA", sizeof(info->bus_info));
1309}
1310
1311static const struct ethtool_ops bgmac_ethtool_ops = {
1312 .get_settings = bgmac_get_settings,
1313 .get_drvinfo = bgmac_get_drvinfo,
1314};
1315
1316/**************************************************
Rafał Miłecki11e5e762013-03-07 01:53:28 +00001317 * MII
1318 **************************************************/
1319
1320static int bgmac_mii_read(struct mii_bus *bus, int mii_id, int regnum)
1321{
1322 return bgmac_phy_read(bus->priv, mii_id, regnum);
1323}
1324
1325static int bgmac_mii_write(struct mii_bus *bus, int mii_id, int regnum,
1326 u16 value)
1327{
1328 return bgmac_phy_write(bus->priv, mii_id, regnum, value);
1329}
1330
1331static int bgmac_mii_register(struct bgmac *bgmac)
1332{
1333 struct mii_bus *mii_bus;
1334 int i, err = 0;
1335
1336 mii_bus = mdiobus_alloc();
1337 if (!mii_bus)
1338 return -ENOMEM;
1339
1340 mii_bus->name = "bgmac mii bus";
1341 sprintf(mii_bus->id, "%s-%d-%d", "bgmac", bgmac->core->bus->num,
1342 bgmac->core->core_unit);
1343 mii_bus->priv = bgmac;
1344 mii_bus->read = bgmac_mii_read;
1345 mii_bus->write = bgmac_mii_write;
1346 mii_bus->parent = &bgmac->core->dev;
1347 mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
1348
1349 mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
1350 if (!mii_bus->irq) {
1351 err = -ENOMEM;
1352 goto err_free_bus;
1353 }
1354 for (i = 0; i < PHY_MAX_ADDR; i++)
1355 mii_bus->irq[i] = PHY_POLL;
1356
1357 err = mdiobus_register(mii_bus);
1358 if (err) {
1359 bgmac_err(bgmac, "Registration of mii bus failed\n");
1360 goto err_free_irq;
1361 }
1362
1363 bgmac->mii_bus = mii_bus;
1364
1365 return err;
1366
1367err_free_irq:
1368 kfree(mii_bus->irq);
1369err_free_bus:
1370 mdiobus_free(mii_bus);
1371 return err;
1372}
1373
1374static void bgmac_mii_unregister(struct bgmac *bgmac)
1375{
1376 struct mii_bus *mii_bus = bgmac->mii_bus;
1377
1378 mdiobus_unregister(mii_bus);
1379 kfree(mii_bus->irq);
1380 mdiobus_free(mii_bus);
1381}
1382
1383/**************************************************
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001384 * BCMA bus ops
1385 **************************************************/
1386
1387/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
1388static int bgmac_probe(struct bcma_device *core)
1389{
1390 struct net_device *net_dev;
1391 struct bgmac *bgmac;
1392 struct ssb_sprom *sprom = &core->bus->sprom;
1393 u8 *mac = core->core_unit ? sprom->et1mac : sprom->et0mac;
1394 int err;
1395
1396 /* We don't support 2nd, 3rd, ... units, SPROM has to be adjusted */
1397 if (core->core_unit > 1) {
1398 pr_err("Unsupported core_unit %d\n", core->core_unit);
1399 return -ENOTSUPP;
1400 }
1401
Rafał Miłeckid166f212013-02-07 00:27:17 +00001402 if (!is_valid_ether_addr(mac)) {
1403 dev_err(&core->dev, "Invalid MAC addr: %pM\n", mac);
1404 eth_random_addr(mac);
1405 dev_warn(&core->dev, "Using random MAC: %pM\n", mac);
1406 }
1407
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001408 /* Allocation and references */
1409 net_dev = alloc_etherdev(sizeof(*bgmac));
1410 if (!net_dev)
1411 return -ENOMEM;
1412 net_dev->netdev_ops = &bgmac_netdev_ops;
1413 net_dev->irq = core->irq;
1414 SET_ETHTOOL_OPS(net_dev, &bgmac_ethtool_ops);
1415 bgmac = netdev_priv(net_dev);
1416 bgmac->net_dev = net_dev;
1417 bgmac->core = core;
1418 bcma_set_drvdata(core, bgmac);
1419
1420 /* Defaults */
1421 bgmac->autoneg = true;
1422 bgmac->full_duplex = true;
1423 bgmac->speed = BGMAC_SPEED_10 | BGMAC_SPEED_100 | BGMAC_SPEED_1000;
1424 memcpy(bgmac->net_dev->dev_addr, mac, ETH_ALEN);
1425
1426 /* On BCM4706 we need common core to access PHY */
1427 if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
1428 !core->bus->drv_gmac_cmn.core) {
1429 bgmac_err(bgmac, "GMAC CMN core not found (required for BCM4706)\n");
1430 err = -ENODEV;
1431 goto err_netdev_free;
1432 }
1433 bgmac->cmn = core->bus->drv_gmac_cmn.core;
1434
1435 bgmac->phyaddr = core->core_unit ? sprom->et1phyaddr :
1436 sprom->et0phyaddr;
1437 bgmac->phyaddr &= BGMAC_PHY_MASK;
1438 if (bgmac->phyaddr == BGMAC_PHY_MASK) {
1439 bgmac_err(bgmac, "No PHY found\n");
1440 err = -ENODEV;
1441 goto err_netdev_free;
1442 }
1443 bgmac_info(bgmac, "Found PHY addr: %d%s\n", bgmac->phyaddr,
1444 bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : "");
1445
1446 if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
1447 bgmac_err(bgmac, "PCI setup not implemented\n");
1448 err = -ENOTSUPP;
1449 goto err_netdev_free;
1450 }
1451
1452 bgmac_chip_reset(bgmac);
1453
1454 err = bgmac_dma_alloc(bgmac);
1455 if (err) {
1456 bgmac_err(bgmac, "Unable to alloc memory for DMA\n");
1457 goto err_netdev_free;
1458 }
1459
1460 bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK;
Ralf Baechleedb15d82013-02-21 16:16:55 +01001461 if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0)
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001462 bgmac->int_mask &= ~BGMAC_IS_TX_MASK;
1463
1464 /* TODO: reset the external phy. Specs are needed */
1465 bgmac_phy_reset(bgmac);
1466
1467 bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo &
1468 BGMAC_BFL_ENETROBO);
1469 if (bgmac->has_robosw)
1470 bgmac_warn(bgmac, "Support for Roboswitch not implemented\n");
1471
1472 if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM)
1473 bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n");
1474
Rafał Miłecki11e5e762013-03-07 01:53:28 +00001475 err = bgmac_mii_register(bgmac);
1476 if (err) {
1477 bgmac_err(bgmac, "Cannot register MDIO\n");
1478 err = -ENOTSUPP;
1479 goto err_dma_free;
1480 }
1481
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001482 err = register_netdev(bgmac->net_dev);
1483 if (err) {
1484 bgmac_err(bgmac, "Cannot register net device\n");
1485 err = -ENOTSUPP;
Rafał Miłecki11e5e762013-03-07 01:53:28 +00001486 goto err_mii_unregister;
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001487 }
1488
1489 netif_carrier_off(net_dev);
1490
1491 netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT);
1492
1493 return 0;
1494
Rafał Miłecki11e5e762013-03-07 01:53:28 +00001495err_mii_unregister:
1496 bgmac_mii_unregister(bgmac);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001497err_dma_free:
1498 bgmac_dma_free(bgmac);
1499
1500err_netdev_free:
1501 bcma_set_drvdata(core, NULL);
1502 free_netdev(net_dev);
1503
1504 return err;
1505}
1506
1507static void bgmac_remove(struct bcma_device *core)
1508{
1509 struct bgmac *bgmac = bcma_get_drvdata(core);
1510
1511 netif_napi_del(&bgmac->napi);
1512 unregister_netdev(bgmac->net_dev);
Rafał Miłecki11e5e762013-03-07 01:53:28 +00001513 bgmac_mii_unregister(bgmac);
Rafał Miłeckidd4544f2013-01-08 20:06:23 +00001514 bgmac_dma_free(bgmac);
1515 bcma_set_drvdata(core, NULL);
1516 free_netdev(bgmac->net_dev);
1517}
1518
1519static struct bcma_driver bgmac_bcma_driver = {
1520 .name = KBUILD_MODNAME,
1521 .id_table = bgmac_bcma_tbl,
1522 .probe = bgmac_probe,
1523 .remove = bgmac_remove,
1524};
1525
1526static int __init bgmac_init(void)
1527{
1528 int err;
1529
1530 err = bcma_driver_register(&bgmac_bcma_driver);
1531 if (err)
1532 return err;
1533 pr_info("Broadcom 47xx GBit MAC driver loaded\n");
1534
1535 return 0;
1536}
1537
1538static void __exit bgmac_exit(void)
1539{
1540 bcma_driver_unregister(&bgmac_bcma_driver);
1541}
1542
1543module_init(bgmac_init)
1544module_exit(bgmac_exit)
1545
1546MODULE_AUTHOR("Rafał Miłecki");
1547MODULE_LICENSE("GPL");