/** * e1000_setup_rx_resources - allocate Rx resources (Descriptors) * * @v adapter e1000 private structure * * @ret rc Returns 0 on success, negative on failure **/ static int e1000_setup_rx_resources ( struct e1000_adapter *adapter ) { int i, rc = 0; DBG ( "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 = e1000_refill_rx_ring ( adapter ); if ( rc < 0 ) e1000_free_rx_resources ( adapter ); return rc; }
/** * e1000_close - Disables a network interface * * @v netdev network interface device structure * **/ static void e1000_close ( struct net_device *netdev ) { struct e1000_adapter *adapter = netdev_priv ( netdev ); struct e1000_hw *hw = &adapter->hw; uint32_t rctl; uint32_t icr; DBG ( "e1000_close\n" ); /* Acknowledge interrupts */ icr = E1000_READ_REG ( hw, ICR ); e1000_irq_disable ( adapter ); /* disable receives */ rctl = E1000_READ_REG ( hw, RCTL ); E1000_WRITE_REG ( hw, RCTL, rctl & ~E1000_RCTL_EN ); E1000_WRITE_FLUSH ( hw ); e1000_reset_hw ( hw ); e1000_free_tx_resources ( adapter ); e1000_free_rx_resources ( adapter ); }
static int e1000_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct e1000_adapter *adapter = netdev->priv; e1000_mac_type mac_type = adapter->hw.mac_type; struct e1000_desc_ring *txdr = &adapter->tx_ring; struct e1000_desc_ring *rxdr = &adapter->rx_ring; struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new; int err; tx_old = adapter->tx_ring; rx_old = adapter->rx_ring; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; if(netif_running(adapter->netdev)) e1000_down(adapter); rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD); rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ? E1000_MAX_RXD : E1000_MAX_82544_RXD)); E1000_ROUNDUP(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE); txdr->count = max(ring->tx_pending,(uint32_t)E1000_MIN_TXD); txdr->count = min(txdr->count,(uint32_t)(mac_type < e1000_82544 ? E1000_MAX_TXD : E1000_MAX_82544_TXD)); E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); if(netif_running(adapter->netdev)) { /* Try to get new resources before deleting old */ if((err = e1000_setup_rx_resources(adapter))) goto err_setup_rx; if((err = e1000_setup_tx_resources(adapter))) goto err_setup_tx; /* save the new, restore the old in order to free it, * then restore the new back again */ rx_new = adapter->rx_ring; tx_new = adapter->tx_ring; adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; e1000_free_rx_resources(adapter); e1000_free_tx_resources(adapter); adapter->rx_ring = rx_new; adapter->tx_ring = tx_new; if((err = e1000_up(adapter))) return err; } return 0; err_setup_tx: e1000_free_rx_resources(adapter); err_setup_rx: adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; e1000_up(adapter); return err; }