diff options
| -rw-r--r-- | drivers/net/ethernet/atheros/alx/main.c | 99 |
1 files changed, 78 insertions, 21 deletions
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index 8935766829b1..193da6799979 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
| @@ -632,45 +632,96 @@ static int alx_alloc_rings(struct alx_priv *alx) | |||
| 632 | offset = alx_alloc_tx_ring(alx, &alx->txq, offset); | 632 | offset = alx_alloc_tx_ring(alx, &alx->txq, offset); |
| 633 | if (offset < 0) { | 633 | if (offset < 0) { |
| 634 | netdev_err(alx->dev, "Allocation of tx buffer failed!\n"); | 634 | netdev_err(alx->dev, "Allocation of tx buffer failed!\n"); |
| 635 | goto out_free; | 635 | return -ENOMEM; |
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | offset = alx_alloc_rx_ring(alx, &alx->rxq, offset); | 638 | offset = alx_alloc_rx_ring(alx, &alx->rxq, offset); |
| 639 | if (offset < 0) { | 639 | if (offset < 0) { |
| 640 | netdev_err(alx->dev, "Allocation of rx buffer failed!\n"); | 640 | netdev_err(alx->dev, "Allocation of rx buffer failed!\n"); |
| 641 | goto out_free; | 641 | return -ENOMEM; |
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | alx->int_mask &= ~ALX_ISR_ALL_QUEUES; | ||
| 645 | alx->int_mask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0; | ||
| 646 | |||
| 647 | netif_napi_add(alx->dev, &alx->napi, alx_poll, 64); | ||
| 648 | |||
| 649 | alx_reinit_rings(alx); | 644 | alx_reinit_rings(alx); |
| 650 | 645 | ||
| 651 | return 0; | 646 | return 0; |
| 652 | out_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; | ||
| 660 | } | 647 | } |
| 661 | 648 | ||
| 662 | static void alx_free_rings(struct alx_priv *alx) | 649 | static void alx_free_rings(struct alx_priv *alx) |
| 663 | { | 650 | { |
| 664 | netif_napi_del(&alx->napi); | ||
| 665 | alx_free_buffers(alx); | 651 | alx_free_buffers(alx); |
| 666 | 652 | ||
| 667 | kfree(alx->txq.bufs); | 653 | kfree(alx->txq.bufs); |
| 668 | kfree(alx->rxq.bufs); | 654 | kfree(alx->rxq.bufs); |
| 669 | 655 | ||
| 670 | dma_free_coherent(&alx->hw.pdev->dev, | 656 | if (!alx->descmem.virt) |
| 671 | alx->descmem.size, | 657 | dma_free_coherent(&alx->hw.pdev->dev, |
| 672 | alx->descmem.virt, | 658 | alx->descmem.size, |
| 673 | alx->descmem.dma); | 659 | alx->descmem.virt, |
| 660 | alx->descmem.dma); | ||
| 661 | } | ||
| 662 | |||
| 663 | static void alx_free_napis(struct alx_priv *alx) | ||
| 664 | { | ||
| 665 | struct alx_napi *np; | ||
| 666 | |||
| 667 | np = alx->qnapi[0]; | ||
| 668 | if (!np) | ||
| 669 | return; | ||
| 670 | |||
| 671 | netif_napi_del(&alx->napi); | ||
| 672 | kfree(np->txq); | ||
| 673 | kfree(np->rxq); | ||
| 674 | kfree(np); | ||
| 675 | alx->qnapi[0] = NULL; | ||
| 676 | } | ||
| 677 | |||
| 678 | static int alx_alloc_napis(struct alx_priv *alx) | ||
| 679 | { | ||
| 680 | struct alx_napi *np; | ||
| 681 | struct alx_rx_queue *rxq; | ||
| 682 | struct alx_tx_queue *txq; | ||
| 683 | |||
| 684 | alx->int_mask &= ~ALX_ISR_ALL_QUEUES; | ||
| 685 | alx->int_mask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0; | ||
| 686 | |||
| 687 | /* allocate alx_napi structures */ | ||
| 688 | np = kzalloc(sizeof(struct alx_napi), GFP_KERNEL); | ||
| 689 | if (!np) | ||
| 690 | goto err_out; | ||
| 691 | |||
| 692 | np->alx = alx; | ||
| 693 | netif_napi_add(alx->dev, &alx->napi, alx_poll, 64); | ||
| 694 | alx->qnapi[0] = np; | ||
| 695 | |||
| 696 | /* allocate tx queues */ | ||
| 697 | np = alx->qnapi[0]; | ||
| 698 | txq = kzalloc(sizeof(*txq), GFP_KERNEL); | ||
| 699 | if (!txq) | ||
| 700 | goto err_out; | ||
| 701 | |||
| 702 | np->txq = txq; | ||
| 703 | txq->count = alx->tx_ringsz; | ||
| 704 | txq->netdev = alx->dev; | ||
| 705 | txq->dev = &alx->hw.pdev->dev; | ||
| 706 | |||
| 707 | /* allocate rx queues */ | ||
| 708 | np = alx->qnapi[0]; | ||
| 709 | rxq = kzalloc(sizeof(*rxq), GFP_KERNEL); | ||
| 710 | if (!rxq) | ||
| 711 | goto err_out; | ||
| 712 | |||
| 713 | np->rxq = rxq; | ||
| 714 | rxq->np = alx->qnapi[0]; | ||
| 715 | rxq->count = alx->rx_ringsz; | ||
| 716 | rxq->netdev = alx->dev; | ||
| 717 | rxq->dev = &alx->hw.pdev->dev; | ||
| 718 | |||
| 719 | return 0; | ||
| 720 | |||
| 721 | err_out: | ||
| 722 | netdev_err(alx->dev, "error allocating internal structures\n"); | ||
| 723 | alx_free_napis(alx); | ||
| 724 | return -ENOMEM; | ||
| 674 | } | 725 | } |
| 675 | 726 | ||
| 676 | static void alx_config_vector_mapping(struct alx_priv *alx) | 727 | static void alx_config_vector_mapping(struct alx_priv *alx) |
| @@ -1031,10 +1082,14 @@ static int __alx_open(struct alx_priv *alx, bool resume) | |||
| 1031 | if (!resume) | 1082 | if (!resume) |
| 1032 | netif_carrier_off(alx->dev); | 1083 | netif_carrier_off(alx->dev); |
| 1033 | 1084 | ||
| 1034 | err = alx_alloc_rings(alx); | 1085 | err = alx_alloc_napis(alx); |
| 1035 | if (err) | 1086 | if (err) |
| 1036 | goto out_disable_adv_intr; | 1087 | goto out_disable_adv_intr; |
| 1037 | 1088 | ||
| 1089 | err = alx_alloc_rings(alx); | ||
| 1090 | if (err) | ||
| 1091 | goto out_free_rings; | ||
| 1092 | |||
| 1038 | alx_configure(alx); | 1093 | alx_configure(alx); |
| 1039 | 1094 | ||
| 1040 | err = alx_request_irq(alx); | 1095 | err = alx_request_irq(alx); |
| @@ -1054,6 +1109,7 @@ static int __alx_open(struct alx_priv *alx, bool resume) | |||
| 1054 | 1109 | ||
| 1055 | out_free_rings: | 1110 | out_free_rings: |
| 1056 | alx_free_rings(alx); | 1111 | alx_free_rings(alx); |
| 1112 | alx_free_napis(alx); | ||
| 1057 | out_disable_adv_intr: | 1113 | out_disable_adv_intr: |
| 1058 | alx_disable_advanced_intr(alx); | 1114 | alx_disable_advanced_intr(alx); |
| 1059 | return err; | 1115 | return err; |
| @@ -1064,6 +1120,7 @@ static void __alx_stop(struct alx_priv *alx) | |||
| 1064 | alx_halt(alx); | 1120 | alx_halt(alx); |
| 1065 | alx_free_irq(alx); | 1121 | alx_free_irq(alx); |
| 1066 | alx_free_rings(alx); | 1122 | alx_free_rings(alx); |
| 1123 | alx_free_napis(alx); | ||
| 1067 | } | 1124 | } |
| 1068 | 1125 | ||
| 1069 | static const char *alx_speed_desc(struct alx_hw *hw) | 1126 | static const char *alx_speed_desc(struct alx_hw *hw) |
