/********************************************************************* * * 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); } }
/*------------------------------------------------------------------------ * _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); }
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; }
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); }
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; } }
/** * 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; }
/* * 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)); } }