aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/atheros/alx/main.c97
1 files changed, 53 insertions, 44 deletions
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index eccbacd96201..8935766829b1 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -573,19 +573,41 @@ static int alx_set_mac_address(struct net_device *netdev, void *data)
573 return 0; 573 return 0;
574} 574}
575 575
576static int alx_alloc_descriptors(struct alx_priv *alx) 576static int alx_alloc_tx_ring(struct alx_priv *alx, struct alx_tx_queue *txq,
577 int offset)
577{ 578{
578 alx->txq.bufs = kcalloc(alx->tx_ringsz, 579 txq->bufs = kcalloc(alx->tx_ringsz, sizeof(struct alx_buffer), GFP_KERNEL);
579 sizeof(struct alx_buffer), 580 if (!txq->bufs)
580 GFP_KERNEL);
581 if (!alx->txq.bufs)
582 return -ENOMEM; 581 return -ENOMEM;
583 582
584 alx->rxq.bufs = kcalloc(alx->rx_ringsz, 583 txq->tpd = alx->descmem.virt + offset;
585 sizeof(struct alx_buffer), 584 txq->tpd_dma = alx->descmem.dma + offset;
586 GFP_KERNEL); 585 offset += sizeof(struct alx_txd) * alx->tx_ringsz;
587 if (!alx->rxq.bufs) 586
588 goto out_free; 587 return offset;
588}
589
590static int alx_alloc_rx_ring(struct alx_priv *alx, struct alx_rx_queue *rxq,
591 int offset)
592{
593 rxq->bufs = kcalloc(alx->rx_ringsz, sizeof(struct alx_buffer), GFP_KERNEL);
594 if (!rxq->bufs)
595 return -ENOMEM;
596
597 rxq->rrd = alx->descmem.virt + offset;
598 rxq->rrd_dma = alx->descmem.dma + offset;
599 offset += sizeof(struct alx_rrd) * alx->rx_ringsz;
600
601 rxq->rfd = alx->descmem.virt + offset;
602 rxq->rfd_dma = alx->descmem.dma + offset;
603 offset += sizeof(struct alx_rfd) * alx->rx_ringsz;
604
605 return offset;
606}
607
608static int alx_alloc_rings(struct alx_priv *alx)
609{
610 int offset = 0;
589 611
590 /* physical tx/rx ring descriptors 612 /* physical tx/rx ring descriptors
591 * 613 *
@@ -601,45 +623,23 @@ static int alx_alloc_descriptors(struct alx_priv *alx)
601 &alx->descmem.dma, 623 &alx->descmem.dma,
602 GFP_KERNEL); 624 GFP_KERNEL);
603 if (!alx->descmem.virt) 625 if (!alx->descmem.virt)
604 goto out_free; 626 return -ENOMEM;
605
606 alx->txq.tpd = alx->descmem.virt;
607 alx->txq.tpd_dma = alx->descmem.dma;
608 627
609 /* alignment requirement for next block */ 628 /* alignment requirements */
610 BUILD_BUG_ON(sizeof(struct alx_txd) % 8); 629 BUILD_BUG_ON(sizeof(struct alx_txd) % 8);
611
612 alx->rxq.rrd =
613 (void *)((u8 *)alx->descmem.virt +
614 sizeof(struct alx_txd) * alx->tx_ringsz);
615 alx->rxq.rrd_dma = alx->descmem.dma +
616 sizeof(struct alx_txd) * alx->tx_ringsz;
617
618 /* alignment requirement for next block */
619 BUILD_BUG_ON(sizeof(struct alx_rrd) % 8); 630 BUILD_BUG_ON(sizeof(struct alx_rrd) % 8);
620 631
621 alx->rxq.rfd = 632 offset = alx_alloc_tx_ring(alx, &alx->txq, offset);
622 (void *)((u8 *)alx->descmem.virt + 633 if (offset < 0) {
623 sizeof(struct alx_txd) * alx->tx_ringsz + 634 netdev_err(alx->dev, "Allocation of tx buffer failed!\n");
624 sizeof(struct alx_rrd) * alx->rx_ringsz); 635 goto out_free;
625 alx->rxq.rfd_dma = alx->descmem.dma + 636 }
626 sizeof(struct alx_txd) * alx->tx_ringsz +
627 sizeof(struct alx_rrd) * alx->rx_ringsz;
628
629 return 0;
630out_free:
631 kfree(alx->txq.bufs);
632 kfree(alx->rxq.bufs);
633 return -ENOMEM;
634}
635
636static int alx_alloc_rings(struct alx_priv *alx)
637{
638 int err;
639 637
640 err = alx_alloc_descriptors(alx); 638 offset = alx_alloc_rx_ring(alx, &alx->rxq, offset);
641 if (err) 639 if (offset < 0) {
642 return err; 640 netdev_err(alx->dev, "Allocation of rx buffer failed!\n");
641 goto out_free;
642 }
643 643
644 alx->int_mask &= ~ALX_ISR_ALL_QUEUES; 644 alx->int_mask &= ~ALX_ISR_ALL_QUEUES;
645 alx->int_mask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0; 645 alx->int_mask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0;
@@ -647,7 +647,16 @@ static int alx_alloc_rings(struct alx_priv *alx)
647 netif_napi_add(alx->dev, &alx->napi, alx_poll, 64); 647 netif_napi_add(alx->dev, &alx->napi, alx_poll, 64);
648 648
649 alx_reinit_rings(alx); 649 alx_reinit_rings(alx);
650
650 return 0; 651 return 0;
652out_free:
653 kfree(alx->txq.bufs);
654 kfree(alx->rxq.bufs);
655 dma_free_coherent(&alx->hw.pdev->dev,
656 alx->descmem.size,
657 alx->descmem.virt,
658 alx->descmem.dma);
659 return -ENOMEM;
651} 660}
652 661
653static void alx_free_rings(struct alx_priv *alx) 662static void alx_free_rings(struct alx_priv *alx)