/** Fill the Initiator section of the iSCSI Boot Firmware Table. @param[in] Table The ACPI table. @param[in, out] Heap The heap. @param[in] Handle The handle associated with the iSCSI session. **/ VOID IScsiFillInitiatorSection ( IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table, IN OUT UINT8 **Heap, IN EFI_HANDLE Handle ) { EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control; EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *Initiator; ISCSI_DRIVER_DATA *DriverData; ISCSI_SESSION *Session; ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier; EFI_STATUS Status; Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1); // // Initiator section immediately follows the control section. // Initiator = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *) ((UINT8 *) Control + IBFT_ROUNDUP (Control->Header.Length)); Control->InitiatorOffset = (UINT16) ((UINTN) Initiator - (UINTN) Table); ZeroMem (Initiator, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)); Initiator->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_ID; Initiator->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_VERSION; Initiator->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE); Initiator->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BOOT_SELECTED; // // Get the identifier from the handle. // Status = gBS->HandleProtocol (Handle, &gEfiCallerIdGuid, (VOID **) &IScsiIdentifier); if (EFI_ERROR (Status)) { ASSERT (FALSE); return ; } DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier); Session = &DriverData->Session; // // Fill the iSCSI Initiator Name into the heap. // IScsiAddHeapItem (Heap, Session->InitiatorName, Session->InitiatorNameLength - 1); Initiator->IScsiNameLength = (UINT16) (Session->InitiatorNameLength - 1); Initiator->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); }
STATIC VOID IScsiFillNICAndTargetSections ( IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table, IN OUT UINT8 **Heap, IN UINTN HandleCount, IN EFI_HANDLE *Handles ) /*++ Routine Description: Fill the NIC and target sections in iSCSI Boot Firmware Table. Arguments: Table - The buffer of the ACPI table. Heap - The heap buffer used to store the variable length parameters such as iSCSI name. HandleCount - The number of handles having iSCSI private protocol installed. Handles - The handle buffer. Returns: None. --*/ { EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control; EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic; EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target; ISCSI_DRIVER_DATA *DriverData; ISCSI_SESSION_CONFIG_DATA *SessionConfigData; ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig; UINT16 *SectionOffset; UINTN Index; UINT16 Length; EFI_MAC_ADDRESS *Mac; ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier; EFI_STATUS Status; // // Get the offset of the first Nic and Target section. // Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1); Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table + Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE))); Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE))); SectionOffset = &Control->NIC0Offset; for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (Handles[Index], &mIScsiPrivateGuid, &IScsiIdentifier); if (EFI_ERROR (Status)) { ASSERT (FALSE); return ; } DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier); SessionConfigData = &DriverData->Session.ConfigData; AuthConfig = &DriverData->Session.AuthData.AuthConfig; // // Fill the Nic section. // NetZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)); Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID; Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION; Nic->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE); Nic->Header.Index = (UINT8) Index; Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL; // // Get the subnet mask prefix length. // Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&SessionConfigData->NvData.SubnetMask); if (SessionConfigData->NvData.InitiatorInfoFromDhcp) { Nic->Origin = IpPrefixOriginDhcp; } else { Nic->Origin = IpPrefixOriginManual; } // // Map the various v4 addresses into v6 addresses. // IScsiMapV4ToV6Addr (&SessionConfigData->NvData.LocalIp, &Nic->Ip); IScsiMapV4ToV6Addr (&SessionConfigData->NvData.Gateway, &Nic->Gateway); IScsiMapV4ToV6Addr (&SessionConfigData->PrimaryDns, &Nic->PrimaryDns); IScsiMapV4ToV6Addr (&SessionConfigData->SecondaryDns, &Nic->SecondaryDns); IScsiMapV4ToV6Addr (&SessionConfigData->DhcpServer, &Nic->DhcpServer); Mac = IScsiGetMacAddress (DriverData->Controller); NetCopyMem (Nic->Mac, Mac, sizeof (Nic->Mac)); // // Get the PCI location of the Nic. // Nic->PciLocation = IScsiGetNICPciLocation (DriverData->Controller); *SectionOffset = (UINT16) ((UINTN) Nic - (UINTN) Table); SectionOffset++; // // Fill the Target section. // NetZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)); Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID; Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION; Target->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE); Target->Header.Index = (UINT8) Index; Target->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BOOT_SELECTED; Target->Port = SessionConfigData->NvData.TargetPort; Target->CHAPType = AuthConfig->CHAPType; Target->NicIndex = (UINT8) Index; IScsiMapV4ToV6Addr (&SessionConfigData->NvData.TargetIp, &Target->Ip); NetCopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun)); // // Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret. // Length = (UINT16) EfiAsciiStrLen (SessionConfigData->NvData.TargetName); IScsiAddHeapItem (Heap, SessionConfigData->NvData.TargetName, Length); Target->IScsiNameLength = Length; Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); if (Target->CHAPType != ISCSI_CHAP_NONE) { // // CHAP Name // Length = (UINT16) EfiAsciiStrLen (AuthConfig->CHAPName); IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length); Target->CHAPNameLength = Length; Target->CHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); // // CHAP Secret // Length = (UINT16) EfiAsciiStrLen (AuthConfig->CHAPSecret); IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length); Target->CHAPSecretLength = Length; Target->CHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); if (Target->CHAPType == ISCSI_CHAP_MUTUAL) { // // Reverse CHAP Name // Length = (UINT16) EfiAsciiStrLen (AuthConfig->ReverseCHAPName); IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length); Target->ReverseCHAPNameLength = Length; Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); // // Reverse CHAP Secret // Length = (UINT16) EfiAsciiStrLen (AuthConfig->ReverseCHAPSecret); IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length); Target->ReverseCHAPSecretLength = Length; Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); } } *SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table); SectionOffset++; // // Advance to the next NIC/Target pair // Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE))); Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE))); } }
/** Fill the NIC and target sections in iSCSI Boot Firmware Table. @param[in] Table The buffer of the ACPI table. @param[in, out] Heap The heap buffer used to store the variable length parameters such as iSCSI name. @param[in] HandleCount Count The number of handles having iSCSI private protocol installed. @param[in] Handles The handle buffer. **/ VOID IScsiFillNICAndTargetSections ( IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table, IN OUT UINT8 **Heap, IN UINTN HandleCount, IN EFI_HANDLE *Handles ) { EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control; EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic; EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target; ISCSI_DRIVER_DATA *DriverData; ISCSI_SESSION_CONFIG_DATA *SessionConfigData; ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig; UINT16 *SectionOffset; UINTN Index; UINT16 Length; EFI_MAC_ADDRESS MacAddress; UINTN HwAddressSize; ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier; EFI_STATUS Status; // // Get the offset of the first Nic and Target section. // Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1); Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table + Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE))); Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE))); SectionOffset = &Control->NIC0Offset; for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (Handles[Index], &gEfiCallerIdGuid, (VOID **)&IScsiIdentifier); if (EFI_ERROR (Status)) { ASSERT (FALSE); return ; } DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier); SessionConfigData = &DriverData->Session.ConfigData; AuthConfig = &DriverData->Session.AuthData.AuthConfig; // // Fill the Nic section. // ZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)); Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID; Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION; Nic->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE); Nic->Header.Index = (UINT8) Index; Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL; // // Get the subnet mask prefix length. // Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&SessionConfigData->NvData.SubnetMask); if (SessionConfigData->NvData.InitiatorInfoFromDhcp) { Nic->Origin = IpPrefixOriginDhcp; } else { Nic->Origin = IpPrefixOriginManual; } // // Map the various v4 addresses into v6 addresses. // IScsiMapV4ToV6Addr (&SessionConfigData->NvData.LocalIp, &Nic->Ip); IScsiMapV4ToV6Addr (&SessionConfigData->NvData.Gateway, &Nic->Gateway); IScsiMapV4ToV6Addr (&SessionConfigData->PrimaryDns, &Nic->PrimaryDns); IScsiMapV4ToV6Addr (&SessionConfigData->SecondaryDns, &Nic->SecondaryDns); IScsiMapV4ToV6Addr (&SessionConfigData->DhcpServer, &Nic->DhcpServer); Nic->VLanTag = NetLibGetVlanId (DriverData->Controller); Status = NetLibGetMacAddress (DriverData->Controller, &MacAddress, &HwAddressSize); ASSERT (Status == EFI_SUCCESS); CopyMem (Nic->Mac, MacAddress.Addr, sizeof (Nic->Mac)); // // Get the PCI location of the Nic. // Nic->PciLocation = IScsiGetNICPciLocation (DriverData->Controller); *SectionOffset = (UINT16) ((UINTN) Nic - (UINTN) Table); SectionOffset++; // // Fill the Target section. // ZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)); Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID; Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION; Target->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE); Target->Header.Index = (UINT8) Index; Target->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BOOT_SELECTED; Target->Port = SessionConfigData->NvData.TargetPort; Target->NicIndex = (UINT8) Index; if (AuthConfig->CHAPType == ISCSI_CHAP_NONE) { Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_NO_CHAP; } if (AuthConfig->CHAPType == ISCSI_CHAP_UNI) { Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_CHAP; } else if (AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL) { Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_MUTUAL_CHAP; } IScsiMapV4ToV6Addr (&SessionConfigData->NvData.TargetIp, &Target->Ip); CopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun)); // // Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret. // Length = (UINT16) AsciiStrLen (SessionConfigData->NvData.TargetName); IScsiAddHeapItem (Heap, SessionConfigData->NvData.TargetName, Length); Target->IScsiNameLength = Length; Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); if (Target->CHAPType != EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_NO_CHAP) { // // CHAP Name // Length = (UINT16) AsciiStrLen (AuthConfig->CHAPName); IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length); Target->CHAPNameLength = Length; Target->CHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); // // CHAP Secret // Length = (UINT16) AsciiStrLen (AuthConfig->CHAPSecret); IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length); Target->CHAPSecretLength = Length; Target->CHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); if (Target->CHAPType == EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_MUTUAL_CHAP) { // // Reverse CHAP Name // Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPName); IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length); Target->ReverseCHAPNameLength = Length; Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); // // Reverse CHAP Secret // Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPSecret); IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length); Target->ReverseCHAPSecretLength = Length; Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table); } } *SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table); SectionOffset++; // // Advance to the next NIC/Target pair // Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE))); Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE))); } }