/************************************************************************************************** * @fn macRxOff * * @brief Turn off the receiver if it's not already off. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxOff(void) { halIntState_t s; DBG_PRINT1(DBGSYS, "macRxOff(): macRxOnFlag = 0x%X", macRxOnFlag); HAL_ENTER_CRITICAL_SECTION(s); if (macRxOnFlag) { macRxOnFlag = 0; DBG_PRINT0(DBGSYS, "MAC_RADIO_RXTX_OFF()"); MAC_RADIO_RXTX_OFF(); /* Wait till RX is completely off before issuing another RX related * command which may fail if issued beforehand. */ macCheckCommnadDone(&macRxEdScan.rxCmd.rfOpCmd); /* Wait till all FG commands are done */ macCheckCommnadDone(&macCsmaCaCmd.rfOpCmd); macCheckCommnadDone(&macTxCmd.rfOpCmd); macCheckCommnadDone(&macRxAckCmd.rfOpCmd); MAC_DEBUG_TURN_OFF_RX_LED(); /* just in case a receive was about to start, flush the receive FIFO */ MAC_RADIO_FLUSH_RX_FIFO(); /* clear any receive interrupt that happened to squeak through */ MAC_RADIO_CLEAR_RX_THRESHOLD_INTERRUPT_FLAG(); } HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxOnRequest * * @brief Turn on the receiver if any rx enable flag is set. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxOnRequest(void) { halIntState_t s; DBG_PRINT0(DBGSYS, "macRxOnRequest()"); HAL_ENTER_CRITICAL_SECTION(s); if (macRxEnableFlags) { macRxOn(); } HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxOn * * @brief Turn on the receiver if it's not already on. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxOn(void) { halIntState_t s; DBG_PRINT0(DBGSYS, "macRxOn()"); HAL_ENTER_CRITICAL_SECTION(s); if (!macRxOnFlag) { macRxOnFlag = 1; MAC_RADIO_RX_ON(); MAC_DEBUG_TURN_ON_RX_LED(); } HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxOffRequest * * @brief Turn off receiver if permitted. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxOffRequest(void) { halIntState_t s; DBG_PRINT0(DBGSYS, "macRxOffRequest()"); HAL_ENTER_CRITICAL_SECTION(s); if (!macRxEnableFlags) { if (!MAC_RX_IS_PHYSICALLY_ACTIVE() && !MAC_TX_IS_PHYSICALLY_ACTIVE()) { macRxOff(); } } HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxHardDisable * * @brief Clear all enable flags and turn off receiver. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxHardDisable(void) { halIntState_t s; DBG_PRINT0(DBGSYS, "macRxHardDisable()"); HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags = 0; MAC_DEBUG_TURN_OFF_RX_LED(); HAL_EXIT_CRITICAL_SECTION(s); /* force off and clean up */ macRxHaltCleanup(); /* Power management state may change. Hence, vote. */ macPwrVote(); }
static #endif /* USE_ICALL */ void macBackoffTimerEventHandler(void) { halIntState_t is; uint8 events; HAL_ENTER_CRITICAL_SECTION(is); events = macBackoffTimerEvents; macBackoffTimerEvents = 0; HAL_EXIT_CRITICAL_SECTION(is); if (events & MAC_BACKOFF_TIMER_EVENT_POWER_WAKEUP) { // Wakeup radio // Turning on radio domain before clock set up seems to cause // unexpected interrupt. // Hence interrupt shall be disabled here. MB_DisableInts(); // Enable clocks for all radio internal modules. // Use Non-Buff access for safety and check for sanity HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = 0x7FF; /* Setup mailbox */ macSetupMailbox(); #ifdef DEBUG_SW_TRACE /* re-enable RF trace output for FPGA */ MB_SendCommand( BUILD_DIRECT_PARAM_EXT_CMD( CMD_ENABLE_DEBUG, 0x1D40 ) ); /* or 0x1940 for less trace */ DBG_PRINT0(DBGSYS, "RF Trace Resumes..."); #endif /* DEBUG_SW_TRACE */ /* Start off CM0. Patch it. */ macSetupRfHal(); /* Restore states */ MAC_RADIO_SET_CHANNEL(macPhyChannel); MAC_RADIO_SET_PAN_COORDINATOR(macPanCoordinator); MAC_RADIO_SET_PAN_ID(pMacPib->panId); MAC_RADIO_SET_SHORT_ADDR(pMacPib->shortAddress); MAC_RADIO_SET_IEEE_ADDR(pMacPib->extendedAddress.addr.extAddr); #if !defined( USE_FPGA ) #ifdef USE_ICALL // Switch back to HFOSC. while (!ICall_pwrIsStableXOSCHF()); ICall_pwrSwitchXOSCHF(); #endif /* USE_ICALL */ #ifdef OSAL_PORT2TIRTOS // Switches back to HFOSC. while (!Power_isStableXOSC_HF()); Power_switchXOSC_HF(); #endif /* OSAL_PORT2TIRTOS */ #endif /* !defined( USE_FPGA ) */ /* Synchronize RAT timer */ macSyncStartRAT(macRATValue); /* Turn on autoack */ MAC_RADIO_TURN_ON_AUTO_ACK(); /* Initialize SRCEXTPENDEN and SRCSHORTPENDEN to zeros */ MAC_RADIO_SRC_MATCH_INIT_EXTPENDEN(); MAC_RADIO_SRC_MATCH_INIT_SHORTPENDEN(); /* Start 15.4 Radio */ macSetupRadio(); /* Restore timer comparators */ MAC_RADIO_BACKOFF_SET_PERIOD(macBackoffTimerRollover); MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerTrigger); #if 0 /* Following code should be disabled normally */ /* Code for wakeup lead time calibration */ { static uint32 macBackoffTimerMinMargin = 0xffffffffu; uint32 delta = macPrevPeriodRatCount + backoffTimerTrigger * MAC_BACKOFF_TO_RAT_RATIO - MAC_RAT_COUNT; if (delta < macBackoffTimerMinMargin) { macBackoffTimerMinMargin = delta; } } #endif } /* Note that MAC_BACKOFF_TIMER_EVENT_POWER_TIMER_EXP handling must always * occur after handling of MAC_BACKOFF_TIMER_EVENT_POWER_WAKEUP event * because the device might be waking up upon the timer event itself * in which case, radio has to be turned on before updating the RAT timer. */ if (events & MAC_BACKOFF_TIMER_EVENT_POWER_TIMER_EXP) { /* Update wakeup schedule, which most likely would vote not to enter * sleep state. */ HAL_ENTER_CRITICAL_SECTION(is); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(is); } }
/* * Here we actually start growing the file system. We basically read the * cylinder summary from the first cylinder group as we want to update * this on the fly during our various operations. First we handle the * changes in the former last cylinder group. Afterwards we create all new * cylinder groups. Now we handle the cylinder group containing the * cylinder summary which might result in a relocation of the whole * structure. In the end we write back the updated cylinder summary, the * new superblock, and slightly patched versions of the super block * copies. */ static void growfs(int fsi, int fso, unsigned int Nflag) { DBG_FUNC("growfs") time_t modtime; uint cylno; int i, j, width; char tmpbuf[100]; DBG_ENTER; time(&modtime); /* * Get the cylinder summary into the memory. */ fscs = (struct csum *)calloc((size_t)1, (size_t)sblock.fs_cssize); if (fscs == NULL) errx(1, "calloc failed"); for (i = 0; i < osblock.fs_cssize; i += osblock.fs_bsize) { rdfs(fsbtodb(&osblock, osblock.fs_csaddr + numfrags(&osblock, i)), (size_t)MIN(osblock.fs_cssize - i, osblock.fs_bsize), (void *)(((char *)fscs) + i), fsi); } #ifdef FS_DEBUG { struct csum *dbg_csp; u_int32_t dbg_csc; char dbg_line[80]; dbg_csp = fscs; for (dbg_csc = 0; dbg_csc < osblock.fs_ncg; dbg_csc++) { snprintf(dbg_line, sizeof(dbg_line), "%d. old csum in old location", dbg_csc); DBG_DUMP_CSUM(&osblock, dbg_line, dbg_csp++); } } #endif /* FS_DEBUG */ DBG_PRINT0("fscs read\n"); /* * Do all needed changes in the former last cylinder group. */ updjcg(osblock.fs_ncg - 1, modtime, fsi, fso, Nflag); /* * Dump out summary information about file system. */ #ifdef FS_DEBUG #define B2MBFACTOR (1 / (1024.0 * 1024.0)) printf("growfs: %.1fMB (%jd sectors) block size %d, fragment size %d\n", (float)sblock.fs_size * sblock.fs_fsize * B2MBFACTOR, (intmax_t)fsbtodb(&sblock, sblock.fs_size), sblock.fs_bsize, sblock.fs_fsize); printf("\tusing %d cylinder groups of %.2fMB, %d blks, %d inodes.\n", sblock.fs_ncg, (float)sblock.fs_fpg * sblock.fs_fsize * B2MBFACTOR, sblock.fs_fpg / sblock.fs_frag, sblock.fs_ipg); if (sblock.fs_flags & FS_DOSOFTDEP) printf("\twith soft updates\n"); #undef B2MBFACTOR #endif /* FS_DEBUG */ /* * Now build the cylinders group blocks and * then print out indices of cylinder groups. */ printf("super-block backups (for fsck_ffs -b #) at:\n"); i = 0; width = charsperline(); /* * Iterate for only the new cylinder groups. */ for (cylno = osblock.fs_ncg; cylno < sblock.fs_ncg; cylno++) { initcg(cylno, modtime, fso, Nflag); j = sprintf(tmpbuf, " %jd%s", (intmax_t)fsbtodb(&sblock, cgsblock(&sblock, cylno)), cylno < (sblock.fs_ncg - 1) ? "," : "" ); if (i + j >= width) { printf("\n"); i = 0; } i += j; printf("%s", tmpbuf); fflush(stdout); } printf("\n"); /* * Do all needed changes in the first cylinder group. * allocate blocks in new location */ updcsloc(modtime, fsi, fso, Nflag); /* * Now write the cylinder summary back to disk. */ for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize) { wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)), (size_t)MIN(sblock.fs_cssize - i, sblock.fs_bsize), (void *)(((char *)fscs) + i), fso, Nflag); } DBG_PRINT0("fscs written\n"); #ifdef FS_DEBUG { struct csum *dbg_csp; u_int32_t dbg_csc; char dbg_line[80]; dbg_csp = fscs; for (dbg_csc = 0; dbg_csc < sblock.fs_ncg; dbg_csc++) { snprintf(dbg_line, sizeof(dbg_line), "%d. new csum in new location", dbg_csc); DBG_DUMP_CSUM(&sblock, dbg_line, dbg_csp++); } } #endif /* FS_DEBUG */ /* * Now write the new superblock back to disk. */ sblock.fs_time = modtime; wtfs(sblockloc, (size_t)SBLOCKSIZE, (void *)&sblock, fso, Nflag); DBG_PRINT0("sblock written\n"); DBG_DUMP_FS(&sblock, "new initial sblock"); /* * Clean up the dynamic fields in our superblock copies. */ sblock.fs_fmod = 0; sblock.fs_clean = 1; sblock.fs_ronly = 0; sblock.fs_cgrotor = 0; sblock.fs_state = 0; memset((void *)&sblock.fs_fsmnt, 0, sizeof(sblock.fs_fsmnt)); sblock.fs_flags &= FS_DOSOFTDEP; /* * XXX * The following fields are currently distributed from the superblock * to the copies: * fs_minfree * fs_rotdelay * fs_maxcontig * fs_maxbpg * fs_minfree, * fs_optim * fs_flags regarding SOFTPDATES * * We probably should rather change the summary for the cylinder group * statistics here to the value of what would be in there, if the file * system were created initially with the new size. Therefor we still * need to find an easy way of calculating that. * Possibly we can try to read the first superblock copy and apply the * "diffed" stats between the old and new superblock by still copying * certain parameters onto that. */ /* * Write out the duplicate super blocks. */ for (cylno = 0; cylno < sblock.fs_ncg; cylno++) { wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), (size_t)SBLOCKSIZE, (void *)&sblock, fso, Nflag); } DBG_PRINT0("sblock copies written\n"); DBG_DUMP_FS(&sblock, "new other sblocks"); DBG_LEAVE; return; }