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