1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** Asix Class */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28 #include "ux_host_class_asix.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_asix_setup PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function prepares the Asix chip Phy and rx and xmit registers. */
45 /* */
46 /* INPUT */
47 /* */
48 /* asix Pointer to asix class */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* Completion Status */
53 /* */
54 /* CALLS */
55 /* */
56 /* _ux_host_stack_transfer_request Transfer request */
57 /* _ux_utility_memory_allocate Allocate memory */
58 /* _ux_utility_memory_free Free memory */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* _ux_host_class_asix_activate */
63 /* */
64 /* RELEASE HISTORY */
65 /* */
66 /* DATE NAME DESCRIPTION */
67 /* */
68 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
69 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
70 /* verified memset and memcpy */
71 /* cases, */
72 /* resulting in version 6.1 */
73 /* */
74 /**************************************************************************/
_ux_host_class_asix_setup(UX_HOST_CLASS_ASIX * asix)75 UINT _ux_host_class_asix_setup(UX_HOST_CLASS_ASIX *asix)
76 {
77
78 UCHAR *setup_buffer;
79 UX_ENDPOINT *control_endpoint;
80 UX_TRANSFER *transfer_request;
81 ULONG phy_register_value;
82 UINT status;
83
84 /* We need to get the default control endpoint transfer request pointer. */
85 control_endpoint = &asix -> ux_host_class_asix_device -> ux_device_control_endpoint;
86 transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
87
88 /* Need to allocate memory for the buffer. */
89 setup_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_ASIX_SETUP_BUFFER_SIZE);
90 if (setup_buffer == UX_NULL)
91 return(UX_MEMORY_INSUFFICIENT);
92
93 /* Get the Ethernet Phy Address register. */
94 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
95 transfer_request -> ux_transfer_request_requested_length = 2;
96 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_READ_PHY_ID;
97 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
98 transfer_request -> ux_transfer_request_value = 0;
99 transfer_request -> ux_transfer_request_index = 0;
100
101 /* Send request to HCD layer. */
102 status = _ux_host_stack_transfer_request(transfer_request);
103
104 /* Check status, if error, do not proceed. */
105 if ((status != UX_SUCCESS) || (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS) ||
106 (transfer_request -> ux_transfer_request_actual_length != 2))
107 {
108
109 /* Free all used resources. */
110 _ux_utility_memory_free(setup_buffer);
111
112 /* Return completion status. */
113 return(UX_TRANSFER_ERROR);
114
115 }
116
117 /* Extract the PHY IDs and the type. */
118 asix -> ux_host_class_asix_primary_phy_id = *(setup_buffer + UX_HOST_CLASS_ASIX_PHY_ID_PRIMARY) & UX_HOST_CLASS_ASIX_PHY_ID_MASK;
119 asix -> ux_host_class_asix_primary_phy_type = (*(setup_buffer + UX_HOST_CLASS_ASIX_PHY_ID_PRIMARY) >> UX_HOST_CLASS_ASIX_PHY_TYPE_SHIFT) & UX_HOST_CLASS_ASIX_PHY_TYPE_MASK;
120
121 asix -> ux_host_class_asix_secondary_phy_id = *(setup_buffer + UX_HOST_CLASS_ASIX_PHY_ID_SECONDARY) & UX_HOST_CLASS_ASIX_PHY_ID_MASK;
122 asix -> ux_host_class_asix_secondary_phy_type = (*(setup_buffer + UX_HOST_CLASS_ASIX_PHY_ID_SECONDARY) >> UX_HOST_CLASS_ASIX_PHY_TYPE_SHIFT) & UX_HOST_CLASS_ASIX_PHY_TYPE_MASK;
123
124 /* Set the GPIO 2 register. */
125 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
126 transfer_request -> ux_transfer_request_requested_length = 0;
127 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_GPIO_STATUS;
128 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
129 transfer_request -> ux_transfer_request_value = (UX_HOST_CLASS_ASIX_GPIO_RSE | UX_HOST_CLASS_ASIX_GPIO_GPO2EN | UX_HOST_CLASS_ASIX_GPIO_GPO_2);
130 transfer_request -> ux_transfer_request_index = 0;
131
132 /* Send request to HCD layer. */
133 status = _ux_host_stack_transfer_request(transfer_request);
134
135 /* Check status, if error, do not proceed. */
136 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
137 {
138
139 /* Free all used resources. */
140 _ux_utility_memory_free(setup_buffer);
141
142 /* Return completion status. */
143 return(UX_TRANSFER_ERROR);
144
145 }
146
147 /* Set the Software PHY Select register. */
148 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
149 transfer_request -> ux_transfer_request_requested_length = 0;
150 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_SW_PHY_SELECT_STATUS;
151 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
152 transfer_request -> ux_transfer_request_value = 1;
153 transfer_request -> ux_transfer_request_index = 0;
154
155 /* Send request to HCD layer. */
156 status = _ux_host_stack_transfer_request(transfer_request);
157
158 /* Check status, if error, do not proceed. */
159 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
160 {
161
162 /* Free all used resources. */
163 _ux_utility_memory_free(setup_buffer);
164
165 /* Return completion status. */
166 return(UX_TRANSFER_ERROR);
167
168 }
169
170 /* Perform a software reset of IPPD. */
171 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
172 transfer_request -> ux_transfer_request_requested_length = 0;
173 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_SW_RESET;
174 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
175 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_ASIX_SW_RESET_IPPD;
176 transfer_request -> ux_transfer_request_index = 0;
177
178 /* Send request to HCD layer. */
179 status = _ux_host_stack_transfer_request(transfer_request);
180
181 /* Check status, if error, do not proceed. */
182 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
183 {
184
185 /* Free all used resources. */
186 _ux_utility_memory_free(setup_buffer);
187
188 /* Return completion status. */
189 return(UX_TRANSFER_ERROR);
190
191 }
192
193 /* Perform a software reset. */
194 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
195 transfer_request -> ux_transfer_request_requested_length = 0;
196 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_SW_RESET;
197 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
198 transfer_request -> ux_transfer_request_value = 0;
199 transfer_request -> ux_transfer_request_index = 0;
200
201 /* Send request to HCD layer. */
202 status = _ux_host_stack_transfer_request(transfer_request);
203
204 /* Check status, if error, do not proceed. */
205 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
206 {
207
208 /* Free all used resources. */
209 _ux_utility_memory_free(setup_buffer);
210
211 /* Return completion status. */
212 return(UX_TRANSFER_ERROR);
213
214 }
215
216
217 /* Perform a software reset of IPRL and PRL. */
218 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
219 transfer_request -> ux_transfer_request_requested_length = 0;
220 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_SW_RESET;
221 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
222 transfer_request -> ux_transfer_request_value = (UX_HOST_CLASS_ASIX_SW_RESET_IPRL | UX_HOST_CLASS_ASIX_SW_RESET_PRL);
223 transfer_request -> ux_transfer_request_index = 0;
224
225 /* Send request to HCD layer. */
226 status = _ux_host_stack_transfer_request(transfer_request);
227
228 /* Check status, if error, do not proceed. */
229 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
230 {
231
232 /* Free all used resources. */
233 _ux_utility_memory_free(setup_buffer);
234
235 /* Return completion status. */
236 return(UX_TRANSFER_ERROR);
237
238 }
239
240 /* Write the value of the Receive Control register. */
241 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
242 transfer_request -> ux_transfer_request_requested_length = 0;
243 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_RX_CTL;
244 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
245 transfer_request -> ux_transfer_request_value = 0;
246 transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_RXCR_MFB_2048;
247
248 /* Send request to HCD layer. */
249 status = _ux_host_stack_transfer_request(transfer_request);
250
251 /* Check status, if error, do not proceed. */
252 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
253 {
254
255 /* Free all used resources. */
256 _ux_utility_memory_free(setup_buffer);
257
258 /* Return completion status. */
259 return(UX_TRANSFER_ERROR);
260
261 }
262
263 /* Get the Ethernet Phy Address register. */
264 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
265 transfer_request -> ux_transfer_request_requested_length = UX_HOST_CLASS_ASIX_NODE_ID_LENGTH;
266 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_READ_NODE_ID;
267 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
268 transfer_request -> ux_transfer_request_value = 0;
269 transfer_request -> ux_transfer_request_index = 0;
270
271 /* Send request to HCD layer. */
272 status = _ux_host_stack_transfer_request(transfer_request);
273
274 /* Check status, if error, do not proceed. */
275 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
276 transfer_request -> ux_transfer_request_actual_length != UX_HOST_CLASS_ASIX_NODE_ID_LENGTH)
277 {
278
279 /* Free all used resources. */
280 _ux_utility_memory_free(setup_buffer);
281
282 /* Return completion status. */
283 return(UX_TRANSFER_ERROR);
284
285 }
286
287
288 /* Copy the node id into the Asix instance. */
289 _ux_utility_memory_copy(asix -> ux_host_class_asix_node_id, setup_buffer, UX_HOST_CLASS_ASIX_NODE_ID_LENGTH); /* Use case of memcpy is verified. */
290
291 /* Request ownership of Serial Management Interface. */
292 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
293 transfer_request -> ux_transfer_request_requested_length = 0;
294 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_OWN_SMI ;
295 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
296 transfer_request -> ux_transfer_request_value = 0;
297 transfer_request -> ux_transfer_request_index = 0;
298
299 /* Send request to HCD layer. */
300 status = _ux_host_stack_transfer_request(transfer_request);
301
302 /* Check status, if error, do not proceed. */
303 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
304 {
305
306 /* Free all used resources. */
307 _ux_utility_memory_free(setup_buffer);
308
309 /* Return completion status. */
310 return(UX_TRANSFER_ERROR);
311
312 }
313
314
315 /* Get the value of the PHYIDR1 in the PHY register. */
316 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
317 transfer_request -> ux_transfer_request_requested_length = 2;
318 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_READ_PHY_REG;
319 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
320 transfer_request -> ux_transfer_request_value = asix -> ux_host_class_asix_primary_phy_id;
321 transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_PHY_REG_PHYIDR1;
322
323 /* Send request to HCD layer. */
324 status = _ux_host_stack_transfer_request(transfer_request);
325
326 /* Check status, if error, do not proceed. */
327 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
328 transfer_request -> ux_transfer_request_actual_length != 2)
329 {
330
331 /* Free all used resources. */
332 _ux_utility_memory_free(setup_buffer);
333
334 /* Return completion status. */
335 return(UX_TRANSFER_ERROR);
336
337 }
338
339 /* Extract the Vendor model number and model revision number. First get the value
340 in proper 16 bit little endian. */
341 phy_register_value = _ux_utility_short_get(setup_buffer);
342
343 /* Get the model revision number. */
344 asix -> ux_host_class_asix_model_revision_number = (phy_register_value >> UX_HOST_CLASS_ASIX_PHY_REG_PHYIDR1_MDL_REV_SHIFT) & UX_HOST_CLASS_ASIX_PHY_REG_PHYIDR1_MDL_REV_MASK;
345
346 /* Get the vendor model number. */
347 asix -> ux_host_class_asix_vendor_model_number = (phy_register_value >> UX_HOST_CLASS_ASIX_PHY_REG_PHYIDR1_VNDR_REV_SHIFT) & UX_HOST_CLASS_ASIX_PHY_REG_PHYIDR1_VNDR_REV_MASK ;
348
349
350 /* Perform a software reset. External Phy Reset Pin level. */
351 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
352 transfer_request -> ux_transfer_request_requested_length = 0;
353 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_SW_RESET;
354 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
355 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_ASIX_SW_RESET_PRL;
356 transfer_request -> ux_transfer_request_index = 0;
357
358 /* Send request to HCD layer. */
359 status = _ux_host_stack_transfer_request(transfer_request);
360
361 /* Check status, if error, do not proceed. */
362 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
363 {
364
365 /* Free all used resources. */
366 _ux_utility_memory_free(setup_buffer);
367
368 /* Return completion status. */
369 return(UX_TRANSFER_ERROR);
370
371 }
372
373 /* Perform a software reset. Internal Phy reset Control and external Phy Reset Pin level. */
374 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
375 transfer_request -> ux_transfer_request_requested_length = 0;
376 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_SW_RESET;
377 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
378 transfer_request -> ux_transfer_request_value = (UX_HOST_CLASS_ASIX_SW_RESET_IPRL | UX_HOST_CLASS_ASIX_SW_RESET_PRL);
379 transfer_request -> ux_transfer_request_index = 0;
380
381 /* Send request to HCD layer. */
382 status = _ux_host_stack_transfer_request(transfer_request);
383
384 /* Check status, if error, do not proceed. */
385 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
386 {
387
388 /* Free all used resources. */
389 _ux_utility_memory_free(setup_buffer);
390
391 /* Return completion status. */
392 return(UX_TRANSFER_ERROR);
393
394 }
395
396
397 /* Write the value of the BMCR register in the PHY register. */
398 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
399 transfer_request -> ux_transfer_request_requested_length = 2;
400 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_PHY_REG;
401 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
402 transfer_request -> ux_transfer_request_value = asix -> ux_host_class_asix_primary_phy_id;
403 transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_PHY_REG_BMCR;
404
405 /* Set the value for the PHY reg. */
406 phy_register_value = UX_HOST_CLASS_ASIX_PHY_REG_BMCR_RESET;
407
408 /* Insert the value into the target buffer. */
409 _ux_utility_short_put(setup_buffer, (USHORT)phy_register_value);
410
411 /* Send request to HCD layer. */
412 status = _ux_host_stack_transfer_request(transfer_request);
413
414 /* Check status, if error, do not proceed. */
415 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
416 transfer_request -> ux_transfer_request_actual_length != 2)
417 {
418
419 /* Free all used resources. */
420 _ux_utility_memory_free(setup_buffer);
421
422 /* Return completion status. */
423 return(UX_TRANSFER_ERROR);
424
425 }
426
427
428 /* Read the value of the BMCR register in the PHY register. */
429 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
430 transfer_request -> ux_transfer_request_requested_length = 2;
431 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_READ_PHY_REG;
432 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
433 transfer_request -> ux_transfer_request_value = asix -> ux_host_class_asix_primary_phy_id;
434 transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_PHY_REG_BMCR;
435
436 /* Send request to HCD layer. */
437 status = _ux_host_stack_transfer_request(transfer_request);
438
439 /* Check status, if error, do not proceed. */
440 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS || transfer_request -> ux_transfer_request_actual_length != 2)
441 {
442
443 /* Free all used resources. */
444 _ux_utility_memory_free(setup_buffer);
445
446 /* Return completion status. */
447 return(UX_TRANSFER_ERROR);
448
449 }
450
451 /* Extract the speed selected by the PHY. */
452 phy_register_value = _ux_utility_short_get(setup_buffer);
453
454 /* Isolate the speed and memorize it. */
455 if (phy_register_value & UX_HOST_CLASS_ASIX_PHY_REG_BMCR_SPEED_100MBS)
456
457 /* Select 100 MBPS as our speed. */
458 asix -> ux_host_class_asix_speed_selected = UX_HOST_CLASS_ASIX_SPEED_SELECTED_100MPBS;
459
460 else
461
462 /* Select 10 MBPS as our speed. */
463 asix -> ux_host_class_asix_speed_selected = UX_HOST_CLASS_ASIX_SPEED_SELECTED_10MPBS;
464
465 /* Set the value of the ANAR in the PHY register. */
466 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
467 transfer_request -> ux_transfer_request_requested_length = 2;
468 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_PHY_REG;
469 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
470 transfer_request -> ux_transfer_request_value = asix -> ux_host_class_asix_primary_phy_id;
471 transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_PHY_REG_ANAR;
472
473 /* Set the value for the PHY reg. */
474 phy_register_value = (UX_HOST_CLASS_ASIX_PHY_REG_ANAR_DEFAULT_SELECTOR |
475 UX_HOST_CLASS_ASIX_PHY_REG_ANAR_10_HD |
476 UX_HOST_CLASS_ASIX_PHY_REG_ANAR_10_FD |
477 UX_HOST_CLASS_ASIX_PHY_REG_ANAR_TX_HD |
478 UX_HOST_CLASS_ASIX_PHY_REG_ANAR_TX_FD |
479 UX_HOST_CLASS_ASIX_PHY_REG_ANAR_PAUSE);
480
481 /* Insert the value into the target buffer. */
482 _ux_utility_short_put(setup_buffer, (USHORT)phy_register_value);
483
484
485 /* Send request to HCD layer. */
486 status = _ux_host_stack_transfer_request(transfer_request);
487
488 /* Check status, if error, do not proceed. */
489 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
490 transfer_request -> ux_transfer_request_actual_length != 2)
491 {
492
493 /* Free all used resources. */
494 _ux_utility_memory_free(setup_buffer);
495
496 /* Return completion status. */
497 return(UX_TRANSFER_ERROR);
498
499 }
500
501 /* Set the value of the BMCR in the PHY register. */
502 transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
503 transfer_request -> ux_transfer_request_requested_length = 2;
504 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_PHY_REG;
505 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
506 transfer_request -> ux_transfer_request_value = asix -> ux_host_class_asix_primary_phy_id;
507 transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_PHY_REG_BMCR;
508
509 /* Check speed. */
510 if (asix -> ux_host_class_asix_speed_selected == UX_HOST_CLASS_ASIX_SPEED_SELECTED_100MPBS)
511
512 /* Set speed at 100MBPS. */
513 phy_register_value = UX_HOST_CLASS_ASIX_PHY_REG_BMCR_SPEED_100MBS;
514
515 /* Set the value for the PHY reg. */
516 phy_register_value |= (UX_HOST_CLASS_ASIX_PHY_REG_BMCR_AUTO_NEGOTIATION | UX_HOST_CLASS_ASIX_PHY_REG_BMCR_RESTART_NEG |
517 UX_HOST_CLASS_ASIX_PHY_REG_BMCR_DUPLEX_MODE);
518
519 /* Insert the value into the target buffer. */
520 _ux_utility_short_put(setup_buffer, (USHORT)phy_register_value);
521
522 /* Send request to HCD layer. */
523 status = _ux_host_stack_transfer_request(transfer_request);
524
525 /* Check status, if error, do not proceed. */
526 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
527 transfer_request -> ux_transfer_request_actual_length != 2)
528 {
529
530 /* Free all used resources. */
531 _ux_utility_memory_free(setup_buffer);
532
533 /* Return completion status. */
534 return(UX_TRANSFER_ERROR);
535
536 }
537
538
539 /* Check speed. */
540 if (asix -> ux_host_class_asix_speed_selected == UX_HOST_CLASS_ASIX_SPEED_SELECTED_100MPBS)
541
542 /* Set speed at 100MBPS. */
543 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_ASIX_MEDIUM_PS;
544
545 /* Write the value of the Medium Mode. */
546 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
547 transfer_request -> ux_transfer_request_requested_length = 0;
548 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_MEDIUM_MODE;
549 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
550 transfer_request -> ux_transfer_request_value |= (UX_HOST_CLASS_ASIX_MEDIUM_FD | UX_HOST_CLASS_ASIX_MEDIUM_BIT2 | UX_HOST_CLASS_ASIX_MEDIUM_RFC_ENABLED |
551 UX_HOST_CLASS_ASIX_MEDIUM_TFC_ENABLED | UX_HOST_CLASS_ASIX_MEDIUM_RE_ENABLED);
552 transfer_request -> ux_transfer_request_index = 0;
553
554 /* Send request to HCD layer. */
555 status = _ux_host_stack_transfer_request(transfer_request);
556
557 /* Check status, if error, do not proceed. */
558 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
559 {
560
561 /* Free all used resources. */
562 _ux_utility_memory_free(setup_buffer);
563
564 /* Return completion status. */
565 return(UX_TRANSFER_ERROR);
566
567 }
568
569
570 /* Write the value of the IPG0/IPG1/IPG2. */
571 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
572 transfer_request -> ux_transfer_request_requested_length = 0;
573 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_IPG012;
574 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
575 transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_ASIX_PPG0_IPG1;
576 transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_PPG2;
577
578 /* Send request to HCD layer. */
579 status = _ux_host_stack_transfer_request(transfer_request);
580
581 /* Check status, if error, do not proceed. */
582 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
583 {
584
585 /* Free all used resources. */
586 _ux_utility_memory_free(setup_buffer);
587
588 /* Return completion status. */
589 return(UX_TRANSFER_ERROR);
590
591 }
592
593 /* Release SMI ownership. */
594 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
595 transfer_request -> ux_transfer_request_requested_length = 0;
596 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_RELEASE_SMI;
597 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
598 transfer_request -> ux_transfer_request_value = 0;
599 transfer_request -> ux_transfer_request_index = 0;
600
601 /* Send request to HCD layer. */
602 status = _ux_host_stack_transfer_request(transfer_request);
603
604 /* Check status, if error, do not proceed. */
605 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
606 {
607
608 /* Free all used resources. */
609 _ux_utility_memory_free(setup_buffer);
610
611 /* Return completion status. */
612 return(UX_TRANSFER_ERROR);
613
614 }
615
616 /* Set the Rx Control register value. */
617 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
618 transfer_request -> ux_transfer_request_requested_length = 0;
619 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_RX_CTL;
620 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
621 transfer_request -> ux_transfer_request_value = (UX_HOST_CLASS_ASIX_RXCR_AB | UX_HOST_CLASS_ASIX_RXCR_SO | UX_HOST_CLASS_ASIX_RXCR_MFB_2048);
622 transfer_request -> ux_transfer_request_index = 0;
623
624 /* Send request to HCD layer. */
625 status = _ux_host_stack_transfer_request(transfer_request);
626
627 /* Check status, if error, do not proceed. */
628 if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
629 {
630
631 /* Free all used resources. */
632 _ux_utility_memory_free(setup_buffer);
633
634 /* Return completion status. */
635 return(UX_TRANSFER_ERROR);
636
637 }
638
639 /* Free all used resources. */
640 _ux_utility_memory_free(setup_buffer);
641
642 /* Return completion status. */
643 return(status);
644 }
645
646