1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#ifndef __PHY_H
17#define __PHY_H
18
19#include <linux/compiler.h>
20#include <linux/spinlock.h>
21#include <linux/ethtool.h>
22#include <linux/mdio.h>
23#include <linux/mii.h>
24#include <linux/module.h>
25#include <linux/timer.h>
26#include <linux/workqueue.h>
27#include <linux/mod_devicetable.h>
28
29#include <linux/atomic.h>
30
31#define PHY_DEFAULT_FEATURES (SUPPORTED_Autoneg | \
32 SUPPORTED_TP | \
33 SUPPORTED_MII)
34
35#define PHY_10BT_FEATURES (SUPPORTED_10baseT_Half | \
36 SUPPORTED_10baseT_Full)
37
38#define PHY_100BT_FEATURES (SUPPORTED_100baseT_Half | \
39 SUPPORTED_100baseT_Full)
40
41#define PHY_1000BT_FEATURES (SUPPORTED_1000baseT_Half | \
42 SUPPORTED_1000baseT_Full)
43
44#define PHY_BASIC_FEATURES (PHY_10BT_FEATURES | \
45 PHY_100BT_FEATURES | \
46 PHY_DEFAULT_FEATURES)
47
48#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \
49 PHY_1000BT_FEATURES)
50
51
52
53
54
55
56
57#define PHY_POLL -1
58#define PHY_IGNORE_INTERRUPT -2
59
60#define PHY_HAS_INTERRUPT 0x00000001
61#define PHY_IS_INTERNAL 0x00000002
62#define MDIO_DEVICE_IS_PHY 0x80000000
63
64
65typedef enum {
66 PHY_INTERFACE_MODE_NA,
67 PHY_INTERFACE_MODE_INTERNAL,
68 PHY_INTERFACE_MODE_MII,
69 PHY_INTERFACE_MODE_GMII,
70 PHY_INTERFACE_MODE_SGMII,
71 PHY_INTERFACE_MODE_TBI,
72 PHY_INTERFACE_MODE_REVMII,
73 PHY_INTERFACE_MODE_RMII,
74 PHY_INTERFACE_MODE_RGMII,
75 PHY_INTERFACE_MODE_RGMII_ID,
76 PHY_INTERFACE_MODE_RGMII_RXID,
77 PHY_INTERFACE_MODE_RGMII_TXID,
78 PHY_INTERFACE_MODE_RTBI,
79 PHY_INTERFACE_MODE_SMII,
80 PHY_INTERFACE_MODE_XGMII,
81 PHY_INTERFACE_MODE_MOCA,
82 PHY_INTERFACE_MODE_QSGMII,
83 PHY_INTERFACE_MODE_TRGMII,
84 PHY_INTERFACE_MODE_1000BASEX,
85 PHY_INTERFACE_MODE_2500BASEX,
86 PHY_INTERFACE_MODE_RXAUI,
87 PHY_INTERFACE_MODE_XAUI,
88
89 PHY_INTERFACE_MODE_10GKR,
90 PHY_INTERFACE_MODE_MAX,
91} phy_interface_t;
92
93
94
95
96
97
98
99
100
101
102
103
104unsigned int phy_supported_speeds(struct phy_device *phy,
105 unsigned int *speeds,
106 unsigned int size);
107
108
109
110
111
112
113static inline const char *phy_modes(phy_interface_t interface)
114{
115 switch (interface) {
116 case PHY_INTERFACE_MODE_NA:
117 return "";
118 case PHY_INTERFACE_MODE_INTERNAL:
119 return "internal";
120 case PHY_INTERFACE_MODE_MII:
121 return "mii";
122 case PHY_INTERFACE_MODE_GMII:
123 return "gmii";
124 case PHY_INTERFACE_MODE_SGMII:
125 return "sgmii";
126 case PHY_INTERFACE_MODE_TBI:
127 return "tbi";
128 case PHY_INTERFACE_MODE_REVMII:
129 return "rev-mii";
130 case PHY_INTERFACE_MODE_RMII:
131 return "rmii";
132 case PHY_INTERFACE_MODE_RGMII:
133 return "rgmii";
134 case PHY_INTERFACE_MODE_RGMII_ID:
135 return "rgmii-id";
136 case PHY_INTERFACE_MODE_RGMII_RXID:
137 return "rgmii-rxid";
138 case PHY_INTERFACE_MODE_RGMII_TXID:
139 return "rgmii-txid";
140 case PHY_INTERFACE_MODE_RTBI:
141 return "rtbi";
142 case PHY_INTERFACE_MODE_SMII:
143 return "smii";
144 case PHY_INTERFACE_MODE_XGMII:
145 return "xgmii";
146 case PHY_INTERFACE_MODE_MOCA:
147 return "moca";
148 case PHY_INTERFACE_MODE_QSGMII:
149 return "qsgmii";
150 case PHY_INTERFACE_MODE_TRGMII:
151 return "trgmii";
152 case PHY_INTERFACE_MODE_1000BASEX:
153 return "1000base-x";
154 case PHY_INTERFACE_MODE_2500BASEX:
155 return "2500base-x";
156 case PHY_INTERFACE_MODE_RXAUI:
157 return "rxaui";
158 case PHY_INTERFACE_MODE_XAUI:
159 return "xaui";
160 case PHY_INTERFACE_MODE_10GKR:
161 return "10gbase-kr";
162 default:
163 return "unknown";
164 }
165}
166
167
168#define PHY_INIT_TIMEOUT 100000
169#define PHY_STATE_TIME 1
170#define PHY_FORCE_TIMEOUT 10
171#define PHY_AN_TIMEOUT 10
172
173#define PHY_MAX_ADDR 32
174
175
176#define PHY_ID_FMT "%s:%02x"
177
178#define MII_BUS_ID_SIZE 61
179
180
181
182#define MII_ADDR_C45 (1<<30)
183
184struct device;
185struct phylink;
186struct sk_buff;
187
188
189
190
191
192struct mii_bus {
193 struct module *owner;
194 const char *name;
195 char id[MII_BUS_ID_SIZE];
196 void *priv;
197 int (*read)(struct mii_bus *bus, int addr, int regnum);
198 int (*write)(struct mii_bus *bus, int addr, int regnum, u16 val);
199 int (*reset)(struct mii_bus *bus);
200
201
202
203
204
205 struct mutex mdio_lock;
206
207 struct device *parent;
208 enum {
209 MDIOBUS_ALLOCATED = 1,
210 MDIOBUS_REGISTERED,
211 MDIOBUS_UNREGISTERED,
212 MDIOBUS_RELEASED,
213 } state;
214 struct device dev;
215
216
217 struct mdio_device *mdio_map[PHY_MAX_ADDR];
218
219
220 u32 phy_mask;
221
222
223 u32 phy_ignore_ta_mask;
224
225
226
227
228
229 int irq[PHY_MAX_ADDR];
230
231
232 int reset_delay_us;
233
234 struct gpio_desc *reset_gpiod;
235};
236#define to_mii_bus(d) container_of(d, struct mii_bus, dev)
237
238struct mii_bus *mdiobus_alloc_size(size_t);
239static inline struct mii_bus *mdiobus_alloc(void)
240{
241 return mdiobus_alloc_size(0);
242}
243
244int __mdiobus_register(struct mii_bus *bus, struct module *owner);
245#define mdiobus_register(bus) __mdiobus_register(bus, THIS_MODULE)
246void mdiobus_unregister(struct mii_bus *bus);
247void mdiobus_free(struct mii_bus *bus);
248struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv);
249static inline struct mii_bus *devm_mdiobus_alloc(struct device *dev)
250{
251 return devm_mdiobus_alloc_size(dev, 0);
252}
253
254void devm_mdiobus_free(struct device *dev, struct mii_bus *bus);
255struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
256
257#define PHY_INTERRUPT_DISABLED 0x0
258#define PHY_INTERRUPT_ENABLED 0x80000000
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
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340enum phy_state {
341 PHY_DOWN = 0,
342 PHY_STARTING,
343 PHY_READY,
344 PHY_PENDING,
345 PHY_UP,
346 PHY_AN,
347 PHY_RUNNING,
348 PHY_NOLINK,
349 PHY_FORCING,
350 PHY_CHANGELINK,
351 PHY_HALTED,
352 PHY_RESUMING
353};
354
355
356
357
358
359
360struct phy_c45_device_ids {
361 u32 devices_in_package;
362 u32 device_ids[8];
363};
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398struct phy_device {
399 struct mdio_device mdio;
400
401
402
403 struct phy_driver *drv;
404
405 u32 phy_id;
406
407 struct phy_c45_device_ids c45_ids;
408 bool is_c45;
409 bool is_internal;
410 bool is_pseudo_fixed_link;
411 bool has_fixups;
412 bool suspended;
413 bool sysfs_links;
414 bool loopback_enabled;
415
416 enum phy_state state;
417
418 u32 dev_flags;
419
420 phy_interface_t interface;
421
422
423
424
425
426 int speed;
427 int duplex;
428 int pause;
429 int asym_pause;
430
431
432 int link;
433
434
435 u32 interrupts;
436
437
438
439 u32 supported;
440 u32 advertising;
441 u32 lp_advertising;
442
443
444 u32 eee_broken_modes;
445
446 int autoneg;
447
448 int link_timeout;
449
450#ifdef CONFIG_LED_TRIGGER_PHY
451 struct phy_led_trigger *phy_led_triggers;
452 unsigned int phy_num_led_triggers;
453 struct phy_led_trigger *last_triggered;
454
455 struct phy_led_trigger *led_link_trigger;
456#endif
457
458
459
460
461
462 int irq;
463
464
465
466 void *priv;
467
468
469 struct work_struct phy_queue;
470 struct delayed_work state_queue;
471 atomic_t irq_disable;
472
473 struct mutex lock;
474
475 struct phylink *phylink;
476 struct net_device *attached_dev;
477
478 u8 mdix;
479 u8 mdix_ctrl;
480
481 void (*phy_link_change)(struct phy_device *, bool up, bool do_carrier);
482 void (*adjust_link)(struct net_device *dev);
483};
484#define to_phy_device(d) container_of(to_mdio_device(d), \
485 struct phy_device, mdio)
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508struct phy_driver {
509 struct mdio_driver_common mdiodrv;
510 u32 phy_id;
511 char *name;
512 unsigned int phy_id_mask;
513 u32 features;
514 u32 flags;
515 const void *driver_data;
516
517
518
519
520 int (*soft_reset)(struct phy_device *phydev);
521
522
523
524
525
526 int (*config_init)(struct phy_device *phydev);
527
528
529
530
531
532 int (*probe)(struct phy_device *phydev);
533
534
535 int (*suspend)(struct phy_device *phydev);
536 int (*resume)(struct phy_device *phydev);
537
538
539
540
541
542
543
544 int (*config_aneg)(struct phy_device *phydev);
545
546
547 int (*aneg_done)(struct phy_device *phydev);
548
549
550 int (*read_status)(struct phy_device *phydev);
551
552
553 int (*ack_interrupt)(struct phy_device *phydev);
554
555
556 int (*config_intr)(struct phy_device *phydev);
557
558
559
560
561
562 int (*did_interrupt)(struct phy_device *phydev);
563
564
565 void (*remove)(struct phy_device *phydev);
566
567
568
569
570
571 int (*match_phy_device)(struct phy_device *phydev);
572
573
574 int (*ts_info)(struct phy_device *phydev, struct ethtool_ts_info *ti);
575
576
577 int (*hwtstamp)(struct phy_device *phydev, struct ifreq *ifr);
578
579
580
581
582
583
584
585
586 bool (*rxtstamp)(struct phy_device *dev, struct sk_buff *skb, int type);
587
588
589
590
591
592
593
594 void (*txtstamp)(struct phy_device *dev, struct sk_buff *skb, int type);
595
596
597
598
599 int (*set_wol)(struct phy_device *dev, struct ethtool_wolinfo *wol);
600
601
602 void (*get_wol)(struct phy_device *dev, struct ethtool_wolinfo *wol);
603
604
605
606
607
608
609
610
611 void (*link_change_notify)(struct phy_device *dev);
612
613
614
615
616
617
618
619
620
621
622 int (*read_mmd)(struct phy_device *dev, int devnum, u16 regnum);
623
624
625
626
627
628
629
630
631
632
633
634 int (*write_mmd)(struct phy_device *dev, int devnum, u16 regnum,
635 u16 val);
636
637
638
639 int (*module_info)(struct phy_device *dev,
640 struct ethtool_modinfo *modinfo);
641
642
643 int (*module_eeprom)(struct phy_device *dev,
644 struct ethtool_eeprom *ee, u8 *data);
645
646
647 int (*get_sset_count)(struct phy_device *dev);
648 void (*get_strings)(struct phy_device *dev, u8 *data);
649 void (*get_stats)(struct phy_device *dev,
650 struct ethtool_stats *stats, u64 *data);
651
652
653 int (*get_tunable)(struct phy_device *dev,
654 struct ethtool_tunable *tuna, void *data);
655 int (*set_tunable)(struct phy_device *dev,
656 struct ethtool_tunable *tuna,
657 const void *data);
658 int (*set_loopback)(struct phy_device *dev, bool enable);
659};
660#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
661 struct phy_driver, mdiodrv)
662
663#define PHY_ANY_ID "MATCH ANY PHY"
664#define PHY_ANY_UID 0xffffffff
665
666
667struct phy_fixup {
668 struct list_head list;
669 char bus_id[MII_BUS_ID_SIZE + 3];
670 u32 phy_uid;
671 u32 phy_uid_mask;
672 int (*run)(struct phy_device *phydev);
673};
674
675const char *phy_speed_to_str(int speed);
676const char *phy_duplex_to_str(unsigned int duplex);
677
678
679
680
681struct phy_setting {
682 u32 speed;
683 u8 duplex;
684 u8 bit;
685};
686
687const struct phy_setting *
688phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
689 size_t maxbit, bool exact);
690size_t phy_speeds(unsigned int *speeds, size_t size,
691 unsigned long *mask, size_t maxbit);
692
693
694
695
696
697
698
699
700
701
702int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
703
704
705
706
707
708
709
710
711
712
713static inline int phy_read(struct phy_device *phydev, u32 regnum)
714{
715 return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, regnum);
716}
717
718
719
720
721
722
723
724
725
726
727
728static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val)
729{
730 return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
731}
732
733
734
735
736
737
738
739
740static inline bool phy_interrupt_is_valid(struct phy_device *phydev)
741{
742 return phydev->irq != PHY_POLL && phydev->irq != PHY_IGNORE_INTERRUPT;
743}
744
745
746
747
748
749static inline bool phy_is_internal(struct phy_device *phydev)
750{
751 return phydev->is_internal;
752}
753
754
755
756
757
758
759static inline bool phy_interface_mode_is_rgmii(phy_interface_t mode)
760{
761 return mode >= PHY_INTERFACE_MODE_RGMII &&
762 mode <= PHY_INTERFACE_MODE_RGMII_TXID;
763};
764
765
766
767
768
769
770static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
771{
772 return phy_interface_mode_is_rgmii(phydev->interface);
773};
774
775
776
777
778
779
780static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev)
781{
782 return phydev->is_pseudo_fixed_link;
783}
784
785
786
787
788
789
790
791
792
793
794
795int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
796
797struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
798 bool is_c45,
799 struct phy_c45_device_ids *c45_ids);
800#if IS_ENABLED(CONFIG_PHYLIB)
801struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45);
802int phy_device_register(struct phy_device *phy);
803void phy_device_free(struct phy_device *phydev);
804#else
805static inline
806struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
807{
808 return NULL;
809}
810
811static inline int phy_device_register(struct phy_device *phy)
812{
813 return 0;
814}
815
816static inline void phy_device_free(struct phy_device *phydev) { }
817#endif
818void phy_device_remove(struct phy_device *phydev);
819int phy_init_hw(struct phy_device *phydev);
820int phy_suspend(struct phy_device *phydev);
821int phy_resume(struct phy_device *phydev);
822int phy_loopback(struct phy_device *phydev, bool enable);
823struct phy_device *phy_attach(struct net_device *dev, const char *bus_id,
824 phy_interface_t interface);
825struct phy_device *phy_find_first(struct mii_bus *bus);
826int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
827 u32 flags, phy_interface_t interface);
828int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
829 void (*handler)(struct net_device *),
830 phy_interface_t interface);
831struct phy_device *phy_connect(struct net_device *dev, const char *bus_id,
832 void (*handler)(struct net_device *),
833 phy_interface_t interface);
834void phy_disconnect(struct phy_device *phydev);
835void phy_detach(struct phy_device *phydev);
836void phy_start(struct phy_device *phydev);
837void phy_stop(struct phy_device *phydev);
838int phy_start_aneg(struct phy_device *phydev);
839int phy_aneg_done(struct phy_device *phydev);
840
841int phy_stop_interrupts(struct phy_device *phydev);
842int phy_restart_aneg(struct phy_device *phydev);
843
844static inline int phy_read_status(struct phy_device *phydev)
845{
846 if (!phydev->drv)
847 return -EIO;
848
849 return phydev->drv->read_status(phydev);
850}
851
852#define phydev_err(_phydev, format, args...) \
853 dev_err(&_phydev->mdio.dev, format, ##args)
854
855#define phydev_dbg(_phydev, format, args...) \
856 dev_dbg(&_phydev->mdio.dev, format, ##args)
857
858static inline const char *phydev_name(const struct phy_device *phydev)
859{
860 return dev_name(&phydev->mdio.dev);
861}
862
863void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
864 __printf(2, 3);
865void phy_attached_info(struct phy_device *phydev);
866
867
868int genphy_config_init(struct phy_device *phydev);
869int genphy_setup_forced(struct phy_device *phydev);
870int genphy_restart_aneg(struct phy_device *phydev);
871int genphy_config_aneg(struct phy_device *phydev);
872int genphy_aneg_done(struct phy_device *phydev);
873int genphy_update_link(struct phy_device *phydev);
874int genphy_read_status(struct phy_device *phydev);
875int genphy_suspend(struct phy_device *phydev);
876int genphy_resume(struct phy_device *phydev);
877int genphy_loopback(struct phy_device *phydev, bool enable);
878int genphy_soft_reset(struct phy_device *phydev);
879static inline int genphy_no_soft_reset(struct phy_device *phydev)
880{
881 return 0;
882}
883
884
885int genphy_c45_restart_aneg(struct phy_device *phydev);
886int genphy_c45_aneg_done(struct phy_device *phydev);
887int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask);
888int genphy_c45_read_lpa(struct phy_device *phydev);
889int genphy_c45_read_pma(struct phy_device *phydev);
890int genphy_c45_pma_setup_forced(struct phy_device *phydev);
891int genphy_c45_an_disable_aneg(struct phy_device *phydev);
892
893void phy_driver_unregister(struct phy_driver *drv);
894void phy_drivers_unregister(struct phy_driver *drv, int n);
895int phy_driver_register(struct phy_driver *new_driver, struct module *owner);
896int phy_drivers_register(struct phy_driver *new_driver, int n,
897 struct module *owner);
898void phy_state_machine(struct work_struct *work);
899void phy_change(struct phy_device *phydev);
900void phy_change_work(struct work_struct *work);
901void phy_mac_interrupt(struct phy_device *phydev, int new_link);
902void phy_start_machine(struct phy_device *phydev);
903void phy_stop_machine(struct phy_device *phydev);
904void phy_trigger_machine(struct phy_device *phydev, bool sync);
905int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
906void phy_ethtool_ksettings_get(struct phy_device *phydev,
907 struct ethtool_link_ksettings *cmd);
908int phy_ethtool_ksettings_set(struct phy_device *phydev,
909 const struct ethtool_link_ksettings *cmd);
910int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
911int phy_start_interrupts(struct phy_device *phydev);
912void phy_print_status(struct phy_device *phydev);
913int phy_set_max_speed(struct phy_device *phydev, u32 max_speed);
914
915int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
916 int (*run)(struct phy_device *));
917int phy_register_fixup_for_id(const char *bus_id,
918 int (*run)(struct phy_device *));
919int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
920 int (*run)(struct phy_device *));
921
922int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask);
923int phy_unregister_fixup_for_id(const char *bus_id);
924int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask);
925
926int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable);
927int phy_get_eee_err(struct phy_device *phydev);
928int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data);
929int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data);
930int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);
931void phy_ethtool_get_wol(struct phy_device *phydev,
932 struct ethtool_wolinfo *wol);
933int phy_ethtool_get_link_ksettings(struct net_device *ndev,
934 struct ethtool_link_ksettings *cmd);
935int phy_ethtool_set_link_ksettings(struct net_device *ndev,
936 const struct ethtool_link_ksettings *cmd);
937int phy_ethtool_nway_reset(struct net_device *ndev);
938
939#if IS_ENABLED(CONFIG_PHYLIB)
940int __init mdio_bus_init(void);
941void mdio_bus_exit(void);
942#endif
943
944extern struct bus_type mdio_bus_type;
945
946struct mdio_board_info {
947 const char *bus_id;
948 char modalias[MDIO_NAME_SIZE];
949 int mdio_addr;
950 const void *platform_data;
951};
952
953#if IS_ENABLED(CONFIG_MDIO_DEVICE)
954int mdiobus_register_board_info(const struct mdio_board_info *info,
955 unsigned int n);
956#else
957static inline int mdiobus_register_board_info(const struct mdio_board_info *i,
958 unsigned int n)
959{
960 return 0;
961}
962#endif
963
964
965
966
967
968
969
970
971
972
973#define phy_module_driver(__phy_drivers, __count) \
974static int __init phy_module_init(void) \
975{ \
976 return phy_drivers_register(__phy_drivers, __count, THIS_MODULE); \
977} \
978module_init(phy_module_init); \
979static void __exit phy_module_exit(void) \
980{ \
981 phy_drivers_unregister(__phy_drivers, __count); \
982} \
983module_exit(phy_module_exit)
984
985#define module_phy_driver(__phy_drivers) \
986 phy_module_driver(__phy_drivers, ARRAY_SIZE(__phy_drivers))
987
988#endif
989