1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: wlan_mgmt_txrx_rx_reo_i.h 19 * This file contains mgmt rx re-ordering related APIs 20 */ 21 22 #ifndef _WLAN_MGMT_TXRX_RX_REO_I_H 23 #define _WLAN_MGMT_TXRX_RX_REO_I_H 24 25 #ifdef WLAN_MGMT_RX_REO_SUPPORT 26 #include <qdf_list.h> 27 #include <qdf_timer.h> 28 #include <qdf_lock.h> 29 #include <qdf_nbuf.h> 30 #include <wlan_mgmt_txrx_rx_reo_utils_api.h> 31 #include <wlan_mgmt_txrx_rx_reo_public_structs.h> 32 #include <wlan_objmgr_pdev_obj.h> 33 #include <wlan_objmgr_psoc_obj.h> 34 35 #define MGMT_RX_REO_MAX_LIST_SIZE (100) 36 #define MGMT_RX_REO_LIST_TIMEOUT (10 * USEC_PER_MSEC) 37 #define MGMT_RX_REO_STATUS_WAIT_FOR_FRAME_ON_OTHER_LINKS (BIT(0)) 38 #define MGMT_RX_REO_STATUS_AGED_OUT (BIT(1)) 39 /** 40 * TODO: Dummy macro for Maximum MLO links on the system 41 * This is added only as a place holder for the time being. 42 * Remove this once the actual one is implemented. 43 */ 44 #define MGMT_RX_REO_MAX_LINKS (16) 45 /* Reason to release an entry from the reorder list */ 46 #define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_ZERO_WAIT_COUNT (BIT(0)) 47 #define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_AGED_OUT (BIT(1)) 48 #define MGMT_RX_REO_LIST_ENTRY_RELEASE_REASON_OLDER_THAN_AGED_OUT_FRAME (BIT(2)) 49 50 #define MGMT_RX_REO_LIST_ENTRY_IS_WAITING_FOR_FRAME_ON_OTHER_LINK(entry) \ 51 ((entry)->status & MGMT_RX_REO_STATUS_WAIT_FOR_FRAME_ON_OTHER_LINKS) 52 #define MGMT_RX_REO_LIST_ENTRY_IS_AGED_OUT(entry) \ 53 ((entry)->status & MGMT_RX_REO_STATUS_AGED_OUT) 54 #define MGMT_RX_REO_LIST_ENTRY_IS_OLDER_THAN_LATEST_AGED_OUT_FRAME(ts, entry) \ 55 (mgmt_rx_reo_compare_global_timestamps_gte( \ 56 (ts)->global_ts, mgmt_rx_reo_get_global_ts((entry)->rx_params))) 57 58 /** 59 * enum mgmt_rx_reo_frame_descriptor_type - Enumeration for management frame 60 * descriptor type. 61 * @MGMT_RX_REO_FRAME_DESC_HOST_CONSUMED_FRAME: Management frame to be consumed 62 * by host. 63 * @MGMT_RX_REO_FRAME_DESC_FW_CONSUMED_FRAME: Management frame consumed by FW 64 * @MGMT_RX_REO_FRAME_DESC_ERROR_FRAME: Management frame which got dropped 65 * at host due to any error 66 */ 67 enum mgmt_rx_reo_frame_descriptor_type { 68 MGMT_RX_REO_FRAME_DESC_HOST_CONSUMED_FRAME, 69 MGMT_RX_REO_FRAME_DESC_FW_CONSUMED_FRAME, 70 MGMT_RX_REO_FRAME_DESC_ERROR_FRAME, 71 }; 72 73 /** 74 * struct mgmt_rx_reo_global_ts_info - This structure holds the global time 75 * stamp information of a frame. 76 * @global_ts: Global time stamp value 77 * @valid: Indicates whether global time stamp is valid 78 */ 79 struct mgmt_rx_reo_global_ts_info { 80 bool valid; 81 uint32_t global_ts; 82 }; 83 84 /** 85 * struct mgmt_rx_reo_list – Linked list used to reorder the management frames 86 * received. Each list entry would correspond to a management frame. List 87 * entries would be sorted in the same order in which they are received by MAC 88 * HW. 89 * @list: List used for reordering 90 * @list_lock: Lock to protect the list 91 * @max_list_size: Maximum size of the reorder list 92 * @ageout_timer: Periodic timer to age-out the list entries 93 * @ts_latest_aged_out_frame: Stores the global time stamp for the latest aged 94 * out frame. Latest aged out frame is the aged out frame in reorder list which 95 * has the largest global time stamp value. 96 */ 97 struct mgmt_rx_reo_list { 98 qdf_list_t list; 99 qdf_spinlock_t list_lock; 100 uint32_t max_list_size; 101 qdf_timer_t ageout_timer; 102 struct mgmt_rx_reo_global_ts_info ts_latest_aged_out_frame; 103 }; 104 105 /* 106 * struct mgmt_rx_reo_wait_count - Wait count for a mgmt frame 107 * @per_link_count: Array of wait counts for all MLO links. Each array entry 108 * holds the number of frames this mgmt frame should wait for on that 109 * particular link. 110 * @total_count: Sum of entries in @per_link_count 111 */ 112 struct mgmt_rx_reo_wait_count { 113 unsigned int per_link_count[MGMT_RX_REO_MAX_LINKS]; 114 unsigned long long int total_count; 115 }; 116 117 /** 118 * struct mgmt_rx_reo_list_entry - Entry in the Management reorder list 119 * @node: List node 120 * @nbuf: nbuf corresponding to this frame 121 * @rx_params: Management rx event parameters 122 * @wait_count: Wait counts for the frame 123 * @insertion_ts: Host time stamp when this entry is inserted to 124 * the list. 125 * @status: Status for this entry 126 */ 127 struct mgmt_rx_reo_list_entry { 128 qdf_list_node_t node; 129 qdf_nbuf_t nbuf; 130 struct mgmt_rx_event_params *rx_params; 131 struct mgmt_rx_reo_wait_count wait_count; 132 uint64_t insertion_ts; 133 uint32_t status; 134 }; 135 136 /** 137 * struct mgmt_rx_reo_context - This structure holds the info required for 138 * management rx-reordering. Reordering is done across all the psocs. 139 * So there should be only one instance of this structure defined. 140 * @reo_list: Linked list used for reordering 141 * @ts_last_delivered_frame: Stores the global time stamp for the last frame 142 * delivered to the upper layer 143 * @num_mlo_links: Number of MLO links on the system 144 */ 145 struct mgmt_rx_reo_context { 146 struct mgmt_rx_reo_list reo_list; 147 struct mgmt_rx_reo_global_ts_info ts_last_delivered_frame; 148 uint8_t num_mlo_links; 149 }; 150 151 /** 152 * struct mgmt_rx_reo_frame_descriptor - Frame Descriptor used to describe 153 * a management frame in mgmt rx reo module. 154 * @type: Frame descriptor type 155 * @nbuf: nbuf corresponding to this frame 156 * @rx_params: Management rx event parameters 157 * @wait_count: Wait counts for the frame 158 */ 159 struct mgmt_rx_reo_frame_descriptor { 160 enum mgmt_rx_reo_frame_descriptor_type type; 161 qdf_nbuf_t nbuf; 162 struct mgmt_rx_event_params *rx_params; 163 struct mgmt_rx_reo_wait_count wait_count; 164 }; 165 166 /** 167 * mgmt_rx_reo_get_global_ts() - Helper API to get global time stamp 168 * corresponding to the mgmt rx event 169 * @rx_params: Management rx event params 170 * 171 * Return: global time stamp corresponding to the mgmt rx event 172 */ 173 static inline uint32_t 174 mgmt_rx_reo_get_global_ts(struct mgmt_rx_event_params *rx_params) 175 { 176 qdf_assert_always(rx_params); 177 qdf_assert_always(rx_params->reo_params); 178 179 return rx_params->reo_params->global_timestamp; 180 } 181 182 /** 183 * mgmt_rx_reo_get_pkt_counter() - Helper API to get packet counter 184 * corresponding to the mgmt rx event 185 * @rx_params: Management rx event params 186 * 187 * Return: Management packet counter corresponding to the mgmt rx event 188 */ 189 static inline uint16_t 190 mgmt_rx_reo_get_pkt_counter(struct mgmt_rx_event_params *rx_params) 191 { 192 qdf_assert_always(rx_params); 193 qdf_assert_always(rx_params->reo_params); 194 195 return rx_params->reo_params->mgmt_pkt_ctr; 196 } 197 198 /** 199 * mgmt_rx_reo_get_link_id() - Helper API to get link id corresponding to the 200 * mgmt rx event 201 * @rx_params: Management rx event params 202 * 203 * Return: link id corresponding to the mgmt rx event 204 */ 205 static inline uint8_t 206 mgmt_rx_reo_get_link_id(struct mgmt_rx_event_params *rx_params) 207 { 208 qdf_assert_always(rx_params); 209 qdf_assert_always(rx_params->reo_params); 210 211 return rx_params->reo_params->link_id; 212 } 213 214 /** 215 * mgmt_rx_reo_get_pdev_id() - Helper API to get pdev id corresponding to the 216 * mgmt rx event 217 * @rx_params: Management rx event params 218 * 219 * Return: pdev id corresponding to the mgmt rx event 220 */ 221 static inline uint8_t 222 mgmt_rx_reo_get_pdev_id(struct mgmt_rx_event_params *rx_params) 223 { 224 qdf_assert_always(rx_params); 225 qdf_assert_always(rx_params->reo_params); 226 227 return rx_params->reo_params->pdev_id; 228 } 229 230 /** 231 * mgmt_rx_reo_init_context() - Initialize the management rx-reorder context 232 * 233 * API to initialize the global management rx-reorder context object. 234 * 235 * Return: QDF_STATUS 236 */ 237 QDF_STATUS 238 mgmt_rx_reo_init_context(void); 239 240 /** 241 * mgmt_rx_reo_deinit_context() - De initialize the management rx-reorder 242 * context 243 * 244 * API to de initialize the global management rx-reorder context object. 245 * 246 * Return: QDF_STATUS 247 */ 248 QDF_STATUS 249 mgmt_rx_reo_deinit_context(void); 250 251 /** 252 * is_mgmt_rx_reo_required() - Whether MGMT REO required for this frame/event 253 * @pdev: pdev for which this frame/event is intended 254 * @desc: Descriptor corresponding to this frame/event 255 * 256 * Return: true if REO is required; else false 257 */ 258 static inline bool is_mgmt_rx_reo_required( 259 struct wlan_objmgr_pdev *pdev, 260 struct mgmt_rx_reo_frame_descriptor *desc) 261 { 262 /** 263 * TODO: Need to implement the actual policy based on WMI service bit. 264 * For now, returning false so that algorithm won't kick in on mainline. 265 */ 266 return false; 267 } 268 269 /** 270 * wlan_mgmt_rx_reo_algo_entry() - Entry point to the MGMT Rx REO algorithm for 271 * a given MGMT frame/event. 272 * @pdev: pdev for which this frame/event is intended 273 * @desc: Descriptor corresponding to this frame/event 274 * @is_queued: Whether this frame/event is queued in the REO list 275 * 276 * Return: QDF_STATUS of operation 277 */ 278 QDF_STATUS 279 wlan_mgmt_rx_reo_algo_entry(struct wlan_objmgr_pdev *pdev, 280 struct mgmt_rx_reo_frame_descriptor *desc, 281 bool *is_queued); 282 #endif /* WLAN_MGMT_RX_REO_SUPPORT */ 283 #endif /* _WLAN_MGMT_TXRX_RX_REO_I_H */ 284