/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file mac/pbproc/src/fsm_rx_beacon.c * \brief FSM RX beacon part. * \ingroup mac_pbproc */ #include "common/std.h" #include "pbproc.h" #include "inc/context.h" #include "inc/fsm_handle_fc.h" #include "inc/fsm_rx_beacon.h" void pbproc_frbe_init (pbproc_t *ctx) { dbg_assert (ctx); ctx->fsm.states[PBPROC_FSM_STATE_RX_BEACON].pbdma_cb = CALLBACK (pbproc_frbe__rx_beacon__pbdma); } void ARCH_ILRAM pbproc_frbe__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_beacon_t *beacon) { dbg_claim (ctx); dbg_claim (beacon); /* Update stats. */ ctx->stats.rx_beacon++; /* Compute number of symbol. */ tonemap_t *tm = &ctx->config->tonemask_info.tonemap_robo[PHY_MOD_MINI_ROBO]; uint bits_per_pb = tm->bits_per_pb[PHY_PB_SIZE_136]; uint symb_nb = (1 * bits_per_pb + tm->bits_per_symbol - 1) / tm->bits_per_symbol; /* Compute beacon end of frame. */ u32 flp_tck = ctx->times.pre_fcs_tck + MAC_PAYLOAD_TCK (symb_nb, MAC_DX567_TCK) + MAC_B2BIFS_TCK; ctx->recv_mpdu.ack_date = rx_date + flp_tck; /* Ignore frames ending after the allocation, handle pool exhaustion. */ if ((!ctx->alloc.merge && less_mod2p32 (ctx->alloc.end_date, ctx->recv_mpdu.ack_date - MAC_B2BIFS_TCK)) || ctx->rx_pool_size < 1) { /* Ignore. */ if (ctx->rx_pool_size < 1) ctx->stats.rx_pool_shortage++; else ctx->stats.rx_out_of_alloc++; phy_rx_prepare_short (ctx->phy); ca_access_vcs_restart (ctx->ca, ctx->recv_mpdu.ack_date); pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE); return; } /* Unlock the hardware. */ phy_rx_prepare (ctx->phy, 1, PHY_COMBO_PARAMS ( PHY_MOD_MINI_ROBO, PHY_FEC_RATE_1_2, PHY_PB_SIZE_136), PHY_GIL_567, symb_nb, tm->tcc_halfit); /* Program PB DMA. */ phy_pbdma_start (ctx->phy, true, NULL, 1, 1, &ctx->rx_pool_head->phy_pb, NULL, true); /* Save received beacon parameters. */ pbproc_rx_beacon_params_t *params = (void *) (ctx->rx_pool_head->data + MAC_PB136_BYTES); params->preamble_sysdate = phy_rx_sysdate (ctx->phy); params->preamble_date = rx_date; params->bts = beacon->bts_msb8 << 24 | beacon->bts_lsb24; params->bto[0] = beacon->bto0; params->bto[1] = beacon->bto1_msb8 << 8 | beacon->bto1_lsb8; params->bto[2] = beacon->bto2; params->bto[3] = beacon->bto3_msb8 << 8 | beacon->bto3_lsb8; params->snid = beacon->snid; params->access = beacon->access; /* Wait PB reception. */ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_RX_BEACON); } void ARCH_ILRAM pbproc_frbe__rx_beacon__pbdma (pbproc_t *ctx) { dbg_claim (ctx); /* Unchain used PB. */ pb_t *pb_beacon = slist_pop_front (ctx->rx_pool_, paste_size); /* Received frame is given to upper layer in DSR. */ slist_push_back (ctx->commit.rx_beacon_, (pb_beacon_t *) pb_beacon); pbproc_fsm_schedule_deferred (ctx); /* Restart VCS */ ca_access_vcs_restart (ctx->ca, ctx->recv_mpdu.ack_date); /* Done. */ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE); }