1 /*
2  * Copyright (c) 2022, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef USB_HUB_H
7 #define USB_HUB_H
8 
9 /* HUB Class Descriptor Types */
10 #define HUB_DESCRIPTOR_TYPE_HUB  0x29
11 #define HUB_DESCRIPTOR_TYPE_HUB3 0x2A
12 
13 #define HUB_MAX_DEPTH 5
14 
15 #define HUB_SUBCLASS     0x00
16 #define HUB_PROTOCOL_STT 0x01
17 #define HUB_PROTOCOL_MTT 0x02
18 
19 /* Hub class requests */
20 #define HUB_REQUEST_GET_STATUS      USB_REQUEST_GET_STATUS
21 #define HUB_REQUEST_CLEAR_FEATURE   USB_REQUEST_CLEAR_FEATURE
22 #define HUB_REQUEST_SET_FEATURE     USB_REQUEST_SET_FEATURE
23 #define HUB_REQUEST_GET_DESCRIPTOR  USB_REQUEST_GET_DESCRIPTOR
24 #define HUB_REQUEST_SET_DESCRIPTOR  USB_REQUEST_SET_DESCRIPTOR
25 #define HUB_REQUEST_CLEAR_TT_BUFFER (0x08)
26 #define HUB_REQUEST_RESET_TT        (0x09)
27 #define HUB_REQUEST_GET_TT_STATE    (0x0a)
28 #define HUB_REQUEST_STOP_TT         (0x0b)
29 #define HUB_REQUEST_SET_HUB_DEPTH   (0x0C)
30 
31 /* Hub class features */
32 #define HUB_FEATURE_HUB_C_LOCALPOWER  (0x0)
33 #define HUB_FEATURE_HUB_C_OVERCURRENT (0x1)
34 
35 /* Port features */
36 #define HUB_PORT_FEATURE_CONNECTION  (0x00)
37 #define HUB_PORT_FEATURE_ENABLE      (0x01)
38 #define HUB_PORT_FEATURE_SUSPEND     (0x02)
39 #define HUB_PORT_FEATURE_OVERCURRENT (0x03)
40 #define HUB_PORT_FEATURE_RESET       (0x04)
41 #define HUB_PORT_FEATURE_L1          (0x05) /* USB 2.0 only */
42 
43 #define HUB_PORT_FEATURE_POWER    (0x08) /* USB 2.0 only */
44 #define HUB_PORT_FEATURE_POWER_SS (0x09) /* USB 3.0 only */
45 /* This is a bit tricky because HUB_PORT_FEATURE_POWER_SS and
46    HUB_PORT_FEATURE_LOWSPEED share the same bit. */
47 #define HUB_PORT_FEATURE_LOWSPEED  (0x09) /* USB 2.0 only */
48 #define HUB_PORT_FEATURE_HIGHSPEED (0x0a) /* USB 2.0 only */
49 #define HUB_PORT_FEATURE_TEST      (0x0b) /* USB 2.0 only */
50 #define HUB_PORT_FEATURE_INDICATOR (0x0c) /* USB 2.0 only */
51 
52 /* Port status change (wPortChange) */
53 #define HUB_PORT_FEATURE_C_CONNECTION  (0x10)
54 #define HUB_PORT_FEATURE_C_ENABLE      (0x11) /* USB 2.0 only */
55 #define HUB_PORT_FEATURE_C_SUSPEND     (0x12) /* USB 2.0 only */
56 #define HUB_PORT_FEATURE_C_OVER_CURREN (0x13)
57 #define HUB_PORT_FEATURE_C_RESET       (0x14)
58 #define HUB_PORT_FEATURE_C_BH_RESET    (0x15) /* USB 3.0 only */
59 #define HUB_PORT_FEATURE_C_LINK_STATE  (0x16) /* USB 3.0 only */
60 #define HUB_PORT_FEATURE_C_CONFIG_ERR  (0x17) /* USB 3.0 only */
61 
62 /* Hub status */
63 #define HUB_STATUS_LOCALPOWER  (1 << 0)
64 #define HUB_STATUS_OVERCURRENT (1 << 1)
65 
66 /* Hub status change */
67 #define HUB_STATUS_C_LOCALPOWER  (1 << 0)
68 #define HUB_STATUS_C_OVERCURRENT (1 << 1)
69 
70 /* Hub port status */
71 #define HUB_PORT_STATUS_CONNECTION  (1 << 0)
72 #define HUB_PORT_STATUS_ENABLE      (1 << 1)
73 #define HUB_PORT_STATUS_SUSPEND     (1 << 2) /* USB 2.0 only */
74 #define HUB_PORT_STATUS_OVERCURRENT (1 << 3)
75 #define HUB_PORT_STATUS_RESET       (1 << 4)
76 #define HUB_PORT_STATUS_L1          (1 << 5) /* USB 2.0 only */
77 
78 /* Port Link State (PORT_LINK_STATE), USB 3.0 only */
79 #define HUB_PORT_STATUS_LS_U0          (0x00 << 5)
80 #define HUB_PORT_STATUS_LS_U1          (0x01 << 5)
81 #define HUB_PORT_STATUS_LS_U2          (0x02 << 5)
82 #define HUB_PORT_STATUS_LS_U3          (0x03 << 5)
83 #define HUB_PORT_STATUS_LS_SS_DISABLED (0x04 << 5)
84 #define HUB_PORT_STATUS_LS_RX_DETECT   (0x05 << 5)
85 #define HUB_PORT_STATUS_LS_SS_INACTIVE (0x06 << 5)
86 #define HUB_PORT_STATUS_LS_POLLING     (0x07 << 5)
87 #define HUB_PORT_STATUS_LS_RECOVERY    (0x08 << 5)
88 #define HUB_PORT_STATUS_LS_HOT_RESET   (0x09 << 5)
89 #define HUB_PORT_STATUS_LS_COMP_MOD    (0x0a << 5)
90 #define HUB_PORT_STATUS_LS_LOOPBACK    (0x0b << 5)
91 
92 #define HUB_PORT_STATUS_POWER      (1 << 8)
93 #define HUB_PORT_STATUS_POWER_SS   (1 << 9)  /* USB 3.0 only */
94 #define HUB_PORT_STATUS_LOW_SPEED  (1 << 9)  /* USB 2.0 only */
95 #define HUB_PORT_STATUS_HIGH_SPEED (1 << 10) /* USB 2.0 only */
96 #define HUB_PORT_STATUS_TEST       (1 << 11) /* USB 2.0 only */
97 #define HUB_PORT_STATUS_INDICATOR  (1 << 12) /* USB 2.0 only */
98 
99 /* Hub port status change */
100 #define HUB_PORT_STATUS_C_CONNECTION  (1 << 0)
101 #define HUB_PORT_STATUS_C_ENABLE      (1 << 1) /* USB 2.0 only */
102 #define HUB_PORT_STATUS_C_SUSPEND     (1 << 2) /* USB 2.0 only */
103 #define HUB_PORT_STATUS_C_OVERCURRENT (1 << 3)
104 #define HUB_PORT_STATUS_C_RESET       (1 << 4)
105 #define HUB_PORT_STATUS_C_L1          (1 << 5) /* USB 2.0 only */
106 #define HUB_PORT_STATUS_C_BH_RESET    (1 << 5) /* USB 3.0 only */
107 #define HUB_PORT_STATUS_C_PORTLINK    (1 << 6) /* USB 3.0 only */
108 #define HUB_PORT_STATUS_C_CONFIGERR   (1 << 7) /* USB 3.0 only */
109 
110 /* Hub characteristics */
111 #define HUB_CHAR_LPSM_SHIFT      (0) /* Bits 0-1: Logical Power Switching Mode */
112 #define HUB_CHAR_LPSM_MASK       (3 << HUB_CHAR_LPSM_SHIFT)
113 #define HUB_CHAR_LPSM_GANGED     (0 << HUB_CHAR_LPSM_SHIFT)
114 #define HUB_CHAR_LPSM_INDIVIDUAL (1 << HUB_CHAR_LPSM_SHIFT)
115 #define HUB_CHAR_COMPOUND        (1 << 2) /* Bit 2: Compound device */
116 #define HUB_CHAR_OCPM_SHIFT      (3)      /* Bits 3-4: Over-current Protection Mode */
117 #define HUB_CHAR_OCPM_MASK       (3 << HUB_CHAR_OCPM_SHIFT)
118 #define HUB_CHAR_OCPM_GLOBAL     (0 << HUB_CHAR_OCPM_SHIFT)
119 #define HUB_CHAR_OCPM_INDIVIDUAL (1 << HUB_CHAR_OCPM_SHIFT)
120 #define HUB_CHAR_TTTT_SHIFT      (5) /* Bits 5-6: TT Think Time */
121 #define HUB_CHAR_TTTT_MASK       (3 << HUB_CHAR_TTTT_SHIFT)
122 #define HUB_CHAR_TTTT_8_BITS     (0 << HUB_CHAR_TTTT_SHIFT)
123 #define HUB_CHAR_TTTT_16_BITS    (1 << HUB_CHAR_TTTT_SHIFT)
124 #define HUB_CHAR_TTTT_24_BITS    (2 << HUB_CHAR_TTTT_SHIFT)
125 #define HUB_CHAR_TTTT_32_BITS    (3 << HUB_CHAR_TTTT_SHIFT)
126 #define HUB_CHAR_PORTIND         (1 << 7) /* Bit 7: Port Indicators Supported */
127 
128 /* Hub descriptor */
129 struct usb_hub_descriptor {
130     uint8_t bLength;
131     uint8_t bDescriptorType;
132     uint8_t bNbrPorts;
133     uint16_t wHubCharacteristics;
134     uint8_t bPwrOn2PwrGood;
135     uint8_t bHubContrCurrent;
136     uint8_t DeviceRemovable;
137     uint8_t PortPwrCtrlMask;
138 } __PACKED;
139 
140 #define USB_SIZEOF_HUB_DESC 9
141 
142 /* Super speed Hub descriptor */
143 struct usb_hub_ss_descriptor {
144     uint8_t bLength;
145     uint8_t bDescriptorType;
146     uint8_t bNbrPorts;
147     uint16_t wHubCharacteristics;
148     uint8_t bPwrOn2PwrGood;
149     uint8_t bHubContrCurrent;
150     uint8_t bHubHdrDecLat;
151     uint16_t wHubDelay;
152     uint8_t DeviceRemovable;
153 } __PACKED;
154 
155 #define USB_SIZEOF_HUB_SS_DESC 11
156 
157 /* Hub status */
158 struct hub_status {
159     uint16_t wPortStatus;
160     uint16_t wPortChange;
161 };
162 
163 /* Hub port status */
164 struct hub_port_status {
165     uint16_t wPortStatus;
166     uint16_t wPortChange;
167 };
168 
169 #endif /* USB_HUB_H */
170