/****************************************************************************** * * Copyright(c) 2019 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * *****************************************************************************/ #ifndef _PHL_TWT_H_ #define _PHL_TWT_H_ #ifdef CONFIG_PHL_TWT #define MIN_TWT_ELE_LEN 15 #define MAX_NUM_HW_TWT_CONFIG 4 #define CONTROL_LENGTH 1 #define REQUEST_TYPE_LENGTH 2 #define NOMINAL_MINIMUM_TWT_WAKE_DURATION_LENGTH 1 #define TARGET_WAKE_TIME_LENGTH 8 #define BTWT_TARGET_WAKE_TIME_LENGTH 2 #define NOMINAL_MIN_TWT_WAKE_DURATION_LENGTH 1 #define TWT_WAKE_INTERVAL_MANTISSA_LENGTH 2 #define TWT_CHANNEL_LENGTH 1 #define TWT_FLOW_FIELD_LENGTH 1 #define TWT_INFO_FIELD_BASIC_LENGTH 1 #define BTWT_INFO_LENGTH 2 #define MIN_BTWT_PARA_LEN (REQUEST_TYPE_LENGTH + BTWT_TARGET_WAKE_TIME_LENGTH + \ NOMINAL_MINIMUM_TWT_WAKE_DURATION_LENGTH + \ TWT_WAKE_INTERVAL_MANTISSA_LENGTH + BTWT_INFO_LENGTH) #define TOKEN_OFFSET 2 #define TOKEN_LENGTH 1 #define ELEM_ID_LEN 1 /* Length of element id*/ #define ELEM_LEN_LEN 1 /* Length of element Length*/ #define C2H_FUN_WAIT_ANNC 0x0 #define get_twt_info(_phl) (struct phl_twt_info *)(_phl->phl_twt_info) #define set_config_state(_state, set_state) (_state = set_state) #define twt_init(_phl) (NULL != (get_twt_info(_phl))) #define twt_sup(_phl) (((struct phl_info_t *)_phl)->phl_com->dev_cap.twt_sup) enum phl_operate_config_type { PHL_OP_TYPE_NONE = 0, PHL_GET_NEW_CONFIG, PHL_FREE_CONFIG, PHL_GET_CONFIG_BY_ID, PHL_GET_CONFIG_BY_ROLE, PHL_GET_CONFIG_BY_PARA, PHL_GET_NEXT_CONFIG, PHL_GET_HEAD_CONFIG }; enum phl_twt_action { PHL_TWT_ACTION_NONE = 0, PHL_TWT_ACTION_FREE, PHL_TWT_ACTION_ALLOC, PHL_TWT_ACTION_ENABLE, PHL_TWT_ACTION_DISABLE, PHL_TWT_ACTION_UP_ERROR }; enum twt_config_state { twt_config_state_free = 0, twt_config_state_idle, twt_config_state_enable, twt_config_state_error, twt_config_state_unknown }; struct phl_twt_config{ u8 idx; enum twt_config_state state; struct rtw_wifi_role_t *role; struct rtw_wifi_role_link_t *rlink; struct rtw_phl_twt_info twt_info; struct phl_queue twt_sta_queue; /*struct rtw_twt_sta_info*/ }; struct phl_twt_cfg_info { u8 twt_cfg_num; void *twt_cfg_ring; /*struct phl_twt_config*/ }; struct phl_twt_info { struct phl_twt_cfg_info twt_cfg_info; struct phl_queue twt_annc_queue;/*struct _twt_announce_info*/ /* pkt ofld token */ u32 qos_null_pkt_token; }; struct _twt_announce_info{ _os_list list; u8 map_offset; u32 wait_macid_map; }; struct _twt_compare { struct rtw_phl_twt_setup_info twt_setup; struct rtw_wifi_role_t *role; }; struct _twt_teardown { struct rtw_phl_stainfo_t *phl_sta; enum rtw_phl_nego_type nego_type; u8 id; }; /* TWT Information field -Start*/ #define SET_TWT_INFO_FLOW_ID(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 0, 3, _val) #define SET_TWT_INFO_RSP_REQ(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 3, 1, _val) #define SET_TWT_INFO_NEXT_TWT_REQ(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 4, 1, _val) #define SET_TWT_INFO_NEXT_TWT_SIZE(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 5, 2, _val) #define SET_TWT_INFO_ALL_TWT(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 7, 1, _val) #define SET_TWT_INFO_NEXT_TWT(_ele_start, _size, _val) \ do { \ if (_size == 32) { \ SET_BITS_TO_LE_4BYTE(_ele_start + 1, 0, 32, (u32)(_val & 0xFFFFFFFF)); \ } else if (_size == 48) { \ SET_BITS_TO_LE_4BYTE(_ele_start + 1, 0, 32, (u32)(_val & 0xFFFFFFFF)); \ SET_BITS_TO_LE_2BYTE(_ele_start + 5, 0, 16, (u16)((_val >> 32) & 0xFFFFFFFF)); \ } else if (_size == 64) { \ SET_BITS_TO_LE_4BYTE(_ele_start + 1, 0, 32, (u32)(_val & 0xFFFFFFFF)); \ SET_BITS_TO_LE_4BYTE(_ele_start + 5, 0, 16, (u32)((_val >> 32) & 0xFFFFFFFF)); \ } else { \ break; \ }\ } while(false); /* Bit0-2 */ #define GET_TWT_INFO_FLOW_ID(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 3) /* Bit3 */ #define GET_TWT_INFO_RSP_REQ(_buf) \ LE_BITS_TO_1BYTE(_buf, 3, 1) /* Bit4 */ #define GET_TWT_INFO_NEXT_TWT_REQ(_buf) \ LE_BITS_TO_1BYTE(_buf, 4, 1) /* Bit5-6 */ #define GET_TWT_INFO_NEXT_TWT_SIZE(_buf) \ LE_BITS_TO_1BYTE(_buf, 5, 2) /* Bit7 */ #define GET_TWT_INFO_ALL_TWT(_buf) \ LE_BITS_TO_1BYTE(_buf, 7, 1) #define GET_TWT_INFO_NEXT_TWT(_buf, _size, _val) \ do { \ u32 h = 0, l = 0; \ if (_size == 32) { \ l = LE_BITS_TO_4BYTE(_buf + 1, 0, 32); \ *_val = l; \ } else if (_size == 48) { \ l = LE_BITS_TO_4BYTE(_buf + 1, 0, 32); \ h = LE_BITS_TO_2BYTE(_buf + 5, 0, 16); \ *_val = h; \ *_val = (*_val << 32); \ *_val |= l; \ } else if (_size == 64) { \ l = LE_BITS_TO_4BYTE(_buf + 1, 0, 32); \ h = LE_BITS_TO_4BYTE(_buf + 5, 0, 32); \ *_val = h; \ *_val = (*_val << 32); \ *_val |= l; \ } else { \ *_val = 0; \ break; \ }\ } while(false) /* TWT Information field -End*/ /* TWT element */ /*Control*/ #define SET_TWT_CONTROL_NDP_PAGING_INDICATOR(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 0, 1, _val) #define SET_TWT_CONTROL_RESPONDER_PM_MODE(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 1, 1, _val) #define SET_TWT_CONTROL_NEGOTIATION_TYPE(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 2, 2, _val) #define SET_TWT_CONTROL_TWT_INFORMATION_FRAME_DISABLE(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 4, 1, _val) #define SET_TWT_CONTROL_WAKE_DURATION_UNIT(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 5, 1, _val) /* Individual TWT Parameter Set field-Start */ /*Request Type*/ #define SET_TWT_REQ_TYPE_TWT_REQUEST(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 0, 1, _val) #define SET_TWT_REQ_TYPE_TWT_SETUP_COMMAND(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 1, 3, _val) #define SET_TWT_REQ_TYPE_TRIGGER(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 4, 1, _val) #define SET_TWT_REQ_TYPE_IMPLICIT(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 5, 1, _val) #define SET_TWT_REQ_TYPE_FLOW_TYPE(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 6, 1, _val) #define SET_TWT_REQ_TYPE_TWT_FLOW_IDENTIFER(_ele_start, _val) \ SET_BITS_TO_LE_2BYTE(_ele_start, 7, 3, _val) #define SET_TWT_REQ_TYPE_TWT_WAKE_INTERVAL_EXPONENT(_ele_start, _val) \ SET_BITS_TO_LE_2BYTE(_ele_start, 10, 5, _val) #define SET_TWT_REQ_TYPE_TWT_PROTECTION(_ele_start, _val) \ SET_BITS_TO_LE_2BYTE(_ele_start, 15, 1, _val) #define SET_TWT_TARGET_WAKE_TIME_L(_ele_start, _val) \ SET_BITS_TO_LE_4BYTE((_ele_start) + 2, 0, 32, _val) #define SET_TWT_TARGET_WAKE_TIME_H(_ele_start, _val) \ SET_BITS_TO_LE_4BYTE((_ele_start) + 6, 0, 32, _val) /*twt group assignment*/ #define SET_TWT_NOMINAL_MINIMUM_TWT_WAKE_DURATION(_ele_start, _offset, _val) \ SET_BITS_TO_LE_1BYTE((_ele_start) + _offset, 0, 8, _val) #define SET_TWT_TWT_WAKE_INTERVAL_MANTISSA(_ele_start, _offset, _val) \ SET_BITS_TO_LE_2BYTE((_ele_start) + _offset, 0, 16, _val) #define SET_TWT_TWT_CHANNEL(_ele_start, _offset, _val) \ SET_BITS_TO_LE_1BYTE((_ele_start) + _offset, 0, 8, _val) /* Individual TWT Parameter Set field-End */ /* Broadcast TWT Parameter Set field-Start */ /*Request Type*/ #define SET_BTWT_REQ_TYPE_TWT_REQUEST(_buf, _val) \ SET_BITS_TO_LE_1BYTE(_buf, 0, 1, _val) #define SET_BTWT_REQ_TYPE_TWT_SETUP_COMMAND(_buf, _val) \ SET_BITS_TO_LE_1BYTE(_buf, 1, 3, _val) #define SET_BTWT_REQ_TYPE_TRIGGER(_buf, _val) \ SET_BITS_TO_LE_1BYTE(_buf, 4, 1, _val) #define SET_BTWT_REQ_TYPE_LST_BC_PARA_SET(_buf, _val) \ SET_BITS_TO_LE_1BYTE(_buf, 5, 1, _val) #define SET_BTWT_REQ_TYPE_FLOW_TYPE(_buf, _val) \ SET_BITS_TO_LE_1BYTE(_buf, 6, 1, _val) #define SET_BTWT_REQ_TYPE_RCMD(_buf, _val) \ SET_BITS_TO_LE_2BYTE(_buf, 7, 3, _val) #define SET_BTWT_REQ_TYPE_TWT_WAKE_INTERVAL_EXPONENT(_buf, _val) \ SET_BITS_TO_LE_2BYTE(_buf, 10, 5, _val) #define SET_BTWT_REQ_TYPE_RSVD(_buf, _val) \ SET_BITS_TO_LE_2BYTE(_buf, 15, 1, _val) #define SET_BTWT_TARGET_WAKE_TIME(_buf, _val) \ SET_BITS_TO_LE_2BYTE(_buf, 0, 16, _val) #define SET_BTWT_NOMINAL_MINIMUM_TWT_WAKE_DURATION(_buf, _val) \ SET_BITS_TO_LE_1BYTE(_buf, 0, 8, _val) #define SET_BTWT_TWT_WAKE_INTERVAL_MANTISSA(_buf, _val) \ SET_BITS_TO_LE_2BYTE(_buf, 0, 16, _val) /* BTWT Info */ #define SET_BTWT_ID(_buf, _val) \ SET_BITS_TO_LE_2BYTE(_buf, 3, 5, _val) #define SET_BTWT_PRSTNC(_buf, _val) \ SET_BITS_TO_LE_2BYTE(_buf, 8, 8, _val) /* Broadcast TWT Parameter Set field-End */ /*TWT FLOW field*/ #define SET_TWT_FLOW_ID(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 0, 3, _val) #define SET_NEGOTIATION_TYPE(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 5, 2, _val) #define SET_TEARDOWN_ALL_TWT(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 7, 1, _val) #define SET_BROADCAST_TWT_ID(_ele_start, _val) \ SET_BITS_TO_LE_1BYTE(_ele_start, 0, 5, _val) /*Control*/ /*Bit0*/ #define GET_TWT_CONTROL_NDP_PAGING_INDICATOR(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 1) /*Bit1*/ #define GET_TWT_CONTROL_RESPONDER_PM_MODE(_buf) \ LE_BITS_TO_1BYTE(_buf, 1, 1) /*Bit2-3*/ #define GET_TWT_CONTROL_NEGOTIATION_TYPE(_buf) \ LE_BITS_TO_1BYTE(_buf, 2, 2) /*Bit4*/ #define GET_TWT_CONTROL_TWT_INFORMATION_FRAME_DISABLE(_buf) \ LE_BITS_TO_1BYTE(_buf, 4, 1) /*Bit5*/ #define GET_TWT_CONTROL_WAKE_DURATION_UNIT(_buf) \ LE_BITS_TO_1BYTE(_buf, 5, 1) /* Individual TWT Parameter Set field-Start */ /* Request Type */ /*Bit0*/ #define GET_TWT_REQ_TYPE_TWT_REQUEST(_buf) \ LE_BITS_TO_2BYTE(_buf, 0, 1) /*Bit1-3*/ #define GET_TWT_REQ_TYPE_TWT_SETUP_COMMAND(_buf) \ LE_BITS_TO_2BYTE(_buf, 1, 3) /*Bit4*/ #define GET_TWT_REQ_TYPE_TRIGGER(_buf) \ LE_BITS_TO_2BYTE(_buf, 4, 1) /*Bit5*/ #define GET_TWT_REQ_TYPE_IMPLICIT(_buf) \ LE_BITS_TO_2BYTE(_buf, 5, 1) /*Bit6*/ #define GET_TWT_REQ_TYPE_FLOW_TYPE(_buf) \ LE_BITS_TO_2BYTE(_buf, 6, 1) /*Bit7-9*/ #define GET_TWT_REQ_TYPE_TWT_FLOW_IDENTIFER(_buf) \ LE_BITS_TO_2BYTE(_buf, 7, 3) /*Bit10-14*/ #define GET_TWT_REQ_TYPE_TWT_WAKE_INTERVAL_EXPONENT(_buf) \ LE_BITS_TO_2BYTE(_buf, 10, 5) /*Bit15*/ #define GET_TWT_REQ_TYPE_TWT_PROTECTION(_buf) \ LE_BITS_TO_2BYTE(_buf, 15, 1) #define GET_TWT_TARGET_WAKE_TIME_L(_buf) \ LE_BITS_TO_4BYTE(_buf, 0, 32) #define GET_TWT_TARGET_WAKE_TIME_H(_buf) \ LE_BITS_TO_4BYTE((_buf) + 4, 0, 32) #define GET_TWT_NOMINAL_MINIMUM_TWT_WAKE_DURATION(_buf) \ LE_BITS_TO_1BYTE(_buf, 0 , 8); #define GET_TWT_TWT_WAKE_INTERVAL_MANTISSA(_buf) \ LE_BITS_TO_2BYTE(_buf, 0, 16); #define GET_TWT_TWT_CHANNEL(_buf) \ LE_BITS_TO_1BYTE(_buf, 0 ,8); /* Individual TWT Parameter Set field-End */ /* Broadcast TWT Parameter Set field-Start */ /*Request Type*/ #define GET_BTWT_REQ_TYPE_TWT_REQUEST(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 1) #define GET_BTWT_REQ_TYPE_TWT_SETUP_COMMAND(_buf) \ LE_BITS_TO_1BYTE(_buf, 1, 3) #define GET_BTWT_REQ_TYPE_TRIGGER(_buf) \ LE_BITS_TO_1BYTE(_buf, 4, 1) #define GET_BTWT_REQ_TYPE_LST_BC_PARA_SET(_buf) \ LE_BITS_TO_1BYTE(_buf, 5, 1) #define GET_BTWT_REQ_TYPE_FLOW_TYPE(_buf) \ LE_BITS_TO_1BYTE(_buf, 6, 1) #define GET_BTWT_REQ_TYPE_RCMD(_buf) \ LE_BITS_TO_2BYTE(_buf, 7, 3) #define GET_BTWT_REQ_TYPE_TWT_WAKE_INTERVAL_EXPONENT(_buf) \ LE_BITS_TO_2BYTE(_buf, 10, 5) #define GET_BTWT_REQ_TYPE_RSVD(_buf) \ LE_BITS_TO_2BYTE(_buf, 15, 1) #define GET_BTWT_TARGET_WAKE_TIME(_buf) \ LE_BITS_TO_2BYTE(_buf, 0, 16) #define GET_BTWT_NOMINAL_MINIMUM_TWT_WAKE_DURATION(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 8) #define GET_BTWT_TWT_WAKE_INTERVAL_MANTISSA(_buf) \ LE_BITS_TO_2BYTE(_buf, 0, 16) /* BTWT Info */ #define GET_BTWT_ID(_buf) \ LE_BITS_TO_2BYTE(_buf, 3, 5) #define GET_BTWT_PRSTNC(_buf) \ LE_BITS_TO_2BYTE(_buf, 8, 8) /* Broadcast TWT Parameter Set field-End */ /* TWT FLOW field-Start */ /*Bit0-2*/ #define GET_TWT_FLOW_ID(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 3) /*Bit5-6*/ #define GET_NEGOTIATION_TYPE(_buf) \ LE_BITS_TO_1BYTE(_buf, 5 , 2); /*Bit7*/ #define GET_TEARDOWN_ALL_TWT(_buf) \ LE_BITS_TO_1BYTE(_buf, 7, 1) /*Bit0-4*/ #define GET_BROADCAST_TWT_ID(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 5) #define GET_ELE_ID(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 8); #define GET_ELE_LEN(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 8); #define GET_DIALOG_TOKEN(_buf) \ LE_BITS_TO_1BYTE(_buf, 0, 8); /* TWT FLOW field-End */ enum rtw_phl_status phl_twt_init(void *phl); void phl_twt_deinit(void *phl); enum rtw_phl_status rtw_phl_twt_disable_all_twt_by_role(void *phl, struct rtw_wifi_role_t *role); enum rtw_phl_status rtw_phl_twt_free_all_twt_by_role(void *phl, struct rtw_wifi_role_t *role); enum rtw_phl_status rtw_phl_twt_alloc_twt_config(void *phl, struct rtw_wifi_role_link_t *rlink, struct rtw_phl_twt_setup_info setup_info, u8 benable, u8 *id); enum rtw_phl_status rtw_phl_twt_free_twt_config(void *phl, u8 id); enum rtw_phl_status rtw_phl_twt_add_sta_info(void *phl, struct rtw_phl_stainfo_t *phl_sta, u8 config_id, u8 id); enum rtw_phl_status phl_twt_get_target_wake_time(struct phl_info_t *phl, u8 *param); enum rtw_phl_status phl_twt_accept_for_sta_mode(struct phl_info_t *phl, u8 *param); enum rtw_phl_status phl_twt_teardown_for_sta_mode(struct phl_info_t *phl, u8 *param); enum rtw_phl_status phl_twt_info_f_hrl(struct phl_info_t *phl, u8 *param); enum rtw_phl_status rtw_phl_twt_handle_c2h_wait_annc(struct phl_info_t *phl, u8 *buf); #else #define phl_twt_init(_phl) RTW_PHL_STATUS_SUCCESS #define phl_twt_deinit(_phl) #endif /* CONFIG_PHL_TWT */ #endif /*_PHL_TWT_H_*/