| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- #include "headers.h"
- /*
- Function: InterfaceIdleModeWakeup
- Description: This is the hardware specific Function for
- waking up HW device from Idle mode.
- A software abort pattern is written to the
- device to wake it and necessary power state
- transitions from host are performed here.
- Input parameters: IN struct bcm_mini_adapter *Adapter
- - Miniport Adapter Context
- Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface
- was successful.
- Other - If an error occurred.
- */
- /*
- Function: InterfaceIdleModeRespond
- Description: This is the hardware specific Function for
- responding to Idle mode request from target.
- Necessary power state transitions from host for
- idle mode or other device specific initializations
- are performed here.
- Input parameters: IN struct bcm_mini_adapter * Adapter
- - Miniport Adapter Context
- Return: BCM_STATUS_SUCCESS - If Idle mode response related
- HW configuration was successful.
- Other - If an error occurred.
- */
- /*
- "dmem bfc02f00 100" tells how many time device went in Idle mode.
- this value will be at address bfc02fa4.just before value d0ea1dle.
- Set time value by writing at bfc02f98 7d0
- checking the Ack timer expire on kannon by running command
- d qcslog .. if it shows e means host has not send response
- to f/w with in 200 ms. Response should be
- send to f/w with in 200 ms after the Idle/Shutdown req issued
- */
- int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter,
- unsigned int *puiBuffer)
- {
- int status = STATUS_SUCCESS;
- unsigned int uiRegRead = 0;
- int bytes;
- if (ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD) {
- if (ntohl(*(puiBuffer+1)) == 0) {
- status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC,
- &uiRegRead, sizeof(uiRegRead));
- if (status)
- return status;
- if (Adapter->ulPowerSaveMode ==
- DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) {
- uiRegRead = 0x00000000;
- status = wrmalt(Adapter,
- DEBUG_INTERRUPT_GENERATOR_REGISTOR,
- &uiRegRead, sizeof(uiRegRead));
- if (status)
- return status;
- }
- /* Below Register should not br read in case of
- * Manual and Protocol Idle mode */
- else if (Adapter->ulPowerSaveMode !=
- DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) {
- /* clear on read Register */
- bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0,
- &uiRegRead, sizeof(uiRegRead));
- if (bytes < 0) {
- status = bytes;
- return status;
- }
- /* clear on read Register */
- bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1,
- &uiRegRead, sizeof(uiRegRead));
- if (bytes < 0) {
- status = bytes;
- return status;
- }
- }
- /* Set Idle Mode Flag to False and
- * Clear IdleMode reg. */
- Adapter->IdleMode = false;
- Adapter->bTriedToWakeUpFromlowPowerMode = false;
- wake_up(&Adapter->lowpower_mode_wait_queue);
- } else {
- if (TRUE == Adapter->IdleMode)
- return status;
- uiRegRead = 0;
- if (Adapter->chip_id == BCS220_2 ||
- Adapter->chip_id == BCS220_2BC ||
- Adapter->chip_id == BCS250_BC ||
- Adapter->chip_id == BCS220_3) {
- bytes = rdmalt(Adapter, HPM_CONFIG_MSW,
- &uiRegRead, sizeof(uiRegRead));
- if (bytes < 0) {
- status = bytes;
- return status;
- }
- uiRegRead |= (1<<17);
- status = wrmalt(Adapter, HPM_CONFIG_MSW,
- &uiRegRead, sizeof(uiRegRead));
- if (status)
- return status;
- }
- SendIdleModeResponse(Adapter);
- }
- } else if (ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG) {
- OverrideServiceFlowParams(Adapter, puiBuffer);
- }
- return status;
- }
- static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter,
- unsigned int Pattern)
- {
- int status = STATUS_SUCCESS;
- unsigned int value;
- unsigned int chip_id;
- unsigned long timeout = 0, itr = 0;
- int lenwritten = 0;
- unsigned char aucAbortPattern[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF};
- struct bcm_interface_adapter *psInterfaceAdapter =
- Adapter->pvInterfaceAdapter;
- /* Abort Bus suspend if its already suspended */
- if ((TRUE == psInterfaceAdapter->bSuspended) &&
- (TRUE == Adapter->bDoSuspend))
- status = usb_autopm_get_interface(
- psInterfaceAdapter->interface);
- if ((Adapter->ulPowerSaveMode ==
- DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) ||
- (Adapter->ulPowerSaveMode ==
- DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) {
- /* write the SW abort pattern. */
- status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC,
- &Pattern, sizeof(Pattern));
- if (status)
- return status;
- }
- if (Adapter->ulPowerSaveMode ==
- DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) {
- value = 0x80000000;
- status = wrmalt(Adapter,
- DEBUG_INTERRUPT_GENERATOR_REGISTOR,
- &value, sizeof(value));
- if (status)
- return status;
- } else if (Adapter->ulPowerSaveMode !=
- DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) {
- /*
- * Get a Interrupt Out URB and send 8 Bytes Down
- * To be Done in Thread Context.
- * Not using Asynchronous Mechanism.
- */
- status = usb_interrupt_msg(psInterfaceAdapter->udev,
- usb_sndintpipe(psInterfaceAdapter->udev,
- psInterfaceAdapter->sIntrOut.int_out_endpointAddr),
- aucAbortPattern,
- 8,
- &lenwritten,
- 5000);
- if (status)
- return status;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
- IDLE_MODE, DBG_LVL_ALL,
- "NOB Sent down :%d", lenwritten);
- /* mdelay(25); */
- timeout = jiffies + msecs_to_jiffies(50);
- while (time_after(timeout, jiffies)) {
- itr++;
- rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT));
- if (0xbece3200 == (chip_id&~(0xF0)))
- chip_id = chip_id&~(0xF0);
- if (chip_id == Adapter->chip_id)
- break;
- }
- if (time_before(timeout, jiffies))
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
- IDLE_MODE, DBG_LVL_ALL,
- "Not able to read chip-id even after 25 msec");
- else
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
- IDLE_MODE, DBG_LVL_ALL,
- "Number of completed iteration to read chip-id :%lu", itr);
- status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC,
- &Pattern, sizeof(status));
- if (status)
- return status;
- }
- return status;
- }
- int InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter)
- {
- if (Adapter->bTriedToWakeUpFromlowPowerMode) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
- IDLE_MODE, DBG_LVL_ALL,
- "Wake up already attempted.. ignoring\n");
- } else {
- Adapter->bTriedToWakeUpFromlowPowerMode = TRUE;
- InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern);
- }
- return 0;
- }
- void InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter)
- {
- unsigned int uiRegVal = 0;
- INT Status = 0;
- int bytes;
- if (Adapter->ulPowerSaveMode ==
- DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) {
- /* clear idlemode interrupt. */
- uiRegVal = 0;
- Status = wrmalt(Adapter,
- DEBUG_INTERRUPT_GENERATOR_REGISTOR,
- &uiRegVal, sizeof(uiRegVal));
- if (Status)
- return;
- }
- else {
- /* clear Interrupt EP registers. */
- bytes = rdmalt(Adapter,
- DEVICE_INT_OUT_EP_REG0,
- &uiRegVal, sizeof(uiRegVal));
- if (bytes < 0) {
- Status = bytes;
- return;
- }
- bytes = rdmalt(Adapter,
- DEVICE_INT_OUT_EP_REG1,
- &uiRegVal, sizeof(uiRegVal));
- if (bytes < 0) {
- Status = bytes;
- return;
- }
- }
- }
|