00001
00013 #ifndef _PS_H_
00014 #define _PS_H_
00015
00025
00026
00027
00028
00029
00030
00031 #include "rwnx_config.h"
00032
00033 #include "co_list.h"
00034
00035 #include "mac.h"
00036
00037 #include "vif_mgmt.h"
00038 #include "reg_mac_pl.h"
00039 #include "co_math.h"
00040 #if (NX_P2P)
00041 #include "p2p.h"
00042 #endif //(NX_P2P)
00043 #if (RW_UMESH_EN)
00044 #include "mesh_ps.h"
00045 #endif //(RW_UMESH_EN)
00046
00047 #if NX_POWERSAVE
00048
00049
00050
00051
00052
00053
00054
00056 #define PS_VIF_WAITING_BCN CO_BIT(0)
00058 #define PS_VIF_WAITING_BCMC CO_BIT(1)
00060 #define PS_VIF_WAITING_UC CO_BIT(2)
00062 #define PS_VIF_WAITING_EOSP CO_BIT(3)
00064 #define PS_VIF_ASSOCIATING CO_BIT(4)
00066 #define PS_VIF_P2P_GO_PRESENT CO_BIT(5)
00068 #define PS_VIF_P2P_WAIT_TBTT CO_BIT(6)
00070 #define PS_VIF_MONITOR CO_BIT(7)
00071
00072
00074 #define PS_TX_CFM_UPLOADING CO_BIT(0)
00076 #define PS_SCAN_ONGOING CO_BIT(1)
00078 #define PS_IDLE_REQ_PENDING CO_BIT(2)
00080 #define PS_PSM_PAUSED CO_BIT(3)
00082 #define PS_CAC_STARTED CO_BIT(4)
00083
00085 #define PS_ALL_UAPSD_ACS 0x0F
00086
00089 #define PS_SP_INTERRUPTED 0xff
00090
00091
00092
00093
00094
00095
00096 #if (NX_DPSM)
00098 #define PS_DPSM_STATE_GET(bit_pos) \
00099 (ps_env.dpsm_state & (1 << PS_DPSM_STATE_ ## bit_pos))
00101 #define PS_DPSM_STATE_SET(bit_pos) \
00102 (ps_env.dpsm_state |= (1 << PS_DPSM_STATE_ ## bit_pos))
00104 #define PS_DPSM_STATE_CLEAR(bit_pos) \
00105 (ps_env.dpsm_state &= ~(1 << PS_DPSM_STATE_ ## bit_pos))
00106 #endif //(NX_DPSM)
00107
00108 #endif //(NX_POWERSAVE)
00109
00110
00111
00112
00113
00114
00116 enum
00117 {
00119 PS_MODE_OFF,
00121 PS_MODE_ON,
00123 PS_MODE_ON_DYN,
00124 };
00125
00126 #if (NX_POWERSAVE)
00127
00128 #if NX_UAPSD
00130 enum
00131 {
00133 PS_UAPSD_TMR_START,
00135 PS_UAPSD_TMR_STOP,
00136 };
00137 #endif
00138
00139 #if (NX_DPSM)
00141 enum ps_dpsm_state_bit_pos
00142 {
00144 PS_DPSM_STATE_ON = 0,
00146 PS_DPSM_STATE_PAUSING,
00148 PS_DPSM_STATE_RESUMING,
00150 PS_DPSM_STATE_PAUSE,
00151
00152
00153
00154
00155 PS_DPSM_STATE_SET_MODE_REQ,
00156 };
00157 #endif //(NX_DPSM)
00158
00159
00160
00161
00162
00163
00165 struct ps_env_tag
00166 {
00168 bool ps_on;
00170 ke_task_id_t taskid;
00172 uint32_t prevent_sleep;
00174 uint8_t cfm_cnt;
00175
00176 #if NX_UAPSD
00178 struct mm_timer_tag uapsd_timer;
00180 bool uapsd_tmr_on;
00182 bool uapsd_on;
00184 uint32_t uapsd_timeout;
00185 #endif
00186
00187 #if (NX_DPSM)
00189 uint8_t dpsm_state;
00191 uint8_t next_mode;
00192 #endif //(NX_DPSM)
00193 };
00194
00195
00196
00197
00198
00199 extern struct ps_env_tag ps_env;
00200
00201
00202
00203
00204
00205 #if NX_UAPSD
00206
00213 __INLINE bool ps_uapsd_enabled(void)
00214 {
00215 return (ps_env.uapsd_timeout != 0);
00216 }
00217 #endif
00218
00226 __INLINE bool ps_sleep_check(void)
00227 {
00228 struct vif_info_tag *vif;
00229 bool sleep_allowed = false;
00230
00231 do
00232 {
00233 #if (RW_UMESH_EN)
00234 if (mesh_ps_sleep_check())
00235 {
00236 sleep_allowed = true;
00237 break;
00238 }
00239 #endif //(RW_UMESH_EN)
00240
00241
00242 if (!ps_env.ps_on
00243 #if (NX_P2P_GO)
00244 && (!p2p_go_check_ps_mode())
00245 #endif
00246 )
00247 {
00248 break;
00249 }
00250
00251
00252 if (ps_env.prevent_sleep)
00253 break;
00254
00255
00256 sleep_allowed = true;
00257 vif = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list);
00258 while (vif != NULL)
00259 {
00260 if (vif->prevent_sleep)
00261 {
00262 sleep_allowed = false;
00263 break;
00264 }
00265
00266 vif = (struct vif_info_tag *)co_list_next(&vif->list_hdr);
00267 }
00268 } while (0);
00269
00270
00271 if (sleep_allowed)
00272 {
00273 PROF_PS_SLEEP_SET();
00274 }
00275 else
00276 {
00277 PROF_PS_SLEEP_CLR();
00278 }
00279
00280 return (sleep_allowed);
00281 }
00287 void ps_init(void);
00288
00289
00300 void ps_set_mode(uint8_t mode, ke_task_id_t taskid);
00301
00302 #if (RW_MESH_EN)
00303 bool ps_check_tim(uint32_t a_tim, uint16_t aid);
00304 #endif //(!RW_MESH_EN)
00305
00318 void ps_check_beacon(uint32_t tim, uint16_t len, struct vif_info_tag *vif);
00319
00330 void ps_check_frame(uint8_t *frame, uint32_t statinfo, struct vif_info_tag *vif);
00331
00332 #if (NX_UAPSD)
00333
00342 void ps_uapsd_set(struct vif_info_tag *vif, uint8_t hw_queue, bool uapsd);
00343 #endif //(NX_UAPSD)
00344
00345 #if (NX_UAPSD || NX_DPSM)
00346
00356 bool ps_check_tx_frame(uint8_t staid, uint8_t tid);
00357 #endif //(NX_UAPSD || NX_DPSM)
00358
00359 #if (NX_UAPSD && NX_UMAC_PRESENT)
00360
00381 void ps_check_tx_trigger_sent(struct hostdesc *hostdesc, uint32_t tx_status);
00382 #endif //(NX_UAPSD && NX_UMAC_PRESENT)
00383
00384 #if (NX_DPSM)
00385
00395 void ps_traffic_status_update(uint8_t vif_index, uint8_t new_status);
00396 #endif //(NX_DPSM)
00397
00398 #if (NX_P2P && NX_UAPSD)
00399
00408 void ps_p2p_absence_update(struct vif_info_tag *vif, bool absent);
00409 #endif //(NX_P2P && NX_UAPSD)
00410
00411 #endif // NX_POWERSAVE
00412
00414
00415 #endif // _PS_H_