net/iavf: fix potential out-of-bounds access
[dpdk.git] / drivers / common / cnxk / roc_ie_ot.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2022 Marvell.
3  */
4
5 #ifndef __ROC_IE_OT_H__
6 #define __ROC_IE_OT_H__
7
8 /* CN10K IPSEC opcodes */
9 #define ROC_IE_OT_MAJOR_OP_PROCESS_OUTBOUND_IPSEC 0x28UL
10 #define ROC_IE_OT_MAJOR_OP_PROCESS_INBOUND_IPSEC  0x29UL
11
12 #define ROC_IE_OT_MAJOR_OP_WRITE_SA 0x01UL
13 #define ROC_IE_OT_MINOR_OP_WRITE_SA 0x09UL
14
15 #define ROC_IE_OT_CTX_ILEN 2
16 /* PKIND to be used for CPT Meta parsing */
17 #define ROC_IE_OT_CPT_PKIND       58
18 #define ROC_IE_OT_SA_CTX_HDR_SIZE 1
19
20 enum roc_ie_ot_ucc_ipsec {
21         ROC_IE_OT_UCC_SUCCESS = 0x00,
22         ROC_IE_OT_UCC_ERR_SA_INVAL = 0xb0,
23         ROC_IE_OT_UCC_ERR_SA_EXPIRED = 0xb1,
24         ROC_IE_OT_UCC_ERR_SA_OVERFLOW = 0xb2,
25         ROC_IE_OT_UCC_ERR_SA_ESP_BAD_ALGO = 0xb3,
26         ROC_IE_OT_UCC_ERR_SA_AH_BAD_ALGO = 0xb4,
27         ROC_IE_OT_UCC_ERR_SA_BAD_CTX = 0xb5,
28         ROC_IE_OT_UCC_SA_CTX_FLAG_MISMATCH = 0xb6,
29         ROC_IE_OT_UCC_ERR_AOP_IPSEC = 0xb7,
30         ROC_IE_OT_UCC_ERR_PKT_IP = 0xb8,
31         ROC_IE_OT_UCC_ERR_PKT_IP6_BAD_EXT = 0xb9,
32         ROC_IE_OT_UCC_ERR_PKT_IP6_HBH = 0xba,
33         ROC_IE_OT_UCC_ERR_PKT_IP6_BIGEXT = 0xbb,
34         ROC_IE_OT_UCC_ERR_PKT_IP_ULP = 0xbc,
35         ROC_IE_OT_UCC_ERR_PKT_SA_MISMATCH = 0xbd,
36         ROC_IE_OT_UCC_ERR_PKT_SPI_MISMATCH = 0xbe,
37         ROC_IE_OT_UCC_ERR_PKT_ESP_BADPAD = 0xbf,
38         ROC_IE_OT_UCC_ERR_PKT_BADICV = 0xc0,
39         ROC_IE_OT_UCC_ERR_PKT_REPLAY_SEQ = 0xc1,
40         ROC_IE_OT_UCC_ERR_PKT_BADNH = 0xc2,
41         ROC_IE_OT_UCC_ERR_PKT_SA_PORT_MISMATCH = 0xc3,
42         ROC_IE_OT_UCC_ERR_PKT_BAD_DLEN = 0xc4,
43         ROC_IE_OT_UCC_ERR_SA_ESP_BAD_KEYS = 0xc5,
44         ROC_IE_OT_UCC_ERR_SA_AH_BAD_KEYS = 0xc6,
45         ROC_IE_OT_UCC_ERR_SA_BAD_IP = 0xc7,
46         ROC_IE_OT_UCC_ERR_PKT_IP_FRAG = 0xc8,
47         ROC_IE_OT_UCC_ERR_PKT_REPLAY_WINDOW = 0xc9,
48         ROC_IE_OT_UCC_SUCCESS_SA_SOFTEXP_FIRST = 0xf0,
49         ROC_IE_OT_UCC_SUCCESS_PKT_IP_BADCSUM = 0xf1,
50         ROC_IE_OT_UCC_SUCCESS_SA_SOFTEXP_AGAIN = 0xf2,
51         ROC_IE_OT_UCC_SUCCESS_PKT_L4_GOODCSUM = 0xf3,
52         ROC_IE_OT_UCC_SUCCESS_PKT_L4_BADCSUM = 0xf4,
53         ROC_IE_OT_UCC_SUCCESS_PKT_UDPESP_NZCSUM = 0xf5,
54         ROC_IE_OT_UCC_SUCCESS_PKT_UDP_ZEROCSUM = 0xf6,
55         ROC_IE_OT_UCC_SUCCESS_PKT_IP_GOODCSUM = 0xf7,
56 };
57
58 enum {
59         ROC_IE_OT_SA_AR_WIN_DISABLED = 0,
60         ROC_IE_OT_SA_AR_WIN_64 = 1,
61         ROC_IE_OT_SA_AR_WIN_128 = 2,
62         ROC_IE_OT_SA_AR_WIN_256 = 3,
63         ROC_IE_OT_SA_AR_WIN_512 = 4,
64         ROC_IE_OT_SA_AR_WIN_1024 = 5,
65         ROC_IE_OT_SA_AR_WIN_2048 = 6,
66         ROC_IE_OT_SA_AR_WIN_4096 = 7,
67 };
68
69 enum {
70         ROC_IE_OT_SA_PKT_FMT_FULL = 0,
71         ROC_IE_OT_SA_PKT_FMT_META = 1,
72 };
73
74 enum {
75         ROC_IE_OT_SA_PKT_OUTPUT_DECRYPTED = 0,
76         ROC_IE_OT_SA_PKT_OUTPUT_NO_FRAG = 1,
77         ROC_IE_OT_SA_PKT_OUTPUT_HW_BASED_DEFRAG = 2,
78         ROC_IE_OT_SA_PKT_OUTPUT_UCODE_BASED_DEFRAG = 3,
79 };
80
81 enum {
82         ROC_IE_OT_SA_DEFRAG_ALL = 0,
83         ROC_IE_OT_SA_DEFRAG_IN_ORDER = 1,
84         ROC_IE_OT_SA_DEFRAG_IN_REV_ORDER = 2,
85 };
86
87 enum {
88         ROC_IE_OT_SA_IV_SRC_DEFAULT = 0,
89         ROC_IE_OT_SA_IV_SRC_ENC_CTR = 1,
90         ROC_IE_OT_SA_IV_SRC_FROM_SA = 2,
91 };
92
93 enum {
94         ROC_IE_OT_SA_COPY_FROM_SA = 0,
95         ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR = 1,
96 };
97
98 enum {
99         ROC_IE_OT_SA_INNER_PKT_IP_CSUM_ENABLE = 0,
100         ROC_IE_OT_SA_INNER_PKT_IP_CSUM_DISABLE = 1,
101 };
102
103 enum {
104         ROC_IE_OT_SA_INNER_PKT_L4_CSUM_ENABLE = 0,
105         ROC_IE_OT_SA_INNER_PKT_L4_CSUM_DISABLE = 1,
106 };
107
108 enum {
109         ROC_IE_OT_SA_ENC_NULL = 0,
110         ROC_IE_OT_SA_ENC_3DES_CBC = 2,
111         ROC_IE_OT_SA_ENC_AES_CBC = 3,
112         ROC_IE_OT_SA_ENC_AES_CTR = 4,
113         ROC_IE_OT_SA_ENC_AES_GCM = 5,
114         ROC_IE_OT_SA_ENC_AES_CCM = 6,
115 };
116
117 enum {
118         ROC_IE_OT_SA_AUTH_NULL = 0,
119         ROC_IE_OT_SA_AUTH_SHA1 = 2,
120         ROC_IE_OT_SA_AUTH_SHA2_256 = 4,
121         ROC_IE_OT_SA_AUTH_SHA2_384 = 5,
122         ROC_IE_OT_SA_AUTH_SHA2_512 = 6,
123         ROC_IE_OT_SA_AUTH_AES_GMAC = 7,
124         ROC_IE_OT_SA_AUTH_AES_XCBC_128 = 8,
125 };
126
127 enum {
128         ROC_IE_OT_SA_ENCAP_NONE = 0,
129         ROC_IE_OT_SA_ENCAP_UDP = 1,
130         ROC_IE_OT_SA_ENCAP_TCP = 2,
131 };
132
133 enum {
134         ROC_IE_OT_SA_LIFE_UNIT_OCTETS = 0,
135         ROC_IE_OT_SA_LIFE_UNIT_PKTS = 1,
136 };
137
138 enum {
139         ROC_IE_OT_SA_IP_HDR_VERIFY_DISABLED = 0,
140         ROC_IE_OT_SA_IP_HDR_VERIFY_DST_ADDR = 1,
141         ROC_IE_OT_SA_IP_HDR_VERIFY_SRC_DST_ADDR = 2,
142 };
143
144 enum {
145         ROC_IE_OT_REAS_STS_SUCCESS = 0,
146         ROC_IE_OT_REAS_STS_TIMEOUT = 1,
147         ROC_IE_OT_REAS_STS_EVICT = 2,
148         ROC_IE_OT_REAS_STS_BAD_ORDER = 3,
149         ROC_IE_OT_REAS_STS_TOO_MANY = 4,
150         ROC_IE_OT_REAS_STS_HSH_EVICT = 5,
151         ROC_IE_OT_REAS_STS_OVERLAP = 6,
152         ROC_IE_OT_REAS_STS_ZOMBIE = 7,
153         ROC_IE_OT_REAS_STS_L3P_ERR = 8,
154         ROC_IE_OT_REAS_STS_MAX = 9
155 };
156
157 enum {
158         ROC_IE_OT_ERR_CTL_MODE_NONE = 0,
159         ROC_IE_OT_ERR_CTL_MODE_CLEAR = 1,
160         ROC_IE_OT_ERR_CTL_MODE_RING = 2,
161 };
162
163 /* Context units in bytes */
164 #define ROC_CTX_UNIT_8B           8
165 #define ROC_CTX_UNIT_128B         128
166 #define ROC_CTX_MAX_CKEY_LEN      32
167 #define ROC_CTX_MAX_OPAD_IPAD_LEN 128
168
169 /* Anti reply window size supported */
170 #define ROC_AR_WIN_SIZE_MIN        64
171 #define ROC_AR_WIN_SIZE_MAX        4096
172 #define ROC_LOG_MIN_AR_WIN_SIZE_M1 5
173
174 /* u64 array size to fit anti replay window bits */
175 #define ROC_AR_WINBITS_SZ                                                      \
176         (PLT_ALIGN_CEIL(ROC_AR_WIN_SIZE_MAX, BITS_PER_LONG_LONG) /             \
177          BITS_PER_LONG_LONG)
178
179 #define ROC_IPSEC_ERR_RING_MAX_ENTRY 65536
180
181 union roc_ot_ipsec_err_ring_head {
182         uint64_t u64;
183         struct {
184                 uint16_t tail_pos;
185                 uint16_t tail_gen;
186                 uint16_t head_pos;
187                 uint16_t head_gen;
188         } s;
189 };
190
191 union roc_ot_ipsec_err_ring_entry {
192         uint64_t u64;
193         struct {
194                 uint64_t data0 : 44;
195                 uint64_t data1 : 9;
196                 uint64_t rsvd : 3;
197                 uint64_t comp_code : 8;
198         } s;
199 };
200
201 /* Common bit fields between inbound and outbound SA */
202 union roc_ot_ipsec_sa_word2 {
203         struct {
204                 uint64_t valid : 1;
205                 uint64_t dir : 1;
206                 uint64_t outer_ip_ver : 1;
207                 uint64_t rsvd0 : 1;
208                 uint64_t mode : 1;
209                 uint64_t protocol : 1;
210                 uint64_t aes_key_len : 2;
211
212                 uint64_t enc_type : 3;
213                 uint64_t life_unit : 1;
214                 uint64_t auth_type : 4;
215
216                 uint64_t encap_type : 2;
217                 uint64_t et_ovrwr_ddr_en : 1;
218                 uint64_t esn_en : 1;
219                 uint64_t tport_l4_incr_csum : 1;
220                 uint64_t ip_hdr_verify : 2;
221                 uint64_t udp_ports_verify : 1;
222
223                 uint64_t rsvd2 : 7;
224                 uint64_t async_mode : 1;
225
226                 uint64_t spi : 32;
227         } s;
228         uint64_t u64;
229 };
230
231 PLT_STATIC_ASSERT(sizeof(union roc_ot_ipsec_sa_word2) == 1 * sizeof(uint64_t));
232
233 union roc_ot_ipsec_outer_ip_hdr {
234         struct {
235                 uint32_t dst_addr;
236                 uint32_t src_addr;
237         } ipv4;
238         struct {
239                 uint8_t src_addr[16];
240                 uint8_t dst_addr[16];
241         } ipv6;
242 };
243
244 struct roc_ot_ipsec_inb_ctx_update_reg {
245         uint64_t ar_base;
246         uint64_t ar_valid_mask;
247         uint64_t hard_life;
248         uint64_t soft_life;
249         uint64_t mib_octs;
250         uint64_t mib_pkts;
251         uint64_t ar_winbits[ROC_AR_WINBITS_SZ];
252 };
253
254 union roc_ot_ipsec_outb_iv {
255         uint64_t u64[2];
256         uint8_t iv_dbg[16];
257         struct {
258                 uint8_t iv_dbg1[4];
259                 uint8_t salt[4];
260
261                 uint32_t rsvd;
262                 uint8_t iv_dbg2[4];
263         } s;
264 };
265
266 struct roc_ot_ipsec_outb_ctx_update_reg {
267         union {
268                 struct {
269                         uint64_t reserved_0_2 : 3;
270                         uint64_t address : 57;
271                         uint64_t mode : 4;
272                 } s;
273                 uint64_t u64;
274         } err_ctl;
275
276         uint64_t esn_val;
277         uint64_t hard_life;
278         uint64_t soft_life;
279         uint64_t mib_octs;
280         uint64_t mib_pkts;
281 };
282
283 union roc_ot_ipsec_outb_param1 {
284         uint16_t u16;
285         struct {
286                 uint16_t l4_csum_disable : 1;
287                 uint16_t ip_csum_disable : 1;
288                 uint16_t ttl_or_hop_limit : 1;
289                 uint16_t dummy_pkt : 1;
290                 uint16_t rfc_or_override_mode : 1;
291                 uint16_t reserved_5_15 : 11;
292         } s;
293 };
294
295 union roc_ot_ipsec_inb_param1 {
296         uint16_t u16;
297         struct {
298                 uint16_t l4_csum_disable : 1;
299                 uint16_t ip_csum_disable : 1;
300                 uint16_t esp_trailer_disable : 1;
301                 uint16_t reserved_3_15 : 13;
302         } s;
303 };
304
305 struct roc_ot_ipsec_inb_sa {
306         /* Word0 */
307         union {
308                 struct {
309                         uint64_t ar_win : 3;
310                         uint64_t hard_life_dec : 1;
311                         uint64_t soft_life_dec : 1;
312                         uint64_t count_glb_octets : 1;
313                         uint64_t count_glb_pkts : 1;
314                         uint64_t count_mib_bytes : 1;
315
316                         uint64_t count_mib_pkts : 1;
317                         uint64_t hw_ctx_off : 7;
318
319                         uint64_t ctx_id : 16;
320
321                         uint64_t orig_pkt_fabs : 1;
322                         uint64_t orig_pkt_free : 1;
323                         uint64_t pkind : 6;
324
325                         uint64_t rsvd0 : 1;
326                         uint64_t et_ovrwr : 1;
327                         uint64_t pkt_output : 2;
328                         uint64_t pkt_format : 1;
329                         uint64_t defrag_opt : 2;
330                         uint64_t x2p_dst : 1;
331
332                         uint64_t ctx_push_size : 7;
333                         uint64_t rsvd1 : 1;
334
335                         uint64_t ctx_hdr_size : 2;
336                         uint64_t aop_valid : 1;
337                         uint64_t rsvd2 : 1;
338                         uint64_t ctx_size : 4;
339                 } s;
340                 uint64_t u64;
341         } w0;
342
343         /* Word1 */
344         union {
345                 struct {
346                         uint64_t orig_pkt_aura : 20;
347                         uint64_t rsvd3 : 4;
348                         uint64_t orig_pkt_foff : 8;
349                         uint64_t cookie : 32;
350                 } s;
351                 uint64_t u64;
352         } w1;
353
354         /* Word 2 */
355         union {
356                 struct {
357                         uint64_t valid : 1;
358                         uint64_t dir : 1;
359                         uint64_t outer_ip_ver : 1;
360                         uint64_t rsvd4 : 1;
361                         uint64_t ipsec_mode : 1;
362                         uint64_t ipsec_protocol : 1;
363                         uint64_t aes_key_len : 2;
364
365                         uint64_t enc_type : 3;
366                         uint64_t life_unit : 1;
367                         uint64_t auth_type : 4;
368
369                         uint64_t encap_type : 2;
370                         uint64_t et_ovrwr_ddr_en : 1;
371                         uint64_t esn_en : 1;
372                         uint64_t tport_l4_incr_csum : 1;
373                         uint64_t ip_hdr_verify : 2;
374                         uint64_t udp_ports_verify : 1;
375
376                         uint64_t l3hdr_on_err : 1;
377                         uint64_t rsvd6 : 6;
378                         uint64_t async_mode : 1;
379
380                         uint64_t spi : 32;
381                 } s;
382                 uint64_t u64;
383         } w2;
384
385         /* Word3 */
386         uint64_t rsvd7;
387
388         /* Word4 - Word7 */
389         uint8_t cipher_key[ROC_CTX_MAX_CKEY_LEN];
390
391         /* Word8 - Word9 */
392         union {
393                 struct {
394                         uint32_t rsvd8;
395                         uint8_t salt[4];
396                 } s;
397                 uint64_t u64;
398         } w8;
399         uint64_t rsvd9;
400
401         /* Word10 */
402         union {
403                 struct {
404                         uint64_t rsvd10 : 32;
405                         uint64_t udp_src_port : 16;
406                         uint64_t udp_dst_port : 16;
407                 } s;
408                 uint64_t u64;
409         } w10;
410
411         /* Word11 - Word14 */
412         union roc_ot_ipsec_outer_ip_hdr outer_hdr;
413
414         /* Word15 - Word30 */
415         uint8_t hmac_opad_ipad[ROC_CTX_MAX_OPAD_IPAD_LEN];
416
417         /* Word31 - Word100 */
418         struct roc_ot_ipsec_inb_ctx_update_reg ctx;
419 };
420
421 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_inb_sa, w1) ==
422                   1 * sizeof(uint64_t));
423 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_inb_sa, w2) ==
424                   2 * sizeof(uint64_t));
425 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_inb_sa, cipher_key) ==
426                   4 * sizeof(uint64_t));
427 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_inb_sa, w8) ==
428                   8 * sizeof(uint64_t));
429 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_inb_sa, w10) ==
430                   10 * sizeof(uint64_t));
431 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_inb_sa, outer_hdr) ==
432                   11 * sizeof(uint64_t));
433 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_inb_sa, hmac_opad_ipad) ==
434                   15 * sizeof(uint64_t));
435 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_inb_sa, ctx) ==
436                   31 * sizeof(uint64_t));
437
438 struct roc_ot_ipsec_outb_sa {
439         /* Word0 */
440         union {
441                 struct {
442                         uint64_t esn_en : 1;
443                         uint64_t ip_id : 1;
444                         uint64_t rsvd0 : 1;
445                         uint64_t hard_life_dec : 1;
446                         uint64_t soft_life_dec : 1;
447                         uint64_t count_glb_octets : 1;
448                         uint64_t count_glb_pkts : 1;
449                         uint64_t count_mib_bytes : 1;
450
451                         uint64_t count_mib_pkts : 1;
452                         uint64_t hw_ctx_off : 7;
453
454                         uint64_t ctx_id : 16;
455                         uint64_t rsvd1 : 16;
456
457                         uint64_t ctx_push_size : 7;
458                         uint64_t rsvd2 : 1;
459
460                         uint64_t ctx_hdr_size : 2;
461                         uint64_t aop_valid : 1;
462                         uint64_t rsvd3 : 1;
463                         uint64_t ctx_size : 4;
464                 } s;
465                 uint64_t u64;
466         } w0;
467
468         /* Word1 */
469         union {
470                 struct {
471                         uint64_t rsvd4 : 32;
472                         uint64_t cookie : 32;
473                 } s;
474                 uint64_t u64;
475         } w1;
476
477         /* Word 2 */
478         union {
479                 struct {
480                         uint64_t valid : 1;
481                         uint64_t dir : 1;
482                         uint64_t outer_ip_ver : 1;
483                         uint64_t rsvd5 : 1;
484                         uint64_t ipsec_mode : 1;
485                         uint64_t ipsec_protocol : 1;
486                         uint64_t aes_key_len : 2;
487
488                         uint64_t enc_type : 3;
489                         uint64_t life_unit : 1;
490                         uint64_t auth_type : 4;
491
492                         uint64_t encap_type : 2;
493                         uint64_t ipv4_df_src_or_ipv6_flw_lbl_src : 1;
494                         uint64_t dscp_src : 1;
495                         uint64_t iv_src : 2;
496                         uint64_t ipid_gen : 1;
497                         uint64_t rsvd6 : 1;
498
499                         uint64_t rsvd7 : 7;
500                         uint64_t async_mode : 1;
501
502                         uint64_t spi : 32;
503                 } s;
504                 uint64_t u64;
505         } w2;
506
507         /* Word3 */
508         uint64_t rsvd8;
509
510         /* Word4 - Word7 */
511         uint8_t cipher_key[ROC_CTX_MAX_CKEY_LEN];
512
513         /* Word8 - Word9 */
514         union roc_ot_ipsec_outb_iv iv;
515
516         /* Word10 */
517         union {
518                 struct {
519                         uint64_t rsvd9 : 4;
520                         uint64_t ipv4_df_or_ipv6_flw_lbl : 20;
521
522                         uint64_t dscp : 6;
523                         uint64_t rsvd10 : 2;
524
525                         uint64_t udp_dst_port : 16;
526
527                         uint64_t udp_src_port : 16;
528                 } s;
529                 uint64_t u64;
530         } w10;
531
532         /* Word11 - Word14 */
533         union roc_ot_ipsec_outer_ip_hdr outer_hdr;
534
535         /* Word15 - Word30 */
536         uint8_t hmac_opad_ipad[ROC_CTX_MAX_OPAD_IPAD_LEN];
537
538         /* Word31 - Word36 */
539         struct roc_ot_ipsec_outb_ctx_update_reg ctx;
540 };
541
542 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_outb_sa, w1) ==
543                   1 * sizeof(uint64_t));
544 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_outb_sa, w2) ==
545                   2 * sizeof(uint64_t));
546 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_outb_sa, cipher_key) ==
547                   4 * sizeof(uint64_t));
548 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_outb_sa, iv) ==
549                   8 * sizeof(uint64_t));
550 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_outb_sa, w10) ==
551                   10 * sizeof(uint64_t));
552 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_outb_sa, outer_hdr) ==
553                   11 * sizeof(uint64_t));
554 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_outb_sa, hmac_opad_ipad) ==
555                   15 * sizeof(uint64_t));
556 PLT_STATIC_ASSERT(offsetof(struct roc_ot_ipsec_outb_sa, ctx) ==
557                   31 * sizeof(uint64_t));
558
559 void __roc_api roc_ot_ipsec_inb_sa_init(struct roc_ot_ipsec_inb_sa *sa,
560                                         bool is_inline);
561 void __roc_api roc_ot_ipsec_outb_sa_init(struct roc_ot_ipsec_outb_sa *sa);
562 #endif /* __ROC_IE_OT_H__ */