diff options
author | Chunfeng Yun <chunfeng.yun@mediatek.com> | 2018-09-20 12:13:33 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-28 09:04:45 -0400 |
commit | 95b516c18621d1626662bc161cbbf6281fd8d767 (patch) | |
tree | f4dcb5dc918ede4aefb481a1fd192ce5ec58da9e | |
parent | 87173acc0d8f0987bda8827da35fff67f52ad15d (diff) |
usb: xhci-mtk: improve bandwidth scheduling
Mainly improve SuperSpeed ISOC bandwidth in last microframe,
and LowSpeed/FullSpeed IN INT/ISOC bandwidth in split and
idle microframes by introduing a bandwidth budget table;
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/host/xhci-mtk-sch.c | 162 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mtk.h | 2 |
2 files changed, 104 insertions, 60 deletions
diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 057f453e06c5..7efd8901b2db 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c | |||
@@ -18,6 +18,11 @@ | |||
18 | #define HS_BW_BOUNDARY 6144 | 18 | #define HS_BW_BOUNDARY 6144 |
19 | /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ | 19 | /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ |
20 | #define FS_PAYLOAD_MAX 188 | 20 | #define FS_PAYLOAD_MAX 188 |
21 | /* | ||
22 | * max number of microframes for split transfer, | ||
23 | * for fs isoc in : 1 ss + 1 idle + 7 cs | ||
24 | */ | ||
25 | #define TT_MICROFRAMES_MAX 9 | ||
21 | 26 | ||
22 | /* mtk scheduler bitmasks */ | 27 | /* mtk scheduler bitmasks */ |
23 | #define EP_BPKTS(p) ((p) & 0x3f) | 28 | #define EP_BPKTS(p) ((p) & 0x3f) |
@@ -64,20 +69,57 @@ static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev, | |||
64 | return bw_index; | 69 | return bw_index; |
65 | } | 70 | } |
66 | 71 | ||
72 | static u32 get_esit(struct xhci_ep_ctx *ep_ctx) | ||
73 | { | ||
74 | u32 esit; | ||
75 | |||
76 | esit = 1 << CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info)); | ||
77 | if (esit > XHCI_MTK_MAX_ESIT) | ||
78 | esit = XHCI_MTK_MAX_ESIT; | ||
79 | |||
80 | return esit; | ||
81 | } | ||
82 | |||
83 | static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, | ||
84 | struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx) | ||
85 | { | ||
86 | struct mu3h_sch_ep_info *sch_ep; | ||
87 | u32 len_bw_budget_table; | ||
88 | size_t mem_size; | ||
89 | |||
90 | if (is_fs_or_ls(udev->speed)) | ||
91 | len_bw_budget_table = TT_MICROFRAMES_MAX; | ||
92 | else if ((udev->speed == USB_SPEED_SUPER) | ||
93 | && usb_endpoint_xfer_isoc(&ep->desc)) | ||
94 | len_bw_budget_table = get_esit(ep_ctx); | ||
95 | else | ||
96 | len_bw_budget_table = 1; | ||
97 | |||
98 | mem_size = sizeof(struct mu3h_sch_ep_info) + | ||
99 | len_bw_budget_table * sizeof(u32); | ||
100 | sch_ep = kzalloc(mem_size, GFP_KERNEL); | ||
101 | if (!sch_ep) | ||
102 | return ERR_PTR(-ENOMEM); | ||
103 | |||
104 | sch_ep->ep = ep; | ||
105 | |||
106 | return sch_ep; | ||
107 | } | ||
108 | |||
67 | static void setup_sch_info(struct usb_device *udev, | 109 | static void setup_sch_info(struct usb_device *udev, |
68 | struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep) | 110 | struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep) |
69 | { | 111 | { |
70 | u32 ep_type; | 112 | u32 ep_type; |
71 | u32 ep_interval; | 113 | u32 maxpkt; |
72 | u32 max_packet_size; | ||
73 | u32 max_burst; | 114 | u32 max_burst; |
74 | u32 mult; | 115 | u32 mult; |
75 | u32 esit_pkts; | 116 | u32 esit_pkts; |
76 | u32 max_esit_payload; | 117 | u32 max_esit_payload; |
118 | u32 *bwb_table = sch_ep->bw_budget_table; | ||
119 | int i; | ||
77 | 120 | ||
78 | ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); | 121 | ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); |
79 | ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info)); | 122 | maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); |
80 | max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); | ||
81 | max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2)); | 123 | max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2)); |
82 | mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info)); | 124 | mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info)); |
83 | max_esit_payload = | 125 | max_esit_payload = |
@@ -85,9 +127,10 @@ static void setup_sch_info(struct usb_device *udev, | |||
85 | le32_to_cpu(ep_ctx->ep_info)) << 16) | | 127 | le32_to_cpu(ep_ctx->ep_info)) << 16) | |
86 | CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info)); | 128 | CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info)); |
87 | 129 | ||
88 | sch_ep->esit = 1 << ep_interval; | 130 | sch_ep->esit = get_esit(ep_ctx); |
89 | sch_ep->offset = 0; | 131 | sch_ep->offset = 0; |
90 | sch_ep->burst_mode = 0; | 132 | sch_ep->burst_mode = 0; |
133 | sch_ep->repeat = 0; | ||
91 | 134 | ||
92 | if (udev->speed == USB_SPEED_HIGH) { | 135 | if (udev->speed == USB_SPEED_HIGH) { |
93 | sch_ep->cs_count = 0; | 136 | sch_ep->cs_count = 0; |
@@ -98,7 +141,6 @@ static void setup_sch_info(struct usb_device *udev, | |||
98 | * in a interval | 141 | * in a interval |
99 | */ | 142 | */ |
100 | sch_ep->num_budget_microframes = 1; | 143 | sch_ep->num_budget_microframes = 1; |
101 | sch_ep->repeat = 0; | ||
102 | 144 | ||
103 | /* | 145 | /* |
104 | * xHCI spec section6.2.3.4 | 146 | * xHCI spec section6.2.3.4 |
@@ -106,26 +148,30 @@ static void setup_sch_info(struct usb_device *udev, | |||
106 | * opportunities per microframe | 148 | * opportunities per microframe |
107 | */ | 149 | */ |
108 | sch_ep->pkts = max_burst + 1; | 150 | sch_ep->pkts = max_burst + 1; |
109 | sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; | 151 | sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; |
152 | bwb_table[0] = sch_ep->bw_cost_per_microframe; | ||
110 | } else if (udev->speed == USB_SPEED_SUPER) { | 153 | } else if (udev->speed == USB_SPEED_SUPER) { |
111 | /* usb3_r1 spec section4.4.7 & 4.4.8 */ | 154 | /* usb3_r1 spec section4.4.7 & 4.4.8 */ |
112 | sch_ep->cs_count = 0; | 155 | sch_ep->cs_count = 0; |
156 | sch_ep->burst_mode = 1; | ||
113 | /* | 157 | /* |
114 | * some device's (d)wBytesPerInterval is set as 0, | 158 | * some device's (d)wBytesPerInterval is set as 0, |
115 | * then max_esit_payload is 0, so evaluate esit_pkts from | 159 | * then max_esit_payload is 0, so evaluate esit_pkts from |
116 | * mult and burst | 160 | * mult and burst |
117 | */ | 161 | */ |
118 | esit_pkts = DIV_ROUND_UP(max_esit_payload, max_packet_size); | 162 | esit_pkts = DIV_ROUND_UP(max_esit_payload, maxpkt); |
119 | if (esit_pkts == 0) | 163 | if (esit_pkts == 0) |
120 | esit_pkts = (mult + 1) * (max_burst + 1); | 164 | esit_pkts = (mult + 1) * (max_burst + 1); |
121 | 165 | ||
122 | if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { | 166 | if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { |
123 | sch_ep->pkts = esit_pkts; | 167 | sch_ep->pkts = esit_pkts; |
124 | sch_ep->num_budget_microframes = 1; | 168 | sch_ep->num_budget_microframes = 1; |
125 | sch_ep->repeat = 0; | 169 | bwb_table[0] = maxpkt * sch_ep->pkts; |
126 | } | 170 | } |
127 | 171 | ||
128 | if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { | 172 | if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { |
173 | u32 remainder; | ||
174 | |||
129 | if (sch_ep->esit == 1) | 175 | if (sch_ep->esit == 1) |
130 | sch_ep->pkts = esit_pkts; | 176 | sch_ep->pkts = esit_pkts; |
131 | else if (esit_pkts <= sch_ep->esit) | 177 | else if (esit_pkts <= sch_ep->esit) |
@@ -137,43 +183,37 @@ static void setup_sch_info(struct usb_device *udev, | |||
137 | sch_ep->num_budget_microframes = | 183 | sch_ep->num_budget_microframes = |
138 | DIV_ROUND_UP(esit_pkts, sch_ep->pkts); | 184 | DIV_ROUND_UP(esit_pkts, sch_ep->pkts); |
139 | 185 | ||
140 | if (sch_ep->num_budget_microframes > 1) | 186 | sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1); |
141 | sch_ep->repeat = 1; | 187 | sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; |
142 | else | 188 | |
143 | sch_ep->repeat = 0; | 189 | remainder = sch_ep->bw_cost_per_microframe; |
190 | remainder *= sch_ep->num_budget_microframes; | ||
191 | remainder -= (maxpkt * esit_pkts); | ||
192 | for (i = 0; i < sch_ep->num_budget_microframes - 1; i++) | ||
193 | bwb_table[i] = sch_ep->bw_cost_per_microframe; | ||
194 | |||
195 | /* last one <= bw_cost_per_microframe */ | ||
196 | bwb_table[i] = remainder; | ||
144 | } | 197 | } |
145 | sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; | ||
146 | } else if (is_fs_or_ls(udev->speed)) { | 198 | } else if (is_fs_or_ls(udev->speed)) { |
147 | |||
148 | /* | ||
149 | * usb_20 spec section11.18.4 | ||
150 | * assume worst cases | ||
151 | */ | ||
152 | sch_ep->repeat = 0; | ||
153 | sch_ep->pkts = 1; /* at most one packet for each microframe */ | 199 | sch_ep->pkts = 1; /* at most one packet for each microframe */ |
154 | if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { | 200 | sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX); |
155 | sch_ep->cs_count = 3; /* at most need 3 CS*/ | 201 | sch_ep->num_budget_microframes = sch_ep->cs_count + 2; |
156 | /* one for SS and one for budgeted transaction */ | 202 | sch_ep->bw_cost_per_microframe = |
157 | sch_ep->num_budget_microframes = sch_ep->cs_count + 2; | 203 | (maxpkt < FS_PAYLOAD_MAX) ? maxpkt : FS_PAYLOAD_MAX; |
158 | sch_ep->bw_cost_per_microframe = max_packet_size; | ||
159 | } | ||
160 | if (ep_type == ISOC_OUT_EP) { | ||
161 | 204 | ||
162 | /* | 205 | /* init budget table */ |
163 | * the best case FS budget assumes that 188 FS bytes | 206 | if (ep_type == ISOC_OUT_EP) { |
164 | * occur in each microframe | 207 | for (i = 0; i < sch_ep->num_budget_microframes; i++) |
165 | */ | 208 | bwb_table[i] = sch_ep->bw_cost_per_microframe; |
166 | sch_ep->num_budget_microframes = DIV_ROUND_UP( | 209 | } else if (ep_type == INT_OUT_EP) { |
167 | max_packet_size, FS_PAYLOAD_MAX); | 210 | /* only first one consumes bandwidth, others as zero */ |
168 | sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; | 211 | bwb_table[0] = sch_ep->bw_cost_per_microframe; |
169 | sch_ep->cs_count = sch_ep->num_budget_microframes; | 212 | } else { /* INT_IN_EP or ISOC_IN_EP */ |
170 | } | 213 | bwb_table[0] = 0; /* start split */ |
171 | if (ep_type == ISOC_IN_EP) { | 214 | bwb_table[1] = 0; /* idle */ |
172 | /* at most need additional two CS. */ | 215 | for (i = 2; i < sch_ep->num_budget_microframes; i++) |
173 | sch_ep->cs_count = DIV_ROUND_UP( | 216 | bwb_table[i] = sch_ep->bw_cost_per_microframe; |
174 | max_packet_size, FS_PAYLOAD_MAX) + 2; | ||
175 | sch_ep->num_budget_microframes = sch_ep->cs_count + 2; | ||
176 | sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; | ||
177 | } | 217 | } |
178 | } | 218 | } |
179 | } | 219 | } |
@@ -184,6 +224,7 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, | |||
184 | { | 224 | { |
185 | u32 num_esit; | 225 | u32 num_esit; |
186 | u32 max_bw = 0; | 226 | u32 max_bw = 0; |
227 | u32 bw; | ||
187 | int i; | 228 | int i; |
188 | int j; | 229 | int j; |
189 | 230 | ||
@@ -192,15 +233,17 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, | |||
192 | u32 base = offset + i * sch_ep->esit; | 233 | u32 base = offset + i * sch_ep->esit; |
193 | 234 | ||
194 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { | 235 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { |
195 | if (sch_bw->bus_bw[base + j] > max_bw) | 236 | bw = sch_bw->bus_bw[base + j] + |
196 | max_bw = sch_bw->bus_bw[base + j]; | 237 | sch_ep->bw_budget_table[j]; |
238 | if (bw > max_bw) | ||
239 | max_bw = bw; | ||
197 | } | 240 | } |
198 | } | 241 | } |
199 | return max_bw; | 242 | return max_bw; |
200 | } | 243 | } |
201 | 244 | ||
202 | static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, | 245 | static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, |
203 | struct mu3h_sch_ep_info *sch_ep, int bw_cost) | 246 | struct mu3h_sch_ep_info *sch_ep, bool used) |
204 | { | 247 | { |
205 | u32 num_esit; | 248 | u32 num_esit; |
206 | u32 base; | 249 | u32 base; |
@@ -210,8 +253,14 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, | |||
210 | num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; | 253 | num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; |
211 | for (i = 0; i < num_esit; i++) { | 254 | for (i = 0; i < num_esit; i++) { |
212 | base = sch_ep->offset + i * sch_ep->esit; | 255 | base = sch_ep->offset + i * sch_ep->esit; |
213 | for (j = 0; j < sch_ep->num_budget_microframes; j++) | 256 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { |
214 | sch_bw->bus_bw[base + j] += bw_cost; | 257 | if (used) |
258 | sch_bw->bus_bw[base + j] += | ||
259 | sch_ep->bw_budget_table[j]; | ||
260 | else | ||
261 | sch_bw->bus_bw[base + j] -= | ||
262 | sch_ep->bw_budget_table[j]; | ||
263 | } | ||
215 | } | 264 | } |
216 | } | 265 | } |
217 | 266 | ||
@@ -220,17 +269,12 @@ static int check_sch_bw(struct usb_device *udev, | |||
220 | { | 269 | { |
221 | u32 offset; | 270 | u32 offset; |
222 | u32 esit; | 271 | u32 esit; |
223 | u32 num_budget_microframes; | ||
224 | u32 min_bw; | 272 | u32 min_bw; |
225 | u32 min_index; | 273 | u32 min_index; |
226 | u32 worst_bw; | 274 | u32 worst_bw; |
227 | u32 bw_boundary; | 275 | u32 bw_boundary; |
228 | 276 | ||
229 | if (sch_ep->esit > XHCI_MTK_MAX_ESIT) | ||
230 | sch_ep->esit = XHCI_MTK_MAX_ESIT; | ||
231 | |||
232 | esit = sch_ep->esit; | 277 | esit = sch_ep->esit; |
233 | num_budget_microframes = sch_ep->num_budget_microframes; | ||
234 | 278 | ||
235 | /* | 279 | /* |
236 | * Search through all possible schedule microframes. | 280 | * Search through all possible schedule microframes. |
@@ -239,7 +283,7 @@ static int check_sch_bw(struct usb_device *udev, | |||
239 | min_bw = ~0; | 283 | min_bw = ~0; |
240 | min_index = 0; | 284 | min_index = 0; |
241 | for (offset = 0; offset < esit; offset++) { | 285 | for (offset = 0; offset < esit; offset++) { |
242 | if ((offset + num_budget_microframes) > sch_ep->esit) | 286 | if ((offset + sch_ep->num_budget_microframes) > sch_ep->esit) |
243 | break; | 287 | break; |
244 | 288 | ||
245 | /* | 289 | /* |
@@ -263,11 +307,11 @@ static int check_sch_bw(struct usb_device *udev, | |||
263 | ? SS_BW_BOUNDARY : HS_BW_BOUNDARY; | 307 | ? SS_BW_BOUNDARY : HS_BW_BOUNDARY; |
264 | 308 | ||
265 | /* check bandwidth */ | 309 | /* check bandwidth */ |
266 | if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary) | 310 | if (min_bw > bw_boundary) |
267 | return -ERANGE; | 311 | return -ERANGE; |
268 | 312 | ||
269 | /* update bus bandwidth info */ | 313 | /* update bus bandwidth info */ |
270 | update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe); | 314 | update_bus_bw(sch_bw, sch_ep, 1); |
271 | 315 | ||
272 | return 0; | 316 | return 0; |
273 | } | 317 | } |
@@ -362,8 +406,8 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, | |||
362 | bw_index = get_bw_index(xhci, udev, ep); | 406 | bw_index = get_bw_index(xhci, udev, ep); |
363 | sch_bw = &sch_array[bw_index]; | 407 | sch_bw = &sch_array[bw_index]; |
364 | 408 | ||
365 | sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_NOIO); | 409 | sch_ep = create_sch_ep(udev, ep, ep_ctx); |
366 | if (!sch_ep) | 410 | if (IS_ERR_OR_NULL(sch_ep)) |
367 | return -ENOMEM; | 411 | return -ENOMEM; |
368 | 412 | ||
369 | setup_sch_info(udev, ep_ctx, sch_ep); | 413 | setup_sch_info(udev, ep_ctx, sch_ep); |
@@ -376,7 +420,6 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, | |||
376 | } | 420 | } |
377 | 421 | ||
378 | list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); | 422 | list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); |
379 | sch_ep->ep = ep; | ||
380 | 423 | ||
381 | ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) | 424 | ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) |
382 | | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); | 425 | | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); |
@@ -421,8 +464,7 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, | |||
421 | 464 | ||
422 | list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { | 465 | list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { |
423 | if (sch_ep->ep == ep) { | 466 | if (sch_ep->ep == ep) { |
424 | update_bus_bw(sch_bw, sch_ep, | 467 | update_bus_bw(sch_bw, sch_ep, 0); |
425 | -sch_ep->bw_cost_per_microframe); | ||
426 | list_del(&sch_ep->endpoint); | 468 | list_del(&sch_ep->endpoint); |
427 | kfree(sch_ep); | 469 | kfree(sch_ep); |
428 | break; | 470 | break; |
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index cc59d80b663b..f8864fcbd461 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h | |||
@@ -57,6 +57,7 @@ struct mu3h_sch_bw_info { | |||
57 | * times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets | 57 | * times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets |
58 | * according to @pkts and @repeat. normal mode is used by | 58 | * according to @pkts and @repeat. normal mode is used by |
59 | * default | 59 | * default |
60 | * @bw_budget_table: table to record bandwidth budget per microframe | ||
60 | */ | 61 | */ |
61 | struct mu3h_sch_ep_info { | 62 | struct mu3h_sch_ep_info { |
62 | u32 esit; | 63 | u32 esit; |
@@ -73,6 +74,7 @@ struct mu3h_sch_ep_info { | |||
73 | u32 pkts; | 74 | u32 pkts; |
74 | u32 cs_count; | 75 | u32 cs_count; |
75 | u32 burst_mode; | 76 | u32 burst_mode; |
77 | u32 bw_budget_table[0]; | ||
76 | }; | 78 | }; |
77 | 79 | ||
78 | #define MU3C_U3_PORT_MAX 4 | 80 | #define MU3C_U3_PORT_MAX 4 |