Beispiel #1
0
/**
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
 *
 * @v adapter	e1000 private structure
 *
 * @ret rc	 Returns 0 on success, negative on failure
 **/
static int e1000e_setup_rx_resources ( struct e1000_adapter *adapter )
{
	int i, rc = 0;

	DBGP ( "e1000_setup_rx_resources\n" );

	/* Allocate receive descriptor ring memory.
	   It must not cross a 64K boundary because of hardware errata
	 */

	adapter->rx_base =
		malloc_dma ( adapter->rx_ring_size, adapter->rx_ring_size );

	if ( ! adapter->rx_base ) {
		return -ENOMEM;
	}
	memset ( adapter->rx_base, 0, adapter->rx_ring_size );

	for ( i = 0; i < NUM_RX_DESC; i++ ) {
		/* let e1000_refill_rx_ring() io_buffer allocations */
		adapter->rx_iobuf[i] = NULL;
	}

	/* allocate io_buffers */
	rc = e1000e_refill_rx_ring ( adapter );
	if ( rc < 0 )
		e1000e_free_rx_resources ( adapter );

	return rc;
}
Beispiel #2
0
/**
 * e1000_close - Disables a network interface
 *
 * @v netdev	network interface device structure
 *
 **/
static void e1000e_close ( struct net_device *netdev )
{
	struct e1000_adapter *adapter = netdev_priv ( netdev );
	struct e1000_hw *hw = &adapter->hw;
	uint32_t rctl;
	uint32_t icr;

	DBGP ( "e1000_close\n" );

	/* Acknowledge interrupts */
	icr = E1000_READ_REG ( hw, E1000_ICR );

	e1000e_irq_disable ( adapter );

	/* disable receives */
	rctl = E1000_READ_REG ( hw, E1000_RCTL );
	E1000_WRITE_REG ( hw, E1000_RCTL, rctl & ~E1000_RCTL_EN );
	e1e_flush();

	e1000e_reset ( adapter );

	e1000e_free_tx_resources ( adapter );
	e1000e_free_rx_resources ( adapter );
}
Beispiel #3
0
static int e1000_set_ringparam(struct net_device *netdev,
			       struct ethtool_ringparam *ring)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_ring *temp_tx = NULL, *temp_rx = NULL;
	int err = 0, size = sizeof(struct e1000_ring);
	bool set_tx = false, set_rx = false;
	u16 new_rx_count, new_tx_count;

	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
		return -EINVAL;

	new_rx_count = clamp_t(u32, ring->rx_pending, E1000_MIN_RXD,
			       E1000_MAX_RXD);
	new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);

	new_tx_count = clamp_t(u32, ring->tx_pending, E1000_MIN_TXD,
			       E1000_MAX_TXD);
	new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);

	if ((new_tx_count == adapter->tx_ring_count) &&
	    (new_rx_count == adapter->rx_ring_count))
		/* nothing to do */
		return 0;

	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
		usleep_range(1000, 2000);

	if (!netif_running(adapter->netdev)) {
		/* Set counts now and allocate resources during open() */
		adapter->tx_ring->count = new_tx_count;
		adapter->rx_ring->count = new_rx_count;
		adapter->tx_ring_count = new_tx_count;
		adapter->rx_ring_count = new_rx_count;
		goto clear_reset;
	}

	set_tx = (new_tx_count != adapter->tx_ring_count);
	set_rx = (new_rx_count != adapter->rx_ring_count);

	/* Allocate temporary storage for ring updates */
	if (set_tx) {
		temp_tx = vmalloc(size);
		if (!temp_tx) {
			err = -ENOMEM;
			goto free_temp;
		}
	}
	if (set_rx) {
		temp_rx = vmalloc(size);
		if (!temp_rx) {
			err = -ENOMEM;
			goto free_temp;
		}
	}

	e1000e_down(adapter);

	/*
	 * We can't just free everything and then setup again, because the
	 * ISRs in MSI-X mode get passed pointers to the Tx and Rx ring
	 * structs.  First, attempt to allocate new resources...
	 */
	if (set_tx) {
		memcpy(temp_tx, adapter->tx_ring, size);
		temp_tx->count = new_tx_count;
		err = e1000e_setup_tx_resources(temp_tx);
		if (err)
			goto err_setup;
	}
	if (set_rx) {
		memcpy(temp_rx, adapter->rx_ring, size);
		temp_rx->count = new_rx_count;
		err = e1000e_setup_rx_resources(temp_rx);
		if (err)
			goto err_setup_rx;
	}

	/* ...then free the old resources and copy back any new ring data */
	if (set_tx) {
		e1000e_free_tx_resources(adapter->tx_ring);
		memcpy(adapter->tx_ring, temp_tx, size);
		adapter->tx_ring_count = new_tx_count;
	}
	if (set_rx) {
		e1000e_free_rx_resources(adapter->rx_ring);
		memcpy(adapter->rx_ring, temp_rx, size);
		adapter->rx_ring_count = new_rx_count;
	}

err_setup_rx:
	if (err && set_tx)
		e1000e_free_tx_resources(temp_tx);
err_setup:
	e1000e_up(adapter);
free_temp:
	vfree(temp_tx);
	vfree(temp_rx);
clear_reset:
	clear_bit(__E1000_RESETTING, &adapter->state);
	return err;
}
Beispiel #4
0
static int e1000_set_ringparam(struct net_device *netdev,
			       struct ethtool_ringparam *ring)
{
	struct e1000_adapter *adapter = netdev_priv(netdev);
	struct e1000_ring *tx_ring, *tx_old;
	struct e1000_ring *rx_ring, *rx_old;
	int err;

	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
		return -EINVAL;

	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
		msleep(1);

	if (netif_running(adapter->netdev))
		e1000e_down(adapter);

	tx_old = adapter->tx_ring;
	rx_old = adapter->rx_ring;

	err = -ENOMEM;
	tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
	if (!tx_ring)
		goto err_alloc_tx;
	/*
	 * use a memcpy to save any previously configured
	 * items like napi structs from having to be
	 * reinitialized
	 */
	memcpy(tx_ring, tx_old, sizeof(struct e1000_ring));

	rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
	if (!rx_ring)
		goto err_alloc_rx;
	memcpy(rx_ring, rx_old, sizeof(struct e1000_ring));

	adapter->tx_ring = tx_ring;
	adapter->rx_ring = rx_ring;

	rx_ring->count = max(ring->rx_pending, (u32)E1000_MIN_RXD);
	rx_ring->count = min(rx_ring->count, (u32)(E1000_MAX_RXD));
	rx_ring->count = ALIGN(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE);

	tx_ring->count = max(ring->tx_pending, (u32)E1000_MIN_TXD);
	tx_ring->count = min(tx_ring->count, (u32)(E1000_MAX_TXD));
	tx_ring->count = ALIGN(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE);

	if (netif_running(adapter->netdev)) {
		/* Try to get new resources before deleting old */
		err = e1000e_setup_rx_resources(adapter);
		if (err)
			goto err_setup_rx;
		err = e1000e_setup_tx_resources(adapter);
		if (err)
			goto err_setup_tx;

		/*
		 * restore the old in order to free it,
		 * then add in the new
		 */
		adapter->rx_ring = rx_old;
		adapter->tx_ring = tx_old;
		e1000e_free_rx_resources(adapter);
		e1000e_free_tx_resources(adapter);
		kfree(tx_old);
		kfree(rx_old);
		adapter->rx_ring = rx_ring;
		adapter->tx_ring = tx_ring;
		err = e1000e_up(adapter);
		if (err)
			goto err_setup;
	}

	clear_bit(__E1000_RESETTING, &adapter->state);
	return 0;
err_setup_tx:
	e1000e_free_rx_resources(adapter);
err_setup_rx:
	adapter->rx_ring = rx_old;
	adapter->tx_ring = tx_old;
	kfree(rx_ring);
err_alloc_rx:
	kfree(tx_ring);
err_alloc_tx:
	e1000e_up(adapter);
err_setup:
	clear_bit(__E1000_RESETTING, &adapter->state);
	return err;
}