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