Exemplo n.º 1
0
/**
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
 * @adapter: board private structure
 *
 * Configure the Rx unit of the MAC after a reset.
 **/
static void e1000e_configure_rx ( struct e1000_adapter *adapter )
{
	struct e1000_hw *hw = &adapter->hw;
	uint32_t rctl;

	DBGP ( "e1000_configure_rx\n" );

	/* disable receives while setting up the descriptors */
	rctl = E1000_READ_REG ( hw, E1000_RCTL );
	E1000_WRITE_REG ( hw, E1000_RCTL, rctl & ~E1000_RCTL_EN );
	e1e_flush();
	mdelay(10);

	adapter->rx_curr = 0;

	/* Setup the HW Rx Head and Tail Descriptor Pointers and
	 * the Base and Length of the Rx Descriptor Ring */

	E1000_WRITE_REG ( hw, E1000_RDBAL(0), virt_to_bus ( adapter->rx_base ) );
	E1000_WRITE_REG ( hw, E1000_RDBAH(0), 0 );
	E1000_WRITE_REG ( hw, E1000_RDLEN(0), adapter->rx_ring_size );

	E1000_WRITE_REG ( hw, E1000_RDH(0), 0 );
	E1000_WRITE_REG ( hw, E1000_RDT(0), NUM_RX_DESC - 1 );

	/* Enable Receives */
	rctl |=	 E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
		 E1000_RCTL_MPE;
	E1000_WRITE_REG ( hw, E1000_RCTL, rctl );
	e1e_flush();

	DBG ( "E1000_RDBAL(0): %#08x\n",  E1000_READ_REG ( hw, E1000_RDBAL(0) ) );
	DBG ( "E1000_RDLEN(0): %d\n",	  E1000_READ_REG ( hw, E1000_RDLEN(0) ) );
	DBG ( "E1000_RCTL:  %#08x\n",  E1000_READ_REG ( hw, E1000_RCTL ) );
}
Exemplo n.º 2
0
/**
 * e1000e_irq_enable - Enable default interrupt generation settings
 **/
static void e1000e_irq_enable(struct e1000_adapter *adapter)
{
	struct e1000_hw *hw = &adapter->hw;

	ew32(IMS, IMS_ENABLE_MASK);
	e1e_flush();
}
Exemplo n.º 3
0
/**
 * e1000e_irq_disable - Mask off interrupt generation on the NIC
 **/
static void e1000e_irq_disable(struct e1000_adapter *adapter)
{
	struct e1000_hw *hw = &adapter->hw;

	ew32(IMC, ~0);
	e1e_flush();
}
/**
 * intelConfigureRx - Configure Receive Unit after Reset
 * @adapter: board private structure
 *
 * Configure the Rx unit of the MAC after a reset.
 **/
void IntelMausi::intelConfigureRx(struct e1000_adapter *adapter)
{
	struct e1000_hw *hw = &adapter->hw;
	u32 rctl, rxcsum, ctrl_ext;
    
	/* disable receives while setting up the descriptors */
	rctl = intelReadMem32(E1000_RCTL);
    
	intelFlush();
	usleep_range(10000, 20000);
    
	/* set the Receive Delay Timer Register */
	intelWriteMem32(E1000_RDTR, adapter->rx_int_delay);
    
	/* irq moderation */
	intelWriteMem32(E1000_RADV, adapter->rx_abs_int_delay);
    
    /* Set interrupt throttle value. */
    intelWriteMem32(E1000_ITR, intrThrValue);
    
    /* Auto-Mask interrupts upon ICR access. */
	ctrl_ext = intelReadMem32(E1000_CTRL_EXT);
	ctrl_ext |= E1000_CTRL_EXT_IAME;
	intelWriteMem32(E1000_IAM, 0xffffffff);
	intelWriteMem32(E1000_CTRL_EXT, ctrl_ext);
	e1e_flush();
    
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
	 * the Base and Length of the Rx Descriptor Ring
	 */
    intelInitRxRing();
    
	/* Enable Receive Checksum Offload for TCP and UDP */
	rxcsum = intelReadMem32(E1000_RXCSUM);
    rxcsum |= E1000_RXCSUM_TUOFL;
	intelWriteMem32(E1000_RXCSUM, rxcsum);
    
	/* With jumbo frames, excessive C-state transition latencies result
	 * in dropped transactions.
	 */
	if (mtu > ETH_DATA_LEN) {
		//u32 lat = ((intelReadMem32(E1000_PBA) & E1000_PBA_RXA_MASK) * 1024 - adapter->max_frame_size) * 8 / 1000;
        
		if (adapter->flags & FLAG_IS_ICH) {
			u32 rxdctl = intelReadMem32(E1000_RXDCTL(0));
            
			intelWriteMem32(E1000_RXDCTL(0), rxdctl | 0x3);
		}
        
		//pm_qos_update_request(&adapter->netdev->pm_qos_req, lat);
	} else {
		//pm_qos_update_request(&adapter->netdev->pm_qos_req, PM_QOS_DEFAULT_VALUE);
	}
	intelWriteMem32(E1000_RCTL, rctl);
}
Exemplo n.º 5
0
/**
 * e1000_transmit - Transmit a packet
 *
 * @v netdev	Network device
 * @v iobuf	I/O buffer
 *
 * @ret rc	 Returns 0 on success, negative on failure
 */
static int e1000e_transmit ( struct net_device *netdev, struct io_buffer *iobuf )
{
	struct e1000_adapter *adapter = netdev_priv( netdev );
	struct e1000_hw *hw = &adapter->hw;
	uint32_t tx_curr = adapter->tx_tail;
	struct e1000_tx_desc *tx_curr_desc;

	DBGP ("e1000_transmit\n");

	if ( adapter->tx_fill_ctr == NUM_TX_DESC ) {
		DBG ("TX overflow\n");
		return -ENOBUFS;
	}

	/* Save pointer to iobuf we have been given to transmit,
	   netdev_tx_complete() will need it later
	 */
	adapter->tx_iobuf[tx_curr] = iobuf;

	tx_curr_desc = ( void * ) ( adapter->tx_base ) +
		       ( tx_curr * sizeof ( *adapter->tx_base ) );

	DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) );
	DBG ( "tx_curr_desc + 16 = %#08lx\n", virt_to_bus ( tx_curr_desc ) + 16 );
	DBG ( "iobuf->data = %#08lx\n", virt_to_bus ( iobuf->data ) );

	/* Add the packet to TX ring
	 */
	tx_curr_desc->buffer_addr = virt_to_bus ( iobuf->data );
	tx_curr_desc->upper.data = 0;
	tx_curr_desc->lower.data = adapter->txd_cmd | iob_len ( iobuf );

	DBG ( "TX fill: %d tx_curr: %d addr: %#08lx len: %zd\n", adapter->tx_fill_ctr,
	      tx_curr, virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );

	/* Point to next free descriptor */
	adapter->tx_tail = ( adapter->tx_tail + 1 ) % NUM_TX_DESC;
	adapter->tx_fill_ctr++;

	/* Write new tail to NIC, making packet available for transmit
	 */
	E1000_WRITE_REG ( hw, E1000_TDT(0), adapter->tx_tail );
	e1e_flush();

	return 0;
}
Exemplo n.º 6
0
/**
 *  e1000_mng_write_cmd_header - Writes manageability command header
 *  @hw: pointer to the HW structure
 *  @hdr: pointer to the host interface command header
 *
 *  Writes the command header after does the checksum calculation.
 **/
s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
			       struct e1000_host_mng_command_header *hdr)
{
	u16 i, length = sizeof(struct e1000_host_mng_command_header);

	/* Write the whole command header structure with new checksum. */

	hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);

	length >>= 2;
	/* Write the relevant command block into the ram area. */
	for (i = 0; i < length; i++) {
		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i));
		e1e_flush();
	}

	return 0;
}
Exemplo n.º 7
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 );
}
Exemplo n.º 8
0
Arquivo: ethtool.c Projeto: A-K/linux
static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
{
	struct net_device *netdev = adapter->netdev;
	struct e1000_hw *hw = &adapter->hw;
	u32 mask;
	u32 shared_int = 1;
	u32 irq = adapter->pdev->irq;
	int i;
	int ret_val = 0;
	int int_mode = E1000E_INT_MODE_LEGACY;

	*data = 0;

	/* NOTE: we don't test MSI/MSI-X interrupts here, yet */
	if (adapter->int_mode == E1000E_INT_MODE_MSIX) {
		int_mode = adapter->int_mode;
		e1000e_reset_interrupt_capability(adapter);
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
		e1000e_set_interrupt_capability(adapter);
	}
	/* Hook up test interrupt handler just for this test */
	if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
			 netdev)) {
		shared_int = 0;
	} else if (request_irq(irq, e1000_test_intr, IRQF_SHARED,
		 netdev->name, netdev)) {
		*data = 1;
		ret_val = -1;
		goto out;
	}
	e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared"));

	/* Disable all the interrupts */
	ew32(IMC, 0xFFFFFFFF);
	e1e_flush();
	usleep_range(10000, 20000);

	/* Test each interrupt */
	for (i = 0; i < 10; i++) {
		/* Interrupt to test */
		mask = 1 << i;

		if (adapter->flags & FLAG_IS_ICH) {
			switch (mask) {
			case E1000_ICR_RXSEQ:
				continue;
			case 0x00000100:
				if (adapter->hw.mac.type == e1000_ich8lan ||
				    adapter->hw.mac.type == e1000_ich9lan)
					continue;
				break;
			default:
				break;
			}
		}

		if (!shared_int) {
			/*
			 * Disable the interrupt to be reported in
			 * the cause register and then force the same
			 * interrupt and see if one gets posted.  If
			 * an interrupt was posted to the bus, the
			 * test failed.
			 */
			adapter->test_icr = 0;
			ew32(IMC, mask);
			ew32(ICS, mask);
			e1e_flush();
			usleep_range(10000, 20000);

			if (adapter->test_icr & mask) {
				*data = 3;
				break;
			}
		}

		/*
		 * Enable the interrupt to be reported in
		 * the cause register and then force the same
		 * interrupt and see if one gets posted.  If
		 * an interrupt was not posted to the bus, the
		 * test failed.
		 */
		adapter->test_icr = 0;
		ew32(IMS, mask);
		ew32(ICS, mask);
		e1e_flush();
		usleep_range(10000, 20000);

		if (!(adapter->test_icr & mask)) {
			*data = 4;
			break;
		}

		if (!shared_int) {
			/*
			 * Disable the other interrupts to be reported in
			 * the cause register and then force the other
			 * interrupts and see if any get posted.  If
			 * an interrupt was posted to the bus, the
			 * test failed.
			 */
			adapter->test_icr = 0;
			ew32(IMC, ~mask & 0x00007FFF);
			ew32(ICS, ~mask & 0x00007FFF);
			e1e_flush();
			usleep_range(10000, 20000);

			if (adapter->test_icr) {
				*data = 5;
				break;
			}
		}
	}

	/* Disable all the interrupts */
	ew32(IMC, 0xFFFFFFFF);
	e1e_flush();
	usleep_range(10000, 20000);

	/* Unhook test interrupt handler */
	free_irq(irq, netdev);

out:
	if (int_mode == E1000E_INT_MODE_MSIX) {
		e1000e_reset_interrupt_capability(adapter);
		adapter->int_mode = int_mode;
		e1000e_set_interrupt_capability(adapter);
	}

	return ret_val;
}
Exemplo n.º 9
0
/**
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
 * @adapter: board private structure
 *
 * Configure the Tx unit of the MAC after a reset.
 **/
static void e1000e_configure_tx ( struct e1000_adapter *adapter )
{
	struct e1000_hw *hw = &adapter->hw;
	u32 tctl, tipg, tarc;
	u32 ipgr1, ipgr2;

	DBGP ( "e1000_configure_tx\n" );

	/* disable transmits while setting up the descriptors */
	tctl = E1000_READ_REG ( hw, E1000_TCTL );
	E1000_WRITE_REG ( hw, E1000_TCTL, tctl & ~E1000_TCTL_EN );
	e1e_flush();
	mdelay(10);

	E1000_WRITE_REG ( hw, E1000_TDBAH(0), 0 );
	E1000_WRITE_REG ( hw, E1000_TDBAL(0), virt_to_bus ( adapter->tx_base ) );
	E1000_WRITE_REG ( hw, E1000_TDLEN(0), adapter->tx_ring_size );

	DBG ( "E1000_TDBAL(0): %#08x\n",  E1000_READ_REG ( hw, E1000_TDBAL(0) ) );
	DBG ( "E1000_TDLEN(0): %d\n",	  E1000_READ_REG ( hw, E1000_TDLEN(0) ) );

	/* Setup the HW Tx Head and Tail descriptor pointers */
	E1000_WRITE_REG ( hw, E1000_TDH(0), 0 );
	E1000_WRITE_REG ( hw, E1000_TDT(0), 0 );

	adapter->tx_head = 0;
	adapter->tx_tail = 0;
	adapter->tx_fill_ctr = 0;

	/* Set the default values for the Tx Inter Packet Gap timer */
	tipg = DEFAULT_82543_TIPG_IPGT_COPPER;		/*  8  */
	ipgr1 = DEFAULT_82543_TIPG_IPGR1;		/*  8  */
	ipgr2 = DEFAULT_82543_TIPG_IPGR2;		/*  6  */

	if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN)
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /*  7  */

	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
	ew32(TIPG, tipg);

	/* Program the Transmit Control Register */
	tctl = er32(TCTL);
	tctl &= ~E1000_TCTL_CT;
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);

	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
		tarc = er32(TARC(0));
		/*
		 * set the speed mode bit, we'll clear it if we're not at
		 * gigabit link later
		 */
#define SPEED_MODE_BIT (1 << 21)
		tarc |= SPEED_MODE_BIT;
		ew32(TARC(0), tarc);
	}

	/* errata: program both queues to unweighted RR */
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
		tarc = er32(TARC(0));
		tarc |= 1;
		ew32(TARC(0), tarc);
		tarc = er32(TARC(1));
		tarc |= 1;
		ew32(TARC(1), tarc);
	}

	/* Setup Transmit Descriptor Settings for eop descriptor */
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;

	/* enable Report Status bit */
	adapter->txd_cmd |= E1000_TXD_CMD_RS;

	/*
	 * enable transmits in the hardware, need to do this
	 * after setting TARC(0)
	 */
	tctl |= E1000_TCTL_EN;
	ew32(TCTL, tctl);
	e1e_flush();

	e1000e_config_collision_dist(hw);
}