1 | /* SPDX-License-Identifier: ISC */ |
2 | /* |
3 | * Copyright (c) 2012-2016,2018-2019, The Linux Foundation. All rights reserved. |
4 | */ |
5 | |
6 | #ifndef WIL6210_TXRX_EDMA_H |
7 | #define WIL6210_TXRX_EDMA_H |
8 | |
9 | #include "wil6210.h" |
10 | |
11 | /* limit status ring size in range [ring size..max ring size] */ |
12 | #define WIL_SRING_SIZE_ORDER_MIN (WIL_RING_SIZE_ORDER_MIN) |
13 | #define WIL_SRING_SIZE_ORDER_MAX (WIL_RING_SIZE_ORDER_MAX) |
14 | /* RX sring order should be bigger than RX ring order */ |
15 | #define WIL_RX_SRING_SIZE_ORDER_DEFAULT (12) |
16 | #define WIL_TX_SRING_SIZE_ORDER_DEFAULT (14) |
17 | #define WIL_RX_BUFF_ARR_SIZE_DEFAULT (2600) |
18 | |
19 | #define WIL_DEFAULT_RX_STATUS_RING_ID 0 |
20 | #define WIL_RX_DESC_RING_ID 0 |
21 | #define WIL_RX_STATUS_IRQ_IDX 0 |
22 | #define WIL_TX_STATUS_IRQ_IDX 1 |
23 | |
24 | #define WIL_EDMA_AGG_WATERMARK (0xffff) |
25 | #define WIL_EDMA_AGG_WATERMARK_POS (16) |
26 | |
27 | #define WIL_EDMA_IDLE_TIME_LIMIT_USEC (50) |
28 | #define WIL_EDMA_TIME_UNIT_CLK_CYCLES (330) /* fits 1 usec */ |
29 | |
30 | /* Error field */ |
31 | #define WIL_RX_EDMA_ERROR_MIC (1) |
32 | #define WIL_RX_EDMA_ERROR_KEY (2) /* Key missing */ |
33 | #define WIL_RX_EDMA_ERROR_REPLAY (3) |
34 | #define WIL_RX_EDMA_ERROR_AMSDU (4) |
35 | #define WIL_RX_EDMA_ERROR_FCS (7) |
36 | |
37 | #define WIL_RX_EDMA_ERROR_L3_ERR (BIT(0) | BIT(1)) |
38 | #define WIL_RX_EDMA_ERROR_L4_ERR (BIT(0) | BIT(1)) |
39 | |
40 | #define WIL_RX_EDMA_DLPF_LU_MISS_BIT BIT(11) |
41 | #define WIL_RX_EDMA_DLPF_LU_MISS_CID_TID_MASK 0x7 |
42 | #define WIL_RX_EDMA_DLPF_LU_HIT_CID_TID_MASK 0xf |
43 | |
44 | #define WIL_RX_EDMA_DLPF_LU_MISS_CID_POS 2 |
45 | #define WIL_RX_EDMA_DLPF_LU_HIT_CID_POS 4 |
46 | |
47 | #define WIL_RX_EDMA_DLPF_LU_MISS_TID_POS 5 |
48 | |
49 | #define WIL_RX_EDMA_MID_VALID_BIT BIT(20) |
50 | |
51 | #define WIL_EDMA_DESC_TX_MAC_CFG_0_QID_POS 16 |
52 | #define WIL_EDMA_DESC_TX_MAC_CFG_0_QID_LEN 6 |
53 | |
54 | #define WIL_EDMA_DESC_TX_CFG_EOP_POS 0 |
55 | #define WIL_EDMA_DESC_TX_CFG_EOP_LEN 1 |
56 | |
57 | #define WIL_EDMA_DESC_TX_CFG_TSO_DESC_TYPE_POS 3 |
58 | #define WIL_EDMA_DESC_TX_CFG_TSO_DESC_TYPE_LEN 2 |
59 | |
60 | #define WIL_EDMA_DESC_TX_CFG_SEG_EN_POS 5 |
61 | #define WIL_EDMA_DESC_TX_CFG_SEG_EN_LEN 1 |
62 | |
63 | #define WIL_EDMA_DESC_TX_CFG_INSERT_IP_CHKSUM_POS 6 |
64 | #define WIL_EDMA_DESC_TX_CFG_INSERT_IP_CHKSUM_LEN 1 |
65 | |
66 | #define WIL_EDMA_DESC_TX_CFG_INSERT_TCP_CHKSUM_POS 7 |
67 | #define WIL_EDMA_DESC_TX_CFG_INSERT_TCP_CHKSUM_LEN 1 |
68 | |
69 | #define WIL_EDMA_DESC_TX_CFG_L4_TYPE_POS 15 |
70 | #define WIL_EDMA_DESC_TX_CFG_L4_TYPE_LEN 1 |
71 | |
72 | #define 5 |
73 | #define 1 |
74 | |
75 | /* Enhanced Rx descriptor - MAC part |
76 | * [dword 0] : Reserved |
77 | * [dword 1] : Reserved |
78 | * [dword 2] : Reserved |
79 | * [dword 3] |
80 | * bit 0..15 : Buffer ID |
81 | * bit 16..31 : Reserved |
82 | */ |
83 | struct wil_ring_rx_enhanced_mac { |
84 | u32 d[3]; |
85 | __le16 buff_id; |
86 | u16 reserved; |
87 | } __packed; |
88 | |
89 | /* Enhanced Rx descriptor - DMA part |
90 | * [dword 0] - Reserved |
91 | * [dword 1] |
92 | * bit 0..31 : addr_low:32 The payload buffer address, bits 0-31 |
93 | * [dword 2] |
94 | * bit 0..15 : addr_high_low:16 The payload buffer address, bits 32-47 |
95 | * bit 16..31 : Reserved |
96 | * [dword 3] |
97 | * bit 0..15 : addr_high_high:16 The payload buffer address, bits 48-63 |
98 | * bit 16..31 : length |
99 | */ |
100 | struct wil_ring_rx_enhanced_dma { |
101 | u32 d0; |
102 | struct wil_ring_dma_addr addr; |
103 | u16 w5; |
104 | __le16 addr_high_high; |
105 | __le16 length; |
106 | } __packed; |
107 | |
108 | struct wil_rx_enhanced_desc { |
109 | struct wil_ring_rx_enhanced_mac mac; |
110 | struct wil_ring_rx_enhanced_dma dma; |
111 | } __packed; |
112 | |
113 | /* Enhanced Tx descriptor - DMA part |
114 | * [dword 0] |
115 | * Same as legacy |
116 | * [dword 1] |
117 | * bit 0..31 : addr_low:32 The payload buffer address, bits 0-31 |
118 | * [dword 2] |
119 | * bit 0..15 : addr_high_low:16 The payload buffer address, bits 32-47 |
120 | * bit 16..23 : ip_length:8 The IP header length for the TX IP checksum |
121 | * offload feature |
122 | * bit 24..30 : mac_length:7 |
123 | * bit 31 : ip_version:1 1 - IPv4, 0 - IPv6 |
124 | * [dword 3] |
125 | * bit 0..15 : addr_high_high:16 The payload buffer address, bits 48-63 |
126 | * bit 16..31 : length |
127 | */ |
128 | struct wil_ring_tx_enhanced_dma { |
129 | u8 l4_hdr_len; |
130 | u8 cmd; |
131 | u16 w1; |
132 | struct wil_ring_dma_addr addr; |
133 | u8 ip_length; |
134 | u8 b11; /* 0..6: mac_length; 7:ip_version */ |
135 | __le16 addr_high_high; |
136 | __le16 length; |
137 | } __packed; |
138 | |
139 | /* Enhanced Tx descriptor - MAC part |
140 | * [dword 0] |
141 | * bit 0.. 9 : lifetime_expiry_value:10 |
142 | * bit 10 : interrupt_en:1 |
143 | * bit 11 : status_en:1 |
144 | * bit 12..13 : txss_override:2 |
145 | * bit 14 : timestamp_insertion:1 |
146 | * bit 15 : duration_preserve:1 |
147 | * bit 16..21 : reserved0:6 |
148 | * bit 22..26 : mcs_index:5 |
149 | * bit 27 : mcs_en:1 |
150 | * bit 28..30 : reserved1:3 |
151 | * bit 31 : sn_preserved:1 |
152 | * [dword 1] |
153 | * bit 0.. 3 : pkt_mode:4 |
154 | * bit 4 : pkt_mode_en:1 |
155 | * bit 5..14 : reserved0:10 |
156 | * bit 15 : ack_policy_en:1 |
157 | * bit 16..19 : dst_index:4 |
158 | * bit 20 : dst_index_en:1 |
159 | * bit 21..22 : ack_policy:2 |
160 | * bit 23 : lifetime_en:1 |
161 | * bit 24..30 : max_retry:7 |
162 | * bit 31 : max_retry_en:1 |
163 | * [dword 2] |
164 | * bit 0.. 7 : num_of_descriptors:8 |
165 | * bit 8..17 : reserved:10 |
166 | * bit 18..19 : l2_translation_type:2 00 - bypass, 01 - 802.3, 10 - 802.11 |
167 | * bit 20 : snap_hdr_insertion_en:1 |
168 | * bit 21 : vlan_removal_en:1 |
169 | * bit 22..23 : reserved0:2 |
170 | * bit 24 : Dest ID extension:1 |
171 | * bit 25..31 : reserved0:7 |
172 | * [dword 3] |
173 | * bit 0..15 : tso_mss:16 |
174 | * bit 16..31 : descriptor_scratchpad:16 - mailbox between driver and ucode |
175 | */ |
176 | struct wil_ring_tx_enhanced_mac { |
177 | u32 d[3]; |
178 | __le16 tso_mss; |
179 | u16 scratchpad; |
180 | } __packed; |
181 | |
182 | struct wil_tx_enhanced_desc { |
183 | struct wil_ring_tx_enhanced_mac mac; |
184 | struct wil_ring_tx_enhanced_dma dma; |
185 | } __packed; |
186 | |
187 | #define TX_STATUS_DESC_READY_POS 7 |
188 | |
189 | /* Enhanced TX status message |
190 | * [dword 0] |
191 | * bit 0.. 7 : Number of Descriptor:8 - The number of descriptors that |
192 | * are used to form the packets. It is needed for WB when |
193 | * releasing the packet |
194 | * bit 8..15 : tx_ring_id:8 The transmission ring ID that is related to |
195 | * the message |
196 | * bit 16..23 : Status:8 - The TX status Code |
197 | * 0x0 - A successful transmission |
198 | * 0x1 - Retry expired |
199 | * 0x2 - Lifetime Expired |
200 | * 0x3 - Released |
201 | * 0x4-0xFF - Reserved |
202 | * bit 24..30 : Reserved:7 |
203 | * bit 31 : Descriptor Ready bit:1 - It is initiated to |
204 | * zero by the driver when the ring is created. It is set by the HW |
205 | * to one for each completed status message. Each wrap around, |
206 | * the DR bit value is flipped. |
207 | * [dword 1] |
208 | * bit 0..31 : timestamp:32 - Set when MPDU is transmitted. |
209 | * [dword 2] |
210 | * bit 0.. 4 : MCS:5 - The transmitted MCS value |
211 | * bit 5 : Reserved:1 |
212 | * bit 6.. 7 : CB mode:2 - 0-DMG 1-EDMG 2-Wide |
213 | * bit 8..12 : QID:5 - The QID that was used for the transmission |
214 | * bit 13..15 : Reserved:3 |
215 | * bit 16..20 : Num of MSDUs:5 - Number of MSDUs in the aggregation |
216 | * bit 21..22 : Reserved:2 |
217 | * bit 23 : Retry:1 - An indication that the transmission was retried |
218 | * bit 24..31 : TX-Sector:8 - the antenna sector that was used for |
219 | * transmission |
220 | * [dword 3] |
221 | * bit 0..11 : Sequence number:12 - The Sequence Number that was used |
222 | * for the MPDU transmission |
223 | * bit 12..31 : Reserved:20 |
224 | */ |
225 | struct wil_ring_tx_status { |
226 | u8 num_descriptors; |
227 | u8 ring_id; |
228 | u8 status; |
229 | u8 desc_ready; /* Only the last bit should be set */ |
230 | u32 timestamp; |
231 | u32 d2; |
232 | u16 seq_number; /* Only the first 12 bits */ |
233 | u16 w7; |
234 | } __packed; |
235 | |
236 | /* Enhanced Rx status message - compressed part |
237 | * [dword 0] |
238 | * bit 0.. 2 : L2 Rx Status:3 - The L2 packet reception Status |
239 | * 0-Success, 1-MIC Error, 2-Key Error, 3-Replay Error, |
240 | * 4-A-MSDU Error, 5-Reserved, 6-Reserved, 7-FCS Error |
241 | * bit 3.. 4 : L3 Rx Status:2 - Bit0 - L3I - L3 identified and checksum |
242 | * calculated, Bit1- L3Err - IPv4 Checksum Error |
243 | * bit 5.. 6 : L4 Rx Status:2 - Bit0 - L4I - L4 identified and checksum |
244 | * calculated, Bit1- L4Err - TCP/UDP Checksum Error |
245 | * bit 7 : Reserved:1 |
246 | * bit 8..19 : Flow ID:12 - MSDU flow ID |
247 | * bit 20 : MID_V:1 - The MAC ID field is valid |
248 | * bit 21..22 : MID:2 - The MAC ID |
249 | * bit 23 : L3T:1 - IP types: 0-IPv6, 1-IPv4 |
250 | * bit 24 : L4T:1 - Layer 4 Type: 0-UDP, 1-TCP |
251 | * bit 25 : BC:1 - The received MPDU is broadcast |
252 | * bit 26 : MC:1 - The received MPDU is multicast |
253 | * bit 27 : Raw:1 - The MPDU received with no translation |
254 | * bit 28 : Sec:1 - The FC control (b14) - Frame Protected |
255 | * bit 29 : Error:1 - An error is set when (L2 status != 0) || |
256 | * (L3 status == 3) || (L4 status == 3) |
257 | * bit 30 : EOP:1 - End of MSDU signaling. It is set to mark the end |
258 | * of the transfer, otherwise the status indicates buffer |
259 | * only completion. |
260 | * bit 31 : Descriptor Ready bit:1 - It is initiated to |
261 | * zero by the driver when the ring is created. It is set |
262 | * by the HW to one for each completed status message. |
263 | * Each wrap around, the DR bit value is flipped. |
264 | * [dword 1] |
265 | * bit 0.. 5 : MAC Len:6 - The number of bytes that are used for L2 header |
266 | * bit 6..11 : IPLEN:6 - The number of DW that are used for L3 header |
267 | * bit 12..15 : I4Len:4 - The number of DW that are used for L4 header |
268 | * bit 16..21 : MCS:6 - The received MCS field from the PLCP Header |
269 | * bit 22..23 : CB mode:2 - The CB Mode: 0-DMG, 1-EDMG, 2-Wide |
270 | * bit 24..27 : Data Offset:4 - The data offset, a code that describe the |
271 | * payload shift from the beginning of the buffer: |
272 | * 0 - 0 Bytes, 3 - 2 Bytes |
273 | * bit 28 : A-MSDU Present:1 - The QoS (b7) A-MSDU present field |
274 | * bit 29 : A-MSDU Type:1 The QoS (b8) A-MSDU Type field |
275 | * bit 30 : A-MPDU:1 - Packet is part of aggregated MPDU |
276 | * bit 31 : Key ID:1 - The extracted Key ID from the encryption header |
277 | * [dword 2] |
278 | * bit 0..15 : Buffer ID:16 - The Buffer Identifier |
279 | * bit 16..31 : Length:16 - It indicates the valid bytes that are stored |
280 | * in the current descriptor buffer. For multiple buffer |
281 | * descriptor, SW need to sum the total descriptor length |
282 | * in all buffers to produce the packet length |
283 | * [dword 3] |
284 | * bit 0..31 : timestamp:32 - The MPDU Timestamp. |
285 | */ |
286 | struct wil_rx_status_compressed { |
287 | u32 d0; |
288 | u32 d1; |
289 | __le16 buff_id; |
290 | __le16 length; |
291 | u32 timestamp; |
292 | } __packed; |
293 | |
294 | /* Enhanced Rx status message - extension part |
295 | * [dword 0] |
296 | * bit 0.. 4 : QID:5 - The Queue Identifier that the packet is received |
297 | * from |
298 | * bit 5.. 7 : Reserved:3 |
299 | * bit 8..11 : TID:4 - The QoS (b3-0) TID Field |
300 | * bit 12..15 Source index:4 - The Source index that was found |
301 | during Parsing the TA. This field is used to define the |
302 | source of the packet |
303 | * bit 16..18 : Destination index:3 - The Destination index that |
304 | was found during Parsing the RA. |
305 | * bit 19..20 : DS Type:2 - The FC Control (b9-8) - From / To DS |
306 | * bit 21..22 : MIC ICR:2 - this signal tells the DMA to assert an |
307 | interrupt after it writes the packet |
308 | * bit 23 : ESOP:1 - The QoS (b4) ESOP field |
309 | * bit 24 : RDG:1 |
310 | * bit 25..31 : Reserved:7 |
311 | * [dword 1] |
312 | * bit 0.. 1 : Frame Type:2 - The FC Control (b3-2) - MPDU Type |
313 | (management, data, control and extension) |
314 | * bit 2.. 5 : Syb type:4 - The FC Control (b7-4) - Frame Subtype |
315 | * bit 6..11 : Ext sub type:6 - The FC Control (b11-8) - Frame Extended |
316 | * Subtype |
317 | * bit 12..13 : ACK Policy:2 - The QoS (b6-5) ACK Policy fields |
318 | * bit 14 : DECRYPT_BYP:1 - The MPDU is bypass by the decryption unit |
319 | * bit 15..23 : Reserved:9 |
320 | * bit 24..31 : RSSI/SNR:8 - The RSSI / SNR measurement for the received |
321 | * MPDU |
322 | * [dword 2] |
323 | * bit 0..11 : SN:12 - The received Sequence number field |
324 | * bit 12..15 : Reserved:4 |
325 | * bit 16..31 : PN bits [15:0]:16 |
326 | * [dword 3] |
327 | * bit 0..31 : PN bits [47:16]:32 |
328 | */ |
329 | struct wil_rx_status_extension { |
330 | u32 d0; |
331 | u32 d1; |
332 | __le16 seq_num; /* only lower 12 bits */ |
333 | struct_group_attr(pn, __packed, |
334 | u16 pn_15_0; |
335 | u32 pn_47_16; |
336 | ); |
337 | } __packed; |
338 | |
339 | struct wil_rx_status_extended { |
340 | struct wil_rx_status_compressed comp; |
341 | struct wil_rx_status_extension ext; |
342 | } __packed; |
343 | |
344 | static inline void *wil_skb_rxstatus(struct sk_buff *skb) |
345 | { |
346 | return (void *)skb->cb; |
347 | } |
348 | |
349 | static inline __le16 wil_rx_status_get_length(void *msg) |
350 | { |
351 | return ((struct wil_rx_status_compressed *)msg)->length; |
352 | } |
353 | |
354 | static inline u8 wil_rx_status_get_mcs(void *msg) |
355 | { |
356 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d1, |
357 | b0: 16, b1: 21); |
358 | } |
359 | |
360 | static inline u8 wil_rx_status_get_cb_mode(void *msg) |
361 | { |
362 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d1, |
363 | b0: 22, b1: 23); |
364 | } |
365 | |
366 | static inline u16 wil_rx_status_get_flow_id(void *msg) |
367 | { |
368 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
369 | b0: 8, b1: 19); |
370 | } |
371 | |
372 | static inline u8 wil_rx_status_get_mcast(void *msg) |
373 | { |
374 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
375 | b0: 26, b1: 26); |
376 | } |
377 | |
378 | /** |
379 | * In case of DLPF miss the parsing of flow Id should be as follows: |
380 | * dest_id:2 |
381 | * src_id :3 - cid |
382 | * tid:3 |
383 | * Otherwise: |
384 | * tid:4 |
385 | * cid:4 |
386 | */ |
387 | |
388 | static inline u8 wil_rx_status_get_cid(void *msg) |
389 | { |
390 | u16 val = wil_rx_status_get_flow_id(msg); |
391 | |
392 | if (val & WIL_RX_EDMA_DLPF_LU_MISS_BIT) |
393 | /* CID is in bits 2..4 */ |
394 | return (val >> WIL_RX_EDMA_DLPF_LU_MISS_CID_POS) & |
395 | WIL_RX_EDMA_DLPF_LU_MISS_CID_TID_MASK; |
396 | else |
397 | /* CID is in bits 4..7 */ |
398 | return (val >> WIL_RX_EDMA_DLPF_LU_HIT_CID_POS) & |
399 | WIL_RX_EDMA_DLPF_LU_HIT_CID_TID_MASK; |
400 | } |
401 | |
402 | static inline u8 wil_rx_status_get_tid(void *msg) |
403 | { |
404 | u16 val = wil_rx_status_get_flow_id(msg); |
405 | |
406 | if (val & WIL_RX_EDMA_DLPF_LU_MISS_BIT) |
407 | /* TID is in bits 5..7 */ |
408 | return (val >> WIL_RX_EDMA_DLPF_LU_MISS_TID_POS) & |
409 | WIL_RX_EDMA_DLPF_LU_MISS_CID_TID_MASK; |
410 | else |
411 | /* TID is in bits 0..3 */ |
412 | return val & WIL_RX_EDMA_DLPF_LU_MISS_CID_TID_MASK; |
413 | } |
414 | |
415 | static inline int wil_rx_status_get_eop(void *msg) /* EoP = End of Packet */ |
416 | { |
417 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
418 | b0: 30, b1: 30); |
419 | } |
420 | |
421 | static inline void wil_rx_status_reset_buff_id(struct wil_status_ring *s) |
422 | { |
423 | ((struct wil_rx_status_compressed *) |
424 | (s->va + (s->elem_size * s->swhead)))->buff_id = 0; |
425 | } |
426 | |
427 | static inline __le16 wil_rx_status_get_buff_id(void *msg) |
428 | { |
429 | return ((struct wil_rx_status_compressed *)msg)->buff_id; |
430 | } |
431 | |
432 | static inline u8 wil_rx_status_get_data_offset(void *msg) |
433 | { |
434 | u8 val = WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d1, |
435 | b0: 24, b1: 27); |
436 | |
437 | switch (val) { |
438 | case 0: return 0; |
439 | case 3: return 2; |
440 | default: return 0xFF; |
441 | } |
442 | } |
443 | |
444 | static inline int wil_rx_status_get_frame_type(struct wil6210_priv *wil, |
445 | void *msg) |
446 | { |
447 | if (wil->use_compressed_rx_status) |
448 | return IEEE80211_FTYPE_DATA; |
449 | |
450 | return WIL_GET_BITS(x: ((struct wil_rx_status_extended *)msg)->ext.d1, |
451 | b0: 0, b1: 1) << 2; |
452 | } |
453 | |
454 | static inline int wil_rx_status_get_fc1(struct wil6210_priv *wil, void *msg) |
455 | { |
456 | if (wil->use_compressed_rx_status) |
457 | return 0; |
458 | |
459 | return WIL_GET_BITS(x: ((struct wil_rx_status_extended *)msg)->ext.d1, |
460 | b0: 0, b1: 5) << 2; |
461 | } |
462 | |
463 | static inline __le16 wil_rx_status_get_seq(struct wil6210_priv *wil, void *msg) |
464 | { |
465 | if (wil->use_compressed_rx_status) |
466 | return 0; |
467 | |
468 | return ((struct wil_rx_status_extended *)msg)->ext.seq_num; |
469 | } |
470 | |
471 | static inline u8 wil_rx_status_get_retry(void *msg) |
472 | { |
473 | /* retry bit is missing in EDMA HW. return 1 to be on the safe side */ |
474 | return 1; |
475 | } |
476 | |
477 | static inline int wil_rx_status_get_mid(void *msg) |
478 | { |
479 | if (!(((struct wil_rx_status_compressed *)msg)->d0 & |
480 | WIL_RX_EDMA_MID_VALID_BIT)) |
481 | return 0; /* use the default MID */ |
482 | |
483 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
484 | b0: 21, b1: 22); |
485 | } |
486 | |
487 | static inline int wil_rx_status_get_error(void *msg) |
488 | { |
489 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
490 | b0: 29, b1: 29); |
491 | } |
492 | |
493 | static inline int wil_rx_status_get_l2_rx_status(void *msg) |
494 | { |
495 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
496 | b0: 0, b1: 2); |
497 | } |
498 | |
499 | static inline int wil_rx_status_get_l3_rx_status(void *msg) |
500 | { |
501 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
502 | b0: 3, b1: 4); |
503 | } |
504 | |
505 | static inline int wil_rx_status_get_l4_rx_status(void *msg) |
506 | { |
507 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
508 | b0: 5, b1: 6); |
509 | } |
510 | |
511 | /* L4 L3 Expected result |
512 | * 0 0 Ok. No L3 and no L4 known protocols found. |
513 | * Treated as L2 packet. (no offloads on this packet) |
514 | * 0 1 Ok. It means that L3 was found, and checksum check passed. |
515 | * No known L4 protocol was found. |
516 | * 0 2 It means that L3 protocol was found, and checksum check failed. |
517 | * No L4 known protocol was found. |
518 | * 1 any Ok. It means that L4 was found, and checksum check passed. |
519 | * 3 0 Not a possible scenario. |
520 | * 3 1 Recalculate. It means that L3 protocol was found, and checksum |
521 | * passed. But L4 checksum failed. Need to see if really failed, |
522 | * or due to fragmentation. |
523 | * 3 2 Both L3 and L4 checksum check failed. |
524 | */ |
525 | static inline int wil_rx_status_get_checksum(void *msg, |
526 | struct wil_net_stats *stats) |
527 | { |
528 | int l3_rx_status = wil_rx_status_get_l3_rx_status(msg); |
529 | int l4_rx_status = wil_rx_status_get_l4_rx_status(msg); |
530 | |
531 | if (l4_rx_status == 1) |
532 | return CHECKSUM_UNNECESSARY; |
533 | |
534 | if (l4_rx_status == 0 && l3_rx_status == 1) |
535 | return CHECKSUM_UNNECESSARY; |
536 | |
537 | if (l3_rx_status == 0 && l4_rx_status == 0) |
538 | /* L2 packet */ |
539 | return CHECKSUM_NONE; |
540 | |
541 | /* If HW reports bad checksum, let IP stack re-check it |
542 | * For example, HW doesn't understand Microsoft IP stack that |
543 | * mis-calculates TCP checksum - if it should be 0x0, |
544 | * it writes 0xffff in violation of RFC 1624 |
545 | */ |
546 | stats->rx_csum_err++; |
547 | return CHECKSUM_NONE; |
548 | } |
549 | |
550 | static inline int wil_rx_status_get_security(void *msg) |
551 | { |
552 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d0, |
553 | b0: 28, b1: 28); |
554 | } |
555 | |
556 | static inline u8 wil_rx_status_get_key_id(void *msg) |
557 | { |
558 | return WIL_GET_BITS(x: ((struct wil_rx_status_compressed *)msg)->d1, |
559 | b0: 31, b1: 31); |
560 | } |
561 | |
562 | static inline u8 wil_tx_status_get_mcs(struct wil_ring_tx_status *msg) |
563 | { |
564 | return WIL_GET_BITS(x: msg->d2, b0: 0, b1: 4); |
565 | } |
566 | |
567 | static inline u32 wil_ring_next_head(struct wil_ring *ring) |
568 | { |
569 | return (ring->swhead + 1) % ring->size; |
570 | } |
571 | |
572 | static inline void wil_desc_set_addr_edma(struct wil_ring_dma_addr *addr, |
573 | __le16 *addr_high_high, |
574 | dma_addr_t pa) |
575 | { |
576 | addr->addr_low = cpu_to_le32(lower_32_bits(pa)); |
577 | addr->addr_high = cpu_to_le16((u16)upper_32_bits(pa)); |
578 | *addr_high_high = cpu_to_le16((u16)(upper_32_bits(pa) >> 16)); |
579 | } |
580 | |
581 | static inline |
582 | dma_addr_t wil_tx_desc_get_addr_edma(struct wil_ring_tx_enhanced_dma *dma) |
583 | { |
584 | return le32_to_cpu(dma->addr.addr_low) | |
585 | ((u64)le16_to_cpu(dma->addr.addr_high) << 32) | |
586 | ((u64)le16_to_cpu(dma->addr_high_high) << 48); |
587 | } |
588 | |
589 | static inline |
590 | dma_addr_t wil_rx_desc_get_addr_edma(struct wil_ring_rx_enhanced_dma *dma) |
591 | { |
592 | return le32_to_cpu(dma->addr.addr_low) | |
593 | ((u64)le16_to_cpu(dma->addr.addr_high) << 32) | |
594 | ((u64)le16_to_cpu(dma->addr_high_high) << 48); |
595 | } |
596 | |
597 | void wil_configure_interrupt_moderation_edma(struct wil6210_priv *wil); |
598 | int wil_tx_sring_handler(struct wil6210_priv *wil, |
599 | struct wil_status_ring *sring); |
600 | void wil_rx_handle_edma(struct wil6210_priv *wil, int *quota); |
601 | void wil_init_txrx_ops_edma(struct wil6210_priv *wil); |
602 | |
603 | #endif /* WIL6210_TXRX_EDMA_H */ |
604 | |
605 | |