/* * hfa384x_docmd_wait * * Waits for availability of the Command register, then * issues the given command. Then polls the Evstat register * waiting for command completion. * Arguments: * hw device structure * cmd Command in host order * parm0 Parameter0 in host order * parm1 Parameter1 in host order * parm2 Parameter2 in host order * Returns: * 0 success * >0 command indicated error, Status and Resp0-2 are * in hw structure. */ static int hfa384x_docmd_wait( hfa384x_t *hw, uint16_t cmd, uint16_t parm0, uint16_t parm1, uint16_t parm2) { uint16_t reg = 0; uint16_t counter = 0; /* wait for the busy bit to clear */ counter = 0; reg = hfa384x_getreg(hw, HFA384x_CMD); while ( HFA384x_CMD_ISBUSY(reg) && (counter < 10) ) { reg = hfa384x_getreg(hw, HFA384x_CMD); counter++; udelay(10); } if (HFA384x_CMD_ISBUSY(reg)) { printf("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg); return -ETIMEDOUT; } /* busy bit clear, write command */ hfa384x_setreg(hw, parm0, HFA384x_PARAM0); hfa384x_setreg(hw, parm1, HFA384x_PARAM1); hfa384x_setreg(hw, parm2, HFA384x_PARAM2); hw->lastcmd = cmd; hfa384x_setreg(hw, cmd, HFA384x_CMD); /* Now wait for completion */ counter = 0; reg = hfa384x_getreg(hw, HFA384x_EVSTAT); /* Initialization is the problem. It takes about 100ms. "normal" commands are typically is about 200-400 us (I've never seen less than 200). Longer is better so that we're not hammering the bus. */ while ( !HFA384x_EVSTAT_ISCMD(reg) && (counter < 5000)) { reg = hfa384x_getreg(hw, HFA384x_EVSTAT); counter++; udelay(200); } if ( ! HFA384x_EVSTAT_ISCMD(reg) ) { printf("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg); return -ETIMEDOUT; } /* Read status and response */ hw->status = hfa384x_getreg(hw, HFA384x_STATUS); hw->resp0 = hfa384x_getreg(hw, HFA384x_RESP0); hw->resp1 = hfa384x_getreg(hw, HFA384x_RESP1); hw->resp2 = hfa384x_getreg(hw, HFA384x_RESP2); hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK); return HFA384x_STATUS_RESULT_GET(hw->status); }
int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis) { int result = 0; unsigned long timeout; UINT16 reg; DBFENTER; /* Assert reset and wait awhile * (note: these delays are _really_ long, but they appear to be * necessary.) */ hfa384x_setreg(hw, 0xc5, HFA384x_PCICOR); timeout = jiffies + HZ/4; while(time_before(jiffies, timeout)) udelay(5); if (genesis) { hfa384x_setreg(hw, genesis, HFA384x_PCIHCR); timeout = jiffies + HZ/4; while(time_before(jiffies, timeout)) udelay(5); } /* Clear the reset and wait some more */ hfa384x_setreg(hw, 0x45, HFA384x_PCICOR); timeout = jiffies + HZ/2; while(time_before(jiffies, timeout)) udelay(5); /* Wait for f/w to complete initialization (CMD:BUSY == 0) */ timeout = jiffies + 2*HZ; reg = hfa384x_getreg(hw, HFA384x_CMD); while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) { reg = hfa384x_getreg(hw, HFA384x_CMD); udelay(10); } if (HFA384x_CMD_ISBUSY(reg)) { WLAN_LOG_WARNING("corereset: Timed out waiting for cmd register.\n"); result=1; } DBFEXIT; return result; }