]> git.proxmox.com Git - mirror_edk2.git/blob - OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
Contributed-under: TianoCore Contribution Agreement 1.0
[mirror_edk2.git] / OptionRomPkg / Bus / Usb / UsbNetworking / Ax88772b / SimpleNetwork.c
1 /** @file
2 Provides the Simple Network functions.
3
4 Copyright (c) 2011, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "Ax88772.h"
16
17 /**
18 This function updates the filtering on the receiver.
19
20 This support routine calls ::Ax88772MacAddressSet to update
21 the MAC address. This routine then rebuilds the multicast
22 hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
23 Finally this routine enables the receiver by calling
24 ::Ax88772RxControl.
25
26 @param [in] pSimpleNetwork Simple network mode pointer
27
28 @retval EFI_SUCCESS This operation was successful.
29 @retval EFI_NOT_STARTED The network interface was not started.
30 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
31 EFI_SIMPLE_NETWORK_PROTOCOL structure.
32 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
33 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
34
35 **/
36 EFI_STATUS
37 ReceiveFilterUpdate (
38 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
39 )
40 {
41 EFI_SIMPLE_NETWORK_MODE * pMode;
42 NIC_DEVICE * pNicDevice;
43 EFI_STATUS Status;
44 UINT32 Index;
45
46 //
47 // Set the MAC address
48 //
49 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
50 pMode = pSimpleNetwork->Mode;
51
52 //
53 // Clear the multicast hash table
54 //
55 Ax88772MulticastClear ( pNicDevice );
56
57 //
58 // Load the multicast hash table
59 //
60 if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
61 for ( Index = 0; Index < pMode->MCastFilterCount; Index++ ) {
62 //
63 // Enable the next multicast address
64 //
65 Ax88772MulticastSet ( pNicDevice,
66 &pMode->MCastFilter[ Index ].Addr[0]);
67 }
68 }
69
70 Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
71
72 return Status;
73 }
74
75
76 /**
77 This function updates the SNP driver status.
78
79 This function gets the current interrupt and recycled transmit
80 buffer status from the network interface. The interrupt status
81 and the media status are returned as a bit mask in InterruptStatus.
82 If InterruptStatus is NULL, the interrupt status will not be read.
83 Upon successful return of the media status, the MediaPresent field
84 of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
85 of media status. If TxBuf is not NULL, a recycled transmit buffer
86 address will be retrived. If a recycled transmit buffer address
87 is returned in TxBuf, then the buffer has been successfully
88 transmitted, and the status for that buffer is cleared.
89
90 This function calls ::Ax88772Rx to update the media status and
91 queue any receive packets.
92
93 @param [in] pSimpleNetwork Protocol instance pointer
94 @param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts.
95 If this is NULL, the interrupt status will not be read from
96 the device. If this is not NULL, the interrupt status will
97 be read from teh device. When the interrupt status is read,
98 it will also be cleared. Clearing the transmit interrupt
99 does not empty the recycled transmit buffer array.
100 @param [out] ppTxBuf Recycled transmit buffer address. The network interface will
101 not transmit if its internal recycled transmit buffer array is
102 full. Reading the transmit buffer does not clear the transmit
103 interrupt. If this is NULL, then the transmit buffer status
104 will not be read. If there are not transmit buffers to recycle
105 and TxBuf is not NULL, *TxBuf will be set to NULL.
106
107 @retval EFI_SUCCESS This operation was successful.
108 @retval EFI_NOT_STARTED The network interface was not started.
109 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
110 EFI_SIMPLE_NETWORK_PROTOCOL structure.
111 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
112
113 **/
114 EFI_STATUS
115 EFIAPI
116 SN_GetStatus (
117 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
118 OUT UINT32 * pInterruptStatus,
119 OUT VOID ** ppTxBuf
120 )
121 {
122 EFI_SIMPLE_NETWORK_MODE * pMode;
123 NIC_DEVICE * pNicDevice;
124 EFI_STATUS Status;
125 BOOLEAN bFullDuplex;
126 BOOLEAN bLinkUp;
127 BOOLEAN bSpeed100;
128 EFI_TPL TplPrevious;
129
130 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
131 //
132 // Verify the parameters
133 //
134 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
135 //
136 // Return the transmit buffer
137 //
138
139 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
140 if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
141 *ppTxBuf = pNicDevice->pTxBuffer;
142 pNicDevice->pTxBuffer = NULL;
143 }
144
145 //
146 // Determine if interface is running
147 //
148 pMode = pSimpleNetwork->Mode;
149 if ( EfiSimpleNetworkInitialized == pMode->State ) {
150
151 if ( pNicDevice->LinkIdleCnt > MAX_LINKIDLE_THRESHOLD) {
152
153 bLinkUp = pNicDevice->bLinkUp;
154 bSpeed100 = pNicDevice->b100Mbps;
155 bFullDuplex = pNicDevice->bFullDuplex;
156 Status = Ax88772NegotiateLinkComplete ( pNicDevice,
157 &pNicDevice->PollCount,
158 &pNicDevice->bComplete,
159 &pNicDevice->bLinkUp,
160 &pNicDevice->b100Mbps,
161 &pNicDevice->bFullDuplex );
162
163 //
164 // Determine if the autonegotiation is complete
165 //
166 if ( pNicDevice->bComplete ) {
167 if ( pNicDevice->bLinkUp ) {
168 if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
169 || (( !bSpeed100 ) && pNicDevice->b100Mbps )
170 || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
171 || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
172 pNicDevice->PollCount = 0;
173 DEBUG (( EFI_D_INFO , "Reset to establish proper link setup: %d Mbps, %a duplex\r\n",
174 pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
175 Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
176 }
177 if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
178 //
179 // Display the autonegotiation status
180 //
181 DEBUG (( EFI_D_INFO , "Link: Up, %d Mbps, %a duplex\r\n",
182 pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
183
184 }
185 pNicDevice->LinkIdleCnt = 0;
186 }
187 }
188 //
189 // Update the link status
190 //
191 if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
192 DEBUG (( EFI_D_INFO , "Link: Down\r\n"));
193 }
194 }
195
196 pMode->MediaPresent = pNicDevice->bLinkUp;
197 //
198 // Return the interrupt status
199 //
200 if ( NULL != pInterruptStatus ) {
201 *pInterruptStatus = 0;
202 }
203 Status = EFI_SUCCESS;
204 }
205 else {
206 Status = EFI_NOT_STARTED;
207 }
208
209 }
210 else {
211 Status = EFI_INVALID_PARAMETER;
212 }
213 gBS->RestoreTPL(TplPrevious) ;
214
215 return Status;
216 }
217
218
219 /**
220 Resets the network adapter and allocates the transmit and receive buffers
221 required by the network interface; optionally, also requests allocation of
222 additional transmit and receive buffers. This routine must be called before
223 any other routine in the Simple Network protocol is called.
224
225 @param [in] pSimpleNetwork Protocol instance pointer
226 @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
227 @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
228
229 @retval EFI_SUCCESS This operation was successful.
230 @retval EFI_NOT_STARTED The network interface was not started.
231 @retval EFI_OUT_OF_RESORUCES There was not enough memory for the transmit and receive buffers
232 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
233 EFI_SIMPLE_NETWORK_PROTOCOL structure.
234 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
235 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
236
237 **/
238 EFI_STATUS
239 EFIAPI
240 SN_Initialize (
241 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
242 IN UINTN ExtraRxBufferSize,
243 IN UINTN ExtraTxBufferSize
244 )
245 {
246 EFI_SIMPLE_NETWORK_MODE * pMode;
247 EFI_STATUS Status;
248 UINT32 TmpState;
249 EFI_TPL TplPrevious;
250
251 TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
252 //
253 // Verify the parameters
254 //
255 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
256 //
257 // Determine if the interface is already started
258 //
259 pMode = pSimpleNetwork->Mode;
260 if ( EfiSimpleNetworkStarted == pMode->State ) {
261 if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
262 //
263 // Start the adapter
264 //
265 TmpState = pMode->State;
266 pMode->State = EfiSimpleNetworkInitialized;
267 Status = SN_Reset ( pSimpleNetwork, FALSE );
268 if ( EFI_ERROR ( Status )) {
269 //
270 // Update the network state
271 //
272 pMode->State = TmpState;
273 DEBUG (( EFI_D_ERROR , "SN_reset failed\n"));
274 }
275 }
276 else {
277 DEBUG (( EFI_D_ERROR , "Increase ExtraRxBufferSize = %d ExtraTxBufferSize=%d\n",
278 ExtraRxBufferSize, ExtraTxBufferSize));
279 Status = EFI_UNSUPPORTED;
280 }
281 }
282 else {
283 Status = EFI_NOT_STARTED;
284 }
285 }
286 else {
287 Status = EFI_INVALID_PARAMETER;
288 }
289 gBS->RestoreTPL (TplPrevious);
290
291 return Status;
292 }
293
294
295 /**
296 This function converts a multicast IP address to a multicast HW MAC address
297 for all packet transactions.
298
299 @param [in] pSimpleNetwork Protocol instance pointer
300 @param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460].
301 Set to FALSE if the multicast IP address is IPv4 [RFC 791].
302 @param [in] pIP The multicast IP address that is to be converted to a
303 multicast HW MAC address.
304 @param [in] pMAC The multicast HW MAC address that is to be generated from IP.
305
306 @retval EFI_SUCCESS This operation was successful.
307 @retval EFI_NOT_STARTED The network interface was not started.
308 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
309 EFI_SIMPLE_NETWORK_PROTOCOL structure.
310 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
311 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
312
313 **/
314 EFI_STATUS
315 EFIAPI
316 SN_MCastIPtoMAC (
317 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
318 IN BOOLEAN bIPv6,
319 IN EFI_IP_ADDRESS * pIP,
320 IN EFI_MAC_ADDRESS * pMAC
321 )
322 {
323 EFI_STATUS Status;
324 EFI_TPL TplPrevious;
325
326 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
327 //
328 // Get pointer to SNP driver instance for *this.
329 //
330 if (pSimpleNetwork == NULL) {
331 gBS->RestoreTPL(TplPrevious);
332 return EFI_INVALID_PARAMETER;
333 }
334
335 if (pIP == NULL || pMAC == NULL) {
336 gBS->RestoreTPL(TplPrevious);
337 return EFI_INVALID_PARAMETER;
338 }
339
340 if (bIPv6){
341 Status = EFI_UNSUPPORTED;
342 }
343 else {
344 //
345 // check if the ip given is a mcast IP
346 //
347 if ((pIP->v4.Addr[0] & 0xF0) != 0xE0) {
348 gBS->RestoreTPL(TplPrevious);
349 return EFI_INVALID_PARAMETER;
350 }
351 else {
352 pMAC->Addr[0] = 0x01;
353 pMAC->Addr[1] = 0x00;
354 pMAC->Addr[2] = 0x5e;
355 pMAC->Addr[3] = (UINT8) (pIP->v4.Addr[1] & 0x7f);
356 pMAC->Addr[4] = (UINT8) pIP->v4.Addr[2];
357 pMAC->Addr[5] = (UINT8) pIP->v4.Addr[3];
358 Status = EFI_SUCCESS;
359 gBS->RestoreTPL(TplPrevious);
360 }
361 }
362 return Status;
363 }
364
365
366 /**
367 This function performs read and write operations on the NVRAM device
368 attached to a network interface.
369
370 @param [in] pSimpleNetwork Protocol instance pointer
371 @param [in] ReadWrite TRUE for read operations, FALSE for write operations.
372 @param [in] Offset Byte offset in the NVRAM device at which to start the
373 read or write operation. This must be a multiple of
374 NvRamAccessSize and less than NvRamSize.
375 @param [in] BufferSize The number of bytes to read or write from the NVRAM device.
376 This must also be a multiple of NvramAccessSize.
377 @param [in, out] pBuffer A pointer to the data buffer.
378
379 @retval EFI_SUCCESS This operation was successful.
380 @retval EFI_NOT_STARTED The network interface was not started.
381 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
382 EFI_SIMPLE_NETWORK_PROTOCOL structure.
383 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
384 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
385
386 **/
387 EFI_STATUS
388 EFIAPI
389 SN_NvData (
390 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
391 IN BOOLEAN ReadWrite,
392 IN UINTN Offset,
393 IN UINTN BufferSize,
394 IN OUT VOID * pBuffer
395 )
396 {
397 EFI_STATUS Status;
398 //
399 // This is not currently supported
400 //
401 Status = EFI_UNSUPPORTED;
402 return Status;
403 }
404
405 VOID
406 FillPkt2Queue (
407 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
408 IN UINTN BufLength)
409 {
410
411 UINT16 * pLength;
412 UINT16 * pLengthBar;
413 UINT8* pData;
414 UINT32 offset;
415 NIC_DEVICE * pNicDevice;
416
417 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork);
418 for ( offset = 0; offset < BufLength; ){
419 pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
420 pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
421
422 *pLength &= 0x7ff;
423 *pLengthBar &= 0x7ff;
424 *pLengthBar |= 0xf800;
425
426 if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
427 DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));
428 return;
429 }
430
431 if (TRUE == pNicDevice->pNextFill->f_Used) {
432 return;
433 }
434 else {
435 pData = pNicDevice->pBulkInBuff + offset + 4;
436 pNicDevice->pNextFill->f_Used = TRUE;
437 pNicDevice->pNextFill->Length = *pLength;
438 CopyMem (&pNicDevice->pNextFill->Data[0], pData, *pLength);
439
440 pNicDevice->pNextFill = pNicDevice->pNextFill->pNext;
441 offset += ((*pLength + HW_HDR_LENGTH - 1) &~3) + 1;
442 pNicDevice->PktCntInQueue++;
443 }
444
445 }
446 }
447
448 EFI_STATUS
449 EFIAPI
450 SN_Receive (
451 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
452 OUT UINTN * pHeaderSize,
453 OUT UINTN * pBufferSize,
454 OUT VOID * pBuffer,
455 OUT EFI_MAC_ADDRESS * pSrcAddr,
456 OUT EFI_MAC_ADDRESS * pDestAddr,
457 OUT UINT16 * pProtocol
458 )
459 {
460 EFI_SIMPLE_NETWORK_MODE * pMode;
461 NIC_DEVICE * pNicDevice;
462 EFI_STATUS Status;
463 EFI_TPL TplPrevious;
464 UINT16 Type;
465 EFI_USB_IO_PROTOCOL *pUsbIo;
466 UINTN LengthInBytes;
467 UINT32 TransferStatus;
468 RX_PKT * pFirstFill;
469 TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
470
471 //
472 // Verify the parameters
473 //
474 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
475 //
476 // The interface must be running
477 //
478 pMode = pSimpleNetwork->Mode;
479 if ( EfiSimpleNetworkInitialized == pMode->State ) {
480 //
481 // Update the link status
482 //
483 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
484 pNicDevice->LinkIdleCnt++;
485 pMode->MediaPresent = pNicDevice->bLinkUp;
486
487 if ( pMode->MediaPresent && pNicDevice->bComplete) {
488
489
490 if (pNicDevice->PktCntInQueue != 0 ) {
491 DEBUG (( EFI_D_INFO, "pNicDevice->PktCntInQueue = %d\n",
492 pNicDevice->PktCntInQueue));
493 }
494
495 LengthInBytes = MAX_BULKIN_SIZE;
496 if (pNicDevice->PktCntInQueue == 0 ){
497 //
498 // Attempt to do bulk in
499 //
500 SetMem (&pNicDevice->pBulkInBuff[0], 4, 0);
501 pUsbIo = pNicDevice->pUsbIo;
502 Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
503 USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
504 &pNicDevice->pBulkInBuff[0],
505 &LengthInBytes,
506 BULKIN_TIMEOUT,
507 &TransferStatus );
508
509 if (LengthInBytes != 0 && !EFI_ERROR(Status) && !EFI_ERROR(TransferStatus) ){
510 FillPkt2Queue(pSimpleNetwork, LengthInBytes);
511 }
512 }
513
514 pFirstFill = pNicDevice->pFirstFill;
515
516 if (TRUE == pFirstFill->f_Used) {
517 ETHERNET_HEADER * pHeader;
518 pNicDevice->LinkIdleCnt = 0;
519 CopyMem (pBuffer, &pFirstFill->Data[0], pFirstFill->Length);
520 pHeader = (ETHERNET_HEADER *) &pFirstFill->Data[0];
521
522 DEBUG (( EFI_D_INFO, "RX: %02x-%02x-%02x-%02x-%02x-%02x "
523 "%02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n",
524 pFirstFill->Data[0],
525 pFirstFill->Data[1],
526 pFirstFill->Data[2],
527 pFirstFill->Data[3],
528 pFirstFill->Data[4],
529 pFirstFill->Data[5],
530 pFirstFill->Data[6],
531 pFirstFill->Data[7],
532 pFirstFill->Data[8],
533 pFirstFill->Data[9],
534 pFirstFill->Data[10],
535 pFirstFill->Data[11],
536 pFirstFill->Data[12],
537 pFirstFill->Data[13],
538 pFirstFill->Length));
539
540 if ( NULL != pHeaderSize ) {
541 *pHeaderSize = sizeof ( *pHeader );
542 }
543 if ( NULL != pDestAddr ) {
544 CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
545 }
546 if ( NULL != pSrcAddr ) {
547 CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
548 }
549 if ( NULL != pProtocol ) {
550 Type = pHeader->type;
551 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
552 *pProtocol = Type;
553 }
554 Status = EFI_SUCCESS;
555 if (*pBufferSize < pFirstFill->Length) {
556 DEBUG (( EFI_D_ERROR, "RX: Buffer was too small"));
557 Status = EFI_BUFFER_TOO_SMALL;
558 }
559 *pBufferSize = pFirstFill->Length;
560 pFirstFill->f_Used = FALSE;
561 pNicDevice->pFirstFill = pFirstFill->pNext;
562 pNicDevice->PktCntInQueue--;
563 }
564 else {
565 pNicDevice->LinkIdleCnt++;
566 Status = EFI_NOT_READY;
567 }
568 }
569 else {
570 //
571 // Link no up
572 //
573 pNicDevice->LinkIdleCnt++;
574 Status = EFI_NOT_READY;
575 }
576
577 }
578 else {
579 Status = EFI_NOT_STARTED;
580 }
581 }
582 else {
583 Status = EFI_INVALID_PARAMETER;
584 }
585 gBS->RestoreTPL (TplPrevious);
586 return Status;
587 }
588
589 /**
590 This function is used to enable and disable the hardware and software receive
591 filters for the underlying network device.
592
593 The receive filter change is broken down into three steps:
594
595 1. The filter mask bits that are set (ON) in the Enable parameter
596 are added to the current receive filter settings.
597
598 2. The filter mask bits that are set (ON) in the Disable parameter
599 are subtracted from the updated receive filter settins.
600
601 3. If the resulting filter settigns is not supported by the hardware
602 a more liberal setting is selected.
603
604 If the same bits are set in the Enable and Disable parameters, then the bits
605 in the Disable parameter takes precedence.
606
607 If the ResetMCastFilter parameter is TRUE, then the multicast address list
608 filter is disabled (irregardless of what other multicast bits are set in
609 the enable and Disable parameters). The SNP->Mode->MCastFilterCount field
610 is set to zero. The SNP->Mode->MCastFilter contents are undefined.
611
612 After enableing or disabling receive filter settings, software should
613 verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
614 SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
615
616 Note: Some network drivers and/or devices will automatically promote
617 receive filter settings if the requested setting can not be honored.
618 For example, if a request for four multicast addresses is made and
619 the underlying hardware only supports two multicast addresses the
620 driver might set the promiscuous or promiscuous multicast receive filters
621 instead. The receiving software is responsible for discarding any extra
622 packets that get through the hardware receive filters.
623
624 If ResetMCastFilter is TRUE, then the multicast receive filter list
625 on the network interface will be reset to the default multicast receive
626 filter list. If ResetMCastFilter is FALSE, and this network interface
627 allows the multicast receive filter list to be modified, then the
628 MCastFilterCnt and MCastFilter are used to update the current multicast
629 receive filter list. The modified receive filter list settings can be
630 found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
631
632 This routine calls ::ReceiveFilterUpdate to update the receive
633 state in the network adapter.
634
635 @param [in] pSimpleNetwork Protocol instance pointer
636 @param [in] Enable A bit mask of receive filters to enable on the network interface.
637 @param [in] Disable A bit mask of receive filters to disable on the network interface.
638 For backward compatibility with EFI 1.1 platforms, the
639 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
640 when the ResetMCastFilter parameter is TRUE.
641 @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
642 filters on the network interface to their default values.
643 @param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list.
644 This value must be less than or equal to the MaxMCastFilterCnt
645 field of EFI_SIMPLE_NETWORK_MODE. This field is optional if
646 ResetMCastFilter is TRUE.
647 @param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC
648 addresses. This list will replace any existing multicast
649 HW MAC address list. This field is optional if ResetMCastFilter
650 is TRUE.
651
652 @retval EFI_SUCCESS This operation was successful.
653 @retval EFI_NOT_STARTED The network interface was not started.
654 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
655 EFI_SIMPLE_NETWORK_PROTOCOL structure.
656 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
657 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
658
659 **/
660 EFI_STATUS
661 EFIAPI
662 SN_ReceiveFilters (
663 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
664 IN UINT32 Enable,
665 IN UINT32 Disable,
666 /*
667 #define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01
668 #define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02
669 #define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04
670 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08
671 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
672 */
673 IN BOOLEAN bResetMCastFilter,
674 IN UINTN MCastFilterCnt,
675 IN EFI_MAC_ADDRESS * pMCastFilter
676 )
677 {
678 EFI_SIMPLE_NETWORK_MODE * pMode;
679 EFI_STATUS Status = EFI_SUCCESS;
680 EFI_TPL TplPrevious;
681 NIC_DEVICE * pNicDevice;
682
683 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
684 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
685 pMode = pSimpleNetwork->Mode;
686
687 if (pSimpleNetwork == NULL) {
688 gBS->RestoreTPL(TplPrevious);
689 return EFI_INVALID_PARAMETER;
690 }
691
692 switch (pMode->State) {
693 case EfiSimpleNetworkInitialized:
694 break;
695 case EfiSimpleNetworkStopped:
696 Status = EFI_NOT_STARTED;
697 gBS->RestoreTPL(TplPrevious);
698 return Status;
699 default:
700 Status = EFI_DEVICE_ERROR;
701 gBS->RestoreTPL(TplPrevious);
702 return Status;
703 }
704
705 //
706 // check if we are asked to enable or disable something that the UNDI
707 // does not even support!
708 //
709 if (((Enable &~pMode->ReceiveFilterMask) != 0) ||
710 ((Disable &~pMode->ReceiveFilterMask) != 0)) {
711 Status = EFI_INVALID_PARAMETER;
712 gBS->RestoreTPL(TplPrevious);
713 return Status;
714 }
715
716 if (bResetMCastFilter) {
717 Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & pMode->ReceiveFilterMask);
718 pMode->MCastFilterCount = 0;
719 if ( (0 == (pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST))
720 && Enable == 0 && Disable == 2) {
721 gBS->RestoreTPL(TplPrevious);
722 return EFI_SUCCESS;
723 }
724 }
725 else {
726 if (MCastFilterCnt != 0) {
727 UINTN i;
728 EFI_MAC_ADDRESS * pMulticastAddress;
729 pMulticastAddress = pMCastFilter;
730
731 if ((MCastFilterCnt > pMode->MaxMCastFilterCount) ||
732 (pMCastFilter == NULL)) {
733 Status = EFI_INVALID_PARAMETER;
734 gBS->RestoreTPL(TplPrevious);
735 return Status;
736 }
737
738 for ( i = 0 ; i < MCastFilterCnt ; i++ ) {
739 UINT8 tmp;
740 tmp = pMulticastAddress->Addr[0];
741 if ( (tmp & 0x01) != 0x01 ) {
742 gBS->RestoreTPL(TplPrevious);
743 return EFI_INVALID_PARAMETER;
744 }
745 pMulticastAddress++;
746 }
747
748 pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
749 CopyMem (&pMode->MCastFilter[0],
750 pMCastFilter,
751 MCastFilterCnt * sizeof ( EFI_MAC_ADDRESS));
752 }
753 }
754
755 if (Enable == 0 && Disable == 0 && !bResetMCastFilter && MCastFilterCnt == 0) {
756 Status = EFI_SUCCESS;
757 gBS->RestoreTPL(TplPrevious);
758 return Status;
759 }
760
761 if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
762 Status = EFI_INVALID_PARAMETER;
763 gBS->RestoreTPL(TplPrevious);
764 return Status;
765 }
766
767 pMode->ReceiveFilterSetting |= Enable;
768 pMode->ReceiveFilterSetting &= ~Disable;
769 Status = ReceiveFilterUpdate (pSimpleNetwork);
770
771 if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
772 Status = EFI_SUCCESS;
773
774 gBS->RestoreTPL(TplPrevious);
775 return Status;
776 }
777
778 /**
779 Reset the network adapter.
780
781 Resets a network adapter and reinitializes it with the parameters that
782 were provided in the previous call to Initialize (). The transmit and
783 receive queues are cleared. Receive filters, the station address, the
784 statistics, and the multicast-IP-to-HW MAC addresses are not reset by
785 this call.
786
787 This routine calls ::Ax88772Reset to perform the adapter specific
788 reset operation. This routine also starts the link negotiation
789 by calling ::Ax88772NegotiateLinkStart.
790
791 @param [in] pSimpleNetwork Protocol instance pointer
792 @param [in] bExtendedVerification Indicates that the driver may perform a more
793 exhaustive verification operation of the device
794 during reset.
795
796 @retval EFI_SUCCESS This operation was successful.
797 @retval EFI_NOT_STARTED The network interface was not started.
798 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
799 EFI_SIMPLE_NETWORK_PROTOCOL structure.
800 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
801 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
802
803 **/
804 EFI_STATUS
805 EFIAPI
806 SN_Reset (
807 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
808 IN BOOLEAN bExtendedVerification
809 )
810 {
811 EFI_SIMPLE_NETWORK_MODE * pMode;
812 NIC_DEVICE * pNicDevice;
813 EFI_STATUS Status;
814 EFI_TPL TplPrevious;
815
816 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
817 //
818 // Verify the parameters
819 //
820 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
821 pMode = pSimpleNetwork->Mode;
822 if ( EfiSimpleNetworkInitialized == pMode->State ) {
823 //
824 // Update the device state
825 //
826 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
827 pNicDevice->bComplete = FALSE;
828 pNicDevice->bLinkUp = FALSE;
829 pNicDevice->bHavePkt = FALSE;
830 pMode = pSimpleNetwork->Mode;
831 pMode->MediaPresent = FALSE;
832
833 //
834 // Reset the device
835 //
836 Status = Ax88772Reset ( pNicDevice );
837 if ( !EFI_ERROR ( Status )) {
838 //
839 // Update the receive filters in the adapter
840 //
841 Status = ReceiveFilterUpdate ( pSimpleNetwork );
842
843 //
844 // Try to get a connection to the network
845 //
846 if ( !EFI_ERROR ( Status )) {
847 //
848 // Start the autonegotiation
849 //
850 Status = Ax88772NegotiateLinkStart ( pNicDevice );
851 }
852 }
853 }
854 else {
855 Status = EFI_NOT_STARTED;
856 }
857 }
858 else {
859 Status = EFI_INVALID_PARAMETER;
860 }
861 gBS->RestoreTPL ( TplPrevious );
862 return Status;
863 }
864
865 /**
866 Initialize the simple network protocol.
867
868 This routine calls ::Ax88772MacAddressGet to obtain the
869 MAC address.
870
871 @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer
872
873 @retval EFI_SUCCESS Setup was successful
874
875 **/
876 EFI_STATUS
877 SN_Setup (
878 IN NIC_DEVICE * pNicDevice
879 )
880 {
881
882
883 EFI_SIMPLE_NETWORK_MODE * pMode;
884 EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
885 EFI_STATUS Status;
886 RX_PKT * pCurr = NULL;
887 RX_PKT * pPrev = NULL;
888
889 pSimpleNetwork = &pNicDevice->SimpleNetwork;
890 pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
891 pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
892 pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
893 pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
894 pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
895 pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
896 pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
897 pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
898 pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
899 pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
900 pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
901 pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
902 pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
903 pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
904 pSimpleNetwork->WaitForPacket = NULL;
905 pMode = &pNicDevice->SimpleNetworkData;
906 pSimpleNetwork->Mode = pMode;
907 pMode->State = EfiSimpleNetworkStopped;
908 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
909 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
910 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
911 pMode->NvRamSize = 0;
912 pMode->NvRamAccessSize = 0;
913 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
914 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
915 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
916 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
917 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
918 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
919 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
920 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
921 pMode->MCastFilterCount = 0;
922 SetMem ( &pMode->BroadcastAddress,
923 PXE_HWADDR_LEN_ETHER,
924 0xff );
925 pMode->IfType = EfiNetworkInterfaceUndi;
926 pMode->MacAddressChangeable = TRUE;
927 pMode->MultipleTxSupported = FALSE;
928 pMode->MediaPresentSupported = TRUE;
929 pMode->MediaPresent = FALSE;
930 pNicDevice->LinkIdleCnt = 0;
931 //
932 // Read the MAC address
933 //
934 pNicDevice->PhyId = PHY_ID_INTERNAL;
935 pNicDevice->b100Mbps = TRUE;
936 pNicDevice->bFullDuplex = TRUE;
937
938 Status = Ax88772MacAddressGet (
939 pNicDevice,
940 &pMode->PermanentAddress.Addr[0]);
941
942 if ( !EFI_ERROR ( Status )) {
943 int i;
944 //
945 // Use the hardware address as the current address
946 //
947
948 CopyMem ( &pMode->CurrentAddress,
949 &pMode->PermanentAddress,
950 PXE_HWADDR_LEN_ETHER );
951
952 CopyMem ( &pNicDevice->MAC,
953 &pMode->PermanentAddress,
954 PXE_HWADDR_LEN_ETHER );
955
956 pNicDevice->PktCntInQueue = 0;
957
958 for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
959 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
960 sizeof (RX_PKT),
961 (VOID **) &pCurr);
962 if ( EFI_ERROR(Status)) {
963 DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
964 return Status;
965 }
966 pCurr->f_Used = FALSE;
967
968 if ( i ) {
969 pPrev->pNext = pCurr;
970 }
971 else {
972 pNicDevice->QueueHead = pCurr;
973 }
974
975 if (MAX_QUEUE_SIZE - 1 == i) {
976 pCurr->pNext = pNicDevice->QueueHead;
977 }
978
979 pPrev = pCurr;
980 }
981
982 pNicDevice->pNextFill = pNicDevice->QueueHead;
983 pNicDevice->pFirstFill = pNicDevice->QueueHead;
984
985 Status = gBS->AllocatePool (EfiRuntimeServicesData,
986 MAX_BULKIN_SIZE,
987 (VOID **) &pNicDevice->pBulkInBuff);
988
989 if (EFI_ERROR(Status)) {
990 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",
991 Status));
992 return Status;
993 }
994 }
995 else {
996 DEBUG (( EFI_D_ERROR, "Ax88772MacAddressGet error. Status = %r\n", Status));
997 return Status;
998 }
999
1000 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
1001 sizeof ( RX_TX_PACKET ),
1002 (VOID **) &pNicDevice->pRxTest );
1003
1004 if (EFI_ERROR (Status)) {
1005 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",
1006 Status));
1007 return Status;
1008 }
1009
1010 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
1011 sizeof ( RX_TX_PACKET ),
1012 (VOID **) &pNicDevice->pTxTest );
1013
1014 if (EFI_ERROR (Status)) {
1015 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",
1016 Status));
1017 gBS->FreePool (pNicDevice->pRxTest);
1018 }
1019
1020 return Status;
1021 }
1022
1023
1024 /**
1025 This routine starts the network interface.
1026
1027 @param [in] pSimpleNetwork Protocol instance pointer
1028
1029 @retval EFI_SUCCESS This operation was successful.
1030 @retval EFI_ALREADY_STARTED The network interface was already started.
1031 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1032 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1033 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1034 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1035
1036 **/
1037 EFI_STATUS
1038 EFIAPI
1039 SN_Start (
1040 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1041 )
1042 {
1043 NIC_DEVICE * pNicDevice;
1044 EFI_SIMPLE_NETWORK_MODE * pMode;
1045 EFI_STATUS Status;
1046 EFI_TPL TplPrevious;
1047 int i = 0;
1048 RX_PKT * pCurr = NULL;
1049
1050 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1051 //
1052 // Verify the parameters
1053 //
1054 Status = EFI_INVALID_PARAMETER;
1055 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1056 pMode = pSimpleNetwork->Mode;
1057 if ( EfiSimpleNetworkStopped == pMode->State ) {
1058 //
1059 // Initialize the mode structuref
1060 // NVRAM access is not supported
1061 //
1062 ZeroMem ( pMode, sizeof ( *pMode ));
1063
1064 pMode->State = EfiSimpleNetworkStarted;
1065 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
1066 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
1067 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
1068 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
1069 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
1070 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
1071 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
1072 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
1073 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
1074 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
1075 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1076 Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
1077 CopyMem ( &pMode->CurrentAddress,
1078 &pMode->PermanentAddress,
1079 sizeof ( pMode->CurrentAddress ));
1080 SetMem(&pMode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
1081 pMode->IfType = EfiNetworkInterfaceUndi;
1082 pMode->MacAddressChangeable = TRUE;
1083 pMode->MultipleTxSupported = FALSE;
1084 pMode->MediaPresentSupported = TRUE;
1085 pMode->MediaPresent = FALSE;
1086 pNicDevice->PktCntInQueue = 0;
1087 pNicDevice->pNextFill = pNicDevice->QueueHead;
1088 pNicDevice->pFirstFill = pNicDevice->QueueHead;
1089 pCurr = pNicDevice->QueueHead;
1090
1091 for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
1092 pCurr->f_Used = FALSE;
1093 pCurr = pCurr->pNext;
1094 }
1095
1096 }
1097 else {
1098 Status = EFI_ALREADY_STARTED;
1099 }
1100 }
1101 gBS->RestoreTPL ( TplPrevious );
1102 return Status;
1103 }
1104
1105
1106 /**
1107 Set the MAC address.
1108
1109 This function modifies or resets the current station address of a
1110 network interface. If Reset is TRUE, then the current station address
1111 is set ot the network interface's permanent address. If Reset if FALSE
1112 then the current station address is changed to the address specified by
1113 pNew.
1114
1115 This routine calls ::Ax88772MacAddressSet to update the MAC address
1116 in the network adapter.
1117
1118 @param [in] pSimpleNetwork Protocol instance pointer
1119 @param [in] bReset Flag used to reset the station address to the
1120 network interface's permanent address.
1121 @param [in] pNew New station address to be used for the network
1122 interface.
1123
1124 @retval EFI_SUCCESS This operation was successful.
1125 @retval EFI_NOT_STARTED The network interface was not started.
1126 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1127 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1128 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1129 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1130
1131 **/
1132 EFI_STATUS
1133 EFIAPI
1134 SN_StationAddress (
1135 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1136 IN BOOLEAN bReset,
1137 IN EFI_MAC_ADDRESS * pNew
1138 )
1139 {
1140 NIC_DEVICE * pNicDevice;
1141 EFI_SIMPLE_NETWORK_MODE * pMode;
1142 EFI_STATUS Status;
1143 EFI_TPL TplPrevious;
1144
1145 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1146 //
1147 // Verify the parameters
1148 //
1149 if (( NULL != pSimpleNetwork )
1150 && ( NULL != pSimpleNetwork->Mode )
1151 && (( !bReset ) || ( bReset && ( NULL != pNew )))) {
1152 //
1153 // Verify that the adapter is already started
1154 //
1155 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1156 pMode = pSimpleNetwork->Mode;
1157 if ( EfiSimpleNetworkStarted == pMode->State ) {
1158 //
1159 // Determine the adapter MAC address
1160 //
1161 if ( bReset ) {
1162 //
1163 // Use the permanent address
1164 //
1165 CopyMem ( &pMode->CurrentAddress,
1166 &pMode->PermanentAddress,
1167 sizeof ( pMode->CurrentAddress ));
1168 }
1169 else {
1170 //
1171 // Use the specified address
1172 //
1173 CopyMem ( &pMode->CurrentAddress,
1174 pNew,
1175 sizeof ( pMode->CurrentAddress ));
1176 }
1177
1178 //
1179 // Update the address on the adapter
1180 //
1181 Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
1182 }
1183 else {
1184 Status = EFI_NOT_STARTED;
1185 }
1186 }
1187 else {
1188 Status = EFI_INVALID_PARAMETER;
1189 }
1190 gBS->RestoreTPL ( TplPrevious );
1191 return Status;
1192 }
1193
1194
1195 /**
1196 This function resets or collects the statistics on a network interface.
1197 If the size of the statistics table specified by StatisticsSize is not
1198 big enough for all of the statistics that are collected by the network
1199 interface, then a partial buffer of statistics is returned in
1200 StatisticsTable.
1201
1202 @param [in] pSimpleNetwork Protocol instance pointer
1203 @param [in] bReset Set to TRUE to reset the statistics for the network interface.
1204 @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output
1205 the size, in bytes, of the resulting table of statistics.
1206 @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
1207 conains the statistics.
1208
1209 @retval EFI_SUCCESS This operation was successful.
1210 @retval EFI_NOT_STARTED The network interface was not started.
1211 @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.
1212 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1213 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1214 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1215 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1216
1217 typedef struct {
1218 UINT64 RxTotalFrames;
1219 UINT64 RxGoodFrames;
1220 UINT64 RxUndersizeFrames;
1221 UINT64 RxOversizeFrames;
1222 UINT64 RxDroppedFrames;
1223 UINT64 RxUnicastFrames;
1224 UINT64 RxBroadcastFrames;
1225 UINT64 RxMulticastFrames;
1226 UINT64 RxCrcErrorFrames;
1227 UINT64 RxTotalBytes;
1228 UINT64 TxTotalFrames;
1229 UINT64 TxGoodFrames;
1230 UINT64 TxUndersizeFrames;
1231 UINT64 TxOversizeFrames;
1232 UINT64 TxDroppedFrames;
1233 UINT64 TxUnicastFrames;
1234 UINT64 TxBroadcastFrames;
1235 UINT64 TxMulticastFrames;
1236 UINT64 TxCrcErrorFrames;
1237 UINT64 TxTotalBytes;
1238 UINT64 Collisions;
1239 UINT64 UnsupportedProtocol;
1240 } EFI_NETWORK_STATISTICS;
1241 **/
1242 EFI_STATUS
1243 EFIAPI
1244 SN_Statistics (
1245 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1246 IN BOOLEAN bReset,
1247 IN OUT UINTN * pStatisticsSize,
1248 OUT EFI_NETWORK_STATISTICS * pStatisticsTable
1249 )
1250 {
1251 EFI_STATUS Status;
1252
1253 Status = EFI_UNSUPPORTED;
1254
1255 return Status;
1256 }
1257
1258
1259 /**
1260 This function stops a network interface. This call is only valid
1261 if the network interface is in the started state.
1262
1263 @param [in] pSimpleNetwork Protocol instance pointer
1264
1265 @retval EFI_SUCCESS This operation was successful.
1266 @retval EFI_NOT_STARTED The network interface was not started.
1267 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1268 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1269 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1270 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1271
1272 **/
1273 EFI_STATUS
1274 EFIAPI
1275 SN_Stop (
1276 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1277 )
1278 {
1279 EFI_SIMPLE_NETWORK_MODE * pMode;
1280 EFI_STATUS Status;
1281 EFI_TPL TplPrevious;
1282
1283 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1284 //
1285 // Verify the parameters
1286 //
1287 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1288 //
1289 // Determine if the interface is started
1290 //
1291 pMode = pSimpleNetwork->Mode;
1292 if ( EfiSimpleNetworkStarted == pMode->State ) {
1293 pMode->State = EfiSimpleNetworkStopped;
1294 Status = EFI_SUCCESS;
1295 }
1296 else {
1297 Status = EFI_NOT_STARTED;
1298 }
1299 }
1300 else {
1301 Status = EFI_INVALID_PARAMETER;
1302 }
1303
1304 gBS->RestoreTPL ( TplPrevious );
1305 return Status;
1306 }
1307
1308
1309 /**
1310 This function releases the memory buffers assigned in the Initialize() call.
1311 Pending transmits and receives are lost, and interrupts are cleared and disabled.
1312 After this call, only Initialize() and Stop() calls may be used.
1313
1314 @param [in] pSimpleNetwork Protocol instance pointer
1315
1316 @retval EFI_SUCCESS This operation was successful.
1317 @retval EFI_NOT_STARTED The network interface was not started.
1318 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1319 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1320 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1321 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1322
1323 **/
1324 EFI_STATUS
1325 EFIAPI
1326 SN_Shutdown (
1327 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1328 )
1329 {
1330 EFI_SIMPLE_NETWORK_MODE * pMode;
1331 UINT32 RxFilter;
1332 EFI_STATUS Status;
1333 EFI_TPL TplPrevious;
1334
1335 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1336 //
1337 // Verify the parameters
1338 //
1339 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1340 //
1341 // Determine if the interface is already started
1342 //
1343 pMode = pSimpleNetwork->Mode;
1344 if ( EfiSimpleNetworkInitialized == pMode->State ) {
1345 //
1346 // Stop the adapter
1347 //
1348 RxFilter = pMode->ReceiveFilterSetting;
1349 pMode->ReceiveFilterSetting = 0;
1350 Status = SN_Reset ( pSimpleNetwork, FALSE );
1351 pMode->ReceiveFilterSetting = RxFilter;
1352 if ( !EFI_ERROR ( Status )) {
1353
1354 //
1355 // Update the network state
1356 //
1357 pMode->State = EfiSimpleNetworkStarted;
1358 }
1359 else if ( EFI_DEVICE_ERROR == Status ) {
1360 pMode->State = EfiSimpleNetworkStopped;
1361 }
1362 }
1363 else {
1364 Status = EFI_NOT_STARTED;
1365 }
1366 }
1367 else {
1368 Status = EFI_INVALID_PARAMETER;
1369 }
1370 gBS->RestoreTPL ( TplPrevious );
1371 return Status;
1372 }
1373
1374
1375 /**
1376 Send a packet over the network.
1377
1378 This function places the packet specified by Header and Buffer on
1379 the transmit queue. This function performs a non-blocking transmit
1380 operation. When the transmit is complete, the buffer is returned
1381 via the GetStatus() call.
1382
1383 This routine calls ::Ax88772Rx to empty the network adapter of
1384 receive packets. The routine then passes the transmit packet
1385 to the network adapter.
1386
1387 @param [in] pSimpleNetwork Protocol instance pointer
1388 @param [in] HeaderSize The size, in bytes, of the media header to be filled in by
1389 the Transmit() function. If HeaderSize is non-zero, then
1390 it must be equal to SimpleNetwork->Mode->MediaHeaderSize
1391 and DestAddr and Protocol parameters must not be NULL.
1392 @param [in] BufferSize The size, in bytes, of the entire packet (media header and
1393 data) to be transmitted through the network interface.
1394 @param [in] pBuffer A pointer to the packet (media header followed by data) to
1395 to be transmitted. This parameter can not be NULL. If
1396 HeaderSize is zero, then the media header is Buffer must
1397 already be filled in by the caller. If HeaderSize is nonzero,
1398 then the media header will be filled in by the Transmit()
1399 function.
1400 @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
1401 this parameter is ignored. If HeaderSize is nonzero and
1402 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
1403 is used for the source HW MAC address.
1404 @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
1405 this parameter is ignored.
1406 @param [in] pProtocol The type of header to build. If HeaderSize is zero, then
1407 this parameter is ignored.
1408
1409 @retval EFI_SUCCESS This operation was successful.
1410 @retval EFI_NOT_STARTED The network interface was not started.
1411 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
1412 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
1413 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1414 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1415 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1416
1417 **/
1418 EFI_STATUS
1419 EFIAPI
1420 SN_Transmit (
1421 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1422 IN UINTN HeaderSize,
1423 IN UINTN BufferSize,
1424 IN VOID * pBuffer,
1425 IN EFI_MAC_ADDRESS * pSrcAddr,
1426 IN EFI_MAC_ADDRESS * pDestAddr,
1427 IN UINT16 * pProtocol
1428 )
1429 {
1430 ETHERNET_HEADER * pHeader;
1431 EFI_SIMPLE_NETWORK_MODE * pMode;
1432 NIC_DEVICE * pNicDevice;
1433 EFI_USB_IO_PROTOCOL * pUsbIo;
1434 EFI_STATUS Status;
1435 UINTN TransferLength;
1436 UINT32 TransferStatus;
1437 UINT16 Type;
1438 EFI_TPL TplPrevious;
1439
1440 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1441
1442 // Verify the parameters
1443 //
1444 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1445 //
1446 // The interface must be running
1447 //
1448 pMode = pSimpleNetwork->Mode;
1449 if ( EfiSimpleNetworkInitialized == pMode->State ) {
1450 //
1451 // Update the link status
1452 //
1453 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1454 pMode->MediaPresent = pNicDevice->bLinkUp;
1455
1456 //
1457 // Release the synchronization with Ax88772Timer
1458 //
1459 if ( pMode->MediaPresent && pNicDevice->bComplete) {
1460 //
1461 // Copy the packet into the USB buffer
1462 //
1463
1464 CopyMem ( &pNicDevice->pTxTest->Data[0], pBuffer, BufferSize );
1465 pNicDevice->pTxTest->Length = (UINT16) BufferSize;
1466
1467 //
1468 // Transmit the packet
1469 //
1470 pHeader = (ETHERNET_HEADER *) &pNicDevice->pTxTest->Data[0];
1471 if ( 0 != HeaderSize ) {
1472 if ( NULL != pDestAddr ) {
1473 CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
1474 }
1475 if ( NULL != pSrcAddr ) {
1476 CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
1477 }
1478 else {
1479 CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
1480 }
1481 if ( NULL != pProtocol ) {
1482 Type = *pProtocol;
1483 }
1484 else {
1485 Type = pNicDevice->pTxTest->Length;
1486 }
1487 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
1488 pHeader->type = Type;
1489 }
1490 if ( pNicDevice->pTxTest->Length < MIN_ETHERNET_PKT_SIZE ) {
1491 pNicDevice->pTxTest->Length = MIN_ETHERNET_PKT_SIZE;
1492 ZeroMem ( &pNicDevice->pTxTest->Data[ BufferSize ],
1493 pNicDevice->pTxTest->Length - BufferSize );
1494 }
1495
1496 DEBUG ((EFI_D_INFO, "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x"
1497 " %02x-%02x %d bytes\r\n",
1498 pNicDevice->pTxTest->Data[0],
1499 pNicDevice->pTxTest->Data[1],
1500 pNicDevice->pTxTest->Data[2],
1501 pNicDevice->pTxTest->Data[3],
1502 pNicDevice->pTxTest->Data[4],
1503 pNicDevice->pTxTest->Data[5],
1504 pNicDevice->pTxTest->Data[6],
1505 pNicDevice->pTxTest->Data[7],
1506 pNicDevice->pTxTest->Data[8],
1507 pNicDevice->pTxTest->Data[9],
1508 pNicDevice->pTxTest->Data[10],
1509 pNicDevice->pTxTest->Data[11],
1510 pNicDevice->pTxTest->Data[12],
1511 pNicDevice->pTxTest->Data[13],
1512 pNicDevice->pTxTest->Length ));
1513
1514 pNicDevice->pTxTest->LengthBar = ~(pNicDevice->pTxTest->Length);
1515 TransferLength = sizeof ( pNicDevice->pTxTest->Length )
1516 + sizeof ( pNicDevice->pTxTest->LengthBar )
1517 + pNicDevice->pTxTest->Length;
1518
1519 if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
1520 TransferLength +=4;
1521
1522 //
1523 // Work around USB bus driver bug where a timeout set by receive
1524 // succeeds but the timeout expires immediately after, causing the
1525 // transmit operation to timeout.
1526 //
1527 pUsbIo = pNicDevice->pUsbIo;
1528 Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
1529 BULK_OUT_ENDPOINT,
1530 &pNicDevice->pTxTest->Length,
1531 &TransferLength,
1532 0xfffffffe,
1533 &TransferStatus );
1534 if ( !EFI_ERROR ( Status )) {
1535 Status = TransferStatus;
1536 }
1537
1538 if ( !EFI_ERROR ( Status )) {
1539 pNicDevice->pTxBuffer = pBuffer;
1540 }
1541 else {
1542 if ((TransferLength != (UINTN)( pNicDevice->pTxTest->Length + 4 )) &&
1543 (TransferLength != (UINTN)(( pNicDevice->pTxTest->Length + 4 ) + 4))) {
1544 DEBUG ((EFI_D_INFO, "TransferLength didn't match Packet Length\n"));
1545 }
1546 //
1547 // Reset the controller to fix the error
1548 //
1549 if ( EFI_DEVICE_ERROR == Status ) {
1550 SN_Reset ( pSimpleNetwork, FALSE );
1551 }
1552 Status = EFI_NOT_READY;
1553 }
1554 }
1555 else {
1556 //
1557 // No packets available.
1558 //
1559 Status = EFI_NOT_READY;
1560 }
1561
1562 }
1563 else {
1564 Status = EFI_NOT_STARTED ;
1565 }
1566 }
1567 else {
1568 Status = EFI_INVALID_PARAMETER;
1569 }
1570
1571 gBS->RestoreTPL (TplPrevious);
1572
1573 return Status;
1574 }