mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	* properly format/comment all patches * merge debloat patches * merge Kconfig patches * merge swconfig patches * merge hotplug patches * drop 200-fix_localversion.patch - upstream * drop 222-arm_zimage_none.patch - unused * drop 252-mv_cesa_depends.patch - no longer required * drop 410-mtd-move-forward-declaration-of-struct-mtd_info.patch - unused * drop 661-fq_codel_keep_dropped_stats.patch - outdated * drop 702-phy_add_aneg_done_function.patch - upstream * drop 840-rtc7301.patch - unused * drop 841-rtc_pt7c4338.patch - upstream * drop 921-use_preinit_as_init.patch - unused * drop spio-gpio-old and gpio-mmc - unused Signed-off-by: John Crispin <john@phrozen.org>
		
			
				
	
	
		
			185 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From: Felix Fietkau <nbd@nbd.name>
 | |
| Date: Sun, 12 Apr 2015 23:19:32 +0200
 | |
| Subject: [PATCH] bgmac: simplify dma init/cleanup
 | |
| 
 | |
| Instead of allocating buffers at device init time and initializing
 | |
| descriptors at device open, do both at the same time (during open).
 | |
| Free all buffers when closing the device.
 | |
| 
 | |
| Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| ---
 | |
| 
 | |
| --- a/drivers/net/ethernet/broadcom/bgmac.c
 | |
| +++ b/drivers/net/ethernet/broadcom/bgmac.c
 | |
| @@ -562,18 +562,26 @@ static void bgmac_dma_ring_desc_free(str
 | |
|  			  ring->dma_base);
 | |
|  }
 | |
|  
 | |
| -static void bgmac_dma_free(struct bgmac *bgmac)
 | |
| +static void bgmac_dma_cleanup(struct bgmac *bgmac)
 | |
|  {
 | |
|  	int i;
 | |
|  
 | |
| -	for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
 | |
| +	for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
 | |
|  		bgmac_dma_tx_ring_free(bgmac, &bgmac->tx_ring[i]);
 | |
| -		bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]);
 | |
| -	}
 | |
| -	for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
 | |
| +
 | |
| +	for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
 | |
|  		bgmac_dma_rx_ring_free(bgmac, &bgmac->rx_ring[i]);
 | |
| +}
 | |
| +
 | |
| +static void bgmac_dma_free(struct bgmac *bgmac)
 | |
| +{
 | |
| +	int i;
 | |
| +
 | |
| +	for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
 | |
| +		bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]);
 | |
| +
 | |
| +	for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
 | |
|  		bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]);
 | |
| -	}
 | |
|  }
 | |
|  
 | |
|  static int bgmac_dma_alloc(struct bgmac *bgmac)
 | |
| @@ -621,8 +629,6 @@ static int bgmac_dma_alloc(struct bgmac
 | |
|  	}
 | |
|  
 | |
|  	for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
 | |
| -		int j;
 | |
| -
 | |
|  		ring = &bgmac->rx_ring[i];
 | |
|  		ring->num_slots = BGMAC_RX_RING_SLOTS;
 | |
|  		ring->mmio_base = ring_base[i];
 | |
| @@ -645,15 +651,6 @@ static int bgmac_dma_alloc(struct bgmac
 | |
|  			ring->index_base = lower_32_bits(ring->dma_base);
 | |
|  		else
 | |
|  			ring->index_base = 0;
 | |
| -
 | |
| -		/* Alloc RX slots */
 | |
| -		for (j = 0; j < ring->num_slots; j++) {
 | |
| -			err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]);
 | |
| -			if (err) {
 | |
| -				bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n");
 | |
| -				goto err_dma_free;
 | |
| -			}
 | |
| -		}
 | |
|  	}
 | |
|  
 | |
|  	return 0;
 | |
| @@ -663,10 +660,10 @@ err_dma_free:
 | |
|  	return -ENOMEM;
 | |
|  }
 | |
|  
 | |
| -static void bgmac_dma_init(struct bgmac *bgmac)
 | |
| +static int bgmac_dma_init(struct bgmac *bgmac)
 | |
|  {
 | |
|  	struct bgmac_dma_ring *ring;
 | |
| -	int i;
 | |
| +	int i, err;
 | |
|  
 | |
|  	for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
 | |
|  		ring = &bgmac->tx_ring[i];
 | |
| @@ -698,8 +695,13 @@ static void bgmac_dma_init(struct bgmac
 | |
|  		if (ring->unaligned)
 | |
|  			bgmac_dma_rx_enable(bgmac, ring);
 | |
|  
 | |
| -		for (j = 0; j < ring->num_slots; j++)
 | |
| +		for (j = 0; j < ring->num_slots; j++) {
 | |
| +			err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]);
 | |
| +			if (err)
 | |
| +				goto error;
 | |
| +
 | |
|  			bgmac_dma_rx_setup_desc(bgmac, ring, j);
 | |
| +		}
 | |
|  
 | |
|  		bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
 | |
|  			    ring->index_base +
 | |
| @@ -708,6 +710,12 @@ static void bgmac_dma_init(struct bgmac
 | |
|  		ring->start = 0;
 | |
|  		ring->end = 0;
 | |
|  	}
 | |
| +
 | |
| +	return 0;
 | |
| +
 | |
| +error:
 | |
| +	bgmac_dma_cleanup(bgmac);
 | |
| +	return err;
 | |
|  }
 | |
|  
 | |
|  /**************************************************
 | |
| @@ -1183,11 +1191,8 @@ static void bgmac_enable(struct bgmac *b
 | |
|  }
 | |
|  
 | |
|  /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
 | |
| -static void bgmac_chip_init(struct bgmac *bgmac, bool full_init)
 | |
| +static void bgmac_chip_init(struct bgmac *bgmac)
 | |
|  {
 | |
| -	struct bgmac_dma_ring *ring;
 | |
| -	int i;
 | |
| -
 | |
|  	/* 1 interrupt per received frame */
 | |
|  	bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
 | |
|  
 | |
| @@ -1205,16 +1210,7 @@ static void bgmac_chip_init(struct bgmac
 | |
|  
 | |
|  	bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
 | |
|  
 | |
| -	if (full_init) {
 | |
| -		bgmac_dma_init(bgmac);
 | |
| -		if (1) /* FIXME: is there any case we don't want IRQs? */
 | |
| -			bgmac_chip_intrs_on(bgmac);
 | |
| -	} else {
 | |
| -		for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
 | |
| -			ring = &bgmac->rx_ring[i];
 | |
| -			bgmac_dma_rx_enable(bgmac, ring);
 | |
| -		}
 | |
| -	}
 | |
| +	bgmac_chip_intrs_on(bgmac);
 | |
|  
 | |
|  	bgmac_enable(bgmac);
 | |
|  }
 | |
| @@ -1274,23 +1270,27 @@ static int bgmac_open(struct net_device
 | |
|  	int err = 0;
 | |
|  
 | |
|  	bgmac_chip_reset(bgmac);
 | |
| +
 | |
| +	err = bgmac_dma_init(bgmac);
 | |
| +	if (err)
 | |
| +		return err;
 | |
| +
 | |
|  	/* Specs say about reclaiming rings here, but we do that in DMA init */
 | |
| -	bgmac_chip_init(bgmac, true);
 | |
| +	bgmac_chip_init(bgmac);
 | |
|  
 | |
|  	err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED,
 | |
|  			  KBUILD_MODNAME, net_dev);
 | |
|  	if (err < 0) {
 | |
|  		bgmac_err(bgmac, "IRQ request error: %d!\n", err);
 | |
| -		goto err_out;
 | |
| +		bgmac_dma_cleanup(bgmac);
 | |
| +		return err;
 | |
|  	}
 | |
|  	napi_enable(&bgmac->napi);
 | |
|  
 | |
|  	phy_start(bgmac->phy_dev);
 | |
|  
 | |
|  	netif_carrier_on(net_dev);
 | |
| -
 | |
| -err_out:
 | |
| -	return err;
 | |
| +	return 0;
 | |
|  }
 | |
|  
 | |
|  static int bgmac_stop(struct net_device *net_dev)
 | |
| @@ -1306,6 +1306,7 @@ static int bgmac_stop(struct net_device
 | |
|  	free_irq(bgmac->core->irq, net_dev);
 | |
|  
 | |
|  	bgmac_chip_reset(bgmac);
 | |
| +	bgmac_dma_cleanup(bgmac);
 | |
|  
 | |
|  	return 0;
 | |
|  }
 |