aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath12k/dp_rx.h
blob: 55a31e669b3b062ad8659257c0d5f51d0d65ed26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
 */
#ifndef ATH12K_DP_RX_H
#define ATH12K_DP_RX_H

#include "core.h"
#include "debug.h"

#define DP_MAX_NWIFI_HDR_LEN	30

struct ath12k_reoq_buf {
	void *vaddr;
	dma_addr_t paddr_aligned;
	u32 size;
};

struct ath12k_dp_rx_tid {
	u8 tid;
	u32 ba_win_sz;
	struct ath12k_reoq_buf qbuf;

	/* Info related to rx fragments */
	u32 cur_sn;
	u16 last_frag_no;
	u16 rx_frag_bitmap;

	struct sk_buff_head rx_frags;
	struct hal_reo_dest_ring *dst_ring_desc;

	/* Timer info related to fragments */
	struct timer_list frag_timer;
	struct ath12k_dp *dp;
};

struct ath12k_dp_rx_tid_rxq {
	u8 tid;
	bool active;
	struct ath12k_reoq_buf qbuf;
};

struct ath12k_dp_rx_reo_cache_flush_elem {
	struct list_head list;
	struct ath12k_dp_rx_tid_rxq data;
	unsigned long ts;
};

struct dp_reo_update_rx_queue_elem {
	struct list_head list;
	struct ath12k_dp_rx_tid_rxq rx_tid;
	int peer_id;
	bool is_ml_peer;
	u16 ml_peer_id;
};

struct ath12k_dp_rx_reo_cmd {
	struct list_head list;
	struct ath12k_dp_rx_tid_rxq data;
	int cmd_num;
	void (*handler)(struct ath12k_dp *dp, void *ctx,
			enum hal_reo_cmd_status status);
};

#define ATH12K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ)

#define ATH12K_DP_RX_REO_DESC_FREE_THRES  64
#define ATH12K_DP_RX_REO_DESC_FREE_TIMEOUT_MS 1000

enum ath12k_dp_rx_decap_type {
	DP_RX_DECAP_TYPE_RAW,
	DP_RX_DECAP_TYPE_NATIVE_WIFI,
	DP_RX_DECAP_TYPE_ETHERNET2_DIX,
	DP_RX_DECAP_TYPE_8023,
};

struct ath12k_dp_rx_rfc1042_hdr {
	u8 llc_dsap;
	u8 llc_ssap;
	u8 llc_ctrl;
	u8 snap_oui[3];
	__be16 snap_type;
} __packed;

static inline u32 ath12k_he_gi_to_nl80211_he_gi(u8 sgi)
{
	u32 ret = 0;

	switch (sgi) {
	case RX_MSDU_START_SGI_0_8_US:
		ret = NL80211_RATE_INFO_HE_GI_0_8;
		break;
	case RX_MSDU_START_SGI_1_6_US:
		ret = NL80211_RATE_INFO_HE_GI_1_6;
		break;
	case RX_MSDU_START_SGI_3_2_US:
		ret = NL80211_RATE_INFO_HE_GI_3_2;
		break;
	default:
		ret = NL80211_RATE_INFO_HE_GI_0_8;
		break;
	}

	return ret;
}

static inline bool ath12k_dp_rx_h_more_frags(struct ath12k_hal *hal,
					     struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr;

	hdr = (struct ieee80211_hdr *)(skb->data + hal->hal_desc_sz);
	return ieee80211_has_morefrags(hdr->frame_control);
}

static inline u16 ath12k_dp_rx_h_frag_no(struct ath12k_hal *hal,
					 struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr;

	hdr = (struct ieee80211_hdr *)(skb->data + hal->hal_desc_sz);
	return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
}

static inline u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab,
				      struct hal_rx_desc *desc)
{
	return ab->hal.ops->rx_desc_get_l3_pad_bytes(desc);
}

static inline void ath12k_dp_rx_desc_end_tlv_copy(struct ath12k_hal *hal,
						  struct hal_rx_desc *fdesc,
						  struct hal_rx_desc *ldesc)
{
	hal->ops->rx_desc_copy_end_tlv(fdesc, ldesc);
}

static inline void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_hal *hal,
						 struct hal_rx_desc *desc,
						 u16 len)
{
	hal->ops->rx_desc_set_msdu_len(desc, len);
}

static inline u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab,
					      struct hal_rx_desc *rx_desc)
{
	return ab->hal.ops->rx_desc_get_mpdu_ppdu_id(rx_desc);
}

static inline void ath12k_dp_rx_desc_get_dot11_hdr(struct ath12k_hal *hal,
						   struct hal_rx_desc *desc,
						   struct ieee80211_hdr *hdr)
{
	hal->ops->rx_desc_get_dot11_hdr(desc, hdr);
}

static inline void ath12k_dp_rx_desc_get_crypto_header(struct ath12k_hal *hal,
						       struct hal_rx_desc *desc,
						       u8 *crypto_hdr,
						       enum hal_encrypt_type enctype)
{
	hal->ops->rx_desc_get_crypto_header(desc, crypto_hdr, enctype);
}

static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_hal *hal,
						struct hal_rx_desc *desc)
{
	return hal->ops->rx_desc_get_msdu_src_link_id(desc);
}

static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list)
{
	struct sk_buff *skb;

	while ((skb = __skb_dequeue(skb_list)))
		dev_kfree_skb_any(skb);
}

static inline
void ath12k_dp_extract_rx_desc_data(struct ath12k_hal *hal,
				    struct hal_rx_desc_data *rx_info,
				    struct hal_rx_desc *rx_desc,
				    struct hal_rx_desc *ldesc)
{
	hal->ops->extract_rx_desc_data(rx_info, rx_desc, ldesc);
}

void ath12k_dp_rx_h_undecap(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
			    enum hal_encrypt_type enctype,
			    bool decrypted,
			    struct hal_rx_desc_data *rx_info);
void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struct *napi,
			       struct sk_buff *msdu,
			       struct hal_rx_desc_data *rx_info);
bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_dp *dp,
					    struct sk_buff *msdu,
					    struct hal_rx_desc_data *rx_info);
u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb);
void ath12k_dp_rx_h_sort_frags(struct ath12k_hal *hal,
			       struct sk_buff_head *frag_list,
			       struct sk_buff *cur_frag);
void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
				 enum hal_encrypt_type enctype, u32 flags);
int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
			     struct ieee80211_ampdu_params *params,
			     u8 link_id);
int ath12k_dp_rx_ampdu_stop(struct ath12k *ar,
			    struct ieee80211_ampdu_params *params,
			    u8 link_id);
int ath12k_dp_rx_peer_pn_replay_config(struct ath12k_link_vif *arvif,
				       const u8 *peer_addr,
				       enum set_key_cmd key_cmd,
				       struct ieee80211_key_conf *key);
void ath12k_dp_rx_peer_tid_cleanup(struct ath12k *ar, struct ath12k_dp_link_peer *peer);
void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar,
				  struct ath12k_dp_link_peer *peer, u8 tid);
int ath12k_dp_rx_peer_tid_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id,
				u8 tid, u32 ba_win_sz, u16 ssn,
				enum hal_pn_type pn_type);
int ath12k_dp_rx_pdev_reo_setup(struct ath12k_base *ab);
void ath12k_dp_rx_pdev_reo_cleanup(struct ath12k_base *ab);
int ath12k_dp_rx_htt_setup(struct ath12k_base *ab);
int ath12k_dp_rx_alloc(struct ath12k_base *ab);
void ath12k_dp_rx_free(struct ath12k_base *ab);
int ath12k_dp_rx_pdev_alloc(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_pdev_free(struct ath12k_base *ab, int pdev_idx);
void ath12k_dp_rx_reo_cmd_list_cleanup(struct ath12k_base *ab);
int ath12k_dp_rx_bufs_replenish(struct ath12k_dp *dp,
				struct dp_rxdma_ring *rx_ring,
				struct list_head *used_list,
				int req_entries);
int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar);
int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id);

u8 ath12k_dp_rx_h_l3pad(struct ath12k_base *ab,
			struct hal_rx_desc *desc);
struct ath12k_dp_link_peer *
ath12k_dp_rx_h_find_link_peer(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
			      struct hal_rx_desc_data *rx_info);
u8 ath12k_dp_rx_h_decap_type(struct ath12k_base *ab,
			     struct hal_rx_desc *desc);
u32 ath12k_dp_rx_h_mpdu_err(struct ath12k_base *ab,
			    struct hal_rx_desc *desc);
int ath12k_dp_rx_crypto_mic_len(struct ath12k_dp *dp, enum hal_encrypt_type enctype);
u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab,
				struct hal_rx_desc *rx_desc);
void ath12k_dp_rx_h_ppdu(struct ath12k_pdev_dp *dp_pdev,
			 struct hal_rx_desc_data *rx_info);
struct sk_buff *ath12k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_list,
					       struct sk_buff *first);
void ath12k_dp_reo_cmd_free(struct ath12k_dp *dp, void *ctx,
			    enum hal_reo_cmd_status status);
void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx,
			       enum hal_reo_cmd_status status);
void ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(struct ath12k_dp *dp);
void ath12k_dp_init_rx_tid_rxq(struct ath12k_dp_rx_tid_rxq *rx_tid_rxq,
			       struct ath12k_dp_rx_tid *rx_tid,
			       bool active);
void ath12k_dp_mark_tid_as_inactive(struct ath12k_dp *dp