]> git.proxmox.com Git - mirror_edk2.git/blob - OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
Ax88772: Add logic to separate packet, fix MTU issue. Ax88772b: Fix driver model...
[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 NIC_DEVICE * pNicDevice;
704
705 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
706 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
707 pMode = pSimpleNetwork->Mode;
708
709 if (pSimpleNetwork == NULL) {
710 gBS->RestoreTPL(TplPrevious);
711 return EFI_INVALID_PARAMETER;
712 }
713
714 switch (pMode->State) {
715 case EfiSimpleNetworkInitialized:
716 break;
717 case EfiSimpleNetworkStopped:
718 Status = EFI_NOT_STARTED;
719 gBS->RestoreTPL(TplPrevious);
720 return Status;
721 default:
722 Status = EFI_DEVICE_ERROR;
723 gBS->RestoreTPL(TplPrevious);
724 return Status;
725 }
726
727 //
728 // check if we are asked to enable or disable something that the UNDI
729 // does not even support!
730 //
731 if (((Enable &~pMode->ReceiveFilterMask) != 0) ||
732 ((Disable &~pMode->ReceiveFilterMask) != 0)) {
733 Status = EFI_INVALID_PARAMETER;
734 gBS->RestoreTPL(TplPrevious);
735 return Status;
736 }
737
738 if (bResetMCastFilter) {
739 Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & pMode->ReceiveFilterMask);
740 pMode->MCastFilterCount = 0;
741 if ( (0 == (pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST))
742 && Enable == 0 && Disable == 2) {
743 gBS->RestoreTPL(TplPrevious);
744 return EFI_SUCCESS;
745 }
746 }
747 else {
748 if (MCastFilterCnt != 0) {
749 UINTN i;
750 EFI_MAC_ADDRESS * pMulticastAddress;
751 pMulticastAddress = pMCastFilter;
752
753 if ((MCastFilterCnt > pMode->MaxMCastFilterCount) ||
754 (pMCastFilter == NULL)) {
755 Status = EFI_INVALID_PARAMETER;
756 gBS->RestoreTPL(TplPrevious);
757 return Status;
758 }
759
760 for ( i = 0 ; i < MCastFilterCnt ; i++ ) {
761 UINT8 tmp;
762 tmp = pMulticastAddress->Addr[0];
763 if ( (tmp & 0x01) != 0x01 ) {
764 gBS->RestoreTPL(TplPrevious);
765 return EFI_INVALID_PARAMETER;
766 }
767 pMulticastAddress++;
768 }
769
770 pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
771 CopyMem (&pMode->MCastFilter[0],
772 pMCastFilter,
773 MCastFilterCnt * sizeof ( EFI_MAC_ADDRESS));
774 }
775 }
776
777 if (Enable == 0 && Disable == 0 && !bResetMCastFilter && MCastFilterCnt == 0) {
778 Status = EFI_SUCCESS;
779 gBS->RestoreTPL(TplPrevious);
780 return Status;
781 }
782
783 if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
784 Status = EFI_INVALID_PARAMETER;
785 gBS->RestoreTPL(TplPrevious);
786 return Status;
787 }
788
789 pMode->ReceiveFilterSetting |= Enable;
790 pMode->ReceiveFilterSetting &= ~Disable;
791 Status = ReceiveFilterUpdate (pSimpleNetwork);
792
793 if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
794 Status = EFI_SUCCESS;
795
796 gBS->RestoreTPL(TplPrevious);
797 return Status;
798 }
799
800 /**
801 Reset the network adapter.
802
803 Resets a network adapter and reinitializes it with the parameters that
804 were provided in the previous call to Initialize (). The transmit and
805 receive queues are cleared. Receive filters, the station address, the
806 statistics, and the multicast-IP-to-HW MAC addresses are not reset by
807 this call.
808
809 This routine calls ::Ax88772Reset to perform the adapter specific
810 reset operation. This routine also starts the link negotiation
811 by calling ::Ax88772NegotiateLinkStart.
812
813 @param [in] pSimpleNetwork Protocol instance pointer
814 @param [in] bExtendedVerification Indicates that the driver may perform a more
815 exhaustive verification operation of the device
816 during reset.
817
818 @retval EFI_SUCCESS This operation was successful.
819 @retval EFI_NOT_STARTED The network interface was not started.
820 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
821 EFI_SIMPLE_NETWORK_PROTOCOL structure.
822 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
823 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
824
825 **/
826 EFI_STATUS
827 EFIAPI
828 SN_Reset (
829 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
830 IN BOOLEAN bExtendedVerification
831 )
832 {
833 EFI_SIMPLE_NETWORK_MODE * pMode;
834 NIC_DEVICE * pNicDevice;
835 EFI_STATUS Status;
836 EFI_TPL TplPrevious;
837
838 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
839 //
840 // Verify the parameters
841 //
842 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
843 pMode = pSimpleNetwork->Mode;
844 if ( EfiSimpleNetworkInitialized == pMode->State ) {
845 //
846 // Update the device state
847 //
848 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
849 pNicDevice->bComplete = FALSE;
850 pNicDevice->bLinkUp = FALSE;
851 pNicDevice->bHavePkt = FALSE;
852 pMode = pSimpleNetwork->Mode;
853 pMode->MediaPresent = FALSE;
854
855 //
856 // Reset the device
857 //
858 Status = Ax88772Reset ( pNicDevice );
859 if ( !EFI_ERROR ( Status )) {
860 //
861 // Update the receive filters in the adapter
862 //
863 Status = ReceiveFilterUpdate ( pSimpleNetwork );
864
865 //
866 // Try to get a connection to the network
867 //
868 if ( !EFI_ERROR ( Status )) {
869 //
870 // Start the autonegotiation
871 //
872 Status = Ax88772NegotiateLinkStart ( pNicDevice );
873 }
874 }
875 }
876 else {
877 if (EfiSimpleNetworkStarted == pMode->State) {
878 Status = EFI_DEVICE_ERROR;
879 }
880 else {
881 Status = EFI_NOT_STARTED;
882 }
883 }
884 }
885 else {
886 Status = EFI_INVALID_PARAMETER;
887 }
888 gBS->RestoreTPL ( TplPrevious );
889 return Status;
890 }
891
892 /**
893 Initialize the simple network protocol.
894
895 This routine calls ::Ax88772MacAddressGet to obtain the
896 MAC address.
897
898 @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer
899
900 @retval EFI_SUCCESS Setup was successful
901
902 **/
903 EFI_STATUS
904 SN_Setup (
905 IN NIC_DEVICE * pNicDevice
906 )
907 {
908
909
910 EFI_SIMPLE_NETWORK_MODE * pMode;
911 EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
912 EFI_STATUS Status;
913 RX_PKT * pCurr = NULL;
914 RX_PKT * pPrev = NULL;
915
916 pSimpleNetwork = &pNicDevice->SimpleNetwork;
917 pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
918 pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
919 pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
920 pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
921 pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
922 pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
923 pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
924 pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
925 pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
926 pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
927 pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
928 pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
929 pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
930 pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
931 pSimpleNetwork->WaitForPacket = NULL;
932 pMode = &pNicDevice->SimpleNetworkData;
933 pSimpleNetwork->Mode = pMode;
934 pMode->State = EfiSimpleNetworkStopped;
935 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
936 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
937 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
938 pMode->NvRamSize = 0;
939 pMode->NvRamAccessSize = 0;
940 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
941 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
942 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
943 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
944 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
945 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
946 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
947 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
948 pMode->MCastFilterCount = 0;
949 SetMem ( &pMode->BroadcastAddress,
950 PXE_HWADDR_LEN_ETHER,
951 0xff );
952 pMode->IfType = EfiNetworkInterfaceUndi;
953 pMode->MacAddressChangeable = TRUE;
954 pMode->MultipleTxSupported = FALSE;
955 pMode->MediaPresentSupported = TRUE;
956 pMode->MediaPresent = FALSE;
957 pNicDevice->LinkIdleCnt = 0;
958 //
959 // Read the MAC address
960 //
961 pNicDevice->PhyId = PHY_ID_INTERNAL;
962 pNicDevice->b100Mbps = TRUE;
963 pNicDevice->bFullDuplex = TRUE;
964
965 Status = Ax88772MacAddressGet (
966 pNicDevice,
967 &pMode->PermanentAddress.Addr[0]);
968
969 if ( !EFI_ERROR ( Status )) {
970 int i;
971 //
972 // Use the hardware address as the current address
973 //
974
975 CopyMem ( &pMode->CurrentAddress,
976 &pMode->PermanentAddress,
977 PXE_HWADDR_LEN_ETHER );
978
979 CopyMem ( &pNicDevice->MAC,
980 &pMode->PermanentAddress,
981 PXE_HWADDR_LEN_ETHER );
982
983 pNicDevice->PktCntInQueue = 0;
984
985 for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
986 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
987 sizeof (RX_PKT),
988 (VOID **) &pCurr);
989 if ( EFI_ERROR(Status)) {
990 DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
991 return Status;
992 }
993 pCurr->f_Used = FALSE;
994
995 if ( i ) {
996 pPrev->pNext = pCurr;
997 }
998 else {
999 pNicDevice->QueueHead = pCurr;
1000 }
1001
1002 if (MAX_QUEUE_SIZE - 1 == i) {
1003 pCurr->pNext = pNicDevice->QueueHead;
1004 }
1005
1006 pPrev = pCurr;
1007 }
1008
1009 pNicDevice->pNextFill = pNicDevice->QueueHead;
1010 pNicDevice->pFirstFill = pNicDevice->QueueHead;
1011
1012 Status = gBS->AllocatePool (EfiRuntimeServicesData,
1013 MAX_BULKIN_SIZE,
1014 (VOID **) &pNicDevice->pBulkInBuff);
1015
1016 if (EFI_ERROR(Status)) {
1017 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",
1018 Status));
1019 return Status;
1020 }
1021 }
1022 else {
1023 DEBUG (( EFI_D_ERROR, "Ax88772MacAddressGet error. Status = %r\n", Status));
1024 return Status;
1025 }
1026
1027 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
1028 sizeof ( RX_TX_PACKET ),
1029 (VOID **) &pNicDevice->pRxTest );
1030
1031 if (EFI_ERROR (Status)) {
1032 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",
1033 Status));
1034 return Status;
1035 }
1036
1037 Status = gBS->AllocatePool ( EfiRuntimeServicesData,
1038 sizeof ( RX_TX_PACKET ),
1039 (VOID **) &pNicDevice->pTxTest );
1040
1041 if (EFI_ERROR (Status)) {
1042 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",
1043 Status));
1044 gBS->FreePool (pNicDevice->pRxTest);
1045 }
1046
1047 return Status;
1048 }
1049
1050
1051 /**
1052 This routine starts the network interface.
1053
1054 @param [in] pSimpleNetwork Protocol instance pointer
1055
1056 @retval EFI_SUCCESS This operation was successful.
1057 @retval EFI_ALREADY_STARTED The network interface was already started.
1058 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1059 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1060 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1061 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1062
1063 **/
1064 EFI_STATUS
1065 EFIAPI
1066 SN_Start (
1067 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1068 )
1069 {
1070 NIC_DEVICE * pNicDevice;
1071 EFI_SIMPLE_NETWORK_MODE * pMode;
1072 EFI_STATUS Status;
1073 EFI_TPL TplPrevious;
1074 int i = 0;
1075 RX_PKT * pCurr = NULL;
1076
1077 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1078 //
1079 // Verify the parameters
1080 //
1081 Status = EFI_INVALID_PARAMETER;
1082 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1083 pMode = pSimpleNetwork->Mode;
1084 if ( EfiSimpleNetworkStopped == pMode->State ) {
1085 //
1086 // Initialize the mode structuref
1087 // NVRAM access is not supported
1088 //
1089 ZeroMem ( pMode, sizeof ( *pMode ));
1090
1091 pMode->State = EfiSimpleNetworkStarted;
1092 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
1093 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
1094 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
1095 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
1096 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
1097 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
1098 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
1099 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
1100 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
1101 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
1102 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1103 Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
1104 CopyMem ( &pMode->CurrentAddress,
1105 &pMode->PermanentAddress,
1106 sizeof ( pMode->CurrentAddress ));
1107 SetMem(&pMode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
1108 pMode->IfType = EfiNetworkInterfaceUndi;
1109 pMode->MacAddressChangeable = TRUE;
1110 pMode->MultipleTxSupported = FALSE;
1111 pMode->MediaPresentSupported = TRUE;
1112 pMode->MediaPresent = FALSE;
1113 pNicDevice->PktCntInQueue = 0;
1114 pNicDevice->pNextFill = pNicDevice->QueueHead;
1115 pNicDevice->pFirstFill = pNicDevice->QueueHead;
1116 pCurr = pNicDevice->QueueHead;
1117
1118 for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
1119 pCurr->f_Used = FALSE;
1120 pCurr = pCurr->pNext;
1121 }
1122
1123 }
1124 else {
1125 Status = EFI_ALREADY_STARTED;
1126 }
1127 }
1128 gBS->RestoreTPL ( TplPrevious );
1129 return Status;
1130 }
1131
1132
1133 /**
1134 Set the MAC address.
1135
1136 This function modifies or resets the current station address of a
1137 network interface. If Reset is TRUE, then the current station address
1138 is set ot the network interface's permanent address. If Reset if FALSE
1139 then the current station address is changed to the address specified by
1140 pNew.
1141
1142 This routine calls ::Ax88772MacAddressSet to update the MAC address
1143 in the network adapter.
1144
1145 @param [in] pSimpleNetwork Protocol instance pointer
1146 @param [in] bReset Flag used to reset the station address to the
1147 network interface's permanent address.
1148 @param [in] pNew New station address to be used for the network
1149 interface.
1150
1151 @retval EFI_SUCCESS This operation was successful.
1152 @retval EFI_NOT_STARTED The network interface was not started.
1153 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1154 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1155 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1156 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1157
1158 **/
1159 EFI_STATUS
1160 EFIAPI
1161 SN_StationAddress (
1162 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1163 IN BOOLEAN bReset,
1164 IN EFI_MAC_ADDRESS * pNew
1165 )
1166 {
1167 NIC_DEVICE * pNicDevice;
1168 EFI_SIMPLE_NETWORK_MODE * pMode;
1169 EFI_STATUS Status;
1170 EFI_TPL TplPrevious;
1171
1172 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1173 //
1174 // Verify the parameters
1175 //
1176 if (( NULL != pSimpleNetwork )
1177 && ( NULL != pSimpleNetwork->Mode )
1178 && (( bReset ) || ( ( !bReset) && ( NULL != pNew )))) {
1179 //
1180 // Verify that the adapter is already started
1181 //
1182 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1183 pMode = pSimpleNetwork->Mode;
1184 if ( EfiSimpleNetworkInitialized == pMode->State ) {
1185 //
1186 // Determine the adapter MAC address
1187 //
1188 if ( bReset ) {
1189 //
1190 // Use the permanent address
1191 //
1192 CopyMem ( &pMode->CurrentAddress,
1193 &pMode->PermanentAddress,
1194 sizeof ( pMode->CurrentAddress ));
1195 }
1196 else {
1197 //
1198 // Use the specified address
1199 //
1200 CopyMem ( &pMode->CurrentAddress,
1201 pNew,
1202 sizeof ( pMode->CurrentAddress ));
1203 }
1204
1205 //
1206 // Update the address on the adapter
1207 //
1208 Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
1209 }
1210 else {
1211 if (EfiSimpleNetworkStarted == pMode->State) {
1212 Status = EFI_DEVICE_ERROR;
1213 }
1214 else {
1215 Status = EFI_NOT_STARTED;
1216 }
1217 }
1218 }
1219 else {
1220 Status = EFI_INVALID_PARAMETER;
1221 }
1222 gBS->RestoreTPL ( TplPrevious );
1223 return Status;
1224 }
1225
1226
1227 /**
1228 This function resets or collects the statistics on a network interface.
1229 If the size of the statistics table specified by StatisticsSize is not
1230 big enough for all of the statistics that are collected by the network
1231 interface, then a partial buffer of statistics is returned in
1232 StatisticsTable.
1233
1234 @param [in] pSimpleNetwork Protocol instance pointer
1235 @param [in] bReset Set to TRUE to reset the statistics for the network interface.
1236 @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output
1237 the size, in bytes, of the resulting table of statistics.
1238 @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
1239 conains the statistics.
1240
1241 @retval EFI_SUCCESS This operation was successful.
1242 @retval EFI_NOT_STARTED The network interface was not started.
1243 @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.
1244 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1245 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1246 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1247 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1248
1249 typedef struct {
1250 UINT64 RxTotalFrames;
1251 UINT64 RxGoodFrames;
1252 UINT64 RxUndersizeFrames;
1253 UINT64 RxOversizeFrames;
1254 UINT64 RxDroppedFrames;
1255 UINT64 RxUnicastFrames;
1256 UINT64 RxBroadcastFrames;
1257 UINT64 RxMulticastFrames;
1258 UINT64 RxCrcErrorFrames;
1259 UINT64 RxTotalBytes;
1260 UINT64 TxTotalFrames;
1261 UINT64 TxGoodFrames;
1262 UINT64 TxUndersizeFrames;
1263 UINT64 TxOversizeFrames;
1264 UINT64 TxDroppedFrames;
1265 UINT64 TxUnicastFrames;
1266 UINT64 TxBroadcastFrames;
1267 UINT64 TxMulticastFrames;
1268 UINT64 TxCrcErrorFrames;
1269 UINT64 TxTotalBytes;
1270 UINT64 Collisions;
1271 UINT64 UnsupportedProtocol;
1272 } EFI_NETWORK_STATISTICS;
1273 **/
1274 EFI_STATUS
1275 EFIAPI
1276 SN_Statistics (
1277 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1278 IN BOOLEAN bReset,
1279 IN OUT UINTN * pStatisticsSize,
1280 OUT EFI_NETWORK_STATISTICS * pStatisticsTable
1281 )
1282 {
1283 EFI_STATUS Status;
1284 EFI_SIMPLE_NETWORK_MODE * pMode;
1285 //
1286 // Verify the prarameters
1287 //
1288 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1289 pMode = pSimpleNetwork->Mode;
1290 //
1291 // Determine if the interface is started
1292 //
1293 if (EfiSimpleNetworkInitialized == pMode->State){
1294 //
1295 // Determine if the StatisticsSize is big enough
1296 //
1297 if (sizeof (EFI_NETWORK_STATISTICS) <= *pStatisticsSize){
1298 if (bReset) {
1299 Status = EFI_SUCCESS;
1300 }
1301 else {
1302 Status = EFI_UNSUPPORTED;
1303 }
1304 }
1305 else {
1306 Status = EFI_BUFFER_TOO_SMALL;
1307 }
1308 }
1309 else{
1310 if (EfiSimpleNetworkStarted == pMode->State) {
1311 Status = EFI_DEVICE_ERROR;
1312 }
1313 else {
1314 Status = EFI_NOT_STARTED;
1315 }
1316 }
1317 }
1318 else {
1319 Status = EFI_INVALID_PARAMETER;
1320 }
1321
1322 return Status;
1323 }
1324
1325
1326 /**
1327 This function stops a network interface. This call is only valid
1328 if the network interface is in the started state.
1329
1330 @param [in] pSimpleNetwork Protocol instance pointer
1331
1332 @retval EFI_SUCCESS This operation was successful.
1333 @retval EFI_NOT_STARTED The network interface was not started.
1334 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1335 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1336 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1337 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1338
1339 **/
1340 EFI_STATUS
1341 EFIAPI
1342 SN_Stop (
1343 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1344 )
1345 {
1346 EFI_SIMPLE_NETWORK_MODE * pMode;
1347 EFI_STATUS Status;
1348 EFI_TPL TplPrevious;
1349
1350 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1351 //
1352 // Verify the parameters
1353 //
1354 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1355 //
1356 // Determine if the interface is started
1357 //
1358 pMode = pSimpleNetwork->Mode;
1359 if ( EfiSimpleNetworkStarted == pMode->State ) {
1360 pMode->State = EfiSimpleNetworkStopped;
1361 Status = EFI_SUCCESS;
1362 }
1363 else {
1364 Status = EFI_NOT_STARTED;
1365 }
1366 }
1367 else {
1368 Status = EFI_INVALID_PARAMETER;
1369 }
1370
1371 gBS->RestoreTPL ( TplPrevious );
1372 return Status;
1373 }
1374
1375
1376 /**
1377 This function releases the memory buffers assigned in the Initialize() call.
1378 Pending transmits and receives are lost, and interrupts are cleared and disabled.
1379 After this call, only Initialize() and Stop() calls may be used.
1380
1381 @param [in] pSimpleNetwork Protocol instance pointer
1382
1383 @retval EFI_SUCCESS This operation was successful.
1384 @retval EFI_NOT_STARTED The network interface was not started.
1385 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1386 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1387 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1388 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1389
1390 **/
1391 EFI_STATUS
1392 EFIAPI
1393 SN_Shutdown (
1394 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
1395 )
1396 {
1397 EFI_SIMPLE_NETWORK_MODE * pMode;
1398 UINT32 RxFilter;
1399 EFI_STATUS Status;
1400 EFI_TPL TplPrevious;
1401
1402 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1403 //
1404 // Verify the parameters
1405 //
1406 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
1407 //
1408 // Determine if the interface is already started
1409 //
1410 pMode = pSimpleNetwork->Mode;
1411 if ( EfiSimpleNetworkInitialized == pMode->State ) {
1412 //
1413 // Stop the adapter
1414 //
1415 RxFilter = pMode->ReceiveFilterSetting;
1416 pMode->ReceiveFilterSetting = 0;
1417 Status = SN_Reset ( pSimpleNetwork, FALSE );
1418 pMode->ReceiveFilterSetting = RxFilter;
1419 if ( !EFI_ERROR ( Status )) {
1420
1421 //
1422 // Update the network state
1423 //
1424 pMode->State = EfiSimpleNetworkStarted;
1425 }
1426 else if ( EFI_DEVICE_ERROR == Status ) {
1427 pMode->State = EfiSimpleNetworkStopped;
1428 }
1429 }
1430 else {
1431 Status = EFI_NOT_STARTED;
1432 }
1433 }
1434 else {
1435 Status = EFI_INVALID_PARAMETER;
1436 }
1437 gBS->RestoreTPL ( TplPrevious );
1438 return Status;
1439 }
1440
1441
1442 /**
1443 Send a packet over the network.
1444
1445 This function places the packet specified by Header and Buffer on
1446 the transmit queue. This function performs a non-blocking transmit
1447 operation. When the transmit is complete, the buffer is returned
1448 via the GetStatus() call.
1449
1450 This routine calls ::Ax88772Rx to empty the network adapter of
1451 receive packets. The routine then passes the transmit packet
1452 to the network adapter.
1453
1454 @param [in] pSimpleNetwork Protocol instance pointer
1455 @param [in] HeaderSize The size, in bytes, of the media header to be filled in by
1456 the Transmit() function. If HeaderSize is non-zero, then
1457 it must be equal to SimpleNetwork->Mode->MediaHeaderSize
1458 and DestAddr and Protocol parameters must not be NULL.
1459 @param [in] BufferSize The size, in bytes, of the entire packet (media header and
1460 data) to be transmitted through the network interface.
1461 @param [in] pBuffer A pointer to the packet (media header followed by data) to
1462 to be transmitted. This parameter can not be NULL. If
1463 HeaderSize is zero, then the media header is Buffer must
1464 already be filled in by the caller. If HeaderSize is nonzero,
1465 then the media header will be filled in by the Transmit()
1466 function.
1467 @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
1468 this parameter is ignored. If HeaderSize is nonzero and
1469 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
1470 is used for the source HW MAC address.
1471 @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
1472 this parameter is ignored.
1473 @param [in] pProtocol The type of header to build. If HeaderSize is zero, then
1474 this parameter is ignored.
1475
1476 @retval EFI_SUCCESS This operation was successful.
1477 @retval EFI_NOT_STARTED The network interface was not started.
1478 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
1479 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
1480 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1481 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1482 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1483
1484 **/
1485 EFI_STATUS
1486 EFIAPI
1487 SN_Transmit (
1488 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
1489 IN UINTN HeaderSize,
1490 IN UINTN BufferSize,
1491 IN VOID * pBuffer,
1492 IN EFI_MAC_ADDRESS * pSrcAddr,
1493 IN EFI_MAC_ADDRESS * pDestAddr,
1494 IN UINT16 * pProtocol
1495 )
1496 {
1497 ETHERNET_HEADER * pHeader;
1498 EFI_SIMPLE_NETWORK_MODE * pMode;
1499 NIC_DEVICE * pNicDevice;
1500 EFI_USB_IO_PROTOCOL * pUsbIo;
1501 EFI_STATUS Status;
1502 UINTN TransferLength;
1503 UINT32 TransferStatus;
1504 UINT16 Type;
1505 EFI_TPL TplPrevious;
1506
1507 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
1508
1509 // Verify the parameters
1510 //
1511 if (( NULL != pSimpleNetwork ) &&
1512 ( NULL != pSimpleNetwork->Mode ) &&
1513 ( NULL != pBuffer) &&
1514 ( (HeaderSize == 0) || ( (NULL != pDestAddr) && (NULL != pProtocol) ))) {
1515 //
1516 // The interface must be running
1517 //
1518 pMode = pSimpleNetwork->Mode;
1519 //
1520 // Verify parameter of HeaderSize
1521 //
1522 if ((HeaderSize == 0) || (HeaderSize == pMode->MediaHeaderSize)){
1523 //
1524 // Determine if BufferSize is big enough
1525 //
1526 if (BufferSize >= pMode->MediaHeaderSize){
1527 if ( EfiSimpleNetworkInitialized == pMode->State ) {
1528 //
1529 // Update the link status
1530 //
1531 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
1532 pMode->MediaPresent = pNicDevice->bLinkUp;
1533
1534 //
1535 // Release the synchronization with Ax88772Timer
1536 //
1537 if ( pMode->MediaPresent && pNicDevice->bComplete) {
1538 //
1539 // Copy the packet into the USB buffer
1540 //
1541
1542 CopyMem ( &pNicDevice->pTxTest->Data[0], pBuffer, BufferSize );
1543 pNicDevice->pTxTest->Length = (UINT16) BufferSize;
1544
1545 //
1546 // Transmit the packet
1547 //
1548 pHeader = (ETHERNET_HEADER *) &pNicDevice->pTxTest->Data[0];
1549 if ( 0 != HeaderSize ) {
1550 if ( NULL != pDestAddr ) {
1551 CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
1552 }
1553 if ( NULL != pSrcAddr ) {
1554 CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
1555 }
1556 else {
1557 CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
1558 }
1559 if ( NULL != pProtocol ) {
1560 Type = *pProtocol;
1561 }
1562 else {
1563 Type = pNicDevice->pTxTest->Length;
1564 }
1565 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
1566 pHeader->type = Type;
1567 }
1568 if ( pNicDevice->pTxTest->Length < MIN_ETHERNET_PKT_SIZE ) {
1569 pNicDevice->pTxTest->Length = MIN_ETHERNET_PKT_SIZE;
1570 ZeroMem ( &pNicDevice->pTxTest->Data[ BufferSize ],
1571 pNicDevice->pTxTest->Length - BufferSize );
1572 }
1573
1574 DEBUG ((EFI_D_INFO, "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x"
1575 " %02x-%02x %d bytes\r\n",
1576 pNicDevice->pTxTest->Data[0],
1577 pNicDevice->pTxTest->Data[1],
1578 pNicDevice->pTxTest->Data[2],
1579 pNicDevice->pTxTest->Data[3],
1580 pNicDevice->pTxTest->Data[4],
1581 pNicDevice->pTxTest->Data[5],
1582 pNicDevice->pTxTest->Data[6],
1583 pNicDevice->pTxTest->Data[7],
1584 pNicDevice->pTxTest->Data[8],
1585 pNicDevice->pTxTest->Data[9],
1586 pNicDevice->pTxTest->Data[10],
1587 pNicDevice->pTxTest->Data[11],
1588 pNicDevice->pTxTest->Data[12],
1589 pNicDevice->pTxTest->Data[13],
1590 pNicDevice->pTxTest->Length ));
1591
1592 pNicDevice->pTxTest->LengthBar = ~(pNicDevice->pTxTest->Length);
1593 TransferLength = sizeof ( pNicDevice->pTxTest->Length )
1594 + sizeof ( pNicDevice->pTxTest->LengthBar )
1595 + pNicDevice->pTxTest->Length;
1596
1597 if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
1598 TransferLength +=4;
1599
1600 //
1601 // Work around USB bus driver bug where a timeout set by receive
1602 // succeeds but the timeout expires immediately after, causing the
1603 // transmit operation to timeout.
1604 //
1605 pUsbIo = pNicDevice->pUsbIo;
1606 Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
1607 BULK_OUT_ENDPOINT,
1608 &pNicDevice->pTxTest->Length,
1609 &TransferLength,
1610 0xfffffffe,
1611 &TransferStatus );
1612 if ( !EFI_ERROR ( Status )) {
1613 Status = TransferStatus;
1614 }
1615
1616 if ( !EFI_ERROR ( Status )) {
1617 pNicDevice->pTxBuffer = pBuffer;
1618 }
1619 else {
1620 if ((TransferLength != (UINTN)( pNicDevice->pTxTest->Length + 4 )) &&
1621 (TransferLength != (UINTN)(( pNicDevice->pTxTest->Length + 4 ) + 4))) {
1622 DEBUG ((EFI_D_INFO, "TransferLength didn't match Packet Length\n"));
1623 }
1624 //
1625 // Reset the controller to fix the error
1626 //
1627 if ( EFI_DEVICE_ERROR == Status ) {
1628 SN_Reset ( pSimpleNetwork, FALSE );
1629 }
1630 Status = EFI_NOT_READY;
1631 }
1632 }
1633 else {
1634 //
1635 // No packets available.
1636 //
1637 Status = EFI_NOT_READY;
1638 }
1639
1640 }
1641 else {
1642 if (EfiSimpleNetworkStarted == pMode->State) {
1643 Status = EFI_DEVICE_ERROR;
1644 }
1645 else {
1646 Status = EFI_NOT_STARTED ;
1647 }
1648 }
1649 }
1650 else {
1651 Status = EFI_BUFFER_TOO_SMALL;
1652 }
1653 }
1654 else {
1655 Status = EFI_INVALID_PARAMETER;
1656 }
1657 }
1658 else {
1659 Status = EFI_INVALID_PARAMETER;
1660 }
1661
1662 gBS->RestoreTPL (TplPrevious);
1663
1664 return Status;
1665 }