lin
2025-07-31 065ea569db06206874bbfa18eb25ff6121aec09b
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
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/* SPDX-License-Identifier: GPL-2.0 */
 
/******************************************************************************
 *
 * Copyright (C) 2020 SeekWave Technology Co.,Ltd.
 *
 * 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 __SKW_RX_H__
#define __SKW_RX_H__
 
#include <net/ieee80211_radiotap.h>
 
#include "skw_platform_data.h"
#include "skw_iface.h"
#include "skw_core.h"
#include "skw_tx.h"
 
#define SKW_MAX_AMPDU_BUF_SIZE            0x100 /* 256 */
 
#define SKW_AMSDU_FLAG_TAINT              BIT(0)
#define SKW_AMSDU_FLAG_VALID              BIT(1)
 
#define SKW_SDIO_RX_DESC_HDR_OFFSET       0
#define SKW_SDIO_RX_DESC_MSDU_OFFSET      52
#define SKW_USB_RX_DESC_HDR_OFFSET        52
#define SKW_USB_RX_DESC_MSDU_OFFSET       0
#define SKW_PCIE_RX_DESC_HDR_OFFSET       44
#define SKW_PCIE_RX_DESC_MSDU_OFFSET      8
 
#ifndef ETH_P_80211_RAW
#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
#endif
 
enum SKW_RELEASE_REASON {
   SKW_RELEASE_INVALID,
   SKW_RELEASE_EXPIRED,
   SKW_RELEASE_OOB,
   SKW_RELEASE_BAR,
   SKW_RELEASE_FREE,
};
 
struct skw_skb_rxcb {
   unsigned long rx_time;
   u16 rx_desc_offset;
   u8 amsdu_bitmap;
   u8 amsdu_mask;
   u16 amsdu_flags;
   u8 skw_created;
   u8 lmac_id;
   u8 skip_replay_detect;
};
 
struct skw_drop_sn_info {
   u16 sn;
   u8 amsdu_idx;
   u8 amsdu_first: 1;
   u8 amsdu_last: 1;
   u8 is_amsdu: 1;
   u8 qos: 1;
   u8 tid: 4;
   u32 peer_idx: 5;
   u32 inst: 2;
   u32 resved: 25;
} __packed;
 
struct skw_rx_desc {
   /* word 13 */
   u16 eosp:1;
   u16 more_data:1;
   u16 pm:1;
   u16 retry_frame:1;
   u16 is_eof:1; //mpdu_eof_flag
   u16 ba_session:1;
   u16 resv1:1;
   u16 resv:1;
   u16 cipher:4;
   u16 snap_type:1;
   u16 vlan:1;
   u16 eapol:1;
   u16 rcv_in_ps_mode:1;
   u16 msdu_len;
 
   /* word 14 */
   u8 csum_valid:1;
   u8 is_ampdu:1;
   u8 snap_match:1;
   u8 is_amsdu:1;
   u8 is_qos_data:1;
   u8 amsdu_first_idx:1;
   u8 amsdu_last_idx:1;
   u8 mpdu_sniff:1;
   u16 csum;
   u8 msdu_filter;
 
   /* word 15 */
   u16 sn:12; /* seq number */
   u16 frag_num:4;
   u16 inst_id:2; //mpdu_ra_index
   u16 inst_id_valid:1;
   u16 more_frag:1;
   u16 peer_idx:5;
   u16 peer_idx_valid:1;
   u16 is_mc_addr:1; //bc_mc_flag
   u16 first_msdu_in_buff:1;
   u16 tid:4;
 
   /* word 16 & word17*/
   u8 pn[6];   //u16 msdu_len; //32:47
   u8 msdu_offset;
   u8 amsdu_idx:6;
   u16 need_forward:1;//da_ra_diff
   u16 mac_drop_frag:1;
} __packed;
 
struct skw_phy_rx_desc {
   /* word 8 */
   u32 lgacy_len:12;
   u32 psdu_len:20;
 
   /* word 9 */
   u32 flock_rssi0:11;
   u32 flock_rssi1:11;
   u32 lp_snr0:7;
   u32 nss:2;
   u32 sigb_dcm:1;
 
   /* word 10 */
   u32 full_rssi0:11;
   u32 full_rssi1:11;
   u32 lp_snr1:7;
   u32 sbw:3;
 
   /* word 11 */
   u8 agc_gain0;
   u8 agc_gain1;
   u8 ppdu_mode:4;
   u8 dcm:1;
   u8 gi_type:2;
   u8 fec_coding:1;
   u8 data_rate:6;
   u8 ess_n_est_ss:2;
 
   /* word 12 */
   u16 sta_id:11;
   u16 ru_size:3;
   u16 he_sigb_comp:1;
   u16 doppler:1;
   u16 sr4:4;
   u16 sr3:4;
   u16 sr2:4;
   u16 sr1:4;
 
   /* word 13 */
   u16 grp_id:6;
   u16 partial_aid:9;
   u16 befmed:1;
   u16 top_dura:14;
   u16 ltf_type:2;
 
   /* word 14 */
   u8 ch1_agc_gain0;
   u8 ch1_agc_gain1;
   u16 serv_field;
 
   /* word 15 */
   u32 sfo_ppm_init:24;
   u32 plcp_delay:8;
 
   /* word 16 */
   u32 slock_rssi0:11;
   u32 slock_rssi2:11;
   u32 nsts:2;
   u32 bss_color:6;
   u32 tgnf_flag0:1;
   u32 tgnf_flag1:1;
 
   /* word 17 */
   u8 ofdma:1;
   u8 mimo:1;
   u8 sifb_mcs:3;
   u8 pe_dur:3;
   u8 user_num:7;
   u8 stbc:1;
   u16 mu3_nsts:3;
   u16 mu2_nsts:3;
   u16 mu1_nsts:3;
   u16 mu0_nsts:3;
   u16 ltf_num:2;
   u16 mimo_ofdma:1;
   u16 resv8:1;
 
};
 
struct skw_sniffer_desc {
   u32 resv1;
   /* word 4 */
   u8 mac_hdr_proc:7;
   u8 sniff_flag:1;
   u8 mpdu_proc_status;
   u8 buf_num_mpdu;
   u8 mac_hdr_len:6;
   u8 dir_data_sniff:1;
   u8 resv2:1;
 
   /* word 5 */
   u16 mpdu_len:14;
   u16 resv3:2;
   u16 psdu_cnt;
 
   /* word 6 */
   u8 sniff_rsv_num;
   u8 resv4:1;
   u8 is_ampdu:1;
   u8 is_amsdu:1;
   u8 mpdu2host:1;
   u8 mpdu_defrag:1;
   u8 mpdu_uc:1;
   u8 mpdu_bc:1;
   u8 resv5:1;
   u8 peer_lut_idx:5;
   u8 peer_lut_idx_vaild:1;
   u8 resv6:2;
   u8 cipher:4;
   u8 inst_id:2; //mpdu_ra_index
   u8 inst_id_vaild:1;
   u8 resv7:1;
 
   /* word 7 */
   u16 sniff_status:12;
   u16 pad_len:4;
   u16 sn:12;
   u16 frag_num:4;
 
   /* word 8 - 17 */
   struct skw_phy_rx_desc phy_desc;
} __packed;
 
struct skw_radiotap_desc {
   struct ieee80211_radiotap_header radiotap_hdr;
   u8 radiotap_flag;
} __packed;
 
static inline void skw_snap_unmatch_handler(struct sk_buff *skb)
{
   skb_reset_mac_header(skb);
   eth_hdr(skb)->h_proto = htons(skb->len & 0xffff);
}
 
static inline void skw_event_add_credit(struct skw_core *skw, void *data)
{
   u16 *credit = data;
 
   skw_add_credit(skw, 0, *credit);
   skw_add_credit(skw, 1, *(credit + 1));
}
 
static inline void skw_data_add_credit(struct skw_core *skw, void *data)
{
}
 
static inline bool is_skw_monitor_data(struct skw_core *skw, void *data)
{
   struct skw_sniffer_desc *desc = NULL;
 
   if (skw->hw.bus == SKW_BUS_USB)
       desc = (struct skw_sniffer_desc *)((u8 *)(data + 12));    //offset word0 ~ word2
   else if (skw->hw.bus == SKW_BUS_SDIO)
       desc = (struct skw_sniffer_desc *)((u8 *)(data));
   else if (skw->hw.bus == SKW_BUS_PCIE) //TODO
       return false;
 
   if (!desc)
       return -EINVAL;
 
   skw_detail("sniffer flag:%d\n", desc->sniff_flag);
 
   if (desc->sniff_flag) {
       skw_detail("recv sniffer data, desc len:%ld\n", sizeof(struct skw_sniffer_desc));
       return true;
   }
 
   return false;
}
 
static inline struct skw_skb_rxcb *SKW_SKB_RXCB(struct sk_buff *skb)
{
   return (struct skw_skb_rxcb *)skb->cb;
}
 
int skw_add_tid_rx(struct skw_peer *peer, u16 tid, u16 ssn, u16 buf_size);
int skw_update_tid_rx(struct skw_peer *peer, u16 tid, u16 ssn, u16 win_size);
int skw_del_tid_rx(struct skw_peer *peer, u16 tid);
 
int skw_rx_process(struct skw_core *skw,
   struct sk_buff_head *rx_dat_q, struct skw_list *rx_todo_list);
void skw_rx_todo(struct skw_list *todo_list);
 
int skw_rx_init(struct skw_core *skw);
int skw_rx_deinit(struct skw_core *skw);
int skw_rx_cb(int port, struct scatterlist *sglist, int nents, void *priv);
int skw_register_rx_callback(struct skw_core *skw, void *cmd_cb, void *cmd_ctx,
           void *dat_cb, void *dat_ctx);
 
#endif