#ifndef mac_common_mfs_h #define mac_common_mfs_h /* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file mac/common/mfs.h * \brief MAC frame stream. * \ingroup mac_common */ #include "mac/common/pb.h" #include "mac/ca/mfs.h" #include "lib/list.h" #include "mac/common/link_stats.h" /** Default encoded RX window size for data (corresponding to 16). */ #define MFS_RX_WINDOW_SIZE_DATA_DEFAULT_ENCODED 0x2 /** Delay during the one the MFS TX is still active. */ #define MFS_TX_ACTIVITY_DELAY_MS 1000 /** Delay during the one the MFS RX is still active. */ #define MFS_RX_ACTIVITY_DELAY_MS 1500 /** Release timeout. */ #define MFS_RELEASE_DELAY_MS 1000 /** Delay TX PBs have to pass through MAC layer. */ #define MFS_PB_TX_DELAY_MS 100 /** Delay RX PBs have to pass through MAC layer. */ #define MFS_PB_RX_DELAY_MS 100 /** MFS FSM commands. WARNING: should match AV spec. */ enum mfs_fsm_cmd_t { MFS_FSM_CMD_INIT, MFS_FSM_CMD_IN_SYNC, MFS_FSM_CMD_RE_SYNC, MFS_FSM_CMD_RELEASE, MFS_FSM_CMD_NOP, MFS_FSM_CMD_SPC_FAIL, }; typedef enum mfs_fsm_cmd_t mfs_fsm_cmd_t; /** MFS FSM response. WARNING: should match AV spec. */ enum mfs_fsm_rsp_t { MFS_FSM_RSP_ACK, MFS_FSM_RSP_NACK, MFS_FSM_RSP_FAIL, MFS_FSM_RSP_HOLD, MFS_FSM_RSP_NB }; typedef enum mfs_fsm_rsp_t mfs_fsm_rsp_t; /** Window size indexes. */ enum mfs_window_size_idx_t { MFS_WINDOW_SIZE_4, MFS_WINDOW_SIZE_8, MFS_WINDOW_SIZE_16, MFS_WINDOW_SIZE_24, MFS_WINDOW_SIZE_32, MFS_WINDOW_SIZE_48, MFS_WINDOW_SIZE_64, MFS_WINDOW_SIZE_80, MFS_WINDOW_SIZE_96, MFS_WINDOW_SIZE_112, MFS_WINDOW_SIZE_128, MFS_WINDOW_SIZE_144, MFS_WINDOW_SIZE_160, MFS_WINDOW_SIZE_192, MFS_WINDOW_SIZE_224, MFS_WINDOW_SIZE_256, MFS_WINDOW_SIZE_NB }; typedef enum mfs_window_size_idx_t mfs_window_size_idx_t; /** Common fields for TX and RX. */ struct mfs_common_t { /** True if this is a TX MFS. */ bool tx; /** Whether this is a multicast MFS. */ bool bcast; /** True if this is a MME MFS. */ bool mme; /** Include the ATS field in MAC frames. */ bool ats; /** Link identifier. */ u8 lid; /** Destination TEI for TX, source TEI for RX. */ u8 tei; /** Aliased link identifier or MAC_LID_NONE. When a global link is * created, it is first created as a local link, then promoted to a global * link. This field store the local link which still have to be valid * after the promotion. */ u8 lid_alias; /** Communication with an unassociated station. */ bool unassociated; /** Link between unassociated MFS. */ list_node_t store_unassociated_link; /** expiration date of the mfs */ u32 expiration_ntb; /** delay for the expiration */ u32 expiration_delay_tck; }; typedef struct mfs_common_t mfs_common_t; /** TX MFS. * * Here are the clarifications that may be needed about segments chaining: * * There is four distinct segments lists for any given MFS. The first one is * not contained in the MFS. It lists the segments which are currently being * sent by the PB Processing. The second one lists the segments reserved by * the PB Processing which are planned to be sent soon. The third one lists * the segments which are owned by the PB Processing but are not currently * being sent neither planned to be sent. Finally, the last list contains * segments belonging to the SAR layer. Theses segments are not currently * sent of course, and are not available to the PB Processing. They will be * available when the segmentation will be finished. * * The first list is contained in the PB Processing context. * * The segments from the second list are the first segments between * \c head and \c tail pointer counted by the PB Processing context. * * The segments from the third list are the next \c seg_nb segments between * \c head and \c tail pointer. The segments from the last list are the * \c pending_seg_nb next segments. * * If \c pending_seg_nb is greater than 0, this means that the segment pointed * to by \c tail belongs to the SAR layer and therefore this pointer can not * be changed by the PB Processing. The SAR can update this segment at will. * * The number of segments between \c head and \c tail minus those reserved by * the PB Processing is always \c seg_nb + \c pending_seg_nb. */ struct mfs_tx_t { /** Common fields for TX and RX. */ mfs_common_t common; /** Whether this MFS is using a contention free period. */ bool cfp; /** Burst count for global links. */ u8 burst_count; /** List link used by Channel Access for MFS to be held until next beacon * period or priority sorted MFS. */ list_node_t ca_link; /** Channel Access MFS state. */ ca_mfs_state_t ca_state; /** Number of available segments. */ int seg_nb; /** Number of pending segments, they will be available once the bridge DMA * job is finished. */ int pending_seg_nb; /** MFS FSM state. */ mfs_fsm_cmd_t fsm_state; /** Window size at the receiver. */ u16 window_size; /** Number of holes in the MFS, i.e. number of acknowledged or canceled * segment in the MFS. */ u16 holes_seg_nb; /** Difference between the Tx ssn_min and the Rx ssn_min. */ u16 delta_between_ssn_min; /** Channel Access Priority. */ uint cap; /** First segment not being transmitted. This pointer is used by the PB * Processing to find the first segment to transmit or the segment which * was queued to the last one being transmitted. It is also used by the * SAR to expire segments. */ pb_t *head; /** Last segment. */ pb_t *tail; /** Offset in the last segment. Used by the SAR to indicate where in the * last segment the segmentation should restart. Cleared by PB Processing * if the last segment can no longer be used for segmentation. This field * can only be modified by the owner of the last segment. */ uint last_seg_offset; /** SSN to use for the next created segments. */ u16 next_ssn; /** True if this is a beacon MFS. * A beacon MFS looks like a real MFS but there could be only one segment * at a time. * Beacon transmission offsets are placed right after the payload in the * beacon PB. */ bool beacon; /** link stats */ link_stats_tx_t stats; }; typedef struct mfs_tx_t mfs_tx_t; /** RX MFS. */ struct mfs_rx_t { /** Common fields for TX and RX. */ mfs_common_t common; pb_t * head; /** min ssn */ u16 ssn_min; /** ssn window size */ u16 window_size; /** Encoded window size. */ u8 window_size_encoded; /** release state. */ bool release; /** link stats */ link_stats_rx_t stats; }; typedef struct mfs_rx_t mfs_rx_t; /** Any MFS, RX or TX. */ union mfs_t { /** Common fields for TX and RX. */ mfs_common_t common; /** RX MFS. */ mfs_rx_t rx; /** TX MFS. */ mfs_tx_t tx; }; typedef union mfs_t mfs_t; BEGIN_DECLS /** Window size values table (values of the RxWSz field of the FCs in which * it is included). */ extern const u16 mfs_window_size[MFS_WINDOW_SIZE_NB]; /** Global TX MFS number of segment limit. */ extern int mfs_tx_max_seg_nb; /** * Initialise a RX MFS, called from MAC store. * \param mfs MFS to initialise * \param bcast broadcast flag * \param mme MME flag * \param lid link identifier * \param tei TEI * * All other parameters are default initialised. This function should only be * called from MAC store. */ void mfs_rx_init (mfs_rx_t *mfs, bool bcast, bool mme, uint lid, uint tei); /** * Initialise an Unassociated RX MFS, called from MAC store. * \param mfs MFS to initialise * \param bcast broadcast flag * \param mme MME flag * \param lid link identifier * \param tei TEI * * All other parameters are default initialised. This function should only be * called from MAC store. */ void mfs_rx_init_unassociated (mfs_rx_t *mfs, bool bcast, bool mme, uint lid, uint tei); /** * Initialise a TX MFS, called from MAC store. * \param mfs MFS to initialise * \param bcast broadcast flag * \param mme MME flag * \param lid link identifier * \param tei TEI * * All other parameters are default initialised. This function should only be * called from MAC store. */ void mfs_tx_init (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei); /** * Initialise a Unassociated TX MFS, called from MAC store. * \param mfs MFS to initialise * \param bcast broadcast flag * \param mme MME flag * \param lid link identifier * \param tei TEI * * All other parameters are default initialised. This function should only be * called from MAC store. */ void mfs_tx_init_unassociated (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei); /** * Update the MFS TX segment limit. * \param active_nb number of active MFS */ void mfs_tx_max_seg_nb_update (int active_nb); END_DECLS #endif /* mac_common_mfs_h */