bgmac.c (4b62dce450e2447146ff6924a1ce8ad1a6592107) bgmac.c (56faacd04509f0a60ed646473a930fe584f1cb02)
1/*
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

--- 372 unchanged lines hidden (view full) ---

381 */
382
383 dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[desc_idx].dma_addr));
384 dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr));
385 dma_desc->ctl0 = cpu_to_le32(ctl0);
386 dma_desc->ctl1 = cpu_to_le32(ctl1);
387}
388
1/*
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

--- 372 unchanged lines hidden (view full) ---

381 */
382
383 dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[desc_idx].dma_addr));
384 dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr));
385 dma_desc->ctl0 = cpu_to_le32(ctl0);
386 dma_desc->ctl1 = cpu_to_le32(ctl1);
387}
388
389static void bgmac_dma_rx_poison_buf(struct device *dma_dev,
390 struct bgmac_slot_info *slot)
391{
392 struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET;
393
394 dma_sync_single_for_cpu(dma_dev, slot->dma_addr, BGMAC_RX_BUF_SIZE,
395 DMA_FROM_DEVICE);
396 rx->len = cpu_to_le16(0xdead);
397 rx->flags = cpu_to_le16(0xbeef);
398 dma_sync_single_for_device(dma_dev, slot->dma_addr, BGMAC_RX_BUF_SIZE,
399 DMA_FROM_DEVICE);
400}
401
389static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
390 int weight)
391{
392 u32 end_slot;
393 int handled = 0;
394
395 end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS);
396 end_slot &= BGMAC_DMA_RX_STATDPTR;

--- 4 unchanged lines hidden (view full) ---

401 ring->end = end_slot;
402
403 while (ring->start != ring->end) {
404 struct device *dma_dev = bgmac->core->dma_dev;
405 struct bgmac_slot_info *slot = &ring->slots[ring->start];
406 struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET;
407 struct sk_buff *skb;
408 void *buf = slot->buf;
402static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
403 int weight)
404{
405 u32 end_slot;
406 int handled = 0;
407
408 end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS);
409 end_slot &= BGMAC_DMA_RX_STATDPTR;

--- 4 unchanged lines hidden (view full) ---

414 ring->end = end_slot;
415
416 while (ring->start != ring->end) {
417 struct device *dma_dev = bgmac->core->dma_dev;
418 struct bgmac_slot_info *slot = &ring->slots[ring->start];
419 struct bgmac_rx_header *rx = slot->buf + BGMAC_RX_BUF_OFFSET;
420 struct sk_buff *skb;
421 void *buf = slot->buf;
422 dma_addr_t dma_addr = slot->dma_addr;
409 u16 len, flags;
410
423 u16 len, flags;
424
411 /* Unmap buffer to make it accessible to the CPU */
412 dma_sync_single_for_cpu(dma_dev, slot->dma_addr,
413 BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
425 do {
426 /* Prepare new skb as replacement */
427 if (bgmac_dma_rx_skb_for_slot(bgmac, slot)) {
428 bgmac_dma_rx_poison_buf(dma_dev, slot);
429 break;
430 }
414
431
415 /* Get info from the header */
416 len = le16_to_cpu(rx->len);
417 flags = le16_to_cpu(rx->flags);
432 /* Unmap buffer to make it accessible to the CPU */
433 dma_unmap_single(dma_dev, dma_addr,
434 BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
418
435
419 do {
420 dma_addr_t old_dma_addr = slot->dma_addr;
421 int err;
436 /* Get info from the header */
437 len = le16_to_cpu(rx->len);
438 flags = le16_to_cpu(rx->flags);
422
423 /* Check for poison and drop or pass the packet */
424 if (len == 0xdead && flags == 0xbeef) {
425 bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
426 ring->start);
439
440 /* Check for poison and drop or pass the packet */
441 if (len == 0xdead && flags == 0xbeef) {
442 bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
443 ring->start);
427 dma_sync_single_for_device(dma_dev,
428 slot->dma_addr,
429 BGMAC_RX_BUF_SIZE,
430 DMA_FROM_DEVICE);
444 put_page(virt_to_head_page(buf));
431 break;
432 }
433
434 /* Omit CRC. */
435 len -= ETH_FCS_LEN;
436
445 break;
446 }
447
448 /* Omit CRC. */
449 len -= ETH_FCS_LEN;
450
437 /* Prepare new skb as replacement */
438 err = bgmac_dma_rx_skb_for_slot(bgmac, slot);
439 if (err) {
440 /* Poison the old skb */
441 rx->len = cpu_to_le16(0xdead);
442 rx->flags = cpu_to_le16(0xbeef);
443
444 dma_sync_single_for_device(dma_dev,
445 slot->dma_addr,
446 BGMAC_RX_BUF_SIZE,
447 DMA_FROM_DEVICE);
448 break;
449 }
450 bgmac_dma_rx_setup_desc(bgmac, ring, ring->start);
451
452 /* Unmap old skb, we'll pass it to the netfif */
453 dma_unmap_single(dma_dev, old_dma_addr,
454 BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
455
456 skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE);
457 skb_put(skb, BGMAC_RX_FRAME_OFFSET +
458 BGMAC_RX_BUF_OFFSET + len);
459 skb_pull(skb, BGMAC_RX_FRAME_OFFSET +
460 BGMAC_RX_BUF_OFFSET);
461
462 skb_checksum_none_assert(skb);
463 skb->protocol = eth_type_trans(skb, bgmac->net_dev);
464 napi_gro_receive(&bgmac->napi, skb);
465 handled++;
466 } while (0);
467
451 skb = build_skb(buf, BGMAC_RX_ALLOC_SIZE);
452 skb_put(skb, BGMAC_RX_FRAME_OFFSET +
453 BGMAC_RX_BUF_OFFSET + len);
454 skb_pull(skb, BGMAC_RX_FRAME_OFFSET +
455 BGMAC_RX_BUF_OFFSET);
456
457 skb_checksum_none_assert(skb);
458 skb->protocol = eth_type_trans(skb, bgmac->net_dev);
459 napi_gro_receive(&bgmac->napi, skb);
460 handled++;
461 } while (0);
462
463 bgmac_dma_rx_setup_desc(bgmac, ring, ring->start);
464
468 if (++ring->start >= BGMAC_RX_RING_SLOTS)
469 ring->start = 0;
470
471 if (handled >= weight) /* Should never be greater */
472 break;
473 }
474
475 return handled;

--- 51 unchanged lines hidden (view full) ---

527 struct bgmac_dma_ring *ring)
528{
529 struct device *dma_dev = bgmac->core->dma_dev;
530 struct bgmac_slot_info *slot;
531 int i;
532
533 for (i = 0; i < ring->num_slots; i++) {
534 slot = &ring->slots[i];
465 if (++ring->start >= BGMAC_RX_RING_SLOTS)
466 ring->start = 0;
467
468 if (handled >= weight) /* Should never be greater */
469 break;
470 }
471
472 return handled;

--- 51 unchanged lines hidden (view full) ---

524 struct bgmac_dma_ring *ring)
525{
526 struct device *dma_dev = bgmac->core->dma_dev;
527 struct bgmac_slot_info *slot;
528 int i;
529
530 for (i = 0; i < ring->num_slots; i++) {
531 slot = &ring->slots[i];
535 if (!slot->buf)
532 if (!slot->dma_addr)
536 continue;
537
533 continue;
534
538 if (slot->dma_addr)
539 dma_unmap_single(dma_dev, slot->dma_addr,
540 BGMAC_RX_BUF_SIZE,
541 DMA_FROM_DEVICE);
535 dma_unmap_single(dma_dev, slot->dma_addr,
536 BGMAC_RX_BUF_SIZE,
537 DMA_FROM_DEVICE);
542 put_page(virt_to_head_page(slot->buf));
538 put_page(virt_to_head_page(slot->buf));
539 slot->dma_addr = 0;
543 }
544}
545
546static void bgmac_dma_ring_desc_free(struct bgmac *bgmac,
547 struct bgmac_dma_ring *ring)
548{
549 struct device *dma_dev = bgmac->core->dma_dev;
550 int size;

--- 1161 unchanged lines hidden ---
540 }
541}
542
543static void bgmac_dma_ring_desc_free(struct bgmac *bgmac,
544 struct bgmac_dma_ring *ring)
545{
546 struct device *dma_dev = bgmac->core->dma_dev;
547 int size;

--- 1161 unchanged lines hidden ---