/* @brief Stop command timeout detection timer. */ void WiFiEngine__CommandTimeoutStop(void) { DE_TRACE_STATIC(TR_NOISE, "stopping command timeout timer\n"); DriverEnvironment_CancelTimer(wifiEngineState.cmd_timer_id); WES_CLEAR_FLAG(WES_FLAG_CMD_TIMEOUT_RUNNING); }
/*! * @brief Requests to release the hic interface resource. * * @param id Identifies the user that requests the release. * * @return nothing. */ void wei_release_resource_hic(int id) { int users; int thisUser; DE_TRACE_STATIC(TR_PS, "===========> wei_release_resource_hic\n"); DE_TRACE_STRING(TR_PS_DEBUG,"State is: %s \n",state_name[state]); WIFI_RESOURCE_HIC_LOCK(); if((wifiEngineState.users & id) == 0) { /* nothing to release */ WIFI_RESOURCE_HIC_UNLOCK(); return; } thisUser = id; users = wifiEngineState.users; wifiEngineState.users &= ~id; /* trace this only while ps_enabled==TRUE */ DE_TRACE_INT3(TR_PS, "id: %d users: %d=>%d \n",id, users,wifiEngineState.users); if((id == RESOURCE_DISABLE_PS)&&(state == INTERFACE_PS_DISABLED)) { /* The resource to disable power save mechansim for hic interface is released */ state = INTERFACE_PS_OPEN; we_ind_send(WE_IND_HIC_PS_INTERFACE_ENABLED, NULL ); } if (wifiEngineState.users != 0) { /* There is someone that has requested to use the interface*/ WIFI_RESOURCE_HIC_UNLOCK(); return; } /* None is using the interface */ switch(state) { case INTERFACE_PS_DISABLED: {; /* Interface has been disabled now it is time to enable it again */ state = INTERFACE_PS_CLOSED_WAIT; /* Inform firmware that ps hic interface is not used anymore */ WiFiEngine_PsSendInterface_Down(); state = INTERFACE_PS_CLOSED; } break; case INTERFACE_PS_OPEN: { rPowerManagementProperties *powerManagementProperties = NULL; powerManagementProperties = (rPowerManagementProperties *)Registry_GetProperty(ID_powerManagement); /* Interface is temporary open - close it */ if(isLegacyPsNoPsPoll() && (thisUser == RESOURCE_USER_DATA_PATH) && (powerManagementProperties->psTxTrafficTimeout > 0)) { /* Start a tx traffic timeout that will hold firware awake if more data is about to be sent */ if(WES_TEST_FLAG(WES_FLAG_PS_TRAFFIC_TIMEOUT_RUNNING)) { /* Cancel the timer so we can restart it */ DriverEnvironment_CancelTimer(wifiEngineState.ps_traffic_timeout_timer_id); WES_CLEAR_FLAG(WES_FLAG_PS_TRAFFIC_TIMEOUT_RUNNING); } WIFI_RESOURCE_HIC_UNLOCK(); wei_request_resource_hic(RESOURCE_USER_TX_TRAFFIC_TMO); WIFI_RESOURCE_HIC_LOCK(); if (DriverEnvironment_RegisterTimerCallback(powerManagementProperties->psTxTrafficTimeout, wifiEngineState.ps_traffic_timeout_timer_id,ps_traffic_timeout_cb,0) != 1) { DE_TRACE_STATIC(TR_SEVERE,"Failed to register timer callback\n"); /* Skip timer and go to sleep */ wifiEngineState.users = 0; wifiEngineState.dataPathState = DATA_PATH_CLOSED; state = INTERFACE_PS_CLOSED_WAIT; /* Inform firmware that ps hic interface is not used anymore */ WiFiEngine_PsSendInterface_Down(); state = INTERFACE_PS_CLOSED; } else { WES_SET_FLAG(WES_FLAG_PS_TRAFFIC_TIMEOUT_RUNNING); } } else { wifiEngineState.dataPathState = DATA_PATH_CLOSED; state = INTERFACE_PS_CLOSED_WAIT; /* Inform firmware that ps hic interface is not used anymore */ WiFiEngine_PsSendInterface_Down(); state = INTERFACE_PS_CLOSED; } } break; case INTERFACE_PS_CLOSED: DE_TRACE_STATIC(TR_PS, "State is closed no action\n"); break; case INTERFACE_PS_OPEN_WAIT: DE_TRACE_STATIC(TR_PS, "Transit to OPEN state no action\n"); break; case INTERFACE_PS_CLOSED_WAIT: DE_TRACE_STATIC(TR_PS, "Transit to CLOSE state no action\n"); break; default: DE_TRACE_INT(TR_PS,"Unknown state is: %d \n",state); DE_ASSERT(FALSE); break; } WIFI_RESOURCE_HIC_UNLOCK(); DE_TRACE_STRING(TR_PS_DEBUG,"State is: %s \n",state_name[state]); DE_TRACE_STATIC(TR_PS, "<=========== wei_release_resource_hic\n"); }
/*! * @brief Handles packet received when core dump is enabled. * * @param pkt Received packet. * * @return * - Always returns WIFI_ENGINE_SUCCESS */ void WiFiEngine_HandleCoreDumpPkt(char* pkt) { size_t size; unsigned char *msg = NULL; if (!WES_TEST_FLAG(WES_FLAG_HW_PRESENT)) return; switch(core_dump_state) { case W4_SCB_ERROR_CFM: { unsigned char tx_desc[TX_DESC_SIZE]; hic_message_context_t msg_ref; uint8_t messageId; uint8_t messageType; Blob_t blob; Mlme_CreateMessageContext(msg_ref); INIT_BLOB(&blob, pkt, 1500); /* XXX */ /* Remove HIC header and add type/id info to msg_ref */ packer_HIC_Unpack(&msg_ref, &blob); messageId = msg_ref.msg_id; messageType = msg_ref.msg_type; msg_ref.packed = NULL; Mlme_ReleaseMessageContext(msg_ref); if((messageType == HIC_MESSAGE_TYPE_CTRL) && (messageId == HIC_CTRL_SCB_ERROR_CFM)) { /* Handle confirm message */ if(handleSCBErrorCfm(pkt) == 0) { /* SCB_ERROR_CFM has error code 0, this means that firmware. * is executing "normally" (no scb error has occured). * However a command timeout has occured so it would be nice * to force firmware in scb error and try to get a core dump. */ DE_TRACE_STATIC(TR_ALWAYS,"Cancel timer\n"); DriverEnvironment_CancelTimer(wifiEngineState.cmd_timer_id); DE_TRACE_STATIC(TR_ALWAYS,"Suicide requested\n"); sendCommitSuicideRequest(); wifiEngineState.core_dump_state = WEI_CORE_DUMP_DISABLED; return; } if(m_ext_ctx) { /* Coredump already started */ DriverEnvironment_Core_Dump_Abort( registry.network.basic.enableCoredump, registry.network.basic.restartTargetAfterCoredump, m_objId, m_errCode, &m_ext_ctx); } else { DriverEnvironment_indicate(WE_IND_CORE_DUMP_START, NULL, 0); } DriverEnvironment_Core_Dump_Started( registry.network.basic.enableCoredump, registry.network.basic.restartTargetAfterCoredump, m_objId, m_errCode, dump_total_size(dump_address_table), dump_total_size(dump_address_table), &m_ext_ctx); /* Turn off traces */ //trace_mask &= ~(TR_CMD | TR_NOISE | TR_PS | TR_HIGH_RES | TR_DATA ); trace_mask = 0; DriverEnvironment_Enable_Boot(); /* This is to prevent command timeout logic to re-start the timer */ WES_SET_FLAG(WES_FLAG_CMD_TIMEOUT_RUNNING); /* Initiate physical bm-descriptor to point to tx-descriptors */ createDataReq_u32(&msg, StartDescriptorAddress, StartTxBmDesc + OFFSET_TO_POINTER_BM_DESC, &size); /* Clear any pending flags and flush queue*/ wifiEngineState.cmdReplyPending = 0; wei_clear_cmd_queue(); wei_send_cmd_raw((char *)msg, size); /* Initiate targets tx-descriptor to be used */ createTxDescriptor(tx_desc); createDataReq(&msg, tx_desc, sizeof(tx_desc), StartDescriptorAddress, &size); /* Clear any pending flags and flush queue*/ wifiEngineState.cmdReplyPending = 0; wei_clear_cmd_queue(); wei_send_cmd_raw((char *)msg, size); core_dump_state = W4_MEMORY_DUMP; /* * if m_ext_ctx==NULL we are not interested in the coredump and can restart the target directly * Not sure of how to do this in a safe way so will go ahead with the coredump anyway for now and fix this later */ if(m_ext_ctx==NULL) { trace_mask = old_trace_mask; DriverEnvironment_Core_Dump_Complete( FALSE, registry.network.basic.restartTargetAfterCoredump, m_objId, m_errCode, &m_ext_ctx); DriverEnvironment_indicate(WE_IND_CORE_DUMP_COMPLETE, NULL, 0); DriverEnvironment_CancelTimer(wifiEngineState.cmd_timer_id); WES_CLEAR_FLAG(WES_FLAG_CMD_TIMEOUT_RUNNING); return; } currentRegion = dump_address_table; currentAddress = dump_region_start(currentRegion); getNextBlock(currentAddress); } else { DE_TRACE_INT2(TR_ALWAYS, "unexpected message %u.%u\n", messageType, messageId); } } break; case W4_MEMORY_DUMP: { uint32_t len; /* Store recevied packet in a file */ len = HIC_MESSAGE_LENGTH_GET(pkt); /* Move beyond size */ pkt += 2; len -= 2; /* Write dumpfile header (for nrx600 coredumps) */ if (dump_address_table == dump_address_table_nrx600 && m_ext_ctx && currentAddress == dump_region_start(currentRegion)) { DriverEnvironment_Core_Dump_Write(m_ext_ctx, (char *)currentRegion, sizeof(*currentRegion)); } len = DE_MIN(len, dump_region_end(currentRegion) - currentAddress); /* Copy to buffer */ if (m_ext_ctx) { DriverEnvironment_Core_Dump_Write(m_ext_ctx, pkt, len); } currentAddress += len; if(currentAddress >= dump_region_end(currentRegion)) { /* end of region, skip forward */ currentRegion++; currentAddress = dump_region_start(currentRegion); if(dump_region_size(currentRegion) == 0) { /* Complete - Start store data on a file and restart driver */ trace_mask = old_trace_mask; DE_TRACE_STATIC(TR_ALWAYS,"Coredump complete - cancel timer\n"); DriverEnvironment_CancelTimer(wifiEngineState.cmd_timer_id); WES_CLEAR_FLAG(WES_FLAG_CMD_TIMEOUT_RUNNING); DriverEnvironment_Core_Dump_Complete(registry.network.basic.enableCoredump && m_ext_ctx != NULL, /* see driverenv.h */ registry.network.basic.restartTargetAfterCoredump, m_objId, m_errCode, &m_ext_ctx); DriverEnvironment_indicate(WE_IND_CORE_DUMP_COMPLETE, NULL, 0); return; } } getNextBlock(currentAddress); } break; default: DE_BUG_ON(TRUE, "Invalid core dump state\n"); break; } }