# PS
[LMAC]

Power-Save mode implementation. More...

Collaboration diagram for PS:

## Data Structures
struct | ps_env_tag
| PS module environment. More...
## Defines
#define | PS_TX_ERROR_MAX (3)
| Maximum number of TX attempts for a NULL frame indicating PS mode change.
#define | PS_VIF_WAITING_BCN CO_BIT(0)
| Station is waiting for beacon reception.
#define | PS_VIF_WAITING_BCMC CO_BIT(1)
| Station is waiting for broadcast/multicast traffic from AP.
#define | PS_VIF_WAITING_UC CO_BIT(2)
| Station is waiting for unicast traffic from AP.
#define | PS_VIF_WAITING_EOSP CO_BIT(3)
| Station is waiting for WMM-PS end of service period.
#define | PS_VIF_ASSOCIATING CO_BIT(4)
| Station is waiting for the end of the association procedure.
#define | PS_VIF_P2P_GO_PRESENT CO_BIT(5)
| P2P GO is supposed to be present.
#define | PS_VIF_P2P_WAIT_TBTT CO_BIT(6)
| P2P GO is waiting for TBTT interrupt.
#define | PS_VIF_MONITOR CO_BIT(7)
| VIF is configured for monitoring.
#define | PS_TX_CFM_UPLOADING CO_BIT(0)
| Upload of TX confirmations is ongoing.
#define | PS_SCAN_ONGOING CO_BIT(1)
| A scanning process is ongoing.
#define | PS_IDLE_REQ_PENDING CO_BIT(2)
| A request for going to IDLE is pending.
#define | PS_PSM_PAUSED CO_BIT(3)
| PSM is paused in order to allow data traffic.
#define | PS_CAC_STARTED CO_BIT(4)
| A CAC period is active.
#define | PS_ALL_UAPSD_ACS 0x0F
| Mask showing that all ACs UAPSD enabled.
#define | PS_SP_INTERRUPTED 0xff
| This value is sent to host, as the number of packet of a service period, to inicate that current service period has been interrrupted.
#define | PS_DPSM_STATE_GET(bit_pos) (ps_env.dpsm_state & (1 << PS_DPSM_STATE_ ## bit_pos))
| Indicate if specified bit is set to 1 in dpsm_state.
#define | PS_DPSM_STATE_SET(bit_pos) (ps_env.dpsm_state |= (1 << PS_DPSM_STATE_ ## bit_pos))
| Set specified bit to 1 in dpsm_state.
#define | PS_DPSM_STATE_CLEAR(bit_pos) (ps_env.dpsm_state &= ~(1 << PS_DPSM_STATE_ ## bit_pos))
| Set specified bit to 0 in dpsm_state.
## Enumerations
enum | { PS_MODE_OFF, PS_MODE_ON, PS_MODE_ON_DYN }
| Power Save mode setting. More...
enum | { PS_UAPSD_TMR_START, PS_UAPSD_TMR_STOP }
| Possible actions for UAPSD Timer. More...
enum | ps_dpsm_state_bit_pos { PS_DPSM_STATE_ON = 0, PS_DPSM_STATE_PAUSING, PS_DPSM_STATE_RESUMING, PS_DPSM_STATE_PAUSE, PS_DPSM_STATE_SET_MODE_REQ }
| Bit position description for dpsm_state variable. More...
## Functions
static uint8_t | ps_send_pspoll (struct vif_info_tag *vif)
| Sends PS Poll frame to peer AP.
static bool | ps_check_tx_status (struct vif_info_tag *vif, uint32_t status, cfm_func_ptr cfm)
| Checks if NULL frame indicating a PS mode change has been acknowledged by the peer AP.
static void | ps_enable_cfm (void *env, uint32_t status)
| Callback associated to frame sent to inform that interface will enter PS.
static void | ps_disable_cfm (void *env, uint32_t status)
| Callback associated to frame sent to inform that interface left PS.
static void | ps_dpsm_update (bool pause)
| Updates Dynamic Power Save mode status.
static void | ps_uapsd_timer_handle (void *env)
| Callback function for UAPSD timer.
void | ps_init (void)
| Initialize all the entries of the station table.
void | ps_set_mode (uint8_t mode, ke_task_id_t taskid)
| Set the Power-save mode as requested by the upper layers.
bool | ps_check_tim (uint32_t a_tim, uint16_t aid)
| Check if TIM Information Element received from either an AP or a peer Mesh STA if buffered frame targeting us are announced.
void | ps_check_beacon (uint32_t tim, uint16_t len, struct vif_info_tag *vif)
| Checks the TIM IE in the beacon to know if the station has to wait for individually or group addressed traffic following this beacon.
void | ps_check_frame (uint8_t *frame, uint32_t statinfo, struct vif_info_tag *vif)
| Checks the more data bit in the data or management frame passed as parameter and behave accordingly.
bool | ps_check_tx_frame (uint8_t staid, uint8_t tid)
| Check if the frame is a UAPSD trigger frame.
void | ps_uapsd_set (struct vif_info_tag *vif, uint8_t hw_queue, bool uapsd)
| Enable/disable the UAPSD for the HW queue and VIF passed as parameters.
void | ps_traffic_status_update (uint8_t vif_index, uint8_t new_status)
| Handle update of Traffic status generated by the Traffic Detection module.
void | ps_p2p_absence_update (struct vif_info_tag *vif, bool absent)
| Update P2P GO presence status update in order to send a trigger frame when an absence period is over after an interrupted Service Period.
void | ps_check_tx_trigger_sent (struct hostdesc *hostdesc, uint32_t tx_status)
| Re-enable WAIT EOSP status after UAPSD trigger frame transmission.
__INLINE bool | ps_uapsd_enabled (void)
| Checks UAPSD status.
__INLINE bool | ps_sleep_check (void)
| Checks if platform is allowed to sleep.
## Variables
struct ps_env_tag | ps_env
| PS context used to store information related to PS module.
struct ps_env_tag | ps_env
| PS context used to store information related to PS module.

## Detailed Description

Power-Save mode implementation.

## Define Documentation

#define PS_SP_INTERRUPTED 0xff

This value is sent to host, as the number of packet of a service period, to inicate that current service period has been interrrupted.

Definition at line 89 of file ps.h.

## Enumeration Type Documentation

anonymous enum

Power Save mode setting.

Enumerator:

  PS_MODE_OFF | Power-save off.
  PS_MODE_ON | Power-save on - Normal mode.
  PS_MODE_ON_DYN | Power-save on - Dynamic mode.

Definition at line 116 of file ps.h.

anonymous enum

Possible actions for UAPSD Timer.

Enumerator:

  PS_UAPSD_TMR_START | Start UAPSD Timer.
  PS_UAPSD_TMR_STOP | Stop UAPSD Timer.

Definition at line 130 of file ps.h.

enum ps_dpsm_state_bit_pos

Bit position description for dpsm_state variable.

Enumerator:

  PS_DPSM_STATE_ON | Indicate if DPSM is ON (Required by application).
  PS_DPSM_STATE_PAUSING | Indicate if it has been required to pause PS Mode.
  PS_DPSM_STATE_RESUMING | Indicate if it has been required to resume PS Mode.
  PS_DPSM_STATE_PAUSE | Indicate if the PS Mode is currently paused.

Definition at line 141 of file ps.h.

## Function Documentation

void ps_check_beacon | ( | uint32_t | tim,
|  | uint16_t | len,
|  | struct vif_info_tag * | vif |
| ) |  |  |

Checks the TIM IE in the beacon to know if the station has to wait for individually or group addressed traffic following this beacon.

If individually addressed traffic is buffered by AP, this function transmits the PS poll frame.

Parameters:

  `[in]` | tim | Pointer to the TIM element in the beacon
  `[in]` | len | Length of the beacon
  `[in]` | vif | Pointer to the VIF element associated to the beacon

Referenced by rxl_frame_handle().

void ps_check_frame | ( | uint8_t * | frame,
|  | uint32_t | statinfo,
|  | struct vif_info_tag * | vif |
| ) |  |  |

Checks the more data bit in the data or management frame passed as parameter and behave accordingly.

Parameters:

  `[in]` | frame | Pointer to the received data or management packet
  `[in]` | statinfo | MAC HW status of the reception
  `[in]` | vif | Pointer to the VIF element associated to the frame

Referenced by rxl_frame_handle().

bool ps_check_tim | ( | uint32_t | a_tim,
|  | uint16_t | aid |
| ) |  |  |

Check if TIM Information Element received from either an AP or a peer Mesh STA if buffered frame targeting us are announced.

Parameters:

  `[in]` | a_tim | Address of the TIM IE in the memory
  `[in]` | aid | Association ID

Returns:
  true if bit for the aid is set in the TIM IE, false otherwise.

bool ps_check_tx_frame | ( | uint8_t | staid,
|  | uint8_t | tid |
| ) |  |  |

Check if the frame is a UAPSD trigger frame.

In such case, store the transmit time in order to avoid sending a QoS-NULL trigger frame a short period after.

Parameters:

  `[in]` | staid | ID of the destination STA (0xFF if unknown)
  `[in]` | tid | Priority index of the frame (0xFF if not applicable)

Returns:
  true if this is a trigger frame and false otherwise

static bool ps_check_tx_status | ( | struct vif_info_tag * | vif,
|  | uint32_t | status,
|  | cfm_func_ptr | cfm |
| ) |  |  | `[static]`

Checks if NULL frame indicating a PS mode change has been acknowledged by the peer AP.

Up to 3 (PS_TX_ERROR_MAX) retries are allowed. If this limit is reached, we consider the connection with the AP has been lost and we continue processing the confirmation properly so that we can continue the mode update.

Parameters:

  `[in]` | vif | VIF on which the NULL frame has been sent
  `[in]` | status | Transmission status
  `[in]` | cfm | Confirmation callback if we need to resend a NULL frame.

Returns:
  False if a null frame has been resent and confirmation must be awaited. True if the frame has been sucessfully received, or retry limit has been reached.

Definition at line 130 of file ps.c.

References FRAME_SUCCESSFUL_TX_BIT, mm_send_connection_loss_ind(), PS_TX_ERROR_MAX, vif_info_tag::sta, txl_frame_send_null_frame(), and vif_info_tag::u.

Referenced by ps_disable_cfm(), and ps_enable_cfm().

void ps_check_tx_trigger_sent | ( | struct hostdesc * | hostdesc,
|  | uint32_t | tx_status |
| ) |  |  |

Re-enable WAIT EOSP status after UAPSD trigger frame transmission.

When an UAPSD trigger frame has been transmitted (i.e. flag TXU_CNTRL_UASPD_TRIGGER has been set by ps_check_tx_frame), this function will set the PS_VIF_WAITING_EOSP status if the transmission is successful.

In most case the PS_VIF_WAITING_EOSP is already set (because this status is set when ps_check_tx_frame set the TXU_CNTRL_UASPD_TRIGGER flag) so this won't change anything. But there are a few cases where this is needed. For example when 2 trigger frames are pushed "very close" to the HW but not transmitted "very close". AP may send an EOSP frame between the two transmissions and on reception of this EOSP the bit PS_VIF_WAITING_EOSP will be cleared. After transmission on the second frame, without this function, the system may enter sleep mode without waiting for EOSP.

Parameters:

  `[in]` | hostdesc | Hostdesc of the frame that has been transmitted
  `[in]` | tx_status | Transmission status of the frame

Referenced by txl_cfm_evt().

static void ps_disable_cfm | ( | void * | env,
|  | uint32_t | status |
| ) |  |  | `[static]`

Callback associated to frame sent to inform that interface left PS.

This function is called when a frame to indicate the peer that interface left PS has been transmitted. If frame has been sucessfully received by the peer and not more confirmation is pending, this function will notify MM task that Ps is disabled.

Parameters:

  `[in]` | env | VIF that sent the frame
  `[in]` | status | Transmission status

Definition at line 259 of file ps.c.

References vif_info_tag::active, ps_env_tag::cfm_cnt, co_list_next(), co_list_pick(), vif_info_tag::index, ke_msg_send_basic(), vif_info_tag::list_hdr, MM_SET_PS_MODE_CFM, mm_timer_clear(), ps_env_tag::next_mode, vif_info_tag::prevent_sleep, ps_check_tx_status(), PS_DPSM_STATE_CLEAR, PS_DPSM_STATE_GET, PS_DPSM_STATE_SET, ps_env, ps_env_tag::ps_on, ps_set_mode(), PS_VIF_WAITING_BCMC, PS_VIF_WAITING_EOSP, PS_VIF_WAITING_UC, TASK_MM, ps_env_tag::taskid, TRACE_STA, vif_info_tag::type, ps_env_tag::uapsd_timer, ps_env_tag::uapsd_tmr_on, vif_mgmt_env_tag::used_list, vif_mgmt_env, and VIF_STA.

Referenced by ps_dpsm_update().

static void ps_dpsm_update | ( | bool | pause | ) | `[static]`

Updates Dynamic Power Save mode status.

Updates status and send null frame on each active STA vif to indicate that it will enter or leave PS mode.

Parameters:

  `[in]` | pause | Whether Dynamic power save mode should be paused or not

Definition at line 340 of file ps.c.

References vif_info_tag::active, ps_env_tag::cfm_cnt, chan_is_tx_allowed(), co_list_next(), co_list_pick(), FRAME_SUCCESSFUL_TX_BIT, vif_info_tag::list_hdr, ps_env_tag::prevent_sleep, PROF_PS_DPSM_UPDATE_CLR, PROF_PS_DPSM_UPDATE_SET, PROF_PS_PAUSE_CLR, PROF_PS_PAUSE_SET, ps_disable_cfm(), PS_DPSM_STATE_SET, ps_enable_cfm(), ps_env, PS_PSM_PAUSED, vif_info_tag::sta, txl_frame_send_null_frame(), vif_info_tag::type, vif_info_tag::u, vif_mgmt_env_tag::used_list, vif_mgmt_env, and VIF_STA.

static void ps_enable_cfm | ( | void * | env,
|  | uint32_t | status |
| ) |  |  | `[static]`

Callback associated to frame sent to inform that interface will enter PS.

This function is called when a frame to indicate the peer that interface will enter PS has been transmitted. If frame has been sucessfully received by the peer and not more confirmation is pending, this function will notify MM task that Ps is enabled.

Parameters:

  `[in]` | env | VIF that sent the frame
  `[in]` | status | Transmission status

Definition at line 177 of file ps.c.

References vif_info_tag::active, ps_env_tag::cfm_cnt, co_list_next(), co_list_pick(), vif_info_tag::index, ke_msg_send_basic(), ke_time(), vif_info_tag::list_hdr, MM_SET_PS_MODE_CFM, mm_timer_set(), ps_env_tag::next_mode, vif_info_tag::prevent_sleep, ps_check_tx_status(), PS_DPSM_STATE_CLEAR, PS_DPSM_STATE_GET, ps_env, ps_env_tag::ps_on, ps_set_mode(), PS_VIF_WAITING_EOSP, vif_info_tag::sta, TASK_MM, ps_env_tag::taskid, TRACE_STA, vif_info_tag::type, vif_info_tag::u, ps_env_tag::uapsd_on, ps_env_tag::uapsd_timeout, ps_env_tag::uapsd_timer, ps_env_tag::uapsd_tmr_on, vif_mgmt_env_tag::used_list, vif_mgmt_env, and VIF_STA.

Referenced by ps_dpsm_update().

void ps_p2p_absence_update | ( | struct vif_info_tag * | vif,
|  | bool | absent |
| ) |  |  |

Update P2P GO presence status update in order to send a trigger frame when an absence period is over after an interrupted Service Period.

Parameters:

  `[in]` | vif | VIF Entry
  `[in]` | absent | P2P GO presence status

Referenced by p2p_update_go_ps_state().

static uint8_t ps_send_pspoll | ( | struct vif_info_tag * | vif | ) | `[static]`

Sends PS Poll frame to peer AP.

Sends a ps poll to the peer AP to retrieve buffered traffic.

Parameters:

  `[in]` | vif | VIF that need to send the PS Poll frame

Returns:
  CO_OK if frame has been pushed, CO_FAIL otherwise

Definition at line 72 of file ps.c.

References AC_VO, mac_hdr_ctrl::addr1, mac_hdr_ctrl::addr2, sta_info_tag::aid, CO_FAIL, CO_OK, DONT_TOUCH_DUR, mac_hdr_ctrl::durid, mac_hdr_ctrl::fctl, txdesc::host, lmacdesc::hw_desc, sta_info_tag::inst_nbr, txdesc::lmac, vif_info_tag::mac_addr, sta_info_tag::mac_addr, MAC_FCTRL_PSPOLL, tx_hd::macctrlinfo2, vif_info_tag::sta, sta_info_tab, sta_info_tag::staid, hostdesc::staid, tx_hw_desc::thd, tpc_update_frame_tx_power(), TS_VALID_BIT, txl_frame_desc_tag::txdesc, txl_buffer_payload_get(), txl_frame_get(), txl_frame_push(), vif_info_tag::u, hostdesc::vif_idx, and vif_mgmt_get_txtype().

void ps_set_mode | ( | uint8_t | mode,
|  | ke_task_id_t | taskid |
| ) |  |  |

Set the Power-save mode as requested by the upper layers.

This function sends the NULL frame to the AP to indicate them the mode change

Parameters:

  `[in]` | mode | PS_MODE_OFF or PS_MODE_ON
  `[in]` | taskid | ID of the task that requested the power save, and to which the confirmation will be sent

Set the UAPSD ON flag

Referenced by mm_set_ps_mode_req_handler(), ps_disable_cfm(), and ps_enable_cfm().

__INLINE bool ps_sleep_check | ( | void |  | ) |

Checks if platform is allowed to sleep.

Returns:
  Whether sleep is allowed or not.

Definition at line 226 of file ps.h.

References co_list_next(), co_list_pick(), vif_info_tag::list_hdr, NX_P2P_GO, p2p_go_check_ps_mode(), vif_info_tag::prevent_sleep, ps_env_tag::prevent_sleep, PROF_PS_SLEEP_CLR, PROF_PS_SLEEP_SET, ps_env, ps_env_tag::ps_on, vif_mgmt_env_tag::used_list, and vif_mgmt_env.

void ps_traffic_status_update | ( | uint8_t | vif_index,
|  | uint8_t | new_status |
| ) |  |  |

Handle update of Traffic status generated by the Traffic Detection module.

It is used in order to pause/restart the legacy power save mode if DPSM feature has been enabled.

Parameters:

  `[in]` | vif_index | Index of the VIF entry for which the status has been updated
  `[in]` | new_status | Updated status

__INLINE bool ps_uapsd_enabled | ( | void |  | ) |

Checks UAPSD status.

Returns:
  whether uapsd is enabled or not

Definition at line 213 of file ps.h.

References ps_env, and ps_env_tag::uapsd_timeout.

Referenced by me_build_associate_req().

void ps_uapsd_set | ( | struct vif_info_tag * | vif,
|  | uint8_t | hw_queue,
|  | bool | uapsd |
| ) |  |  |

Enable/disable the UAPSD for the HW queue and VIF passed as parameters.

Parameters:

  `[in]` | vif | Pointer to the VIF for UAPSD is enabled/disabled
  `[in]` | hw_queue | HW queue index
  `[in]` | uapsd | Flag indicating if U-APSD has to enabled or disabled

Referenced by mm_set_edca_req_handler().

static void ps_uapsd_timer_handle | ( | void * | env | ) | `[static]`

Callback function for UAPSD timer.

Sends a trigger frame to AP to retrieve the data that are buffered

Parameters:

  `[in]` | env | Pointer to env variable associated to the timer. (NULL in this case)

Definition at line 426 of file ps.c.

References vif_info_tag::active, chan_is_tx_allowed(), co_list_next(), co_list_pick(), CO_OK, vif_info_tag::index, ke_time(), ke_time_past(), vif_info_tag::list_hdr, MAC_QOSCTRL_UP_OFT, mm_timer_set(), vif_info_tag::p2p, vif_info_tag::p2p_index, p2p_is_present(), vif_info_tag::prevent_sleep, ps_env, PS_VIF_WAITING_EOSP, vif_info_tag::sta, TRACE_STA, txl_frame_send_qosnull_frame(), vif_info_tag::type, vif_info_tag::u, ps_env_tag::uapsd_timeout, ps_env_tag::uapsd_timer, ps_env_tag::uapsd_tmr_on, vif_mgmt_env_tag::used_list, vif_mgmt_env, and VIF_STA.