Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC - [intel] Wait until reset is completed #504

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 26 additions & 35 deletions src/drivers/net/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand All @@ -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 );
Expand All @@ -294,44 +315,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 );
Expand Down
9 changes: 7 additions & 2 deletions src/drivers/net/intel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these not lining up intentional?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'll update the patch. I wanted to lining them up and then I did the opposite.

#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
Expand All @@ -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

Expand Down