3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 // TODO: fix comment to add: Module Name: DECODE.C
25 #ifdef _MSC_EXTENSIONS
26 #pragma data_seg("rtdata")
30 // Global variables defined in this file
32 UNDI_CALL_TABLE api_table
[PXE_OPCODE_LAST_VALID
+1] = { \
33 {PXE_CPBSIZE_NOT_USED
,PXE_DBSIZE_NOT_USED
,0, (UINT16
)(ANY_STATE
),UNDI_GetState
},\
34 {(UINT16
)(DONT_CHECK
),PXE_DBSIZE_NOT_USED
,0,(UINT16
)(ANY_STATE
),UNDI_Start
},\
35 {PXE_CPBSIZE_NOT_USED
,PXE_DBSIZE_NOT_USED
,0,MUST_BE_STARTED
,UNDI_Stop
},\
36 {PXE_CPBSIZE_NOT_USED
,sizeof(PXE_DB_GET_INIT_INFO
),0,MUST_BE_STARTED
, UNDI_GetInitInfo
},\
37 {PXE_CPBSIZE_NOT_USED
,sizeof(PXE_DB_GET_CONFIG_INFO
),0,MUST_BE_STARTED
, UNDI_GetConfigInfo
},\
38 {sizeof(PXE_CPB_INITIALIZE
),(UINT16
)(DONT_CHECK
),(UINT16
)(DONT_CHECK
),MUST_BE_STARTED
,UNDI_Initialize
},\
39 {PXE_CPBSIZE_NOT_USED
,PXE_DBSIZE_NOT_USED
,(UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
,UNDI_Reset
},\
40 {PXE_CPBSIZE_NOT_USED
,PXE_DBSIZE_NOT_USED
,0, MUST_BE_INITIALIZED
,UNDI_Shutdown
},\
41 {PXE_CPBSIZE_NOT_USED
,PXE_DBSIZE_NOT_USED
,(UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
,UNDI_Interrupt
},\
42 {(UINT16
)(DONT_CHECK
),(UINT16
)(DONT_CHECK
),(UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
, UNDI_RecFilter
},\
43 {(UINT16
)(DONT_CHECK
),(UINT16
)(DONT_CHECK
),(UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
, UNDI_StnAddr
},\
44 {PXE_CPBSIZE_NOT_USED
, (UINT16
)(DONT_CHECK
), (UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
, UNDI_Statistics
},\
45 {sizeof(PXE_CPB_MCAST_IP_TO_MAC
),sizeof(PXE_DB_MCAST_IP_TO_MAC
), (UINT16
)(DONT_CHECK
),MUST_BE_INITIALIZED
, UNDI_ip2mac
},\
46 {(UINT16
)(DONT_CHECK
),(UINT16
)(DONT_CHECK
),(UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
, UNDI_NVData
},\
47 {PXE_CPBSIZE_NOT_USED
,(UINT16
)(DONT_CHECK
),(UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
, UNDI_Status
},\
48 {(UINT16
)(DONT_CHECK
),PXE_DBSIZE_NOT_USED
,(UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
, UNDI_FillHeader
},\
49 {(UINT16
)(DONT_CHECK
),PXE_DBSIZE_NOT_USED
,(UINT16
)(DONT_CHECK
), MUST_BE_INITIALIZED
, UNDI_Transmit
},\
50 {sizeof(PXE_CPB_RECEIVE
),sizeof(PXE_DB_RECEIVE
),0,MUST_BE_INITIALIZED
, UNDI_Receive
} \
54 // end of global variables
60 IN NIC_DATA_INSTANCE
*AdapterInfo
65 This routine determines the operational state of the UNDI. It updates the state flags in the
66 Command Descriptor Block based on information derived from the AdapterInfo instance data.
68 To ensure the command has completed successfully, CdbPtr->StatCode will contain the result of
69 the command execution.
71 The CdbPtr->StatFlags will contain a STOPPED, STARTED, or INITIALIZED state once the command
72 has successfully completed.
74 Keep in mind the AdapterInfo->State is the active state of the adapter (based on software
75 interrogation), and the CdbPtr->StateFlags is the passed back information that is reflected
76 to the caller of the UNDI API.
79 CdbPtr - Pointer to the command descriptor block.
80 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
87 CdbPtr
->StatFlags
= (PXE_STATFLAGS
) (CdbPtr
->StatFlags
| AdapterInfo
->State
);
94 IN NIC_DATA_INSTANCE
*AdapterInfo
99 This routine is used to change the operational state of the UNDI from stopped to started.
100 It will do this as long as the adapter's state is PXE_STATFLAGS_GET_STATE_STOPPED, otherwise
101 the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr->StatCode will reflect the
102 UNDI as having already been started.
104 This routine is modified to reflect the undi 1.1 specification changes. The
105 changes in the spec are mainly in the callback routines, the new spec adds
106 3 more callbacks and a unique id.
107 Since this UNDI supports both old and new undi specifications,
108 The NIC's data structure is filled in with the callback routines (depending
109 on the version) pointed to in the caller's CpbPtr. This seeds the Delay,
110 Virt2Phys, Block, and Mem_IO for old and new versions and Map_Mem, UnMap_Mem
111 and Sync_Mem routines and a unique id variable for the new version.
112 This is the function which an external entity (SNP, O/S, etc) would call
113 to provide it's I/O abstraction to the UNDI.
115 It's final action is to change the AdapterInfo->State to PXE_STATFLAGS_GET_STATE_STARTED.
118 CdbPtr - Pointer to the command descriptor block.
119 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
126 PXE_CPB_START_30
*CpbPtr
;
127 PXE_CPB_START_31
*CpbPtr_31
;
130 // check if it is already started.
132 if (AdapterInfo
->State
!= PXE_STATFLAGS_GET_STATE_STOPPED
) {
133 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
134 CdbPtr
->StatCode
= PXE_STATCODE_ALREADY_STARTED
;
138 if (CdbPtr
->CPBsize
!= sizeof(PXE_CPB_START_30
) &&
139 CdbPtr
->CPBsize
!= sizeof(PXE_CPB_START_31
)) {
141 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
142 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
146 CpbPtr
= (PXE_CPB_START_30
*) (UINTN
) (CdbPtr
->CPBaddr
);
147 CpbPtr_31
= (PXE_CPB_START_31
*) (UINTN
) (CdbPtr
->CPBaddr
);
149 if (AdapterInfo
->VersionFlag
== 0x30) {
150 AdapterInfo
->Delay_30
= (bsptr_30
) (UINTN
) CpbPtr
->Delay
;
151 AdapterInfo
->Virt2Phys_30
= (virtphys_30
) (UINTN
) CpbPtr
->Virt2Phys
;
152 AdapterInfo
->Block_30
= (block_30
) (UINTN
) CpbPtr
->Block
;
154 // patch for old buggy 3.0 code:
155 // In EFI1.0 undi used to provide the full (absolute) I/O address to the
156 // i/o calls and SNP used to provide a callback that used GlobalIoFncs and
157 // everything worked fine! In EFI 1.1, UNDI is not using the full
158 // i/o or memory address to access the device, The base values for the i/o
159 // and memory address is abstracted by the device specific PciIoFncs and
160 // UNDI only uses the offset values. Since UNDI3.0 cannot provide any
161 // identification to SNP, SNP cannot use nic specific PciIoFncs callback!
163 // To fix this and make undi3.0 work with SNP in EFI1.1 we
164 // use a TmpMemIo function that is defined in init.c
165 // This breaks the runtime driver feature of undi, but what to do
166 // if we have to provide the 3.0 compatibility (including the 3.0 bugs)
168 // This TmpMemIo function also takes a UniqueId parameter
169 // (as in undi3.1 design) and so initialize the UniqueId as well here
170 // Note: AdapterInfo->Mem_Io_30 is just filled for consistency with other
171 // parameters but never used, we only use Mem_Io field in the In/Out routines
174 AdapterInfo
->Mem_Io_30
= (mem_io_30
) (UINTN
) CpbPtr
->Mem_IO
;
175 AdapterInfo
->Mem_Io
= (mem_io
) (UINTN
) TmpMemIo
;
176 AdapterInfo
->Unique_ID
= (UINT64
) (UINTN
) AdapterInfo
;
179 AdapterInfo
->Delay
= (bsptr
) (UINTN
) CpbPtr_31
->Delay
;
180 AdapterInfo
->Virt2Phys
= (virtphys
) (UINTN
) CpbPtr_31
->Virt2Phys
;
181 AdapterInfo
->Block
= (block
) (UINTN
) CpbPtr_31
->Block
;
182 AdapterInfo
->Mem_Io
= (mem_io
) (UINTN
) CpbPtr_31
->Mem_IO
;
184 AdapterInfo
->Map_Mem
= (map_mem
) (UINTN
) CpbPtr_31
->Map_Mem
;
185 AdapterInfo
->UnMap_Mem
= (unmap_mem
) (UINTN
) CpbPtr_31
->UnMap_Mem
;
186 AdapterInfo
->Sync_Mem
= (sync_mem
) (UINTN
) CpbPtr_31
->Sync_Mem
;
187 AdapterInfo
->Unique_ID
= CpbPtr_31
->Unique_ID
;
190 AdapterInfo
->State
= PXE_STATFLAGS_GET_STATE_STARTED
;
198 IN NIC_DATA_INSTANCE
*AdapterInfo
203 This routine is used to change the operational state of the UNDI from started to stopped.
204 It will not do this if the adapter's state is PXE_STATFLAGS_GET_STATE_INITIALIZED, otherwise
205 the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr->StatCode will reflect the
206 UNDI as having already not been shut down.
208 The NIC's data structure will have the Delay, Virt2Phys, and Block, pointers zero'd out..
210 It's final action is to change the AdapterInfo->State to PXE_STATFLAGS_GET_STATE_STOPPED.
213 CdbPtr - Pointer to the command descriptor block.
214 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
221 if (AdapterInfo
->State
== PXE_STATFLAGS_GET_STATE_INITIALIZED
) {
222 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
223 CdbPtr
->StatCode
= PXE_STATCODE_NOT_SHUTDOWN
;
227 AdapterInfo
->Delay_30
= 0;
228 AdapterInfo
->Virt2Phys_30
= 0;
229 AdapterInfo
->Block_30
= 0;
231 AdapterInfo
->Delay
= 0;
232 AdapterInfo
->Virt2Phys
= 0;
233 AdapterInfo
->Block
= 0;
235 AdapterInfo
->Map_Mem
= 0;
236 AdapterInfo
->UnMap_Mem
= 0;
237 AdapterInfo
->Sync_Mem
= 0;
239 AdapterInfo
->State
= PXE_STATFLAGS_GET_STATE_STOPPED
;
247 IN NIC_DATA_INSTANCE
*AdapterInfo
252 This routine is used to retrieve the initialization information that is needed by drivers and
253 applications to initialize the UNDI. This will fill in data in the Data Block structure that is
254 pointed to by the caller's CdbPtr->DBaddr. The fields filled in are as follows:
256 MemoryRequired, FrameDataLen, LinkSpeeds[0-3], NvCount, NvWidth, MediaHeaderLen, HWaddrLen,
257 MCastFilterCnt, TxBufCnt, TxBufSize, RxBufCnt, RxBufSize, IFtype, Duplex, and LoopBack.
259 In addition, the CdbPtr->StatFlags ORs in that this NIC supports cable detection. (APRIORI knowledge)
262 CdbPtr - Pointer to the command descriptor block.
263 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
270 PXE_DB_GET_INIT_INFO
*DbPtr
;
272 DbPtr
= (PXE_DB_GET_INIT_INFO
*) (UINTN
) (CdbPtr
->DBaddr
);
274 DbPtr
->MemoryRequired
= MEMORY_NEEDED
;
275 DbPtr
->FrameDataLen
= PXE_MAX_TXRX_UNIT_ETHER
;
276 DbPtr
->LinkSpeeds
[0] = 10;
277 DbPtr
->LinkSpeeds
[1] = 100;
278 DbPtr
->LinkSpeeds
[2] = DbPtr
->LinkSpeeds
[3] = 0;
279 DbPtr
->NvCount
= MAX_EEPROM_LEN
;
281 DbPtr
->MediaHeaderLen
= PXE_MAC_HEADER_LEN_ETHER
;
282 DbPtr
->HWaddrLen
= PXE_HWADDR_LEN_ETHER
;
283 DbPtr
->MCastFilterCnt
= MAX_MCAST_ADDRESS_CNT
;
285 DbPtr
->TxBufCnt
= TX_BUFFER_COUNT
;
286 DbPtr
->TxBufSize
= sizeof (TxCB
);
287 DbPtr
->RxBufCnt
= RX_BUFFER_COUNT
;
288 DbPtr
->RxBufSize
= sizeof (RxFD
);
290 DbPtr
->IFtype
= PXE_IFTYPE_ETHERNET
;
291 DbPtr
->SupportedDuplexModes
= PXE_DUPLEX_ENABLE_FULL_SUPPORTED
|
292 PXE_DUPLEX_FORCE_FULL_SUPPORTED
;
293 DbPtr
->SupportedLoopBackModes
= PXE_LOOPBACK_INTERNAL_SUPPORTED
|
294 PXE_LOOPBACK_EXTERNAL_SUPPORTED
;
296 CdbPtr
->StatFlags
|= PXE_STATFLAGS_CABLE_DETECT_SUPPORTED
;
303 IN NIC_DATA_INSTANCE
*AdapterInfo
308 This routine is used to retrieve the configuration information about the NIC being controlled by
309 this driver. This will fill in data in the Data Block structure that is pointed to by the caller's CdbPtr->DBaddr.
310 The fields filled in are as follows:
312 DbPtr->pci.BusType, DbPtr->pci.Bus, DbPtr->pci.Device, and DbPtr->pci.
314 In addition, the DbPtr->pci.Config.Dword[0-63] grabs a copy of this NIC's PCI configuration space.
317 CdbPtr - Pointer to the command descriptor block.
318 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
326 PXE_DB_GET_CONFIG_INFO
*DbPtr
;
328 DbPtr
= (PXE_DB_GET_CONFIG_INFO
*) (UINTN
) (CdbPtr
->DBaddr
);
330 DbPtr
->pci
.BusType
= PXE_BUSTYPE_PCI
;
331 DbPtr
->pci
.Bus
= AdapterInfo
->Bus
;
332 DbPtr
->pci
.Device
= AdapterInfo
->Device
;
333 DbPtr
->pci
.Function
= AdapterInfo
->Function
;
335 for (Index
= 0; Index
< MAX_PCI_CONFIG_LEN
; Index
++) {
336 DbPtr
->pci
.Config
.Dword
[Index
] = AdapterInfo
->Config
[Index
];
345 NIC_DATA_INSTANCE
*AdapterInfo
350 This routine resets the network adapter and initializes the UNDI using the parameters supplied in
351 the CPB. This command must be issued before the network adapter can be setup to transmit and
354 Once the memory requirements of the UNDI are obtained by using the GetInitInfo command, a block
355 of non-swappable memory may need to be allocated. The address of this memory must be passed to
356 UNDI during the Initialize in the CPB. This memory is used primarily for transmit and receive buffers.
358 The fields CableDetect, LinkSpeed, Duplex, LoopBack, MemoryPtr, and MemoryLength are set with information
359 that was passed in the CPB and the NIC is initialized.
361 If the NIC initialization fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
362 Otherwise, AdapterInfo->State is updated with PXE_STATFLAGS_GET_STATE_INITIALIZED showing the state of
363 the UNDI is now initialized.
366 CdbPtr - Pointer to the command descriptor block.
367 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
374 PXE_CPB_INITIALIZE
*CpbPtr
;
376 if ((CdbPtr
->OpFlags
!= PXE_OPFLAGS_INITIALIZE_DETECT_CABLE
) &&
377 (CdbPtr
->OpFlags
!= PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
)) {
378 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
379 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
384 // check if it is already initialized
386 if (AdapterInfo
->State
== PXE_STATFLAGS_GET_STATE_INITIALIZED
) {
387 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
388 CdbPtr
->StatCode
= PXE_STATCODE_ALREADY_INITIALIZED
;
392 CpbPtr
= (PXE_CPB_INITIALIZE
*) (UINTN
) CdbPtr
->CPBaddr
;
394 if (CpbPtr
->MemoryLength
< (UINT32
) MEMORY_NEEDED
) {
395 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
396 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CPB
;
401 // default behaviour is to detect the cable, if the 3rd param is 1,
404 AdapterInfo
->CableDetect
= (UINT8
) ((CdbPtr
->OpFlags
== (UINT16
) PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
) ? (UINT8
) 0 : (UINT8
) 1);
405 AdapterInfo
->LinkSpeedReq
= (UINT16
) CpbPtr
->LinkSpeed
;
406 AdapterInfo
->DuplexReq
= CpbPtr
->DuplexMode
;
407 AdapterInfo
->LoopBack
= CpbPtr
->LoopBackMode
;
408 AdapterInfo
->MemoryPtr
= CpbPtr
->MemoryAddr
;
409 AdapterInfo
->MemoryLength
= CpbPtr
->MemoryLength
;
411 CdbPtr
->StatCode
= (PXE_STATCODE
) E100bInit (AdapterInfo
);
413 if (CdbPtr
->StatCode
!= PXE_STATCODE_SUCCESS
) {
414 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
416 AdapterInfo
->State
= PXE_STATFLAGS_GET_STATE_INITIALIZED
;
425 IN NIC_DATA_INSTANCE
*AdapterInfo
430 This routine resets the network adapter and initializes the UNDI using the parameters supplied in
431 the CPB. The transmit and receive queues are emptied and any pending interrupts are cleared.
433 If the NIC reset fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
436 CdbPtr - Pointer to the command descriptor block.
437 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
444 if (CdbPtr
->OpFlags
!= PXE_OPFLAGS_NOT_USED
&&
445 CdbPtr
->OpFlags
!= PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS
&&
446 CdbPtr
->OpFlags
!= PXE_OPFLAGS_RESET_DISABLE_FILTERS
) {
448 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
449 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
453 CdbPtr
->StatCode
= (UINT16
) E100bReset (AdapterInfo
, CdbPtr
->OpFlags
);
455 if (CdbPtr
->StatCode
!= PXE_STATCODE_SUCCESS
) {
456 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
463 IN NIC_DATA_INSTANCE
*AdapterInfo
468 This routine resets the network adapter and leaves it in a safe state for another driver to
469 initialize. Any pending transmits or receives are lost. Receive filters and external
470 interrupt enables are disabled. Once the UNDI has been shutdown, it can then be stopped
471 or initialized again.
473 If the NIC reset fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
475 Otherwise, AdapterInfo->State is updated with PXE_STATFLAGS_GET_STATE_STARTED showing the state of
476 the NIC as being started.
479 CdbPtr - Pointer to the command descriptor block.
480 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
488 // do the shutdown stuff here
490 CdbPtr
->StatCode
= (UINT16
) E100bShutdown (AdapterInfo
);
492 if (CdbPtr
->StatCode
!= PXE_STATCODE_SUCCESS
) {
493 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
495 AdapterInfo
->State
= PXE_STATFLAGS_GET_STATE_STARTED
;
504 IN NIC_DATA_INSTANCE
*AdapterInfo
509 This routine can be used to read and/or change the current external interrupt enable
510 settings. Disabling an external interrupt enable prevents and external (hardware)
511 interrupt from being signaled by the network device. Internally the interrupt events
512 can still be polled by using the UNDI_GetState command.
514 The resulting information on the interrupt state will be passed back in the CdbPtr->StatFlags.
517 CdbPtr - Pointer to the command descriptor block.
518 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
527 IntMask
= (UINT8
)(UINTN
)(CdbPtr
->OpFlags
& (PXE_OPFLAGS_INTERRUPT_RECEIVE
|
528 PXE_OPFLAGS_INTERRUPT_TRANSMIT
|
529 PXE_OPFLAGS_INTERRUPT_COMMAND
|
530 PXE_OPFLAGS_INTERRUPT_SOFTWARE
));
532 switch (CdbPtr
->OpFlags
& PXE_OPFLAGS_INTERRUPT_OPMASK
) {
533 case PXE_OPFLAGS_INTERRUPT_READ
:
536 case PXE_OPFLAGS_INTERRUPT_ENABLE
:
538 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
539 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
543 AdapterInfo
->int_mask
= IntMask
;
544 E100bSetInterruptState (AdapterInfo
);
547 case PXE_OPFLAGS_INTERRUPT_DISABLE
:
549 AdapterInfo
->int_mask
= (UINT16
) (AdapterInfo
->int_mask
& ~(IntMask
));
550 E100bSetInterruptState (AdapterInfo
);
558 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
559 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
563 if ((AdapterInfo
->int_mask
& PXE_OPFLAGS_INTERRUPT_RECEIVE
) != 0) {
564 CdbPtr
->StatFlags
|= PXE_STATFLAGS_INTERRUPT_RECEIVE
;
568 if ((AdapterInfo
->int_mask
& PXE_OPFLAGS_INTERRUPT_TRANSMIT
) != 0) {
569 CdbPtr
->StatFlags
|= PXE_STATFLAGS_INTERRUPT_TRANSMIT
;
573 if ((AdapterInfo
->int_mask
& PXE_OPFLAGS_INTERRUPT_COMMAND
) != 0) {
574 CdbPtr
->StatFlags
|= PXE_STATFLAGS_INTERRUPT_COMMAND
;
584 IN NIC_DATA_INSTANCE
*AdapterInfo
589 This routine is used to read and change receive filters and, if supported, read
590 and change multicast MAC address filter list.
593 CdbPtr - Pointer to the command descriptor block.
594 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
603 PXE_DB_RECEIVE_FILTERS
*DbPtr
;
610 OpFlags
= CdbPtr
->OpFlags
;
611 NewFilter
= (UINT16
) (OpFlags
& 0x1F);
613 switch (OpFlags
& PXE_OPFLAGS_RECEIVE_FILTER_OPMASK
) {
614 case PXE_OPFLAGS_RECEIVE_FILTER_READ
:
617 // not expecting a cpb, not expecting any filter bits
619 if ((NewFilter
!= 0) || (CdbPtr
->CPBsize
!= 0)) {
624 if ((NewFilter
& PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST
) == 0) {
629 NewFilter
= (UINT16
) (NewFilter
| AdapterInfo
->Rx_Filter
);
631 // all other flags are ignored except mcast_reset
635 case PXE_OPFLAGS_RECEIVE_FILTER_ENABLE
:
637 // there should be atleast one other filter bit set.
639 if (NewFilter
== 0) {
646 if (CdbPtr
->CPBsize
!= 0) {
648 // this must be a multicast address list!
649 // don't accept the list unless selective_mcast is set
650 // don't accept confusing mcast settings with this
652 if (((NewFilter
& PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
) == 0) ||
653 ((NewFilter
& PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST
) != 0) ||
654 ((NewFilter
& PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST
) != 0) ||
655 ((CdbPtr
->CPBsize
% sizeof (PXE_MAC_ADDR
)) != 0) ) {
659 MacAddr
= (UINT8
*) ((UINTN
) (CdbPtr
->CPBaddr
));
660 MacCount
= CdbPtr
->CPBsize
/ sizeof (PXE_MAC_ADDR
);
662 for (; MacCount
-- != 0; MacAddr
+= sizeof (PXE_MAC_ADDR
)) {
663 if (MacAddr
[0] != 0x01 || MacAddr
[1] != 0x00 || MacAddr
[2] != 0x5E || (MacAddr
[3] & 0x80) != 0) {
664 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
665 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CPB
;
672 // check selective mcast case enable case
674 if ((OpFlags
& PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
) != 0) {
675 if (((OpFlags
& PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST
) != 0) ||
676 ((OpFlags
& PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST
) != 0) ) {
681 // if no cpb, make sure we have an old list
683 if ((CdbPtr
->CPBsize
== 0) && (AdapterInfo
->mcast_list
.list_len
== 0)) {
688 // if you want to enable anything, you got to have unicast
689 // and you have what you already enabled!
691 NewFilter
= (UINT16
) (NewFilter
| (PXE_OPFLAGS_RECEIVE_FILTER_UNICAST
| AdapterInfo
->Rx_Filter
));
695 case PXE_OPFLAGS_RECEIVE_FILTER_DISABLE
:
698 // mcast list not expected, i.e. no cpb here!
700 if (CdbPtr
->CPBsize
!= PXE_CPBSIZE_NOT_USED
) {
704 NewFilter
= (UINT16
) ((~(CdbPtr
->OpFlags
& 0x1F)) & AdapterInfo
->Rx_Filter
);
712 if ((OpFlags
& PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST
) != 0) {
713 AdapterInfo
->mcast_list
.list_len
= 0;
714 NewFilter
&= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
);
717 E100bSetfilter (AdapterInfo
, NewFilter
, CdbPtr
->CPBaddr
, CdbPtr
->CPBsize
);
721 // give the current mcast list
723 if ((CdbPtr
->DBsize
!= 0) && (AdapterInfo
->mcast_list
.list_len
!= 0)) {
725 // copy the mc list to db
728 DbPtr
= (PXE_DB_RECEIVE_FILTERS
*) (UINTN
) CdbPtr
->DBaddr
;
729 ptr1
= (UINT8
*) (&DbPtr
->MCastList
[0]);
732 // DbPtr->mc_count = AdapterInfo->mcast_list.list_len;
734 copy_len
= (UINT16
) (AdapterInfo
->mcast_list
.list_len
* PXE_MAC_LENGTH
);
736 if (copy_len
> CdbPtr
->DBsize
) {
737 copy_len
= CdbPtr
->DBsize
;
741 ptr2
= (UINT8
*) (&AdapterInfo
->mcast_list
.mc_list
[0]);
742 for (Index
= 0; Index
< copy_len
; Index
++) {
743 ptr1
[Index
] = ptr2
[Index
];
747 // give the stat flags here
749 if (AdapterInfo
->Receive_Started
) {
750 CdbPtr
->StatFlags
= (PXE_STATFLAGS
) (CdbPtr
->StatFlags
| AdapterInfo
->Rx_Filter
);
757 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
758 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
764 IN NIC_DATA_INSTANCE
*AdapterInfo
769 This routine is used to get the current station and broadcast MAC addresses, and to change the
770 current station MAC address.
773 CdbPtr - Pointer to the command descriptor block.
774 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
781 PXE_CPB_STATION_ADDRESS
*CpbPtr
;
782 PXE_DB_STATION_ADDRESS
*DbPtr
;
785 if (CdbPtr
->OpFlags
== PXE_OPFLAGS_STATION_ADDRESS_RESET
) {
787 // configure the permanent address.
788 // change the AdapterInfo->CurrentNodeAddress field.
791 &AdapterInfo
->CurrentNodeAddress
[0],
792 &AdapterInfo
->PermNodeAddress
[0],
795 for (Index
= 0; Index
< PXE_MAC_LENGTH
; Index
++) {
796 AdapterInfo
->CurrentNodeAddress
[Index
] = AdapterInfo
->PermNodeAddress
[Index
];
799 E100bSetupIAAddr (AdapterInfo
);
803 if (CdbPtr
->CPBaddr
!= (UINT64
) 0) {
804 CpbPtr
= (PXE_CPB_STATION_ADDRESS
*) (UINTN
) (CdbPtr
->CPBaddr
);
806 // configure the new address
808 for (Index
= 0; Index
< PXE_MAC_LENGTH
; Index
++) {
809 AdapterInfo
->CurrentNodeAddress
[Index
] = CpbPtr
->StationAddr
[Index
];
812 E100bSetupIAAddr (AdapterInfo
);
815 if (CdbPtr
->DBaddr
!= (UINT64
) 0) {
816 DbPtr
= (PXE_DB_STATION_ADDRESS
*) (UINTN
) (CdbPtr
->DBaddr
);
818 // fill it with the new values
820 for (Index
= 0; Index
< PXE_MAC_LENGTH
; Index
++) {
821 DbPtr
->StationAddr
[Index
] = AdapterInfo
->CurrentNodeAddress
[Index
];
822 DbPtr
->BroadcastAddr
[Index
] = AdapterInfo
->BroadcastNodeAddress
[Index
];
823 DbPtr
->PermanentAddr
[Index
] = AdapterInfo
->PermNodeAddress
[Index
];
833 IN NIC_DATA_INSTANCE
*AdapterInfo
838 This routine is used to read and clear the NIC traffic statistics. This command is supported only
839 if the !PXE structure's Implementation flags say so.
841 Results will be parsed out in the following manner:
842 CdbPtr->DBaddr.Data[0] R Total Frames (Including frames with errors and dropped frames)
843 CdbPtr->DBaddr.Data[1] R Good Frames (All frames copied into receive buffer)
844 CdbPtr->DBaddr.Data[2] R Undersize Frames (Frames below minimum length for media <64 for ethernet)
845 CdbPtr->DBaddr.Data[4] R Dropped Frames (Frames that were dropped because receive buffers were full)
846 CdbPtr->DBaddr.Data[8] R CRC Error Frames (Frames with alignment or CRC errors)
847 CdbPtr->DBaddr.Data[A] T Total Frames (Including frames with errors and dropped frames)
848 CdbPtr->DBaddr.Data[B] T Good Frames (All frames copied into transmit buffer)
849 CdbPtr->DBaddr.Data[C] T Undersize Frames (Frames below minimum length for media <64 for ethernet)
850 CdbPtr->DBaddr.Data[E] T Dropped Frames (Frames that were dropped because of collisions)
851 CdbPtr->DBaddr.Data[14] T Total Collision Frames (Total collisions on this subnet)
854 CdbPtr - Pointer to the command descriptor block.
855 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
862 if ((CdbPtr
->OpFlags
&~(PXE_OPFLAGS_STATISTICS_RESET
)) != 0) {
863 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
864 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
868 if ((CdbPtr
->OpFlags
& PXE_OPFLAGS_STATISTICS_RESET
) != 0) {
870 // Reset the statistics
872 CdbPtr
->StatCode
= (UINT16
) E100bStatistics (AdapterInfo
, 0, 0);
874 CdbPtr
->StatCode
= (UINT16
) E100bStatistics (AdapterInfo
, CdbPtr
->DBaddr
, CdbPtr
->DBsize
);
883 IN NIC_DATA_INSTANCE
*AdapterInfo
888 This routine is used to translate a multicast IP address to a multicast MAC address.
890 This results in a MAC address composed of 25 bits of fixed data with the upper 23 bits of the IP
891 address being appended to it. Results passed back in the equivalent of CdbPtr->DBaddr->MAC[0-5].
894 CdbPtr - Pointer to the command descriptor block.
895 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
902 PXE_CPB_MCAST_IP_TO_MAC
*CpbPtr
;
903 PXE_DB_MCAST_IP_TO_MAC
*DbPtr
;
906 CpbPtr
= (PXE_CPB_MCAST_IP_TO_MAC
*) (UINTN
) CdbPtr
->CPBaddr
;
907 DbPtr
= (PXE_DB_MCAST_IP_TO_MAC
*) (UINTN
) CdbPtr
->DBaddr
;
909 if ((CdbPtr
->OpFlags
& PXE_OPFLAGS_MCAST_IPV6_TO_MAC
) != 0) {
911 // for now this is not supported
913 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
914 CdbPtr
->StatCode
= PXE_STATCODE_UNSUPPORTED
;
918 TmpPtr
= (UINT8
*) (&CpbPtr
->IP
.IPv4
);
920 // check if the ip given is a mcast IP
922 if ((TmpPtr
[0] & 0xF0) != 0xE0) {
923 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
924 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CPB
;
927 // take the last 23 bits in IP.
928 // be very careful. accessing word on a non-word boundary will hang motherboard codenamed Big Sur
929 // casting the mac array (in the middle) to a UINT32 pointer and accessing
930 // the UINT32 content hung the system...
932 DbPtr
->MAC
[0] = 0x01;
933 DbPtr
->MAC
[1] = 0x00;
934 DbPtr
->MAC
[2] = 0x5e;
935 DbPtr
->MAC
[3] = (UINT8
) (TmpPtr
[1] & 0x7f);
936 DbPtr
->MAC
[4] = (UINT8
) TmpPtr
[2];
937 DbPtr
->MAC
[5] = (UINT8
) TmpPtr
[3];
945 IN NIC_DATA_INSTANCE
*AdapterInfo
950 This routine is used to read and write non-volatile storage on the NIC (if supported). The NVRAM
951 could be EEPROM, FLASH, or battery backed RAM.
953 This is an optional function according to the UNDI specification (or will be......)
956 CdbPtr - Pointer to the command descriptor block.
957 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
964 PXE_DB_NVDATA
*DbPtr
;
967 if ((CdbPtr
->OpFlags
== PXE_OPFLAGS_NVDATA_READ
) != 0) {
969 if ((CdbPtr
->DBsize
== PXE_DBSIZE_NOT_USED
) != 0) {
970 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
971 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
975 DbPtr
= (PXE_DB_NVDATA
*) (UINTN
) CdbPtr
->DBaddr
;
977 for (Index
= 0; Index
< MAX_PCI_CONFIG_LEN
; Index
++) {
978 DbPtr
->Data
.Dword
[Index
] = AdapterInfo
->NVData
[Index
];
986 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
987 CdbPtr
->StatCode
= PXE_STATCODE_UNSUPPORTED
;
996 IN NIC_DATA_INSTANCE
*AdapterInfo
1000 Routine Description:
1001 This routine returns the current interrupt status and/or the transmitted buffer addresses.
1002 If the current interrupt status is returned, pending interrupts will be acknowledged by this
1003 command. Transmitted buffer addresses that are written to the DB are removed from the transmit
1006 Normally, this command would be polled with interrupts disabled.
1008 The transmit buffers are returned in CdbPtr->DBaddr->TxBufer[0 - NumEntries].
1009 The interrupt status is returned in CdbPtr->StatFlags.
1012 CdbPtr - Pointer to the command descriptor block.
1013 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
1020 PXE_DB_GET_STATUS
*DbPtr
;
1021 PXE_DB_GET_STATUS TmpGetStatus
;
1028 // Fill in temporary GetStatus storage.
1030 RxPtr
= &AdapterInfo
->rx_ring
[AdapterInfo
->cur_rx_ind
];
1032 if ((RxPtr
->cb_header
.status
& RX_COMPLETE
) != 0) {
1033 TmpGetStatus
.RxFrameLen
= RxPtr
->ActualCount
& 0x3fff;
1035 TmpGetStatus
.RxFrameLen
= 0;
1038 TmpGetStatus
.reserved
= 0;
1041 // Fill in size of next available receive packet and
1042 // reserved field in caller's DB storage.
1044 DbPtr
= (PXE_DB_GET_STATUS
*) (UINTN
) CdbPtr
->DBaddr
;
1046 if (CdbPtr
->DBsize
> 0 && CdbPtr
->DBsize
< sizeof (UINT32
) * 2) {
1047 CopyMem (DbPtr
, &TmpGetStatus
, CdbPtr
->DBsize
);
1049 CopyMem (DbPtr
, &TmpGetStatus
, sizeof (UINT32
) * 2);
1055 if ((CdbPtr
->OpFlags
& PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS
) != 0) {
1057 // DBsize of zero is invalid if Tx buffers are requested.
1059 if (CdbPtr
->DBsize
== 0) {
1060 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1061 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
1066 // remember this b4 we overwrite
1068 NumEntries
= (UINT16
) (CdbPtr
->DBsize
- sizeof (UINT64
));
1071 // We already filled in 2 UINT32s.
1073 CdbPtr
->DBsize
= sizeof (UINT32
) * 2;
1076 // will claim any hanging free CBs
1078 CheckCBList (AdapterInfo
);
1080 if (AdapterInfo
->xmit_done_head
== AdapterInfo
->xmit_done_tail
) {
1081 CdbPtr
->StatFlags
|= PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY
;
1083 for (Index
= 0; NumEntries
>= sizeof (UINT64
); Index
++, NumEntries
-= sizeof (UINT64
)) {
1084 if (AdapterInfo
->xmit_done_head
!= AdapterInfo
->xmit_done_tail
) {
1085 DbPtr
->TxBuffer
[Index
] = AdapterInfo
->xmit_done
[AdapterInfo
->xmit_done_head
];
1086 AdapterInfo
->xmit_done_head
= next (AdapterInfo
->xmit_done_head
);
1087 CdbPtr
->DBsize
+= sizeof (UINT64
);
1094 if (AdapterInfo
->xmit_done_head
!= AdapterInfo
->xmit_done_tail
) {
1095 CdbPtr
->StatFlags
|= PXE_STATFLAGS_DB_WRITE_TRUNCATED
;
1099 // check for a receive buffer and give it's size in db
1105 if ((CdbPtr
->OpFlags
& PXE_OPFLAGS_GET_INTERRUPT_STATUS
) != 0) {
1107 Status
= InWord (AdapterInfo
, AdapterInfo
->ioaddr
+ SCBStatus
);
1108 AdapterInfo
->Int_Status
= (UINT16
) (AdapterInfo
->Int_Status
| Status
);
1111 // acknoledge the interrupts
1113 OutWord (AdapterInfo
, (UINT16
) (Status
& 0xfc00), (UINT32
) (AdapterInfo
->ioaddr
+ SCBStatus
));
1116 // report all the outstanding interrupts
1118 Status
= AdapterInfo
->Int_Status
;
1119 if ((Status
& SCB_STATUS_FR
) != 0) {
1120 CdbPtr
->StatFlags
|= PXE_STATFLAGS_GET_STATUS_RECEIVE
;
1123 if ((Status
& SCB_STATUS_SWI
) != 0) {
1124 CdbPtr
->StatFlags
|= PXE_STATFLAGS_GET_STATUS_SOFTWARE
;
1134 IN NIC_DATA_INSTANCE
*AdapterInfo
1138 Routine Description:
1139 This routine is used to fill media header(s) in transmit packet(s).
1140 Copies the MAC address into the media header whether it is dealing
1141 with fragmented or non-fragmented packets.
1144 CdbPtr - Pointer to the command descriptor block.
1145 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
1152 PXE_CPB_FILL_HEADER
*Cpb
;
1153 PXE_CPB_FILL_HEADER_FRAGMENTED
*Cpbf
;
1154 EtherHeader
*MacHeader
;
1157 if (CdbPtr
->CPBsize
== PXE_CPBSIZE_NOT_USED
) {
1158 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1159 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
1163 if ((CdbPtr
->OpFlags
& PXE_OPFLAGS_FILL_HEADER_FRAGMENTED
) != 0) {
1164 Cpbf
= (PXE_CPB_FILL_HEADER_FRAGMENTED
*) (UINTN
) CdbPtr
->CPBaddr
;
1167 // assume 1st fragment is big enough for the mac header
1169 if ((Cpbf
->FragCnt
== 0) || (Cpbf
->FragDesc
[0].FragLen
< PXE_MAC_HEADER_LEN_ETHER
)) {
1173 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1174 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
1178 MacHeader
= (EtherHeader
*) (UINTN
) Cpbf
->FragDesc
[0].FragAddr
;
1180 // we don't swap the protocol bytes
1182 MacHeader
->type
= Cpbf
->Protocol
;
1184 for (Index
= 0; Index
< PXE_HWADDR_LEN_ETHER
; Index
++) {
1185 MacHeader
->dest_addr
[Index
] = Cpbf
->DestAddr
[Index
];
1186 MacHeader
->src_addr
[Index
] = Cpbf
->SrcAddr
[Index
];
1189 Cpb
= (PXE_CPB_FILL_HEADER
*) (UINTN
) CdbPtr
->CPBaddr
;
1191 MacHeader
= (EtherHeader
*) (UINTN
) Cpb
->MediaHeader
;
1193 // we don't swap the protocol bytes
1195 MacHeader
->type
= Cpb
->Protocol
;
1197 for (Index
= 0; Index
< PXE_HWADDR_LEN_ETHER
; Index
++) {
1198 MacHeader
->dest_addr
[Index
] = Cpb
->DestAddr
[Index
];
1199 MacHeader
->src_addr
[Index
] = Cpb
->SrcAddr
[Index
];
1209 IN NIC_DATA_INSTANCE
*AdapterInfo
1213 Routine Description:
1214 This routine is used to place a packet into the transmit queue. The data buffers given to
1215 this command are to be considered locked and the application or network driver loses
1216 ownership of these buffers and must not free or relocate them until the ownership returns.
1218 When the packets are transmitted, a transmit complete interrupt is generated (if interrupts
1219 are disabled, the transmit interrupt status is still set and can be checked using the UNDI_Status
1222 Some implementations and adapters support transmitting multiple packets with one transmit
1223 command. If this feature is supported, the transmit CPBs can be linked in one transmit
1226 All UNDIs support fragmented frames, now all network devices or protocols do. If a fragmented
1227 frame CPB is given to UNDI and the network device does not support fragmented frames
1228 (see !PXE.Implementation flag), the UNDI will have to copy the fragments into a local buffer
1229 before transmitting.
1233 CdbPtr - Pointer to the command descriptor block.
1234 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
1242 if (CdbPtr
->CPBsize
== PXE_CPBSIZE_NOT_USED
) {
1243 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1244 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
1248 CdbPtr
->StatCode
= (PXE_STATCODE
) E100bTransmit (AdapterInfo
, CdbPtr
->CPBaddr
, CdbPtr
->OpFlags
);
1250 if (CdbPtr
->StatCode
!= PXE_STATCODE_SUCCESS
) {
1251 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1260 IN NIC_DATA_INSTANCE
*AdapterInfo
1264 Routine Description:
1265 When the network adapter has received a frame, this command is used to copy the frame
1266 into the driver/application storage location. Once a frame has been copied, it is
1267 removed from the receive queue.
1270 CdbPtr - Pointer to the command descriptor block.
1271 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
1280 // check if RU has started...
1282 if (!AdapterInfo
->Receive_Started
) {
1283 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1284 CdbPtr
->StatCode
= PXE_STATCODE_NOT_INITIALIZED
;
1289 CdbPtr
->StatCode
= (UINT16
) E100bReceive (AdapterInfo
, CdbPtr
->CPBaddr
, CdbPtr
->DBaddr
);
1290 if (CdbPtr
->StatCode
!= PXE_STATCODE_SUCCESS
) {
1291 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1304 Routine Description:
1305 This is the main SW UNDI API entry using the older nii protocol.
1306 The parameter passed in is a 64 bit flat model virtual
1307 address of the cdb. We then jump into the common routine for both old and
1308 new nii protocol entries.
1311 CdbPtr - Pointer to the command descriptor block.
1312 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
1318 // TODO: cdb - add argument and description to function comment
1321 NIC_DATA_INSTANCE
*AdapterInfo
;
1323 if (cdb
== (UINT64
) 0) {
1328 CdbPtr
= (PXE_CDB
*) (UINTN
) cdb
;
1330 if (CdbPtr
->IFnum
>= pxe
->IFcnt
) {
1331 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1332 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
1336 AdapterInfo
= &(UNDI32DeviceList
[CdbPtr
->IFnum
]->NicInfo
);
1339 // entering from older entry point
1341 AdapterInfo
->VersionFlag
= 0x30;
1342 UNDI_APIEntry_Common (cdb
);
1351 Routine Description:
1352 This is the main SW UNDI API entry using the newer nii protocol.
1353 The parameter passed in is a 64 bit flat model virtual
1354 address of the cdb. We then jump into the common routine for both old and
1355 new nii protocol entries.
1358 CdbPtr - Pointer to the command descriptor block.
1359 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
1365 // TODO: cdb - add argument and description to function comment
1368 NIC_DATA_INSTANCE
*AdapterInfo
;
1370 if (cdb
== (UINT64
) 0) {
1375 CdbPtr
= (PXE_CDB
*) (UINTN
) cdb
;
1377 if (CdbPtr
->IFnum
>= pxe_31
->IFcnt
) {
1378 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1379 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
1383 AdapterInfo
= &(UNDI32DeviceList
[CdbPtr
->IFnum
]->NicInfo
);
1385 // entering from older entry point
1387 AdapterInfo
->VersionFlag
= 0x31;
1388 UNDI_APIEntry_Common (cdb
);
1392 UNDI_APIEntry_Common (
1397 Routine Description:
1398 This is the common routine for both old and new entry point procedures.
1399 The parameter passed in is a 64 bit flat model virtual
1400 address of the cdb. We then jump into the service routine pointed to by the
1404 CdbPtr - Pointer to the command descriptor block.
1405 AdapterInfo - Pointer to the NIC data structure information which the UNDI driver is layering on..
1411 // TODO: cdb - add argument and description to function comment
1414 NIC_DATA_INSTANCE
*AdapterInfo
;
1415 UNDI_CALL_TABLE
*tab_ptr
;
1417 CdbPtr
= (PXE_CDB
*) (UINTN
) cdb
;
1420 // check the OPCODE range
1422 if ((CdbPtr
->OpCode
> PXE_OPCODE_LAST_VALID
) ||
1423 (CdbPtr
->StatCode
!= PXE_STATCODE_INITIALIZE
) ||
1424 (CdbPtr
->StatFlags
!= PXE_STATFLAGS_INITIALIZE
) ||
1425 (CdbPtr
->IFnum
>= pxe_31
->IFcnt
) ) {
1430 if (CdbPtr
->CPBsize
== PXE_CPBSIZE_NOT_USED
) {
1431 if (CdbPtr
->CPBaddr
!= PXE_CPBADDR_NOT_USED
) {
1434 } else if (CdbPtr
->CPBaddr
== PXE_CPBADDR_NOT_USED
) {
1438 if (CdbPtr
->DBsize
== PXE_DBSIZE_NOT_USED
) {
1439 if (CdbPtr
->DBaddr
!= PXE_DBADDR_NOT_USED
) {
1442 } else if (CdbPtr
->DBaddr
== PXE_DBADDR_NOT_USED
) {
1447 // check if cpbsize and dbsize are as needed
1448 // check if opflags are as expected
1450 tab_ptr
= &api_table
[CdbPtr
->OpCode
];
1452 if (tab_ptr
->cpbsize
!= (UINT16
) (DONT_CHECK
) && tab_ptr
->cpbsize
!= CdbPtr
->CPBsize
) {
1456 if (tab_ptr
->dbsize
!= (UINT16
) (DONT_CHECK
) && tab_ptr
->dbsize
!= CdbPtr
->DBsize
) {
1460 if (tab_ptr
->opflags
!= (UINT16
) (DONT_CHECK
) && tab_ptr
->opflags
!= CdbPtr
->OpFlags
) {
1465 AdapterInfo
= &(UNDI32DeviceList
[CdbPtr
->IFnum
]->NicInfo
);
1468 // check if UNDI_State is valid for this call
1470 if (tab_ptr
->state
!= (UINT16
) (-1)) {
1472 // should atleast be started
1474 if (AdapterInfo
->State
== PXE_STATFLAGS_GET_STATE_STOPPED
) {
1475 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1476 CdbPtr
->StatCode
= PXE_STATCODE_NOT_STARTED
;
1480 // check if it should be initialized
1482 if (tab_ptr
->state
== 2) {
1483 if (AdapterInfo
->State
!= PXE_STATFLAGS_GET_STATE_INITIALIZED
) {
1484 CdbPtr
->StatCode
= PXE_STATCODE_NOT_INITIALIZED
;
1485 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1491 // set the return variable for success case here
1493 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_COMPLETE
;
1494 CdbPtr
->StatCode
= PXE_STATCODE_SUCCESS
;
1496 tab_ptr
->api_ptr (CdbPtr
, AdapterInfo
);
1499 // %% AVL - check for command linking
1502 CdbPtr
->StatFlags
= PXE_STATFLAGS_COMMAND_FAILED
;
1503 CdbPtr
->StatCode
= PXE_STATCODE_INVALID_CDB
;
1515 Routine Description:
1516 This does an 8 bit check sum of the passed in buffer for Len bytes.
1517 This is primarily used to update the check sum in the SW UNDI header.
1520 Buffer - Pointer to the passed in buffer to check sum
1521 Len - Length of buffer to be check summed in bytes.
1532 if ((Bp
= Buffer
) != NULL
) {
1534 Chksum
= (UINT8
) (Chksum
+*Bp
++);
1545 IN NIC_DATA_INSTANCE
*NicPtr
,
1546 IN PXE_SW_UNDI
*PxePtr
1550 Routine Description:
1551 When called with a null NicPtr, this routine decrements the number of NICs
1552 this UNDI is supporting and removes the NIC_DATA_POINTER from the array.
1553 Otherwise, it increments the number of NICs this UNDI is supported and
1554 updates the pxe.Fudge to ensure a proper check sum results.
1557 NicPtr - Pointer to the NIC data structure.
1563 // TODO: PxePtr - add argument and description to function comment
1565 if (NicPtr
== NULL
) {
1566 if (PxePtr
->IFcnt
> 0) {
1568 // number of NICs this undi supports
1573 PxePtr
->Fudge
= (UINT8
) (PxePtr
->Fudge
- ChkSum ((VOID
*) PxePtr
, PxePtr
->Len
));
1578 // number of NICs this undi supports
1581 PxePtr
->Fudge
= (UINT8
) (PxePtr
->Fudge
- ChkSum ((VOID
*) PxePtr
, PxePtr
->Len
));
1588 IN PXE_SW_UNDI
*PxePtr
,
1589 IN UINTN VersionFlag
1593 Routine Description:
1594 Initialize the !PXE structure
1597 RemainingDevicePath - Not used, always produce all possible children.
1600 EFI_SUCCESS - This driver is added to Controller.
1601 other - This driver does not support this device.
1604 // TODO: PxePtr - add argument and description to function comment
1605 // TODO: VersionFlag - add argument and description to function comment
1608 // Initialize the !PXE structure
1610 PxePtr
->Signature
= PXE_ROMID_SIGNATURE
;
1611 PxePtr
->Len
= sizeof (PXE_SW_UNDI
);
1617 // number of NICs this undi supports
1620 PxePtr
->Rev
= PXE_ROMID_REV
;
1621 PxePtr
->MajorVer
= PXE_ROMID_MAJORVER
;
1622 PxePtr
->MinorVer
= PXE_ROMID_MINORVER
;
1623 PxePtr
->reserved1
= 0;
1625 PxePtr
->Implementation
= PXE_ROMID_IMP_SW_VIRT_ADDR
|
1626 PXE_ROMID_IMP_FRAG_SUPPORTED
|
1627 PXE_ROMID_IMP_CMD_LINK_SUPPORTED
|
1628 PXE_ROMID_IMP_NVDATA_READ_ONLY
|
1629 PXE_ROMID_IMP_STATION_ADDR_SETTABLE
|
1630 PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
|
1631 PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
|
1632 PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
|
1633 PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED
|
1634 PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED
|
1635 PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED
;
1637 if (VersionFlag
== 0x30) {
1638 PxePtr
->EntryPoint
= (UINT64
) UNDI_APIEntry_old
;
1640 PxePtr
->EntryPoint
= (UINT64
) UNDI_APIEntry_new
;
1641 PxePtr
->MinorVer
= PXE_ROMID_MINORVER_31
;
1644 PxePtr
->reserved2
[0] = 0;
1645 PxePtr
->reserved2
[1] = 0;
1646 PxePtr
->reserved2
[2] = 0;
1648 PxePtr
->BusType
[0] = PXE_BUSTYPE_PCI
;
1650 PxePtr
->Fudge
= (UINT8
) (PxePtr
->Fudge
- ChkSum ((VOID
*) PxePtr
, PxePtr
->Len
));
1653 #ifdef _MSC_EXTENSIONS