1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26#ifndef _SYS_HXGE_HXGE_RXDMA_H 27#define _SYS_HXGE_HXGE_RXDMA_H 28 29#ifdef __cplusplus 30extern "C" { 31#endif 32 33#include <hxge_rdc_hw.h> 34#include <hpi_rxdma.h> 35 36#define RXDMA_CK_DIV_DEFAULT 25000 /* 84 usec */ 37#define RXDMA_RCR_PTHRES_DEFAULT 0x1 38#define RXDMA_RCR_TO_DEFAULT 0x1 39#define RXDMA_HDR_SIZE_DEFAULT 2 40#define RXDMA_HDR_SIZE_FULL 6 /* entire header of 6B */ 41 42/* 43 * Receive Completion Ring (RCR) 44 */ 45#define RCR_PKT_BUF_ADDR_SHIFT 0 /* bit 37:0 */ 46#define RCR_PKT_BUF_ADDR_SHIFT_FULL 6 /* fulll buffer address */ 47#define RCR_PKT_BUF_ADDR_MASK 0x0000003FFFFFFFFFULL 48#define RCR_PKTBUFSZ_SHIFT 38 /* bit 39:38 */ 49#define RCR_PKTBUFSZ_MASK 0x000000C000000000ULL 50#define RCR_L2_LEN_SHIFT 40 /* bit 53:40 */ 51#define RCR_L2_LEN_MASK 0x003fff0000000000ULL 52#define RCR_ERROR_SHIFT 54 /* bit 57:54 */ 53#define RCR_ERROR_MASK 0x03C0000000000000ULL 54#define RCR_PKT_TYPE_SHIFT 61 /* bit 62:61 */ 55#define RCR_PKT_TYPE_MASK 0x6000000000000000ULL 56#define RCR_MULTI_SHIFT 63 /* bit 63 */ 57#define RCR_MULTI_MASK 0x8000000000000000ULL 58 59#define RCR_PKTBUFSZ_0 0x00 60#define RCR_PKTBUFSZ_1 0x01 61#define RCR_PKTBUFSZ_2 0x02 62#define RCR_SINGLE_BLOCK 0x03 63#define N_PKTSIZE_TYPES 0x04 64 65#define RCR_NO_ERROR 0x0 66#define RCR_CTRL_FIFO_DED 0x1 67#define RCR_DATA_FIFO_DED 0x2 68#define RCR_ERROR_RESERVE 0x4 69 70#define RCR_PKT_IS_TCP 0x2000000000000000ULL 71#define RCR_PKT_IS_UDP 0x4000000000000000ULL 72#define RCR_PKT_IS_SCTP 0x6000000000000000ULL 73 74#define RDC_INT_MASK_RBRFULL_SHIFT 34 75#define RDC_INT_MASK_RBRFULL_MASK 0x0000000400000000ULL 76#define RDC_INT_MASK_RBREMPTY_SHIFT 35 77#define RDC_INT_MASK_RBREMPTY_MASK 0x0000000800000000ULL 78#define RDC_INT_MASK_RCRFULL_SHIFT 36 79#define RDC_INT_MASK_RCRFULL_MASK 0x0000001000000000ULL 80#define RDC_INT_MASK_RCRSH_FULL_SHIFT 39 81#define RDC_INT_MASK_RCRSH_FULL_MASK 0x0000008000000000ULL 82#define RDC_INT_MASK_RBR_PRE_EMPTY_SHIFT 40 83#define RDC_INT_MASK_RBR_PRE_EMPTY_MASK 0x0000010000000000ULL 84#define RDC_INT_MASK_RBR_PRE_PAR_SHIFT 43 85#define RDC_INT_MASK_RBR_PRE_PAR_MASK 0x0000080000000000ULL 86#define RDC_INT_MASK_RCR_SHA_PAR_SHIFT 44 87#define RDC_INT_MASK_RCR_SHA_PAR_MASK 0x0000100000000000ULL 88#define RDC_INT_MASK_RCRTO_SHIFT 45 89#define RDC_INT_MASK_RCRTO_MASK 0x0000200000000000ULL 90#define RDC_INT_MASK_THRES_SHIFT 46 91#define RDC_INT_MASK_THRES_MASK 0x0000400000000000ULL 92#define RDC_INT_MASK_PEU_ERR_SHIFT 52 93#define RDC_INT_MASK_PEU_ERR_MASK 0x0010000000000000ULL 94#define RDC_INT_MASK_RBR_CPL_SHIFT 53 95#define RDC_INT_MASK_RBR_CPL_MASK 0x0020000000000000ULL 96#define RDC_INT_MASK_ALL (RDC_INT_MASK_RBRFULL_MASK | \ 97 RDC_INT_MASK_RBREMPTY_MASK | \ 98 RDC_INT_MASK_RCRFULL_MASK | \ 99 RDC_INT_MASK_RCRSH_FULL_MASK | \ 100 RDC_INT_MASK_RBR_PRE_EMPTY_MASK | \ 101 RDC_INT_MASK_RBR_PRE_PAR_MASK | \ 102 RDC_INT_MASK_RCR_SHA_PAR_MASK | \ 103 RDC_INT_MASK_RCRTO_MASK | \ 104 RDC_INT_MASK_THRES_MASK | \ 105 RDC_INT_MASK_PEU_ERR_MASK | \ 106 RDC_INT_MASK_RBR_CPL_MASK) 107 108#define RDC_STAT_PKTREAD_SHIFT 0 /* WO, bit 15:0 */ 109#define RDC_STAT_PKTREAD_MASK 0x000000000000ffffULL 110#define RDC_STAT_PTRREAD_SHIFT 16 /* WO, bit 31:16 */ 111#define RDC_STAT_PTRREAD_MASK 0x00000000FFFF0000ULL 112 113#define RDC_STAT_RBRFULL_SHIFT 34 /* RO, bit 34 */ 114#define RDC_STAT_RBRFULL 0x0000000400000000ULL 115#define RDC_STAT_RBRFULL_MASK 0x0000000400000000ULL 116#define RDC_STAT_RBREMPTY_SHIFT 35 /* RW1C, bit 35 */ 117#define RDC_STAT_RBREMPTY 0x0000000800000000ULL 118#define RDC_STAT_RBREMPTY_MASK 0x0000000800000000ULL 119#define RDC_STAT_RCR_FULL_SHIFT 36 /* RW1C, bit 36 */ 120#define RDC_STAT_RCR_FULL 0x0000001000000000ULL 121#define RDC_STAT_RCR_FULL_MASK 0x0000001000000000ULL 122 123#define RDC_STAT_RCR_SHDW_FULL_SHIFT 39 /* RW1C, bit 39 */ 124#define RDC_STAT_RCR_SHDW_FULL 0x0000008000000000ULL 125#define RDC_STAT_RCR_SHDW_FULL_MASK 0x0000008000000000ULL 126#define RDC_STAT_RBR_PRE_EMPTY_SHIFT 40 /* RO, bit 40 */ 127#define RDC_STAT_RBR_PRE_EMPTY 0x0000010000000000ULL 128#define RDC_STAT_RBR_PRE_EMPTY_MASK 0x0000010000000000ULL 129 130#define RDC_STAT_RBR_PRE_PAR_SHIFT 43 /* RO, bit 43 */ 131#define RDC_STAT_RBR_PRE_PAR 0x0000080000000000ULL 132#define RDC_STAT_RBR_PRE_PAR_MASK 0x0000080000000000ULL 133#define RDC_STAT_RCR_SHA_PAR_SHIFT 44 /* RO, bit 44 */ 134#define RDC_STAT_RCR_SHA_PAR 0x0000100000000000ULL 135#define RDC_STAT_RCR_SHA_PAR_MASK 0x0000100000000000ULL 136 137#define RDC_STAT_RCR_TO_SHIFT 45 /* RW1C, bit 45 */ 138#define RDC_STAT_RCR_TO 0x0000200000000000ULL 139#define RDC_STAT_RCR_TO_MASK 0x0000200000000000ULL 140#define RDC_STAT_RCR_THRES_SHIFT 46 /* RO, bit 46 */ 141#define RDC_STAT_RCR_THRES 0x0000400000000000ULL 142#define RDC_STAT_RCR_THRES_MASK 0x0000400000000000ULL 143#define RDC_STAT_RCR_MEX_SHIFT 47 /* RW, bit 47 */ 144#define RDC_STAT_RCR_MEX 0x0000800000000000ULL 145#define RDC_STAT_RCR_MEX_MASK 0x0000800000000000ULL 146 147#define RDC_STAT_PEU_ERR_SHIFT 52 /* RO, bit 52 */ 148#define RDC_STAT_PEU_ERR 0x0010000000000000ULL 149#define RDC_STAT_PEU_ERR_MASK 0x0010000000000000ULL 150 151#define RDC_STAT_RBR_CPL_SHIFT 53 /* RO, bit 53 */ 152#define RDC_STAT_RBR_CPL 0x0020000000000000ULL 153#define RDC_STAT_RBR_CPL_MASK 0x0020000000000000ULL 154 155#define RDC_STAT_ERROR RDC_INT_MASK_ALL 156 157/* the following are write 1 to clear bits */ 158#define RDC_STAT_WR1C (RDC_STAT_RBREMPTY | \ 159 RDC_STAT_RCR_SHDW_FULL | \ 160 RDC_STAT_RBR_PRE_EMPTY | \ 161 RDC_STAT_RBR_PRE_PAR | \ 162 RDC_STAT_RCR_SHA_PAR | \ 163 RDC_STAT_RBR_CPL | \ 164 RDC_STAT_PEU_ERR) 165 166typedef union _rcr_entry_t { 167 uint64_t value; 168 struct { 169#if defined(_BIG_ENDIAN) 170 uint32_t multi:1; 171 uint32_t pkt_type:2; 172 uint32_t reserved:3; 173 uint32_t error:4; 174 uint32_t l2_len:14; 175 uint32_t pktbufsz:2; 176 uint32_t pkt_buf_addr:6; 177 uint32_t pkt_buf_addr_l:32; 178#else 179 uint32_t pkt_buf_addr_l:32; 180 uint32_t pkt_buf_addr:6; 181 uint32_t pktbufsz:2; 182 uint32_t l2_len:14; 183 uint32_t error:4; 184 uint32_t reserved:3; 185 uint32_t pkt_type:2; 186 uint32_t multi:1; 187#endif 188 } bits; 189} rcr_entry_t, *p_rcr_entry_t; 190 191#define RX_DMA_MAILBOX_BYTE_LENGTH 64 192 193typedef struct _rxdma_mailbox_t { 194 rdc_stat_t rxdma_ctl_stat; /* 8 bytes */ 195 rdc_rbr_qlen_t rbr_stat; /* 8 bytes */ 196 rdc_rbr_head_t rbr_hdh; /* 8 bytes */ 197 uint64_t resv_1; 198 rdc_rcr_tail_t rcrstat_c; /* 8 bytes */ 199 uint64_t resv_2; 200 rdc_rcr_qlen_t rcrstat_a; /* 8 bytes */ 201 uint64_t resv_3; 202} rxdma_mailbox_t, *p_rxdma_mailbox_t; 203 204/* 205 * hardware workarounds: kick 16 (was 8 before) 206 */ 207#define HXGE_RXDMA_POST_BATCH 16 208 209#define RXBUF_START_ADDR(a, index, bsize) ((a & (index * bsize)) 210#define RXBUF_OFFSET_FROM_START(a, start) (start - a) 211#define RXBUF_64B_ALIGNED 64 212 213#define HXGE_RXBUF_EXTRA 34 214 215/* 216 * Receive buffer thresholds and buffer types 217 */ 218#define HXGE_RX_BCOPY_SCALE 8 /* use 1/8 as lowest granularity */ 219 220typedef enum { 221 HXGE_RX_COPY_ALL = 0, /* do bcopy on every packet */ 222 HXGE_RX_COPY_1, /* bcopy on 1/8 of buffer posted */ 223 HXGE_RX_COPY_2, /* bcopy on 2/8 of buffer posted */ 224 HXGE_RX_COPY_3, /* bcopy on 3/8 of buffer posted */ 225 HXGE_RX_COPY_4, /* bcopy on 4/8 of buffer posted */ 226 HXGE_RX_COPY_5, /* bcopy on 5/8 of buffer posted */ 227 HXGE_RX_COPY_6, /* bcopy on 6/8 of buffer posted */ 228 HXGE_RX_COPY_7, /* bcopy on 7/8 of buffer posted */ 229 HXGE_RX_COPY_NONE /* don't do bcopy at all */ 230} hxge_rxbuf_threshold_t; 231 232typedef enum { 233 HXGE_RBR_TYPE0 = RCR_PKTBUFSZ_0, /* bcopy buffer size 0 (small) */ 234 HXGE_RBR_TYPE1 = RCR_PKTBUFSZ_1, /* bcopy buffer size 1 (medium) */ 235 HXGE_RBR_TYPE2 = RCR_PKTBUFSZ_2 /* bcopy buffer size 2 (large) */ 236} hxge_rxbuf_type_t; 237 238typedef struct _rdc_errlog { 239 rdc_pref_par_log_t pre_par; 240 rdc_pref_par_log_t sha_par; 241 uint8_t compl_err_type; 242} rdc_errlog_t; 243 244/* 245 * Receive Statistics. 246 */ 247typedef struct _hxge_rx_ring_stats_t { 248 uint64_t ipackets; 249 uint64_t ibytes; 250 uint32_t ierrors; 251 uint32_t jumbo_pkts; 252 253 /* 254 * Error event stats. 255 */ 256 uint32_t rcr_unknown_err; 257 uint32_t ctrl_fifo_ecc_err; 258 uint32_t data_fifo_ecc_err; 259 uint32_t rbr_tmout; /* rbr_cpl_to */ 260 uint32_t peu_resp_err; /* peu_resp_err */ 261 uint32_t rcr_sha_par; /* rcr_shadow_par_err */ 262 uint32_t rbr_pre_par; /* rbr_prefetch_par_err */ 263 uint32_t rbr_pre_empty; /* rbr_pre_empty */ 264 uint32_t rcr_shadow_full; /* rcr_shadow_full */ 265 uint32_t rcrfull; /* rcr_full */ 266 uint32_t rbr_empty; /* rbr_empty */ 267 uint32_t rbr_empty_fail; /* rbr_empty_fail */ 268 uint32_t rbr_empty_restore; /* rbr_empty_restore */ 269 uint32_t rbrfull; /* rbr_full */ 270 /* 271 * RCR invalids: when processing RCR entries, can 272 * run into invalid RCR entries. This counter provides 273 * a means to account for invalid RCR entries. 274 */ 275 uint32_t rcr_invalids; /* rcr invalids */ 276 uint32_t rcr_to; /* rcr_to */ 277 uint32_t rcr_thres; /* rcr_thres */ 278 /* Packets dropped in order to prevent rbr_empty condition */ 279 uint32_t pkt_drop; 280 rdc_errlog_t errlog; 281} hxge_rx_ring_stats_t, *p_hxge_rx_ring_stats_t; 282 283typedef struct _hxge_rdc_sys_stats { 284 uint32_t ctrl_fifo_sec; 285 uint32_t ctrl_fifo_ded; 286 uint32_t data_fifo_sec; 287 uint32_t data_fifo_ded; 288} hxge_rdc_sys_stats_t, *p_hxge_rdc_sys_stats_t; 289 290typedef struct _rx_msg_t { 291 hxge_os_dma_common_t buf_dma; 292 hxge_os_mutex_t lock; 293 struct _hxge_t *hxgep; 294 struct _rx_rbr_ring_t *rx_rbr_p; 295 boolean_t free; 296 uint32_t ref_cnt; 297 hxge_os_frtn_t freeb; 298 size_t block_size; 299 uint32_t block_index; 300 uint32_t pkt_buf_size; 301 uint32_t pkt_buf_size_code; 302 uint32_t cur_usage_cnt; 303 uint32_t max_usage_cnt; 304 uchar_t *buffer; 305 uint32_t pri; 306 uint32_t shifted_addr; 307 boolean_t use_buf_pool; 308 p_mblk_t rx_mblk_p; 309 boolean_t rx_use_bcopy; 310} rx_msg_t, *p_rx_msg_t; 311 312/* Receive Completion Ring */ 313typedef struct _rx_rcr_ring_t { 314 hxge_os_dma_common_t rcr_desc; 315 struct _hxge_t *hxgep; 316 mac_ring_handle_t rcr_mac_handle; 317 uint64_t rcr_gen_num; 318 boolean_t poll_flag; 319 p_hxge_ldv_t ldvp; 320 p_hxge_ldg_t ldgp; 321 322 p_hxge_rx_ring_stats_t rdc_stats; /* pointer to real kstats */ 323 324 rdc_rcr_cfg_a_t rcr_cfga; 325 rdc_rcr_cfg_b_t rcr_cfgb; 326 327 hxge_os_mutex_t lock; 328 uint16_t index; 329 uint16_t rdc; 330 boolean_t full_hdr_flag; /* 1: 18 bytes header */ 331 uint16_t sw_priv_hdr_len; /* 0 - 192 bytes (SW) */ 332 uint32_t comp_size; /* # of RCR entries */ 333 uint64_t rcr_addr; 334 uint_t comp_wrap_mask; 335 uint_t comp_rd_index; 336 uint_t comp_wt_index; 337 338 p_rcr_entry_t rcr_desc_first_p; 339 p_rcr_entry_t rcr_desc_first_pp; 340 p_rcr_entry_t rcr_desc_last_p; 341 p_rcr_entry_t rcr_desc_last_pp; 342 343 p_rcr_entry_t rcr_desc_rd_head_p; /* software next read */ 344 p_rcr_entry_t rcr_desc_rd_head_pp; 345 uint64_t rcr_tail_begin; 346 347 struct _rx_rbr_ring_t *rx_rbr_p; 348 uint32_t intr_timeout; 349 uint32_t intr_threshold; 350 uint32_t rcvd_pkt_bytes; /* Received bytes of a packet */ 351} rx_rcr_ring_t, *p_rx_rcr_ring_t; 352 353 354/* Buffer index information */ 355typedef struct _rxbuf_index_info_t { 356 uint32_t buf_index; 357 uint32_t start_index; 358 uint32_t buf_size; 359 uint64_t dvma_addr; 360 uint64_t kaddr; 361} rxbuf_index_info_t, *p_rxbuf_index_info_t; 362 363/* Buffer index information */ 364 365typedef struct _rxring_info_t { 366 uint32_t hint[N_PKTSIZE_TYPES]; 367 uint32_t block_size_mask; 368 uint16_t max_iterations; 369 rxbuf_index_info_t buffer[HXGE_DMA_BLOCK]; 370} rxring_info_t, *p_rxring_info_t; 371 372 373typedef enum { 374 RBR_POSTING = 1, /* We may post rx buffers. */ 375 RBR_UNMAPPING, /* We are in the process of unmapping. */ 376 RBR_UNMAPPED /* The ring is unmapped. */ 377} rbr_state_t; 378 379 380/* Receive Buffer Block Ring */ 381typedef struct _rx_rbr_ring_t { 382 hxge_os_dma_common_t rbr_desc; 383 p_rx_msg_t *rx_msg_ring; 384 p_hxge_dma_common_t *dma_bufp; 385 rdc_rbr_cfg_a_t rbr_cfga; 386 rdc_rbr_cfg_b_t rbr_cfgb; 387 rdc_rbr_kick_t rbr_kick; 388 rdc_page_handle_t page_hdl; 389 390 hxge_os_mutex_t lock; 391 hxge_os_mutex_t post_lock; 392 boolean_t rbr_is_empty; 393 uint32_t rbr_used; 394 uint16_t index; 395 struct _hxge_t *hxgep; 396 uint16_t rdc; 397 uint_t rbr_max_size; 398 uint64_t rbr_addr; 399 uint_t rbr_wrap_mask; 400 uint_t rbb_max; 401 uint_t block_size; 402 uint_t num_blocks; 403 uint_t tnblocks; 404 uint_t pkt_buf_size0; 405 uint_t pkt_buf_size0_bytes; 406 uint_t hpi_pkt_buf_size0; 407 uint_t pkt_buf_size1; 408 uint_t pkt_buf_size1_bytes; 409 uint_t hpi_pkt_buf_size1; 410 uint_t pkt_buf_size2; 411 uint_t pkt_buf_size2_bytes; 412 uint_t hpi_pkt_buf_size2; 413 414 uint64_t rbr_head_pp; 415 uint64_t rbr_tail_pp; 416 uint32_t *rbr_desc_vp; 417 418 p_rx_rcr_ring_t rx_rcr_p; 419 420 rdc_rbr_head_t rbr_head; 421 uint_t rbr_wr_index; 422 uint_t rbr_rd_index; 423 uint_t rbr_hw_head_index; 424 uint64_t rbr_hw_head_ptr; 425 426 rxring_info_t *ring_info; 427 uint_t rbr_consumed; 428 uint_t rbr_threshold_hi; 429 uint_t rbr_threshold_lo; 430 hxge_rxbuf_type_t rbr_bufsize_type; 431 boolean_t rbr_use_bcopy; 432 433 /* 434 * <rbr_ref_cnt> is a count of those receive buffers which 435 * have been loaned to the kernel. We will not free this 436 * ring until the reference count reaches zero (0). 437 */ 438 uint32_t rbr_ref_cnt; 439 rbr_state_t rbr_state; /* POSTING, etc */ 440} rx_rbr_ring_t, *p_rx_rbr_ring_t; 441 442/* Receive Mailbox */ 443typedef struct _rx_mbox_t { 444 hxge_os_dma_common_t rx_mbox; 445 rdc_rx_cfg1_t rx_cfg1; 446 rdc_rx_cfg2_t rx_cfg2; 447 uint64_t mbox_addr; 448 boolean_t cfg_set; 449 450 hxge_os_mutex_t lock; 451 uint16_t index; 452 struct _hxge_t *hxgep; 453 uint16_t rdc; 454} rx_mbox_t, *p_rx_mbox_t; 455 456typedef struct _rx_rbr_rings_t { 457 p_rx_rbr_ring_t *rbr_rings; 458 uint32_t ndmas; 459 boolean_t rxbuf_allocated; 460} rx_rbr_rings_t, *p_rx_rbr_rings_t; 461 462typedef struct _rx_rcr_rings_t { 463 p_rx_rcr_ring_t *rcr_rings; 464 uint32_t ndmas; 465 boolean_t cntl_buf_allocated; 466} rx_rcr_rings_t, *p_rx_rcr_rings_t; 467 468typedef struct _rx_mbox_areas_t { 469 p_rx_mbox_t *rxmbox_areas; 470 uint32_t ndmas; 471 boolean_t mbox_allocated; 472} rx_mbox_areas_t, *p_rx_mbox_areas_t; 473 474/* 475 * Receive DMA Prototypes. 476 */ 477hxge_status_t hxge_init_rxdma_channels(p_hxge_t hxgep); 478void hxge_uninit_rxdma_channels(p_hxge_t hxgep); 479hxge_status_t hxge_init_rxdma_channel_cntl_stat(p_hxge_t hxgep, 480 uint16_t channel, rdc_stat_t *cs_p); 481hxge_status_t hxge_enable_rxdma_channel(p_hxge_t hxgep, 482 uint16_t channel, p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, 483 p_rx_mbox_t mbox_p, int n_init_kick); 484hxge_status_t hxge_rxdma_hw_mode(p_hxge_t hxgep, boolean_t enable); 485int hxge_rxdma_get_ring_index(p_hxge_t hxgep, uint16_t channel); 486hxge_status_t hxge_rxdma_handle_sys_errors(p_hxge_t hxgep); 487 488extern int hxge_enable_poll(void *arg); 489extern int hxge_disable_poll(void *arg); 490extern mblk_t *hxge_rx_poll(void *arg, int bytes_to_read); 491 492 493#ifdef __cplusplus 494} 495#endif 496 497#endif /* _SYS_HXGE_HXGE_RXDMA_H */ 498