xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h (revision 6d768494e5ce14eb1603a695c86739d12ecc6ec2)
1 /*
2  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: wlan_vdev_mgr_tgt_if_tx_defs.h
21  *
22  * This file provides definitions to data structures required for vdev Tx ops
23  */
24 
25 #ifndef __WLAN_VDEV_MGR_TX_OPS_DEFS_H__
26 #define __WLAN_VDEV_MGR_TX_OPS_DEFS_H__
27 
28 #include <qdf_nbuf.h>
29 
30 /**
31  * struct mac_ssid - mac ssid structure
32  * @length: ssid length
33  * @mac_ssid: ssid
34  */
35 struct mlme_mac_ssid {
36 	uint8_t length;
37 	uint8_t mac_ssid[WLAN_SSID_MAX_LEN];
38 } qdf_packed;
39 
40 /** slot time long */
41 #define WLAN_MLME_VDEV_SLOT_TIME_LONG   0x1
42 /** slot time short */
43 #define WLAN_MLME_VDEV_SLOT_TIME_SHORT  0x2
44 
45 /**
46  * enum MLME_bcn_tx_rate_code - beacon tx rate code
47  */
48 enum mlme_bcn_tx_rate_code {
49 	MLME_BCN_TX_RATE_CODE_1_M = 0x43,
50 	MLME_BCN_TX_RATE_CODE_2_M = 0x42,
51 	MLME_BCN_TX_RATE_CODE_5_5_M = 0x41,
52 	MLME_BCN_TX_RATE_CODE_6_M = 0x03,
53 	MLME_BCN_TX_RATE_CODE_9_M = 0x07,
54 	MLME_BCN_TX_RATE_CODE_11M = 0x40,
55 	MLME_BCN_TX_RATE_CODE_12_M = 0x02,
56 	MLME_BCN_TX_RATE_CODE_18_M = 0x06,
57 	MLME_BCN_TX_RATE_CODE_24_M = 0x01,
58 	MLME_BCN_TX_RATE_CODE_36_M = 0x05,
59 	MLME_BCN_TX_RATE_CODE_48_M = 0x00,
60 	MLME_BCN_TX_RATE_CODE_54_M = 0x04,
61 };
62 
63 /**
64  * enum wlan_mlme_host_sta_ps_param_uapsd - STA UPASD params
65  */
66 enum wlan_mlme_host_sta_ps_param_uapsd {
67 	WLAN_MLME_HOST_STA_PS_UAPSD_AC0_DELIVERY_EN = (1 << 0),
68 	WLAN_MLME_HOST_STA_PS_UAPSD_AC0_TRIGGER_EN  = (1 << 1),
69 	WLAN_MLME_HOST_STA_PS_UAPSD_AC1_DELIVERY_EN = (1 << 2),
70 	WLAN_MLME_HOST_STA_PS_UAPSD_AC1_TRIGGER_EN  = (1 << 3),
71 	WLAN_MLME_HOST_STA_PS_UAPSD_AC2_DELIVERY_EN = (1 << 4),
72 	WLAN_MLME_HOST_STA_PS_UAPSD_AC2_TRIGGER_EN  = (1 << 5),
73 	WLAN_MLME_HOST_STA_PS_UAPSD_AC3_DELIVERY_EN = (1 << 6),
74 	WLAN_MLME_HOST_STA_PS_UAPSD_AC3_TRIGGER_EN  = (1 << 7),
75 };
76 
77 /**
78  * enum wlan_mlme_host_vdev_start_status - vdev start status code
79  */
80 enum wlan_mlme_host_vdev_start_status {
81 	WLAN_MLME_HOST_VDEV_START_OK = 0,
82 	WLAN_MLME_HOST_VDEV_START_CHAN_INVALID,
83 	WLAN_MLME_HOST_VDEV_START_CHAN_BLOCKED,
84 	WLAN_MLME_HOST_VDEV_START_CHAN_DFS_VIOLATION,
85 	WLAN_MLME_HOST_VDEV_START_CHAN_INVALID_REGDOMAIN,
86 	WLAN_MLME_HOST_VDEV_START_CHAN_INVALID_BAND,
87 	WLAN_MLME_HOST_VDEV_START_TIMEOUT,
88 	/* Add new response status code from here */
89 	WLAN_MLME_HOST_VDEV_START_MAX_REASON,
90 };
91 
92 /**
93  * string_from_start_rsp_status() - Convert start response status to string
94  * @start_rsp - start response status
95  *
96  * Please note to add new string in the array at index equal to
97  * its enum value in wlan_mlme_host_vdev_start_status.
98  */
99 static inline char *string_from_start_rsp_status(
100 			enum wlan_mlme_host_vdev_start_status start_rsp)
101 {
102 	static const char *strings[] = { "START_OK",
103 					"CHAN_INVALID",
104 					"CHAN_BLOCKED",
105 					"CHAN_DFS_VIOLATION",
106 					"CHAN_INVALID_REGDOMAIN",
107 					"CHAN_INVALID_BAND",
108 					"START_RESPONSE_TIMEOUT",
109 					"START_RESPONSE_UNKNOWN"};
110 
111 	if (start_rsp >= WLAN_MLME_HOST_VDEV_START_MAX_REASON)
112 		start_rsp = WLAN_MLME_HOST_VDEV_START_MAX_REASON;
113 
114 	return (char *)strings[start_rsp];
115 }
116 
117 /**
118  * enum wlan_mlme_host_start_event_param - start/restart resp event
119  */
120 enum wlan_mlme_host_start_event_param {
121 	WLAN_MLME_HOST_VDEV_START_RESP_EVENT = 0,
122 	WLAN_MLME_HOST_VDEV_RESTART_RESP_EVENT,
123 };
124 
125 /**
126  * enum wlan_mlme_custom_aggr_type: custon aggregate type
127  * @WLAN_MLME_CUSTOM_AGGR_TYPE_AMPDU: A-MPDU aggregation
128  * @WLAN_MLME_CUSTOM_AGGR_TYPE_AMSDU: A-MSDU aggregation
129  * @WLAN_MLME_CUSTOM_AGGR_TYPE_MAX: Max type
130  */
131 enum wlan_mlme_custom_aggr_type {
132 	WLAN_MLME_CUSTOM_AGGR_TYPE_AMPDU = 0,
133 	WLAN_MLME_CUSTOM_AGGR_TYPE_AMSDU = 1,
134 	WLAN_MLME_CUSTOM_AGGR_TYPE_MAX,
135 };
136 
137 /**
138  * struct sta_ps_params - sta ps cmd parameter
139  * @vdev_id: vdev id
140  * @param_id: sta ps parameter
141  * @value: sta ps parameter value
142  */
143 struct sta_ps_params {
144 	uint32_t vdev_id;
145 	uint32_t param_id;
146 	uint32_t value;
147 };
148 
149 /**
150  * struct rnr_bss_tbtt_info_param: Reported Vdev info
151  * @bss_mac: Mac address
152  * @beacon_intval: Beacon interval of reported AP
153  * @opclass: Channel Opclass
154  * @chan_idx: Channel number
155  * @next_qtime_tbtt_high: Tbtt higher 32bit
156  * @next_qtime_tbtt_low: Tbtt lower 32bit
157  */
158 struct rnr_bss_tbtt_info_param {
159 	uint8_t bss_mac[QDF_MAC_ADDR_SIZE];
160 	uint32_t beacon_intval;
161 	uint32_t opclass;
162 	uint32_t chan_idx;
163 	uint32_t next_qtime_tbtt_high;
164 	uint32_t next_qtime_tbtt_low;
165 };
166 
167 /**
168  * struct rnr_tbtt_multisoc_sync_param - Params to
169  * sync tbtt with non self SoCs timers
170  * @pdev_id: Host pdev_id
171  * @rnr_vap_count: Count of Vap to be included in WMI cmd
172  * @cmd_type: Set/Get tbtt sync info
173  * @rnr_bss_tbtt: Reported AP Vap info
174  */
175 struct rnr_tbtt_multisoc_sync_param {
176 	uint32_t pdev_id;
177 	uint8_t rnr_vap_count;
178 	uint8_t cmd_type;
179 	struct rnr_bss_tbtt_info_param *rnr_bss_tbtt;
180 };
181 
182 /**
183  * struct tbttoffset_params - Tbttoffset event params
184  * @vdev_id: Virtual AP device identifier
185  * @tbttoffset : Tbttoffset for the virtual AP device
186  * @vdev_tbtt_qtime_lo: Tbtt qtime low value
187  * @vdev_tbtt_qtime_hi: Tbtt qtime high value
188  */
189 struct tbttoffset_params {
190 	uint32_t vdev_id;
191 	uint32_t tbttoffset;
192 	uint32_t vdev_tbtt_qtime_lo;
193 	uint32_t vdev_tbtt_qtime_hi;
194 };
195 
196 /**
197  * struct beacon_tmpl_params - beacon template cmd parameter
198  * @vdev_id: vdev id
199  * @tim_ie_offset: tim ie offset
200  * @mbssid_ie_offset: mbssid ie offset
201  * @tmpl_len: beacon template length
202  * @tmpl_len_aligned: beacon template alignment
203  * @csa_switch_count_offset: CSA swith count offset in beacon frame
204  * @ext_csa_switch_count_offset: ECSA switch count offset in beacon frame
205  * @esp_ie_offset: ESP IE offset in beacon frame
206  * @mu_edca_ie_offset: Mu EDCA IE offset in beacon frame
207  * @ema_params: The 4 octets in this field respectively indicate
208  *     ema_beacon_profile_periodicity, ema_beacon_tmpl_idx,
209  *     ema_first_tmpl and ema_last_tmpl in the order of low
210  *     to high
211  * @enable_bigtk: enable bigtk or not
212  * @frm: beacon template parameter
213  */
214 struct beacon_tmpl_params {
215 	uint8_t vdev_id;
216 	uint32_t tim_ie_offset;
217 	uint32_t mbssid_ie_offset;
218 	uint32_t tmpl_len;
219 	uint32_t tmpl_len_aligned;
220 	uint32_t csa_switch_count_offset;
221 	uint32_t ext_csa_switch_count_offset;
222 	uint32_t esp_ie_offset;
223 	uint32_t mu_edca_ie_offset;
224 	uint32_t ema_params;
225 	bool enable_bigtk;
226 	uint8_t *frm;
227 };
228 
229 /**
230  * struct beacon_params - beacon cmd parameter
231  * @vdev_id: vdev id
232  * @beacon_interval: Beacon interval
233  * @wbuf: beacon buffer
234  * @frame_ctrl: frame control field
235  * @bcn_txant: beacon antenna
236  * @is_dtim_count_zero: is it dtim beacon
237  * @is_bitctl_reqd: is Bit control required
238  * @is_high_latency: Is this high latency target
239  */
240 struct beacon_params {
241 	uint8_t vdev_id;
242 	uint16_t beacon_interval;
243 	qdf_nbuf_t wbuf;
244 	uint16_t frame_ctrl;
245 	uint32_t bcn_txant;
246 	bool is_dtim_count_zero;
247 	bool is_bitctl_reqd;
248 	bool is_high_latency;
249 };
250 
251 /* struct fils_discovery_tmpl_params - FILS Discovery template cmd parameter
252  * @vdev_id: vdev ID
253  * @tmpl_len: FILS Discovery template length
254  * @tmpl_aligned: FILS Discovery template alignment
255  * @frm: FILS Discovery template parameter
256  */
257 struct fils_discovery_tmpl_params {
258 	uint8_t vdev_id;
259 	uint32_t tmpl_len;
260 	uint32_t tmpl_len_aligned;
261 	uint8_t *frm;
262 };
263 
264 /**
265  * struct mlme_channel_param - Channel parameters with all
266  *			info required by target.
267  * @chan_id: channel id
268  * @pwr: channel power
269  * @mhz: channel frequency
270  * @half_rate: is half rate
271  * @quarter_rate: is quarter rate
272  * @dfs_set: is dfs channel
273  * @dfs_set_cfreq2: is secondary freq dfs channel
274  * @is_chan_passive: is this passive channel
275  * @allow_ht: HT allowed in chan
276  * @allow_vht: VHT allowed on chan
277  * @set_agile: is agile mode
278  * @phy_mode: phymode (vht80 or ht40 or ...)
279  * @cfreq1: centre frequency on primary
280  * @cfreq2: centre frequency on secondary
281  * @maxpower: max power for channel
282  * @minpower: min power for channel
283  * @maxreqpower: Max regulatory power
284  * @antennamac: Max antenna
285  * @reg_class_id: Regulatory class id.
286  */
287 struct mlme_channel_param {
288 	uint8_t chan_id;
289 	uint8_t pwr;
290 	uint32_t mhz;
291 	uint32_t half_rate:1,
292 		quarter_rate:1,
293 		dfs_set:1,
294 		dfs_set_cfreq2:1,
295 		is_chan_passive:1,
296 		allow_ht:1,
297 		allow_vht:1,
298 		set_agile:1;
299 	enum wlan_phymode phy_mode;
300 	uint32_t cfreq1;
301 	uint32_t cfreq2;
302 	int8_t   maxpower;
303 	int8_t   minpower;
304 	int8_t   maxregpower;
305 	uint8_t  antennamax;
306 	uint8_t  reg_class_id;
307 };
308 
309 /**
310  * struct vdev_mlme_mvr_param - Multiple vdev restart params
311  * @phymode: phymode information
312  */
313 struct vdev_mlme_mvr_param {
314 	uint32_t phymode;
315 };
316 
317 /**
318  * struct multiple_vdev_restart_params - Multiple vdev restart cmd parameter
319  * @pdev_id: Pdev identifier
320  * @requestor_id: Unique id identifying the module
321  * @disable_hw_ack: Flag to indicate disabling HW ACK during CAC
322  * @cac_duration_ms: CAC duration on the given channel
323  * @num_vdevs: No. of vdevs that need to be restarted
324  * @ch_param: Pointer to channel_param
325  * @vdev_ids: Pointer to array of vdev_ids
326  * @mvr_param: array holding multi vdev restart param
327  */
328 struct multiple_vdev_restart_params {
329 	uint32_t pdev_id;
330 	uint32_t requestor_id;
331 	uint32_t disable_hw_ack;
332 	uint32_t cac_duration_ms;
333 	uint32_t num_vdevs;
334 	struct mlme_channel_param ch_param;
335 	uint32_t vdev_ids[WLAN_UMAC_PDEV_MAX_VDEVS];
336 	struct vdev_mlme_mvr_param mvr_param[WLAN_UMAC_PDEV_MAX_VDEVS];
337 };
338 
339 /**
340  * struct peer_flush_params - peer flush cmd parameter
341  * @peer_tid_bitmap: peer tid bitmap
342  * @vdev_id: vdev id
343  * @peer_mac: peer mac address
344  */
345 struct peer_flush_params {
346 	uint32_t peer_tid_bitmap;
347 	uint8_t vdev_id;
348 	uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
349 };
350 
351 /* Default FILS DISCOVERY/probe response sent in period of 20TU */
352 #define DEFAULT_FILS_DISCOVERY_PERIOD 20
353 #define DEFAULT_PROBE_RESP_PERIOD 20
354 
355 /**
356  * struct config_fils_params - FILS config params
357  * @vdev_id:  vdev id
358  * @fd_period:  0 - Disabled, non-zero - Period in ms (mili seconds)
359  * @send_prb_rsp_frame: send broadcast prb resp frame
360  */
361 struct config_fils_params {
362 	uint8_t vdev_id;
363 	uint32_t fd_period;
364 	uint32_t send_prb_rsp_frame: 1;
365 };
366 
367 /**
368  * struct config_ratemask_params - ratemask config parameters
369  * @vdev_id: vdev id
370  * @type: Type
371  * @lower32: Lower 32 bits in the 1st 64-bit value
372  * @higher32: Higher 32 bits in the 1st 64-bit value
373  * @lower32_2: Lower 32 bits in the 2nd 64-bit value
374  */
375 struct config_ratemask_params {
376 	uint8_t vdev_id;
377 	uint8_t type;
378 	uint32_t lower32;
379 	uint32_t higher32;
380 	uint32_t lower32_2;
381 };
382 
383 /**
384  * struct set_custom_aggr_size_params - custom aggr size params
385  * @vdev_id : vdev id
386  * @tx_aggr_size : TX aggr size
387  * @rx_aggr_size : RX aggr size
388  * @enable_bitmap: Bitmap for aggr size check
389  */
390 struct set_custom_aggr_size_params {
391 	uint32_t  vdev_id;
392 	uint32_t tx_aggr_size;
393 	uint32_t rx_aggr_size;
394 	uint32_t ac:2,
395 		 aggr_type:1,
396 		 tx_aggr_size_disable:1,
397 		 rx_aggr_size_disable:1,
398 		 tx_ac_enable:1,
399 		 reserved:26;
400 };
401 
402 /**
403  * struct sifs_trigger_param - sifs_trigger cmd parameter
404  * @vdev_id: vdev id
405  * @param_value: parameter value
406  */
407 struct sifs_trigger_param {
408 	uint32_t vdev_id;
409 	uint32_t param_value;
410 };
411 
412 /**
413  * struct set_neighbour_rx_params - Neighbour RX params
414  * @vdev_id: vdev id
415  * @idx: index of param
416  * @action: action
417  * @type: Type of param
418  */
419 struct set_neighbour_rx_params {
420 	uint8_t vdev_id;
421 	uint32_t idx;
422 	uint32_t action;
423 	uint32_t type;
424 };
425 
426 /**
427  * struct vdev_scan_nac_rssi_params - NAC_RSSI cmd parameter
428  * @vdev_id: vdev id
429  * @bssid_addr: BSSID address
430  * @client_addr: client address
431  * @chan_num: channel number
432  * @action:NAC_RSSI action,
433  */
434 struct vdev_scan_nac_rssi_params {
435 	uint32_t vdev_id;
436 	uint8_t bssid_addr[QDF_MAC_ADDR_SIZE];
437 	uint8_t client_addr[QDF_MAC_ADDR_SIZE];
438 	uint32_t chan_num;
439 	uint32_t action; /* WMI_FILTER_NAC_RSSI_ACTION */
440 };
441 
442 /**
443  * struct vdev_start_params - vdev start cmd parameter
444  * @vdev_id: vdev id
445  * @beacon_interval: beacon interval
446  * @dtim_period: dtim period
447  * @is_restart: flag to check if it is vdev
448  * @disable_hw_ack: to update disable hw ack flag
449  * @hidden_ssid: hidden ssid
450  * @pmf_enabled: pmf enabled
451  * @ssid: ssid MAC
452  * @num_noa_descriptors: number of noa descriptors
453  * @preferred_tx_streams: preferred tx streams
454  * @preferred_rx_streams: preferred rx streams
455  * @cac_duration_ms: cac duration in milliseconds
456  * @regdomain: Regulatory domain
457  * @he_ops: HE ops
458  * @channel_param: Channel params required by target.
459  * @bcn_tx_rate_code: Beacon tx rate code.
460  * @ldpc_rx_enabled: Enable/Disable LDPC RX for this vdev
461  */
462 struct vdev_start_params {
463 	uint8_t vdev_id;
464 	uint32_t beacon_interval;
465 	uint32_t dtim_period;
466 	bool is_restart;
467 	uint32_t disable_hw_ack;
468 	bool hidden_ssid;
469 	bool pmf_enabled;
470 	struct mlme_mac_ssid ssid;
471 	uint32_t num_noa_descriptors;
472 	uint32_t preferred_rx_streams;
473 	uint32_t preferred_tx_streams;
474 	uint32_t cac_duration_ms;
475 	uint32_t regdomain;
476 	uint32_t he_ops;
477 	struct mlme_channel_param channel;
478 	enum mlme_bcn_tx_rate_code bcn_tx_rate_code;
479 	bool ldpc_rx_enabled;
480 };
481 
482 /**
483  * struct vdev_set_params - vdev set cmd parameter
484  * @vdev_id: vdev id
485  * @param_id: parameter id
486  * @param_value: parameter value
487  */
488 struct vdev_set_params {
489 	uint32_t vdev_id;
490 	uint32_t param_id;
491 	uint32_t param_value;
492 };
493 
494 /**
495  * struct vdev_create_params - vdev create cmd parameter
496  * @vdev_id: interface id
497  * @type: interface type
498  * @subtype: interface subtype
499  * @nss_2g: NSS for 2G
500  * @nss_5g: NSS for 5G
501  * @pdev_id: pdev id on pdev for this vdev
502  * @mbssid_flags: MBSS IE flags indicating vdev type
503  * @vdevid_trans: id of transmitting vdev for MBSS IE
504  */
505 struct vdev_create_params {
506 	uint8_t vdev_id;
507 	uint32_t type;
508 	uint32_t subtype;
509 	uint8_t nss_2g;
510 	uint8_t nss_5g;
511 	uint32_t pdev_id;
512 	uint32_t mbssid_flags;
513 	uint8_t vdevid_trans;
514 };
515 
516 /**
517  * struct vdev_delete_params - vdev delete cmd parameter
518  * @vdev_id: vdev id
519  */
520 struct vdev_delete_params {
521 	uint8_t vdev_id;
522 };
523 
524 /**
525  * struct vdev_stop_params - vdev stop cmd parameter
526  * @vdev_id: vdev id
527  */
528 struct vdev_stop_params {
529 	uint8_t vdev_id;
530 };
531 
532 /**
533  * struct vdev_up_params - vdev up cmd parameter
534  * @vdev_id: vdev id
535  * @assoc_id: association id
536  * @profile_idx: profile index of the connected non-trans ap (mbssid case).
537  *		0  means invalid.
538  * @profile_num: the total profile numbers of non-trans aps (mbssid case).
539  *		0 means non-MBSS AP.
540  * @trans_bssid: bssid of transmitted AP (MBSS IE case)
541  */
542 struct vdev_up_params {
543 	uint8_t vdev_id;
544 	uint16_t assoc_id;
545 	uint32_t profile_idx;
546 	uint32_t profile_num;
547 	uint8_t trans_bssid[QDF_MAC_ADDR_SIZE];
548 };
549 
550 /**
551  * struct vdev_down_params - vdev down cmd parameter
552  * @vdev_id: vdev id
553  */
554 struct vdev_down_params {
555 	uint8_t vdev_id;
556 };
557 
558 /**
559  * struct peer_delete_all_params - peer delete all request parameter
560  * @vdev_id: vdev id
561  */
562 struct peer_delete_all_params {
563 	uint8_t vdev_id;
564 };
565 
566 #define AC_MAX 4
567 #define WMI_MUEDCA_PARAM_MASK 0xff
568 /**
569  * struct muedca_params - MU-EDCA parameters
570  * @muedca_ecwmin: CWmin in exponential form
571  * @muedca_ecwmax: CWmax in exponential form
572  * @muedca_aifsn:  AIFSN parameter
573  * @muedca_acm:    ACM parameter
574  * @muedca_timer:  MU EDCA timer value
575  */
576 struct muedca_params {
577 	uint32_t pdev_id;
578 	uint8_t muedca_ecwmin[AC_MAX];      /* CWmin in exponential form */
579 	uint8_t muedca_ecwmax[AC_MAX];      /* CWmax in exponential form */
580 	uint8_t muedca_aifsn[AC_MAX];       /* AIFSN parameter */
581 	uint8_t muedca_acm[AC_MAX];         /* ACM parameter */
582 	uint8_t muedca_timer[AC_MAX];       /* MU EDCA timer value */
583 };
584 
585 #endif /* __WLAN_VDEV_MGR_TX_OPS_DEFS_H__ */
586