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