示例#1
0
/*********************************************************************
 *
 *  Enable transmit unit.
 *
 **********************************************************************/
static void
igb_initialize_transmit_units(struct adapter *adapter)
{
	struct tx_ring	*txr = adapter->tx_rings;
	struct e1000_hw *hw = &adapter->hw;
	u32		tctl, txdctl;
	int	i;
	tctl = txdctl = 0;

	/* Setup the Tx Descriptor Rings */
	for (i = 0; i < adapter->num_queues; i++, txr++) {
		txdctl = 0;
		E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl);

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

		txr->queue_status = IGB_QUEUE_IDLE;

		txdctl |= IGB_TX_PTHRESH;
		txdctl |= IGB_TX_HTHRESH << 8;
		txdctl |= IGB_TX_WTHRESH << 16;
		txdctl |= E1000_TXDCTL_PRIORITY;
		txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
		E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl);
	}

}
示例#2
0
/*------------------------------------------------------------------------
 * _82545EM_configure_tx - Configure Transmit Unit after Reset
 *------------------------------------------------------------------------
 */
local void _82545EM_configure_tx(
	struct 	ether *ethptr
	)
{
	uint32 	tctl, tipg, txdctl;
	uint32 	ipgr1, ipgr2;

	/* Set the transmit descriptor write-back policy for both queues */

	txdctl = e1000_io_readl(ethptr->iobase, E1000_TXDCTL(0));
	txdctl &= ~E1000_TXDCTL_WTHRESH;
	txdctl |= E1000_TXDCTL_GRAN;
	e1000_io_writel(ethptr->iobase, E1000_TXDCTL(0), txdctl);

	/* Program the Transmit Control Register */
	
	tctl = e1000_io_readl(ethptr->iobase, E1000_TCTL);
	tctl &= ~E1000_TCTL_CT;
	tctl |= E1000_TCTL_RTLC |
		E1000_TCTL_EN 	|
		E1000_TCTL_PSP 	|
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
	tctl &= ~E1000_TCTL_COLD;
	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;

	/* Set the default values for the Tx Inter Packet Gap timer */
	
	tipg = E1000_TIPG_IPGT_COPPER_DEFAULT;
	ipgr1 = E1000_TIPG_IPGR1_DEFAULT;
	ipgr2 = E1000_TIPG_IPGR2_DEFAULT;
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
	e1000_io_writel(ethptr->iobase, E1000_TIPG, tipg);

	/* Set the Tx Interrupt Delay register */
	
	e1000_io_writel(ethptr->iobase, E1000_TIDV, E1000_TIDV_DEFAULT);
	e1000_io_writel(ethptr->iobase, E1000_TADV, E1000_TADV_DEFAULT);

	/* Setup the HW Tx Head and Tail descriptor pointers */
	
	e1000_io_writel(ethptr->iobase, E1000_TDBAL(0), 
			(uint32)ethptr->txRing);
	e1000_io_writel(ethptr->iobase, E1000_TDBAH(0), 0);
	e1000_io_writel(ethptr->iobase, E1000_TDLEN(0), 
			E1000_TDSIZE * ethptr->txRingSize);
	e1000_io_writel(ethptr->iobase, E1000_TDH(0), 0);
	e1000_io_writel(ethptr->iobase, E1000_TDT(0), 0);

	e1000_io_writel(ethptr->iobase, E1000_TCTL, tctl);
}
/**
 * intelConfigureTx - Configure Transmit Unit after Reset
 * @adapter: board private structure
 *
 * Configure the Tx unit of the MAC after a reset.
 **/
void IntelMausi::intelConfigureTx(struct e1000_adapter *adapter)
{
	struct e1000_hw *hw = &adapter->hw;
	UInt32 tctl, tarc;
    UInt32 txdctl;
    
    /* Setup the HW Tx Head and Tail descriptor pointers */
    intelInitTxRing();
    
	/* Set the Tx Interrupt Delay register */
	intelWriteMem32(E1000_TIDV, adapter->tx_int_delay);
	/* Tx irq moderation */
	intelWriteMem32(E1000_TADV, adapter->tx_abs_int_delay);
    
    txdctl = intelReadMem32(E1000_TXDCTL(0));

    /* Fix TXDCTL for 82579, I217 and I218. */
    if ((chipType == board_pch_lpt) || (chipType == board_pch2lan)) {
        txdctl = 0x01410101;
        intelWriteMem32(E1000_TXDCTL(0), txdctl);
    }
    /* erratum work around: set txdctl the same for both queues */
    intelWriteMem32(E1000_TXDCTL(1), txdctl);

	/* Program the Transmit Control Register */
	tctl = intelReadMem32(E1000_TCTL);
	tctl &= ~E1000_TCTL_CT;
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
    
	/* errata: program both queues to unweighted RR */
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
		tarc = intelReadMem32(E1000_TARC(0));
		tarc |= 1;
		intelWriteMem32(E1000_TARC(0), tarc);
		tarc = intelReadMem32(E1000_TARC(1));
		tarc |= 1;
		intelWriteMem32(E1000_TARC(1), tarc);
	}
	intelWriteMem32(E1000_TCTL, tctl);
    
	hw->mac.ops.config_collision_dist(hw);
}
示例#4
0
int
igb_resume(device_t *dev)
{
	struct adapter	*adapter;
	struct tx_ring	*txr;
	struct e1000_hw *hw;
	u32		txdctl;
	int	i;
	int error;

	if (NULL == dev) return EINVAL;
	adapter = (struct adapter *)dev->private_data;
	if (NULL == adapter) return ENXIO;

	txr = adapter->tx_rings;
	hw = &adapter->hw;

	txdctl = 0;

	if( sem_wait( adapter->memlock ) != 0 ) {
		return errno;
	}

	/* resume but don't reset the Tx Descriptor Rings */
	for (i = 0; i < adapter->num_queues; i++, txr++) {
		/* idle the queue */
		txdctl |= IGB_TX_PTHRESH;
		txdctl |= IGB_TX_HTHRESH << 8;
		txdctl |= IGB_TX_WTHRESH << 16;
		txdctl |= E1000_TXDCTL_PRIORITY;
		txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
		E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl);
		txr->queue_status = IGB_QUEUE_WORKING;
	}

	if( sem_post( adapter->memlock ) != 0 ) {
		return errno;
	}

	return (0);

 err_lockfail:
	return error;
}
示例#5
0
int
igb_suspend(device_t *dev)
{
	struct adapter	*adapter;
	struct tx_ring	*txr;
	struct e1000_hw *hw;
	u32		txdctl;
	int	i;

	if (NULL == dev) return EINVAL;
	adapter = (struct adapter *)dev->private_data;
	if (NULL == adapter) return ENXIO;

	txr = adapter->tx_rings;
	hw = &adapter->hw;

	txdctl = 0;

	if( sem_wait( adapter->memlock ) != 0 ) {
		return errno;
	}

	/* stop but don't reset the Tx Descriptor Rings */
	for (i = 0; i < adapter->num_queues; i++, txr++) {
		txdctl |= IGB_TX_PTHRESH;
		txdctl |= IGB_TX_HTHRESH << 8;
		txdctl |= IGB_TX_WTHRESH << 16;
		E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl);
		txr->queue_status = IGB_QUEUE_IDLE;
	}

	if( sem_post( adapter->memlock ) != 0 ) {
		return errno;
	}

	return (0);
}
示例#6
0
static void
igb_reset(struct adapter *adapter)
{
	struct tx_ring	*txr = adapter->tx_rings;
	struct e1000_hw *hw = &adapter->hw;
	u32		tctl, txdctl;
	int 	i;

	tctl = txdctl = 0;

	/* Setup the Tx Descriptor Rings, leave queues idle */
	for (i = 0; i < adapter->num_queues; i++, txr++) {
		u64 bus_addr = txr->txdma.paddr;

		/* idle the queue */
		txdctl |= IGB_TX_PTHRESH;
		txdctl |= IGB_TX_HTHRESH << 8;
		txdctl |= IGB_TX_WTHRESH << 16;
		E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl);

		/* reset the descriptor head/tail */
		E1000_WRITE_REG(hw, E1000_TDLEN(i),
		    adapter->num_tx_desc * sizeof(struct e1000_tx_desc));
		E1000_WRITE_REG(hw, E1000_TDBAH(i),
		    (u_int32_t)(bus_addr >> 32));
		E1000_WRITE_REG(hw, E1000_TDBAL(i),
		    (u_int32_t)bus_addr);

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

		txr->queue_status = IGB_QUEUE_IDLE;
	}

}
示例#7
0
/**
 *  e1000_init_hw_82540 - Initialize hardware
 *  @hw: pointer to the HW structure
 *
 *  This inits the hardware readying it for operation.
 **/
static s32 e1000_init_hw_82540(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	u32 txdctl, ctrl_ext;
	s32 ret_val;
	u16 i;

	DEBUGFUNC("e1000_init_hw_82540");

	/* Initialize identification LED */
	ret_val = mac->ops.id_led_init(hw);
	if (ret_val) {
		DEBUGOUT("Error initializing identification LED\n");
		/* This is not fatal and we should not stop init due to this */
	}

	/* Disabling VLAN filtering */
	DEBUGOUT("Initializing the IEEE VLAN\n");
	if (mac->type < e1000_82545_rev_3)
		E1000_WRITE_REG(hw, E1000_VET, 0);

	mac->ops.clear_vfta(hw);

	/* Setup the receive address. */
	e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);

	/* Zero out the Multicast HASH table */
	DEBUGOUT("Zeroing the MTA\n");
	for (i = 0; i < mac->mta_reg_count; i++) {
		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
		/*
		 * Avoid back to back register writes by adding the register
		 * read (flush).  This is to protect against some strange
		 * bridge configurations that may issue Memory Write Block
		 * (MWB) to our register space.  The *_rev_3 hardware at
		 * least doesn't respond correctly to every other dword in an
		 * MWB to our register space.
		 */
		E1000_WRITE_FLUSH(hw);
	}

	if (mac->type < e1000_82545_rev_3)
		e1000_pcix_mmrbc_workaround_generic(hw);

	/* Setup link and flow control */
	ret_val = mac->ops.setup_link(hw);

	txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0));
	txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
		  E1000_TXDCTL_FULL_TX_DESC_WB;
	E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl);

	/*
	 * Clear all of the statistics registers (clear on read).  It is
	 * important that we do this after we have tried to establish link
	 * because the symbol error count will increment wildly if there
	 * is no link.
	 */
	e1000_clear_hw_cntrs_82540(hw);

	if ((hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER) ||
	    (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3)) {
		ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
		/*
		 * Relaxed ordering must be disabled to avoid a parity
		 * error crash in a PCI slot.
		 */
		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
	}

	return ret_val;
}
示例#8
0
/*
 * mac_dump - dump important mac registers
 */
void
mac_dump(void *instance)
{
    struct e1000g *Adapter = (struct e1000g *)instance;
    struct e1000_hw *hw = &Adapter->shared;
    int i;

    /* {name, offset} for each mac register */
    Regi_t macreg[NUM_REGS] = {
        {"CTRL",	E1000_CTRL},	{"STATUS",	E1000_STATUS},
        {"EECD",	E1000_EECD},	{"EERD",	E1000_EERD},
        {"CTRL_EXT", E1000_CTRL_EXT}, {"FLA",	E1000_FLA},
        {"MDIC",	E1000_MDIC},	{"SCTL",	E1000_SCTL},
        {"FCAL",	E1000_FCAL},	{"FCAH",	E1000_FCAH},
        {"FCT",	E1000_FCT},	{"VET",		E1000_VET},
        {"ICR",	E1000_ICR},	{"ITR",		E1000_ITR},
        {"ICS",	E1000_ICS},	{"IMS",		E1000_IMS},
        {"IMC",	E1000_IMC},	{"IAM",		E1000_IAM},
        {"RCTL",	E1000_RCTL},	{"FCTTV",	E1000_FCTTV},
        {"TXCW",	E1000_TXCW},	{"RXCW",	E1000_RXCW},
        {"TCTL",	E1000_TCTL},	{"TIPG",	E1000_TIPG},
        {"AIT",	E1000_AIT},	{"LEDCTL",	E1000_LEDCTL},
        {"PBA",	E1000_PBA},	{"PBS",		E1000_PBS},
        {"EEMNGCTL", E1000_EEMNGCTL}, {"ERT",	E1000_ERT},
        {"FCRTL",	E1000_FCRTL},	{"FCRTH",	E1000_FCRTH},
        {"PSRCTL",	E1000_PSRCTL},	{"RDBAL(0)",	E1000_RDBAL(0)},
        {"RDBAH(0)", E1000_RDBAH(0)}, {"RDLEN(0)",	E1000_RDLEN(0)},
        {"RDH(0)",	E1000_RDH(0)},	{"RDT(0)",	E1000_RDT(0)},
        {"RDTR",	E1000_RDTR},	{"RXDCTL(0)",	E1000_RXDCTL(0)},
        {"RADV",	E1000_RADV},	{"RDBAL(1)",	E1000_RDBAL(1)},
        {"RDBAH(1)", E1000_RDBAH(1)}, {"RDLEN(1)",	E1000_RDLEN(1)},
        {"RDH(1)",	E1000_RDH(1)},	{"RDT(1)",	E1000_RDT(1)},
        {"RXDCTL(1)", E1000_RXDCTL(1)}, {"RSRPD",	E1000_RSRPD},
        {"RAID",	E1000_RAID},	{"CPUVEC",	E1000_CPUVEC},
        {"TDFH",	E1000_TDFH},	{"TDFT",	E1000_TDFT},
        {"TDFHS",	E1000_TDFHS},	{"TDFTS",	E1000_TDFTS},
        {"TDFPC",	E1000_TDFPC},	{"TDBAL(0)",	E1000_TDBAL(0)},
        {"TDBAH(0)", E1000_TDBAH(0)}, {"TDLEN(0)",	E1000_TDLEN(0)},
        {"TDH(0)",	E1000_TDH(0)},	{"TDT(0)",	E1000_TDT(0)},
        {"TIDV",	E1000_TIDV},	{"TXDCTL(0)",	E1000_TXDCTL(0)},
        {"TADV",	E1000_TADV},	{"TARC(0)",	E1000_TARC(0)},
        {"TDBAL(1)", E1000_TDBAL(1)}, {"TDBAH(1)",	E1000_TDBAH(1)},
        {"TDLEN(1)", E1000_TDLEN(1)}, {"TDH(1)",	E1000_TDH(1)},
        {"TDT(1)",	E1000_TDT(1)},	{"TXDCTL(1)",	E1000_TXDCTL(1)},
        {"TARC(1)",	E1000_TARC(1)},	{"ALGNERRC",	E1000_ALGNERRC},
        {"RXERRC",	E1000_RXERRC},	{"MPC",		E1000_MPC},
        {"SCC",	E1000_SCC},	{"ECOL",	E1000_ECOL},
        {"MCC",	E1000_MCC},	{"LATECOL",	E1000_LATECOL},
        {"COLC",	E1000_COLC},	{"DC",		E1000_DC},
        {"TNCRS",	E1000_TNCRS},	{"SEC",		E1000_SEC},
        {"CEXTERR",	E1000_CEXTERR},	{"RLEC",	E1000_RLEC},
        {"XONRXC",	E1000_XONRXC},	{"XONTXC",	E1000_XONTXC},
        {"XOFFRXC",	E1000_XOFFRXC},	{"XOFFTXC",	E1000_XOFFTXC},
        {"FCRUC",	E1000_FCRUC},	{"PRC64",	E1000_PRC64},
        {"PRC127",	E1000_PRC127},	{"PRC255",	E1000_PRC255},
        {"PRC511",	E1000_PRC511},	{"PRC1023",	E1000_PRC1023},
        {"PRC1522",	E1000_PRC1522},	{"GPRC",	E1000_GPRC},
        {"BPRC",	E1000_BPRC},	{"MPRC",	E1000_MPRC},
        {"GPTC",	E1000_GPTC},	{"GORCL",	E1000_GORCL},
        {"GORCH",	E1000_GORCH},	{"GOTCL",	E1000_GOTCL},
        {"GOTCH",	E1000_GOTCH},	{"RNBC",	E1000_RNBC},
        {"RUC",	E1000_RUC},	{"RFC",		E1000_RFC},
        {"ROC",	E1000_ROC},	{"RJC",		E1000_RJC},
        {"MGTPRC",	E1000_MGTPRC},	{"MGTPDC",	E1000_MGTPDC},
        {"MGTPTC",	E1000_MGTPTC},	{"TORL",	E1000_TORL},
        {"TORH",	E1000_TORH},	{"TOTL",	E1000_TOTL},
        {"TOTH",	E1000_TOTH},	{"TPR",		E1000_TPR},
        {"TPT",	E1000_TPT},	{"PTC64",	E1000_PTC64},
        {"PTC127",	E1000_PTC127},	{"PTC255",	E1000_PTC255},
        {"PTC511",	E1000_PTC511},	{"PTC1023",	E1000_PTC1023},
        {"PTC1522",	E1000_PTC1522},	{"MPTC",	E1000_MPTC},
        {"BPTC",	E1000_BPTC},	{"TSCTC",	E1000_TSCTC},
        {"TSCTFC",	E1000_TSCTFC},	{"IAC",		E1000_IAC},
        {"ICRXPTC",	E1000_ICRXPTC},	{"ICRXATC",	E1000_ICRXATC},
        {"ICTXPTC",	E1000_ICTXPTC},	{"ICTXATC",	E1000_ICTXATC},
        {"ICTXQEC",	E1000_ICTXQEC},	{"ICTXQMTC",	E1000_ICTXQMTC},
        {"ICRXDMTC", E1000_ICRXDMTC}, {"ICRXOC",	E1000_ICRXOC},
        {"RXCSUM",	E1000_RXCSUM},	{"RFCTL",	E1000_RFCTL},
        {"WUC",	E1000_WUC},	{"WUFC",	E1000_WUFC},
        {"WUS",	E1000_WUS},	{"MRQC",	E1000_MRQC},
        {"MANC",	E1000_MANC},	{"IPAV",	E1000_IPAV},
        {"MANC2H",	E1000_MANC2H},	{"RSSIM",	E1000_RSSIM},
        {"RSSIR",	E1000_RSSIR},	{"WUPL",	E1000_WUPL},
        {"GCR",	E1000_GCR},	{"GSCL_1",	E1000_GSCL_1},
        {"GSCL_2",	E1000_GSCL_2},	{"GSCL_3",	E1000_GSCL_3},
        {"GSCL_4",	E1000_GSCL_4},	{"FACTPS",	E1000_FACTPS},
        {"FWSM",	E1000_FWSM},
    };

    e1000g_log(Adapter, CE_CONT, "Begin MAC dump\n");

    for (i = 0; i < NUM_REGS; i++) {
        e1000g_log(Adapter, CE_CONT,
                   "macreg %10s offset: 0x%x   value: 0x%x\n",
                   macreg[i].name, macreg[i].offset,
                   e1000_read_reg(hw, macreg[i].offset));
    }
}