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 --- |