mirror of https://github.com/ipxe/ipxe.git
Merge bf871cbdf1
into 7e64e9b670
commit
188a27897a
|
@ -257,6 +257,26 @@ static int intel_fetch_mac ( struct intel_nic *intel, uint8_t *hw_addr ) {
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
static int intel_reset_done ( struct intel_nic *intel )
|
||||
{
|
||||
uint32_t eec, status;
|
||||
uint32_t i = 0;
|
||||
|
||||
while (i < INTEL_RESET_DELAY_MS * 10) {
|
||||
status = readl ( intel->regs + INTEL_STATUS );
|
||||
eec = readl ( intel->regs + INTEL_EEC );
|
||||
if ((eec & INTEL_EEC_AUTO_RD) && (status & INTEL_STATUS_PF_RST_DONE))
|
||||
break;
|
||||
mdelay ( 10 );
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i >= INTEL_RESET_DELAY_MS*10)
|
||||
return -ETIME;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset hardware
|
||||
*
|
||||
|
@ -270,6 +290,7 @@ static int intel_reset ( struct intel_nic *intel ) {
|
|||
uint32_t status;
|
||||
uint32_t orig_ctrl;
|
||||
uint32_t orig_status;
|
||||
uint8_t reset_done;
|
||||
|
||||
/* Record initial control and status register values */
|
||||
orig_ctrl = ctrl = readl ( intel->regs + INTEL_CTRL );
|
||||
|
@ -306,44 +327,14 @@ static int intel_reset ( struct intel_nic *intel ) {
|
|||
writel ( ( ctrl | INTEL_CTRL_RST ), intel->regs + INTEL_CTRL );
|
||||
mdelay ( INTEL_RESET_DELAY_MS );
|
||||
|
||||
/* Set a sensible default configuration */
|
||||
if ( ! ( intel->flags & INTEL_NO_ASDE ) )
|
||||
ctrl |= INTEL_CTRL_ASDE;
|
||||
ctrl |= INTEL_CTRL_SLU;
|
||||
ctrl &= ~( INTEL_CTRL_LRST | INTEL_CTRL_FRCSPD | INTEL_CTRL_FRCDPLX );
|
||||
writel ( ctrl, intel->regs + INTEL_CTRL );
|
||||
mdelay ( INTEL_RESET_DELAY_MS );
|
||||
|
||||
/* On some models (notably ICH), the PHY reset mechanism
|
||||
* appears to be broken. In particular, the PHY_CTRL register
|
||||
* will be correctly loaded from NVM but the values will not
|
||||
* be propagated to the "OEM bits" PHY register. This
|
||||
* typically has the effect of dropping the link speed to
|
||||
* 10Mbps.
|
||||
*
|
||||
* Work around this problem by skipping the PHY reset if
|
||||
* either (a) the link is already up, or (b) this particular
|
||||
* NIC is known to be broken.
|
||||
*/
|
||||
status = readl ( intel->regs + INTEL_STATUS );
|
||||
if ( ( intel->flags & INTEL_NO_PHY_RST ) ||
|
||||
( status & INTEL_STATUS_LU ) ) {
|
||||
DBGC ( intel, "INTEL %p %sMAC reset (%08x/%08x was "
|
||||
"%08x/%08x)\n", intel,
|
||||
( ( intel->flags & INTEL_NO_PHY_RST ) ? "forced " : "" ),
|
||||
ctrl, status, orig_ctrl, orig_status );
|
||||
return 0;
|
||||
reset_done = intel_reset_done(intel);
|
||||
if (reset_done) {
|
||||
DBGC ( intel, "Reset timeout\n");
|
||||
return reset_done;
|
||||
}
|
||||
|
||||
/* Reset PHY and MAC simultaneously */
|
||||
writel ( ( ctrl | INTEL_CTRL_RST | INTEL_CTRL_PHY_RST ),
|
||||
intel->regs + INTEL_CTRL );
|
||||
mdelay ( INTEL_RESET_DELAY_MS );
|
||||
|
||||
/* PHY reset is not self-clearing on all models */
|
||||
writel ( ctrl, intel->regs + INTEL_CTRL );
|
||||
mdelay ( INTEL_RESET_DELAY_MS );
|
||||
status = readl ( intel->regs + INTEL_STATUS );
|
||||
ctrl = readl ( intel->regs + INTEL_CTRL );
|
||||
|
||||
DBGC ( intel, "INTEL %p MAC+PHY reset (%08x/%08x was %08x/%08x)\n",
|
||||
intel, ctrl, status, orig_ctrl, orig_status );
|
||||
|
|
|
@ -70,8 +70,9 @@ struct intel_descriptor {
|
|||
#define INTEL_RESET_DELAY_MS 20
|
||||
|
||||
/** Device Status Register */
|
||||
#define INTEL_STATUS 0x00008UL
|
||||
#define INTEL_STATUS_LU 0x00000002UL /**< Link up */
|
||||
#define INTEL_STATUS 0x00008UL
|
||||
#define INTEL_STATUS_LU 0x00000002UL /**< Link up */
|
||||
#define INTEL_STATUS_PF_RST_DONE 0x00200000UL /**< Software/Device reset completed */
|
||||
|
||||
/** EEPROM Read Register */
|
||||
#define INTEL_EERD 0x00014UL
|
||||
|
@ -82,6 +83,10 @@ struct intel_descriptor {
|
|||
#define INTEL_EERD_ADDR_SHIFT_LARGE 2 /**< Address shift (large) */
|
||||
#define INTEL_EERD_DATA(value) ( (value) >> 16 ) /**< Read data */
|
||||
|
||||
/** EEPROM-Mode Control Register **/
|
||||
#define INTEL_EEC 0x12010UL
|
||||
#define INTEL_EEC_AUTO_RD 0x00000200UL /**< Flash Auto-Read Done */
|
||||
|
||||
/** Maximum time to wait for EEPROM read, in milliseconds */
|
||||
#define INTEL_EEPROM_MAX_WAIT_MS 100
|
||||
|
||||
|
|
Loading…
Reference in New Issue