diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mld/agg.h')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mld/agg.h | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/agg.h b/drivers/net/wireless/intel/iwlwifi/mld/agg.h new file mode 100644 index 000000000000..651c80d1c7cd --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (C) 2024 Intel Corporation + */ +#ifndef __iwl_agg_h__ +#define __iwl_agg_h__ + +#include "mld.h" +#include "fw/api/rx.h" + +/** + * struct iwl_mld_reorder_buffer - per ra/tid/queue reorder buffer + * @head_sn: reorder window head sequence number + * @num_stored: number of MPDUs stored in the buffer + * @queue: queue of this reorder buffer + * @valid: true if reordering is valid for this queue + */ +struct iwl_mld_reorder_buffer { + u16 head_sn; + u16 num_stored; + int queue; + bool valid; +} ____cacheline_aligned_in_smp; + +/** + * struct iwl_mld_reorder_buf_entry - reorder buffer entry per-queue/per-seqno + * @frames: list of skbs stored. a list is necessary because in an A-MSDU, + * all sub-frames share the same sequence number, so they are stored + * together in the same list. + */ +struct iwl_mld_reorder_buf_entry { + struct sk_buff_head frames; +} +#ifndef __CHECKER__ +/* sparse doesn't like this construct: "bad integer constant expression" */ +__aligned(roundup_pow_of_two(sizeof(struct sk_buff_head))) +#endif +; + +/** + * struct iwl_mld_baid_data - Block Ack session data + * @rcu_head: RCU head for freeing this data + * @sta_mask: station mask for the BAID + * @tid: tid of the session + * @baid: baid of the session + * @buf_size: the reorder buffer size as set by the last ADDBA request + * @entries_per_queue: number of buffers per queue, this actually gets + * aligned up to avoid cache line sharing between queues + * @timeout: the timeout value specified in the ADDBA request. + * @last_rx_timestamp: timestamp of the last received packet (in jiffies). This + * value is updated only when the configured @timeout has passed since + * the last update to minimize cache bouncing between RX queues. + * @session_timer: timer is set to expire after 2 * @timeout (since we want + * to minimize the cache bouncing by updating @last_rx_timestamp only once + * after @timeout has passed). If no packets are received within this + * period, it informs mac80211 to initiate delBA flow, terminating the + * BA session. + * @rcu_ptr: BA data RCU protected access + * @mld: mld pointer, needed for timer context + * @reorder_buf: reorder buffer, allocated per queue + * @entries: data + */ +struct iwl_mld_baid_data { + struct rcu_head rcu_head; + u32 sta_mask; + u8 tid; + u8 baid; + u16 buf_size; + u16 entries_per_queue; + u16 timeout; + struct timer_list session_timer; + unsigned long last_rx_timestamp; + struct iwl_mld_baid_data __rcu **rcu_ptr; + struct iwl_mld *mld; + struct iwl_mld_reorder_buffer reorder_buf[IWL_MAX_RX_HW_QUEUES]; + struct iwl_mld_reorder_buf_entry entries[] ____cacheline_aligned_in_smp; +}; + +/** + * struct iwl_mld_delba_data - RX queue sync data for %IWL_MLD_RXQ_NOTIF_DEL_BA + * + * @baid: Block Ack id, used to identify the BA session to be removed + */ +struct iwl_mld_delba_data { + u32 baid; +} __packed; + +/** + * enum iwl_mld_reorder_result - Possible return values for iwl_mld_reorder() + * indicating how the caller should handle the skb based on the result. + * + * @IWL_MLD_PASS_SKB: skb should be passed to upper layer. + * @IWL_MLD_BUFFERED_SKB: skb has been buffered, don't pass it to upper layer. + * @IWL_MLD_DROP_SKB: skb should be dropped and freed by the caller. + */ +enum iwl_mld_reorder_result { + IWL_MLD_PASS_SKB, + IWL_MLD_BUFFERED_SKB, + IWL_MLD_DROP_SKB +}; + +int iwl_mld_ampdu_rx_start(struct iwl_mld *mld, struct ieee80211_sta *sta, + int tid, u16 ssn, u16 buf_size, u16 timeout); +int iwl_mld_ampdu_rx_stop(struct iwl_mld *mld, struct ieee80211_sta *sta, + int tid); + +enum iwl_mld_reorder_result +iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi, + int queue, struct ieee80211_sta *sta, + struct sk_buff *skb, struct iwl_rx_mpdu_desc *desc); + +void iwl_mld_handle_frame_release_notif(struct iwl_mld *mld, + struct napi_struct *napi, + struct iwl_rx_packet *pkt, int queue); +void iwl_mld_handle_bar_frame_release_notif(struct iwl_mld *mld, + struct napi_struct *napi, + struct iwl_rx_packet *pkt, + int queue); + +void iwl_mld_del_ba(struct iwl_mld *mld, int queue, + struct iwl_mld_delba_data *data); + +int iwl_mld_update_sta_baids(struct iwl_mld *mld, + u32 old_sta_mask, + u32 new_sta_mask); + +#endif /* __iwl_agg_h__ */ |